-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day09.hs
78 lines (62 loc) · 2.24 KB
/
Day09.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
-- Marble Mania
-- https://adventofcode.com/2018/day/9
module Day09
( preprocess,
part1,
part2
) where
import Data.Ord (comparing)
import Data.List (sortBy)
import qualified Data.IntMap as IntMap
import qualified Data.List.PointedList as PL
import Data.List.PointedList.Circular (next, previous)
preprocess :: [String] -> (Int, Int)
preprocess s = (people, marbles)
where people = read (ws !! 0)
marbles = read (ws !! 6)
ws = words (head s)
------------
-- Part 1 --
------------
type Player = Int
type Round = Int
part1 :: (Int, Int) -> [(Player, Int)]
part1 (people, marbles) = take 5
$ sortBy (flip (comparing snd))
$ IntMap.toList
$ IntMap.fromListWith (+)
$ go 1 1 start
where start = let Just list = PL.fromList [0]
in list
go :: Player -> Round -> PL.PointedList Int -> [(Player, Int)]
go p r list
| r > marbles = []
| r `mod` 23 == 0 = (p, r)
: (p, sevenAgo list)
: go ((p+1) `mod` people) (r+1) (prune list)
| otherwise = go ((p+1) `mod` people) (r+1) (insert r list)
-- Skip a marble then insert a new one after it
insert :: Int -> PL.PointedList Int -> PL.PointedList Int
insert n = PL.insert n . next
-- Get the value of the marble 7 to the left
sevenAgo :: PL.PointedList Int -> Int
sevenAgo = get . (!! 7) . iterate previous
where get (PL.PointedList _ f _) = f
-- Drop the marble 7 to the left, retain the new focus there
prune :: PL.PointedList Int -> PL.PointedList Int
prune = delete . (!! 7) . iterate previous
where delete l = let Just list = PL.delete l
in list
------------
-- Part 2 --
------------
part2 :: (Int, Int) -> [(Player, Int)]
part2 = part1 . fmap (*100)
{-
jason@ubuntu16:~/aoc-2018$ time stack exec aoc2018-exe
[(167,361466),(297,361017),(90,359588),(374,357662),(298,353807)]
[(45,2945918550),(482,2943153973),(221,2943015432),(336,2942966844),(423,2941621319)]
real 0m13.298s
user 0m11.880s
sys 0m0.720s
-}