blob: 1efe53e8c41b8f0bbf98187839823a16d1bc03d8 (
plain)
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
|
module Main where
import System.Environment (getArgs)
import Text.Printf
import qualified Data.IntMap.Strict as Map
-- This does the same thing as 15a, it's just done in a more memory-optimised way.
-- Parse a string, with one number per line
parseInput :: String -> [Int]
parseInput = map read . lines
-- Parse a file given the path
-- Returns list of instructions
parseFromFile :: String -> IO [Int]
parseFromFile s = do
contents <- readFile s;
return $ parseInput contents;
-- Generate a map from the list of initial numbers
mapFromInitial :: [Int] -> Map.IntMap Int
mapFromInitial xs = foldr (\(i,x) m -> Map.insert x i m) Map.empty (zip [0..] xs)
-- Run till the given turn, this time using a map to store last occurences.
-- This means we don't get the full 'log', just the final turn.
-- map, prev, current index, stopping len
runTillTurn :: Map.IntMap Int -> Int -> Int -> Int -> Int
runTillTurn occ prev i n | i >= n = prev
| otherwise = runTillTurn occ' curr (i + 1) n
where curr = case Map.lookup prev occ of
Nothing -> 0
Just x -> (i - 1) - x
occ' = Map.insert prev (i - 1) occ
-- runghc 15b.hs inputs/day15
main :: IO ()
main = do
args <- getArgs;
ns <- parseFromFile (head args);
let x = runTillTurn (mapFromInitial ns) (last ns) (length ns) 30000000;
printf "Answer = %d\n" x :: IO ();
return ();
|