15
[aoc20.git] / 15 / one.icl
1 module one
2
3 import Data.Maybe
4 import StdEnv
5 from Data.IntMap.Strict import :: IntMap
6 import qualified Data.IntMap.Strict as DM
7
8 input = [6,13,1,15,2,0]
9 input2 = [0,3,6]
10
11 Start = (one, two)
12
13 one = speak 2020 input
14 two = speak 30000000 input
15
16 //Old part I version
17 //speak :: Int [Int] -> Int
18 //speak num inp = speak` num (reverse inp)
19 //where
20 // speak` 0 spoken = spoken!!length inp
21 // speak` idx [ls:spoken] = case [i\\i<-[0..] & s<-spoken | s == ls] of
22 // [] = speak` (idx-1) [0,ls:spoken]
23 // [i:_] = speak` (idx-1) [i+1,ls:spoken]
24
25 speak :: Int [Int] -> Int
26 speak num inp = speak` (length inp) (last inp)
27 ('DM'.fromList [(num, idx)\\idx<-[0..] & num <-init inp])
28 where
29 speak` :: !Int !Int !(IntMap Int) -> Int
30 speak` idx last spoken
31 | idx == num = last
32 = speak` (idx+1) (maybe 0 (\i->idx-i-1) ('DM'.get last spoken)) ('DM'.put last (idx-1) spoken)