--- /dev/null
+module one
+
+import Data.Maybe
+import StdEnv
+from Data.IntMap.Strict import :: IntMap
+import qualified Data.IntMap.Strict as DM
+
+input = [6,13,1,15,2,0]
+input2 = [0,3,6]
+
+Start = (one, two)
+
+one = speak 2020 input
+two = speak 30000000 input
+
+//Old part I version
+//speak :: Int [Int] -> Int
+//speak num inp = speak` num (reverse inp)
+//where
+// speak` 0 spoken = spoken!!length inp
+// speak` idx [ls:spoken] = case [i\\i<-[0..] & s<-spoken | s == ls] of
+// [] = speak` (idx-1) [0,ls:spoken]
+// [i:_] = speak` (idx-1) [i+1,ls:spoken]
+
+speak :: Int [Int] -> Int
+speak num inp = speak` (length inp) (last inp)
+ ('DM'.fromList [(num, idx)\\idx<-[0..] & num <-init inp])
+where
+ speak` :: !Int !Int !(IntMap Int) -> Int
+ speak` idx last spoken
+ | idx == num = last
+ = speak` (idx+1) (maybe 0 (\i->idx-i-1) ('DM'.get last spoken)) ('DM'.put last (idx-1) spoken)