|
1 | 1 | import Text.Parsec
|
2 | 2 | import Parsing
|
3 |
| -import Generic |
4 |
| -import Data.List |
5 |
| -import Chart2d |
6 | 3 | import Data.Char
|
7 | 4 | import qualified Data.HashMap.Strict as M
|
8 | 5 |
|
9 | 6 | main :: IO ()
|
10 | 7 | main = optimisticInteract readD solve
|
11 | 8 |
|
12 |
| -readD :: Parser [String] |
| 9 | +readD :: Parser [(String, Maybe Int)] |
13 | 10 | readD = readStep `sepBy` char ','
|
14 | 11 | where
|
15 | 12 | readStep = do
|
16 | 13 | many newline
|
17 |
| - s <- many1 $ noneOf ",\n" |
18 |
| - many newline |
19 |
| - return s |
| 14 | + s <- many1 alphaNum |
| 15 | + c <- choice [readEq, readMin] |
| 16 | + return (s, c) |
| 17 | + |
| 18 | + readEq = (Just . fromInteger) <$> (char '=' >> number) |
| 19 | + readMin = char '-' >> pure Nothing |
20 | 20 |
|
21 | 21 | solve input = unlines [
|
22 | 22 | show $ input
|
23 |
| - , show $ M.toList . M.filter (not . null) $ algo input |
24 | 23 | , show $ answer
|
25 | 24 | ]
|
26 | 25 | where
|
27 |
| - answer = sum . map score $ end |
| 26 | + answer = sum . map score . M.toList . M.map scoreContent $ algo input |
28 | 27 | where
|
29 |
| - score (box, l) = (1+box) * sum (zipWith (*) [1..] (map snd l)) |
| 28 | + scoreContent c = sum . zipWith (*) [1..] $ map snd c |
| 29 | + score (box, contentScore) = (1+box) * contentScore |
30 | 30 |
|
31 |
| - end = M.toList . M.filter (not . null) $ algo input |
| 31 | + hash str = foldl updateHash 0 str |
| 32 | + where |
| 33 | + updateHash v c = (v + ord c) * 17 `rem` 256 |
32 | 34 |
|
33 |
| - algo instrs = helper (M.fromList $ zip [0..255] (repeat [])) instrs |
| 35 | + algo instrs = helper startState instrs |
34 | 36 | where
|
35 |
| - helper m (i:is) = helper m' is |
36 |
| - where |
37 |
| - (box, op) = getBox 0 i |
38 |
| - label = getLabel i |
39 |
| - m' = case op of |
40 |
| - Just fl -> eqal m label fl box |
41 |
| - Nothing -> dash m label box |
42 |
| - helper m [] = m |
| 37 | + startState = (M.fromList $ zip [0..255] (repeat [])) |
43 | 38 |
|
44 |
| - dash m l box = M.insert box content' m |
| 39 | + helper m ((label,op):is) = helper m' is |
45 | 40 | where
|
46 |
| - content = m M.! box |
47 |
| - content' = filter ((/=l) . fst) content |
| 41 | + box = hash label |
| 42 | + m' = M.adjust (updateBox label op) box m |
| 43 | + helper m [] = m |
48 | 44 |
|
49 |
| - eqal m l fl box = M.insert box content' m |
| 45 | + updateBox l (Just fl) content = insertLens content |
50 | 46 | where
|
51 |
| - content = m M.! box |
52 |
| - content' = insertLens content |
53 |
| - |
54 | 47 | insertLens ((ol, ofl):cs)
|
55 |
| - | l == ol = (l, fl):cs |
| 48 | + | l == ol = (l, fl):cs |
56 | 49 | | otherwise = (ol, ofl):insertLens cs
|
57 | 50 | insertLens [] = [(l,fl)]
|
58 |
| - |
59 |
| - getLabel i = takeWhile (not . (`elem` "=-")) i |
60 |
| - |
61 |
| - getBox :: Int -> String -> (Int, Maybe Int) |
62 |
| - getBox v (c:cs) |
63 |
| - | c == '=' = (v, Just $ read cs) |
64 |
| - | c == '-' = (v, Nothing) |
65 |
| - | otherwise = getBox ((v + ord c) * 17 `rem` 256) cs |
| 51 | + updateBox l Nothing content = filter ((/=l) . fst) content |
0 commit comments