Compare commits
	
		
			No commits in common. "0d2db659cac210e4d1610263dffd58a7fd453e1a" and "2a2936ef02d813355a8375ea2269a4bbb8f993d1" have entirely different histories.
		
	
	
		
			0d2db659ca
			...
			2a2936ef02
		
	
		
| @ -1,198 +0,0 @@ | ||||
| pub trait Functor<T>[Self<T>] | ||||
|     fn map(mapper: fn (t: &T) -> U) -> Self<U> | ||||
| end | ||||
| 
 | ||||
| pub trait Sum<T> | ||||
|     fn sum() -> T | ||||
| end | ||||
| 
 | ||||
| pub trait Default | ||||
|     fn default() -> Self | ||||
| end | ||||
| 
 | ||||
| pub trait Iter<T> | ||||
|     ref fn iter() -> Iterator<&T> | ||||
| end | ||||
| 
 | ||||
| pub trait ConsIter<T> | ||||
|     cons fn consIter() -> Iterator<T> | ||||
| end | ||||
| 
 | ||||
| pub int Iterator<T> | ||||
|     fn next() -> Option<T> | ||||
| end | ||||
| 
 | ||||
| pub int List<T> impl Functor<T>, Iter<T>, ConsIter<T> | ||||
|     fn add(t: T) -> Void | ||||
| end | ||||
| 
 | ||||
| pub class ArrayList<T> : List<T> | ||||
|     let mut currentIndex = 0 | ||||
|     let mut inner: Array<T> | ||||
| 
 | ||||
|     ctor(capacity: Int) where T impl Default | ||||
|         inner = Array(capacity, Default[T]) | ||||
|     end | ||||
| 
 | ||||
|     ctor(capacity: Int, init: fn () -> T) | ||||
|         inner = Array(capacity, init) | ||||
|     end | ||||
| 
 | ||||
|     impl fn add(t: T) -> Void | ||||
|         inner[currentIndex] = t | ||||
|         let currentCapacity = inner.capacity() | ||||
|         currentIndex++ | ||||
|         if currentIndex == currentCapacity then | ||||
|             let oldInner = std::mem::take(inner, Array(currentCapacity * 2)) | ||||
|             arrays::copy(oldInner, inner) | ||||
|         end | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| impl Functor[ArrayList<*>] | ||||
|     fn map(mapper: fn (t: &T) -> U) -> Self<U> | ||||
|         let mut result: Array<U> = Array(inner.capacity) | ||||
|         for (i, t) in inner.iterWithIndex() do | ||||
|             result[i] = mapper(t) | ||||
|         end | ||||
|         result | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| impl Sum[Self = List<Int>, T = Int] | ||||
|     fn sum() -> Int | ||||
|         let mut result = 0 | ||||
|         for value in self do | ||||
|             result += value | ||||
|         end | ||||
|         result | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| impl<T impl Default> Default[ArrayList<T>] | ||||
|     const DEFAULT_SIZE = 10 | ||||
| 
 | ||||
|     static fn default() -> Self = ArrayList(DEFAULT_SIZE, Default[T]::default) | ||||
| end | ||||
| 
 | ||||
| impl<T> Iter[ArrayList<T>] | ||||
|     ref fn iter() -> Iterator<&T> | ||||
|         let mut currentIndex = 0 | ||||
|         return { | ||||
|             if currentIndex < inner.count() then | ||||
|                 let item = inner[currentIndex] | ||||
|                 currentIndex++ | ||||
|                 Some(item) | ||||
|             else | ||||
|                 None | ||||
|             end | ||||
|         } | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| impl<T impl Default> ConsIter[ArrayList<T>] | ||||
|     cons fn consIter() -> Iterator<T> | ||||
|         let mut currentIndex = 0 | ||||
|         let inner = std::mem::take(inner, std::arrays::empty()) | ||||
|         return |inner| { | ||||
|             if currentIndex < inner.count() then | ||||
|                 let item = inner.take(currentIndex, Default[T]::default) | ||||
|                 currentIndex++ | ||||
|                 Some(item) | ||||
|             else | ||||
|                 None | ||||
|             end | ||||
|         } | ||||
|     end | ||||
| end | ||||
| 
 | ||||
| pub enum Option<T> | ||||
|     Some(t: T), | ||||
|     None | ||||
| end | ||||
| 
 | ||||
| impl Default[Option<*>] | ||||
|     static fn default() -> Self = None | ||||
| end | ||||
| 
 | ||||
| pub trait HashCode | ||||
|     fn hash() -> USize | ||||
| end | ||||
| 
 | ||||
| pub int Map<K, V> | ||||
|     fn get(key: K) -> Option<&V> | ||||
|     fn put(key: K, value: V) -> Void | ||||
|     fn take(key: K) -> Option<V> | ||||
| end | ||||
| 
 | ||||
| pub class HashMap<K, V> : Map<K, V> | ||||
|     where K impl HashCode | ||||
| 
 | ||||
|     const LOAD_FACTOR = 0.8 | ||||
| 
 | ||||
|     class Entry<K, V>(pub key: K, pub value: V) end | ||||
| 
 | ||||
|     let mut buckets: List<List<Option<Entry<K, V>>>> = ArrayList(10) | ||||
| 
 | ||||
|     fn getBucketIndex(key: K) -> Int | ||||
|         HashCode[K].hash(key) % buckets.size() | ||||
|     end | ||||
| 
 | ||||
|     fn getCount() -> Int = buckets.map { it.count() }.sum::<Int>() | ||||
| 
 | ||||
|     fn getCapacity() -> Int = buckets.map { it.capacity() }.sum::<Int>() | ||||
| 
 | ||||
|     fn redistribute() | ||||
|         use std::mem::take | ||||
|         let oldBucketCapacity = buckets.first().unwrap().capacity() | ||||
|         let oldBuckets = take(buckets, ArrayList(oldBucketCapacity * 2)) | ||||
|         for bucket in oldBuckets.consIter() do | ||||
|             for entry in bucket.consIter() do | ||||
|                 let newIndex = getBucketIndex(entry.key) | ||||
|                 let newBucket = buckets[newIndex] | ||||
|                 newBucket.add(Entry(entry.key, entry.value)) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| 
 | ||||
|     impl fn put(key: K, value: V) -> Void | ||||
|         let bucket = buckets[getBucketIndex(key)] | ||||
|         bucket.add(Entry(key, value)) | ||||
|         if getCount() / getCapacity() > LOAD_FACTOR then | ||||
|             redistribute() | ||||
|         end | ||||
|     end | ||||
| 
 | ||||
|     impl fn get(key: K) -> Option<&V> | ||||
|         let bucket = buckets[getBucketIndex(key)] // bucket: &List<Entry<K, V>> | ||||
|         bucket.find { it.key == key } // it: &Entry<K, V> | ||||
|             .map { it.value } // it.value: &V | ||||
|     end | ||||
| 
 | ||||
|     impl fn take(key: K) -> Option<V> | ||||
|         let mut bucket = buckets.take(getBucketIndex(key)) // bucket: List<Entry<K, V>> | ||||
|         if bucket.findIndex { it.key == key } is Some(index) then | ||||
|             let entry = bucket.take(index) // entry: Entry<K, V> | ||||
|             Some(entry.value) // moved out of Entry | ||||
|         else | ||||
|             None | ||||
|         end | ||||
|     end | ||||
| 
 | ||||
| end | ||||
| 
 | ||||
| impl HashCode for String | ||||
|     fn hash() -> Int = todo() | ||||
| end | ||||
| 
 | ||||
| class Greeter(pub greeting: String) end | ||||
| 
 | ||||
| fn main() | ||||
|     let greeterMap: Map<String, Greeter> = HashMap() | ||||
|     greeterMap.put("friendly", Greeter("Friendly hello!")) | ||||
|     greeterMap.put("nasty", Greeter("Nasty hello!")) | ||||
|     let friendlyGreeter: &Greeter = greeterMap.get("friendly").unwrap() | ||||
|     println friendlyGreeter.greeting | ||||
|     let nastyGreeter: Greeter = greeterMap.take("nasty").unwrap() | ||||
|     println nastyGreeter.greeting | ||||
| end | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user