Compare commits

...

10 commits

41 changed files with 7515 additions and 2 deletions

View file

@ -1,5 +1,5 @@
! Copyright (C) 2024 Julien (adyxax) Dessaux.
! See https://factorcode.org/license.txt for BSD license.
! See https://git.adyxax.org/adyxax/advent-of-code/tree/LICENSE for EUPL license.
USING: tools.test aoc.2024.02.private ;
IN: aoc.2024.02.tests

View file

@ -1,5 +1,5 @@
! Copyright (C) 2024 Julien (adyxax) Dessaux.
! See https://factorcode.org/license.txt for BSD license.
! See https://git.adyxax.org/adyxax/advent-of-code/tree/LICENSE for EUPL license.
USING: combinators.short-circuit.smart grouping io io.encodings.utf8 io.files
kernel math math.order math.parser prettyprint sequences splitting ;
IN: aoc.2024.02

View file

@ -0,0 +1,7 @@
! Copyright (C) 2024 Julien (adyxax) Dessaux.
! See https://git.adyxax.org/adyxax/advent-of-code/tree/LICENSE for EUPL license.
USING: tools.test aoc.2024.03.private ;
IN: aoc.2024.03.tests
{ 161 } [ "example" part1 ] unit-test
{ 48 } [ "example2" part2 ] unit-test

View file

@ -0,0 +1,113 @@
! Copyright (C) 2024 Julien (adyxax) Dessaux.
! See https://git.adyxax.org/adyxax/advent-of-code/tree/LICENSE for EUPL license.
USING: accessors io.encodings.utf8 io.files kernel make math math.parser
multiline peg peg.ebnf peg.parsers prettyprint regexp sequences ;
IN: aoc.2024.03
<PRIVATE
: load_input ( filename -- string )
"~/git/adyxax/aoc/2024/03-Mull_It_Over/"
swap append utf8 file-contents ;
! ----- Let's do part1 with regexes --------------------------------------------
: get_muls ( string -- instructions )
R/ mul\(\d+,\d+\)/ all-matching-subseqs ;
: mul>result ( string -- n )
R/ \d+/ all-matching-subseqs
[ string>number ] map
product ;
: part1 ( filename -- n )
load_input
get_muls
[ mul>result ] map
sum ;
! ----- And part2 with a real parser -------------------------------------------
TUPLE: computer total multiplying? ;
GENERIC: compute ( computer item -- computer )
TUPLE: do ;
M: do compute
drop
t >>multiplying? ;
TUPLE: dont ;
M: dont compute
drop
f >>multiplying? ;
TUPLE: mul opX opY ;
M: mul compute
over multiplying?>>
[ [ opX>> ] [ opY>> ] bi *
over total>> + >>total ]
[ drop ]
if ;
TUPLE: nop ;
M: nop compute
drop ;
: parse_do ( -- parser )
"do()" token hide [ drop do boa ] action ;
: parse_dont ( -- parser )
"don't()" token hide [ drop dont boa ] action ;
: parse_mul ( -- parser )
[ "mul(" token hide ,
integer-parser ,
"," token hide ,
integer-parser ,
")" token hide ,
] seq*
[ first2 mul boa ] action ;
: parse_nop ( -- parser )
any-char hide [ drop nop boa ] action ;
PEG: parse_input ( string -- ast )
parse_do
parse_dont
parse_mul
parse_nop
4choice
repeat1 ;
: part2 ( filename -- n )
load_input
parse_input
0 t computer boa
swap
[ compute ] each
total>> ;
! ----- part2 again with an EBNF parser this time ------------------------------
EBNF: parse_grammar [=[
number=[0-9]+ => [[ string>number ]]
mul = "mul("~ number:a ","~ number:b ")"~ => [[ a b mul boa ]]
dontblock = "don't()" (!("do()") .)* "do()" => [[ nop boa ]]
ignore = .~ => [[ nop boa ]]
program=(dontblock|mul|ignore)+
]=]
: part2bis ( filename -- n )
load_input
parse_grammar
0 t computer boa
swap
[ compute ] each
total>> ;
PRIVATE>
: aoc202403 ( -- )
"input" part1 .
"input" part2 .
"input" part2bis . ;
MAIN: aoc202403

View file

@ -0,0 +1,4 @@
AAAA
BBCD
BBCC
EEEC

View file

@ -0,0 +1,5 @@
OOOOO
OXOXO
OOOOO
OXOXO
OOOOO

View file

@ -0,0 +1,10 @@
RRRRIICCFF
RRRRIICCCF
VVRRRCCFFF
VVRCCCJFFF
VVVVCJJCFE
VVIVCCJJEE
VVIIICJJEE
MIIIIIJJEE
MIIISIJEEE
MMMISSJEEE

View file

@ -0,0 +1,5 @@
EEEEE
EXXXX
EEEEE
EXXXX
EEEEE

View file

@ -0,0 +1,6 @@
AAAAAA
AAABBA
AAABBA
ABBAAA
ABBAAA
AAAAAA

View file

@ -0,0 +1,80 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
example1ExpectedOutput = 140
example2ExpectedOutput = 772
example3ExpectedOutput = 1930
type Line = VU.Vector Char
type Input = V.Vector Line
type Parser = Parsec Void String
parseLine :: Parser Line
parseLine = do
line <- some letterChar <* eol
return $ VU.generate (length line) (line !!)
parseInput' :: Parser Input
parseInput' = do
line <- some parseLine <* eof
return $ V.generate (length line) (line !!)
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Coord = (Int, Int)
type Visited = M.Map Coord ()
compute :: Input -> Int
compute input = fst $ V.ifoldl' compute' (0, M.empty) input
where
compute' :: (Int, Visited) -> Int -> Line -> (Int, Visited)
compute' (acc, visited) y line = VU.ifoldl' (compute'' y) (acc, visited) line
compute'' :: Int -> (Int, Visited) -> Int -> Char -> (Int, Visited)
compute'' y acc@(cost, visited) x c = case M.lookup (x, y) visited of
Just _ -> acc -- already processed
Nothing -> let (area, perimeter, visited') = enclose c (0, 0, visited) (x, y) in (cost + area * perimeter, M.union visited visited')
enclose :: Char -> (Int, Int, Visited) -> Coord -> (Int, Int, Visited)
enclose c acc@(area, perimeter, visited) (x, y) = case M.lookup (x, y) visited of
Just _ -> acc
Nothing -> case input V.!? y of
Just line -> case line VU.!? x of
Just c' -> let n = neighbors visited c x y in L.foldl' (enclose c) (1 + area, 4 - length n + perimeter, M.insert (x, y) () visited) n
Nothing -> (0, 0, visited)
Nothing -> (0, 0, visited)
neighbors :: Visited -> Char -> Int -> Int -> [Coord]
neighbors visited c x y = filter (valid visited c) [ (x-1, y), (x+1, y), (x, y-1), (x, y+1) ]
valid :: Visited -> Char -> Coord -> Bool
valid visited c (x, y) = case input V.!? y of
Just line -> case line VU.!? x of
Just c' -> c == c'
Nothing -> False
Nothing -> False
main :: IO ()
main = do
example1 <- parseInput "example1"
let exampleOutput = compute example1
when (exampleOutput /= example1ExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show example1ExpectedOutput)
example2 <- parseInput "example2"
let exampleOutput = compute example2
when (exampleOutput /= example2ExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show example2ExpectedOutput)
example3 <- parseInput "example3"
let exampleOutput = compute example3
when (exampleOutput /= example3ExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show example3ExpectedOutput)
input <- parseInput "input"
print $ compute input

140
2024/12-Garden_Groups/input Normal file
View file

@ -0,0 +1,140 @@
QQQQQQQQQQQQQQQQQQQWWWWWWWWRYYYYYYYYYYOOOOMOYYYYBBYYYYBBBGGGGGVVVVVNNNNPPOOOOOOOOOOOOOGGGGGGGGGGKTTTTTTTVVVVKKKKKKKKKKKKKKKKPDPBBBBBBBBBBBBB
QQAQAQQQQQQQQQQQQMMWWWWWWWWRRRYRYOOYOOOOOOOOHHHYBBBYBBBBBGGGVGVVVVVNPPPPPPOOOOOOOOOOOGGQGGGGGGGGGTTTTTTTVVKKKKKKKKKKKKKKKKKKPPPPPBBBBBBBBBBB
QQAAAQQQQQQQQQQQMMMWWWWMMWRRRRYRRROOOOOOOOOHSHIBBBBBBBBBBVGGVVVVVVRPKKPPPPOOOOPPPOOOOGGGGGGGGGGGGTTTTTTTVVVKKKKKKKKKKKKKJJKKPPPBBBBBBBBBBBBB
QAAAAAUQJQQQQQQQQMMMMWMMMMRRRRRRRRROOOOOOOOHHHBBBBBBBBBBBVVVVVVVVVVPPPPPPPPPPOPPOOOOOGTTTTTTTTTTTTTTTTTTVVVKKKKRRKKKKKKKKJPPPBBBBBBBFFFBBBBB
AAAAAAUUJQQQQQQQQMMMMWMMMMRRRRRRRRROOOOOOOOHHHHBBBBBBBBBBVVVVVVVVVVVVPPPPPPPPPAPPPPGGGTTTTTTTTTTTTTTTTVVVVVVKKKKRKRKKRKJJJPPBBBBBBFFFFBBBBBB
AAAAAAAAJQQQQQQMMMMMMMMMMMRRRRRRRRROOOOOOOOHHHDDDDDBDBBBBBVVVVVVVVVPPPPPPPPPPPPPPPPGGGTTTTTTTTTTTTTTTTVVVVVVVKKRRRRRKRRJJJJBBBBBBBBFFFFFBFBB
AAAAAAJJJJQQQQQQRAMMMMMMMMRRRRRRRRROOOUOOOHHHHDDDDDDDDBBBBVVVVVVVVVVPPPPPPPPPPPPPPPGGGGGGGGGGGTTTTTTTTVVVAAVMRRRRRRRRRRJJJJJJBBBBBFFFFFFFFFS
AAAAAJJJJJQQQQQAAAAMMMMMMZZRNRRRRRRRRRUOOOHHDDDDDDDDDDDBBBBBBVVVVVVPPPPPPPPPPPPGGGUGGGGGGGGGGGTTTTTTTTVVVARRRRRRRRRRRRRJJJJJBBBBBBFFFFFFFFFS
JAAAJJJJJJQQQQQAAAAAAMAAZZZRRRRRRRRRRRUOOHHHHHDDDDDDDHHBBBHBBUUUUVVVPPPPPPPPPPPPGGUGGGGGGGGGGGTTTTTTTTAVVARRRRRRRRRRRRJJJJJJBBBBFFFFFFFFFUUS
JAAJJJJJJJJQJLAAAAAAAAAAAZURUUURRRRRRRRRRHHHHHHHHDHDHHHHHHHBBHUUUUUVPPPPPPPPPPPGGGGGGGGGGGGGGGGGXGGAAAAAAARRRRRRRRRRRRRJJJJJBBJBFFFFFFFFFFFS
JJJJJJJEJJJJJAAAAAAAAAAAAUUVUUUURRRRRRRRRRHHHHHHHHHDHHHHHHHBHHUUUUUUPPPPPPPPPPPPGGGGGGGGGGGGGGGGGGGGAAAAAARRRRRRRRRRRRRRVJJJJBJJJFFFFSSSSSSS
JJJJJJJEEEEEEAAAAAAAAAAAAUUUUUUUURRRRRRRNRRHHHHHHHHHHHHHHHHHHHUUUUUUUPPPPPPPPPPPGGGGGGGGGGGGPGGGGGGGGGAAAAARRRRRRRRRRRRRVJJJJJJJSSFFFSSSSSSS
JJJJJEEEEEEEEEAIIIIIIAAAFFUUUUUUUUZRRRRRNPPHHHHHHHHHHHHHHHHHHHHUUUUPPPPFPPFPPPPPPBBGGGBGGGGGGGGGGGGGGGAAAAAAAAARRRRRRRRYVJJJJJJSSSSSSSSSSSSS
JJJJJJEIIIIIIIIIIIIIIAAAFFFUUUUUUURRRRNNNPPPPHHHHHHHHHHHHHHHHHUUUUUPPFFFFFFFPBBBBBBBBBBBBBGGGGGGGGGGGGGAAAAAAAAMRRRRRRRRVVVVJJSSSSSSSSSSSSSS
JJJJJJJIIIIIIIIIIIIIIAAFFFFUUUUUUUUHUNNPPZPPPYHHHYHHHHHIHHHHHHHUUUUUOFFFFFFFBBBBBBBBBBBBBBBBGGGGGGGGGGGGGAAAAARRRRRRVVVVVVVVVJSSSSSSSSSSSSSS
JJJJJJJIIIIIIIIIIIIIIAAFFFFFUUUUUUUUUPPPPPPPPYYYYYHHHHHHRHHHHHHUUUUUOOFFFFFFBBBBBBBBBBFFBBBBBGGGGGGUUGGUAAAAAAARRRRRRVVVVVVVASSSSSSSSSSSSSSS
JJJJEJJIIIIIIIIIIIIIIFFFFFFFFUUUUUUUUUUUPVPPPYYYYYHHHHRRRHHHHHHRROOOOFFFFFXBBBBBBBBBBFFFFBBBGGGGUUUUUUUUAAAVVVVRRRRRVVVVVVVVAASSSSSSSSSSSSSS
JJJJEEEIIIIIIIIIIIIIIFFFFFFFFFFUUUUUUUVUKVPPPYYYXXHHPHRRRRRRRRRRROOOOOOFFFFBBBBBBBBBBFFFFBBBBGGGUUUUUUURAAAVVVVJJRVVVVVVVVVVVASIVGSSSSSMSSSS
VJJJHEEIIIIIIIIIIIIIIFFFFFFFFFFUUUUUVVVKKVVVXXXXXQNHHHRRRRRRRRRRROOOOOFFFFSBBBBBBBBBBFFFFBBBIGGUUUUUUUNUUEEVVVVVVVVVVVVVVVVVVSSVVSSSSSSMMMSS
VJJJJTTIIIIIIIIIIIIIIFFFFFFFFFFUUUUUVVVVVVVVXXQQQQQHHRRRRRRRRRRRRROOOOOOOFSBBBBJJBBBJFFFFFIBIGUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVSSSSSSSMMSS
VVVJTTEEEIIIIIIIIIIFFFFFFFFAFUUUVVVUVVVVVVVVXXXXQQQQHRRRGGRRRRRRRROLOOOOOOBBBJJJJJJJJFFFFFIIIIIUUUUUUUUUUUUVVVVVVVVVVVVVQVVVVVVVWWWSWWMMMMSS
VVVTTTTEEIIIIIIIIIIFFFFFFFFFFUUUUVVVVVVVVVVXXXXQQQQQQRRGGGRRNRRRRROLOOLLOOBBBEEJJJJJJJJOFFIIIIUUUUUUUUUUUUUAVVVVVVVQQQQQQQQQVVVWWWWWWWMKKMMM
VVVTEEEEEIIIIIIIIIIFFFFFFFFFFUUUVVVVVVVVVVVXXXXXQQQQQQQGGGGNNRNNNRRLLOOLOOOLBEEJJJJJOOOOFFFIIIUUUUUUUUUUUUUQVQQQVVVQQQQQQQQQQQQWWWWWWWMMMMMM
VVVVVEEEEIIIIIIIIIIFFFFFFFFUUUUVVVVVVVVVVXXXXXXXQQQQQLLLGLLNNNNNNNNLLLLLLLLLBBZZZJJJJOOIFFIIIIIUUUUUUUUUUUUQQQQQQQVQQQQQQQQQQQQWWWWWWWMMMMMM
VVVVEEEEEIIIIIIIIIIMFFFFFUFUUVUVVVVVVVVVVVVVXXQQQQQQQLLLGLNNNNNNNNNNLLLLLLLLZZZZZZZZIIIIIFIIIIIIIUUUUUUUUUQQQQQQQQQQQQQQQYQYYWWWWWWMMMMMMMMM
VHVHPEEIIIIIIIIIIIIMMMMFUUUUUVVVVVVVVVVVVVVVXXXQQQQMQMLLLLLNNNNNNNNNNLLLLLLLZZZZZZZZZIIIIIIIIIIIUUUUUUUUUUUQQQQQQQQQQQQQQQQQYWWNNNWWWMMMMMMM
VHHHHHHHIIIIIIIIIIIMMMMFFUUUUVVVVVVVVVVVVVXXXXXQQMQMNMMMMLLNNNIINNNNLLLLLLLLLZZZZZZZZPIIIIIIIIUUUUURRRUUUUQQQQQQQQQQQQQQQSSQWWWZNNNWWMMMMMMM
VHHHHHHIIIIIIIMMMMMMMMMUUUUUVVVVVVVVVVVVVVVXXXXXXMMMMMMMIIIIIIIINNNLLLLLLLLLLZZZZZZZZIIIIIIIIIUUUUURRRUUUWQQQQQQQQQQQQQQSSSSWWSZNNNWMMMMMMMM
HHHHHHHHIIIIIIMMMMMMMMMSUMUUUULVYVVVVVVLVVBEEXXXXMMMMMMMIIIIIIINNLLLLLLLLLLLLLZZZZZZZGIIIIIIIIUUUURRRRRSUUUQQQQQQQSSSSSSSSSSSSSSSNWWWMMMMMMM
HHHHHHGGGIVVMMMMMMMMSMSSSUUUUULVYVVVVVVLEEEEEEEEEEMMMMMMMIIIIIIIILLLLLLLLLLLLLLLZZZGGGIIIIIIIIRRURRRRRRRRQQQQQQQQQQSSSSSSSSSSLOOOOOOOMMMMMMM
HHHHHHHHHHHHHPMMMMMMSSSSSUUUUULSSHVVVVVSSFFFEEEEEEMMMMMIIIIIIIRRRRLLLLLLLLLLLLLLZZZCGGIIIIIIIIRRRRRRRRRRRRQRRQQQQQTSYSSSSSSSSLOOOOOOOMMMMMMM
HHHHHHHHUHHHHPPPMMMMMSSSSUUUULLSSHVVVVVSSSFSEEEEEEEMMMIIIIIIIIRRRRRRLLLLLLLLLLLLCZCCGIIIIIIIIIIRRRRRRRRRRRRRRRQTTTTYYSSSSSSSSSOOOOOOOSSMMMMM
HHHHHHHUUUHHHHPPMMMBBJSJJJJKULLSSSSSSSSSSSSSEEEEEEMMMMEEIIIIIIRRRRRRLLLLLLLLLLLLCCCCGIIIIIIIIYRRRRRRRRRRRRRRRRQITTTYSSSSSSGSSSOOOOOOOSSMMMRR
HHHHHHHHUHHHPPPPPPMJJJJJJKKKULSSSSSSSSSSSSSSEEEEEEEEEEEEIIIIIIRRRRRLLLLLLLLGGPPGGCGGGIIIIIIIYYYRRRRRRRRRRRRRRRRTTTTTSSXXXSGSSSOOOOOOOSSSSSRR
HHHHHHHHUHHHHPPPPPPPJJJJJKKKULLSSSSSSSSSSSSSEEEEEEEEEEEIIRIIIIRRRRRRLLLLLLJGGGGGGGGGGIMIIIIYYRRRRRRRRRRRRRRRRRRRTTTXXPXXXXXXBSSSOOOOOSSSSSSS
HHHHHHHHHHHHPPPPPPJJJJJJJKKKKSSSSSSSSSSSSSSSEEEEEEEEEEESIRRRRRRRRRRRRRRLLLJGGGGGGGGGGMMIIXYYYRRRRRRRRRRRRRRRRRRTTTXXXXXXOOOOOOOOOOOOOSSSSSSZ
HHHHHHHHHHPPPPPPPPPJJJJJJKKKKSSSSSSSSSSSSSSEEEEEEEEECCECRRRRRRRRRRRRRRRRLLJGGGGGGGGGGMMIIXYYYYRRRRRQRRRRRRRRRTTTTTXXXXXXOOOOOOOOOOOOOSSSSSSZ
HHHHHHHZZXZPPPPPPJPPJJJJJKKKSSSSSSSSSSSSSSSSEEECECCCCCCCCRRRRRRRRRRRRRRRGGGGGGGGGGGGGXMXXXYXKKKKRRKQQQRRRTTFRTTTTTXXXXXXOOOOOOOOOOOOOSSSSSSZ
HHHHHHZZZZZZZPPPPJJJJJJJJLLKSSSZZSSSSSSSSSEEEEECCCCCCCCCCRRRRRRRBRRRHHRRRGGGGGGGGGUUUXXXXXXXXKKKXKKRRRROROTTTTTTTXXXXXXBOOOOOOOOOOOOOSSSSSSS
HHHHHHHZZZZZZZZPPJJJJJJJJLLLOOSZZZTTSSSWSSEEEEEECCCCCCCCRRRRRRRRBRRHHRRGGGGGGGGGGGUUUXXXXXXXXXKKKKOOOOOOOOTTTTTTTXXXXXBBOOOOOOOOOOOFFSSSSSSS
HHHHHHZZZZZZZZZPPPPPJJJJJLLLOZZZZZZZSSSSEEEEEEEEECCCCCCCRRRRRBBBBBRRHHGGGGGGGGGGGGGGUXXXXXXXXKKKKKOOOOOOOOOTTTTTTXXXXXXBOOOOOOOOOTTFFSSSSSSN
HHHHHHZZZZZZZZPPPPPPPJJKLLLZZZZZZZZZZJSESSSSSSSSSSCCCCCCRRBBRBBBBBRTHHHHGGGGGGGGGGGGUUXXXXXXKKKKKKKOOOOOOOOTTTTTTXXXXXXXOOOOOOOOOTTFDSSSSSSN
HHHHHZZZZZZZZZZZPPPPPJJJLLLZZZZZZZZUZCSESSSSSSSSSSCCCCCCRRBBBBBBBBHHHHHHGGGGGGGGGGGGGUXXXXXXKKKKKKKOOOOOOOOTTOTTTTVXXXXUUUUUUVBFTTTSSSSSNNNN
HHZZZZZZZZZZZZZZPPPPPPJJLLLLZZZZZZZSSSSSSSSSSSSSSSCCCCCCCRBBBBBBBBHHHHHZGGGGGGGGGDGGGGXXXXXXKKKKKKKKOOOOOOOTTOOUUUUUXUUUVVUVVVVVVTTTTSNNNNNN
HHZZZZZZZZZZZZZPPPPPPILLLLLLLZZZZZMSSSSSSSSSSSSSSSIIIICRRRBBBBBBBHHHHHHGGGGGDDDDDDFFGGGXXXXXXKKKKKKOOOOOOOOOOOUUUUUUXUUUVVCVVVVVVVVTTTVNNNNN
HHHZZZZZZZZZZZZZZZZZPIILLLLLLZZZCCCSSSSSSSSSSSSSSSITTTCRRRRBBBBBBBHHHHHHHHGGDNNDDDFFGXXXXXXXKKKXXOOOOOOOOOOHOOUUUUUUXUUUUVVVVVVVVVVTTTVVNVNN
HHHZZZZZZZZZZZZZZZZZIILLLLLLLLLCCCCSSSSSSSSSSSSSSSITTTTZZRBBBBBBBHHHHHHHHHHHDDDDDDDDDXXXXXXXKKXXXOOOOOHOOHOHHHUUUUUUUUUUUXXVVVVVVVVVVVVVVVNN
HHHHHZZZZZZZZZZZZZZZIIIIILLLLLCCCCCSSSSSSSSSSSSSSSQDTTTZZRZBBBBBHHHHHHHHHHHDDDDDDDDDDDXXXXXXKKKXXOOOOOHOOHHHHHUUUUUUUUUUUXXXVVVVVVVVVVVVVVVV
HHHHHZZZZZZZZZZZZZZIIIIIILLLLLCCCCCSSSSSSSSSSSSSSSQTTNNZZZZFFFHHHHHHHHQQQHQPPPPDDDDDDDDDXXXXXXXXXOZOZOHHHHHHHHHHHUUUUUUUUXXVVVVVVVVVVVVVVVVV
HHHHHZZZZZZZZZZZZZZIIIIILLLLLLCCCCCSSSSSSSSSSSSSSSWTTTZZZZZZZHHHHHHQHHQQQQQQQDDDDDDDDDDDXXXXXXXXOOZZZOHHHHHHHHHHUUUUUUUUUUXVVVVVVVVVVVVVVVVV
HHHHHZZZZZHZZZZZZZZZIIVZMLLLLCCCCCCCCCCCSSSSSSSSSSWWTWPZZZZZZHHHHHHQQQQQQQQQQJQQQDDDDDDDXXXXXXXXXZZZZHHHHHHHHHHHUUUUUUUUUUXVVXVVVVVVVVVVNNVP
HHHHHHZZZZHZYZZZZZZZIIZZZLLECCCLCCCCCCCCCGSSSSSSSSSSPPPZZZZZZZHZPHHQQQQQQQQQQQQQDDDDDDDDDXXXXXXXZTZZZZHHHHHHHHHUUUUUUUUXUXXXXXVVVPVVVPPPPPPP
HHHHHHHHHHHZZZZZZZZZZZZZZBLLCCCCSCCCCCCCQQSSSSSSSSSSPZZZZZZZZZZZPDDQQQQQQQQQQQQQQQDDDDDDEEXXXMMZZZZZZZZZHHHHHHHUUUUUUUUXXXXXXXVVVPPPPPPSPPPP
HHHHHHHHHHNDDZZZZZZZZZZZZBBCCCCSSCCCSCCCQQSSSSSSSSSSPZZZZZZZZZZZPPDDDQQQQQQQQQQQUQDDDDDDEDXMMMZZMZZZZZZZHHHHHHUUUUUUUXXXXXXXXXVVPPPPPPPPPPPP
HHHHHHHHHHNDNZZZZZZZZZZZZCCCCSCSSCCSSSQQQQSSSSSSSSSSPPPZZZZZZZZZPPPQQQQQQQQQQQQQQDDDDDDDDDMMMMZZMZZZZZZZZZZHHUUBBUXXXXXXXXXXXVVVPPPPPPPPPPPP
HHHHHHHHHHNNNZZZZZZZZZZZZCMMCSSSSSSSSSSQQSSSSSSSSSSSPPPPOZZZZZZPPPPQQQQQQQQQQQQSSSSSDDDDDMMMMMMZMZZZZZZZZZZHHUUBBAAXXXXXXXXXXVVVPPPPPPPPPPPP
HHHHHHHHHHNNNZZZZZZZZZWZZCCCSSSSSSSSSSSSQSSSSSSSSSSSDPPPOZZZZZPPPPPPQQQQQQQQQQDSSSSSDDDDDDMMCCMMMZZZZZZZZZHHHBBBBABBBXXXXXXXXXVVPPPPPPPPPPPP
HHHHHHHHHHNNNZZZZNZZZZZDCCCCCSSSSSSSSSHHQSSSSSSSSSSSDPPPOZZZZZPPPPPPQQBQQQQQQVDSSSSSDDDHHHHHCCCCMMMZZZZZEEEEBBBBBBBXXXXXXXXXXXVVVVPPPBPVPPPP
HQHHHHHHNNNNNNNNNNZDDDDDCCCCCCSSSHHHHHHHHSSSSSSSSSSSDPPOOOZZXPPPPPPPPPPPQDQQNQKSSSSSDHHHHHHCCCCCCMUUZZUUBBBBBBBBBBBBBXXXXXXXRRVVVVVPPPPPPPPP
QQQHQHNNNNNNNNNNNNNNCCCCCCCCCSSSSSSHHHHHHSSSSSHDDDDDMDPOMOOPPVPPPPPPPPPPDDDQQQQSSSSSDDHHHHHHJJJCCUUUZZUUUBTBBBBBBBBBJJYXXXPPRRVVVVVPPPPPPPPP
QQQQQQNNNNNNNNNNNNNNCCCCCCCCVCSSSSSHHHHHHSSSSSHHDDDMMMPOMMOOPPPPPPPPPPDDDDDDDDDSSSSSYYHHHHHJJJJJUUUUUUUUUBBBBBBBBBBBJBYYYYPPPPPVVVTPPPPPPPPP
QQQQQQNNNQNNNNNNNNNNCCCCCCCCCCCCSHHHHHHHHSSSSSHDDDMMMMMMMMOPPPPPPPPPPPPDDDDDDDDDDDHHHHHHHHHJJJJJUUUUUUUUUBBBBBBBBBBBBBYYYPPPPPPPBPPPPPPPPPPP
QQQQQQQQQQNNNNNNNNOOOCCCCCCCCCCCCHHHHHHHHSSSSSHHMMMMMMMMMMBBPPPPPPPPDDPDDDDDDDDDDDHHHHHHHHHJJJJJJUJUUUUUBBBBBBBBBBBBBBBYYYPPPPPPPDPPPPPPPPPP
QQQQQQQQQOONNNNNNNNOCCCCCCCCCCCCCPPHHHHHHSSSSSHHMMMMMMMMMMBBBPPPPPPPDDDDDDDDDDDDDDHHHHHHHHHJJJJJJJJJUUUBBBBBBBBBBBBBBBBYYYPPPPPPPPPPPPPPPPPP
QQQQQQQQQOONNNNLNNNOCCCCCCCCCCCCCCPHHHHHHSSSSSHHMMMMMMMMMMBBBPOOPPOPDDDDDDDDDDDDDDHHHHHHHHHHJJJJJJJJUUJJJBBBBBBBBBBBBYYYYYYPPPPPPPPPPPPPPPPP
QQQQQQQQQOOONNNLNOOOOCCCCCCCCCCCCCPHHHHPPPHHHHHHHMMMMMMMMMBBBPOOOOODDDDDDDDDDDDDDDDDUHHHHHHJJJJJJJJJJJJJJDBBBBBBBBBYYYYYYYYMPPPSPAAPPPPQQPPU
QQQQQQQQQOOONNNNOOOOCCCCCCCCCCCJCWPPPHPPPPHHHOOMMMMMMMMMMMMOOOOTOOOODDDDDDDDDDNNDDNNHHHHHHHJJJJJJJJZZZZZDBBBBBBIYYBYYYYYYYYYYYYPPAAAPPPQQQPP
QQQQQQQQOOOONNOOOOOORCCCCCCCCCCCCWPPPPPPPPPPHGMMMMMMMMMMMMMMOOTTOOTTDDDDDDDNNNNNNDDNHHHHHHHHJJJJJJZZZZZZDLTBBBBIYYYYYYYYYYYYYLYUPAAAPPQQQQQQ
QQQQQQQQQOOOOOOOOOORRWWCCCCCCCWWWWWPPPPPPGGGGGFGMMMMMMMMXMZZTTTTTTTTTDDDDDDNNNNNNNNNNHHHHHJJZZZJZZZZZZZZDLLBBBBIIIYYIKYYYYYYYLPPPPPPNPQQQQQQ
QQQQQQQQOOOOOOOORROORWWWWWWWWWWWWWWPPPPPPGGGGGGGMMMMMMMMMMTTTTTTTTTTTDDDDDNNNNNNNNNHHHHHZHHJZZZZZZZZZZZZDLLLALBBIIYIIIYYYYYYYPPPPPPPPPQQQQQQ
QQQQQNQQQQOOOORRRRRRRRWWWWWWWWWWWWWPPPPPGGGGGGGGGMMMMMMMMTTTTTTTTTTTTTDDDDNNNNNNNNNNNNNHHHJJZZZZZZZZZZZZDLLLLLBBIIYIYYYYYYRYYYPPPPPPPQQQQQQQ
QQQQQQAAOOOOOOOORZZRRRRWWWWWWWWWWWWWPPPPGGGGGGGGGMMMMMMMMTTTTTTTTTTTTDDDNNNNNNNNNNNNNNNEEHJJZZZZZZZZZDDDDLLLLLLIIIIIYYYYYYRPPPPPPPPPPPQQQQQQ
QQQQQQAAAAOOOOOORRZZRRRWWWWWWWWWWWWWPPPPGGGGGGGGMMMMTTMMNTTTTTTTTTTTTTDNCNNNNNNNNNNNNNNEEPJJZZZZZZZZZDDDLLLZLIIIIITITTYYNNPPPPPPPPPPAQQQQQQQ
QQQQQQAAAAAAOOZZZZZZRRRWWWWWWWWWWWWPPPGGGGGHHHHGGGMITTTTTTTTTTTTTTTTNNNNCCNNNNNNNENNENEEJJJJZZZZZZZZZDDDLLLLLIIIIITTTTTTNNPPPPPPPPPPAQQQQQQQ
AAQQAAAAAAAAAOZZZZZZRRRRWWWWWWWWWPPPPPGGGGGHHHHGIVVIPTITTTTTTTTTTTTTENONCCNNNNNNEEEEEEEEEEYTZZZZZZZZZDDDDDDRLIIIITLTTTTTTNPPPPPPPPPPAAAQQQQQ
AAAQAAAAAAAAZZZZZZZZZZYWWWWWWWWWWWPPPPPGGGHHHHHGIVVIIQITTTTTTTTTTTTYNNNNNNNNNNNNEEEEEEEEEEETZZZZZZZZZFFFZDDRRIIIITTTTTTYYPPPTPPPPPPPAAAAAAAA
AAAAAAAAAAAXXXZZZZZZZZYWWWWWWWWWLLPPPPPGGGHHHHHIIVVIIIIITTTTTTTTTTTYYNNNYNNNNNNHYEEEEEEEEEZZZZZZZZZZZFFFZZZRRRRRITTTTTTTTTTTTTPPPPPAAAAAAAAA
AAAAAAAAAAAZZZZZZZZZZZYYWWYWWWWLLLPPPPRRGGHHHHHIIIVIIIIITTTTTTTWTTTYYNONNNNNNNNHYEEEEEEEEEZZZZZZZZFFFFFFZZRRRRRRTTTTTTTTTTTTTTTPPPPYAAAAAAAA
AAAAAAAAAAAYYZZZZZZZWWYYYYYYWWWWPPPPPPPRRRHHHHHIIIIIIIILLTLTTTTWTTYYYYNNYYNHNNNHHEEEEEEEEEEZZZFZZZFFFFFFZZRUURRRTTTTTTTTTTTTTTTPPPPPAAAAAAAA
AAAAAAAAAYYYYZBBWWWZWWYYYYYYYWWWHPPPPPHHHHHHHHHIIIIIIIILLLLLTTWWWTTYYYYYYHHHHHHHHHHHEEEEEEEZZZFZZZFFFFFFZZUUUUPRTTTTTTTTTRRTTTTPPPAAAAAAAAAA
AAAAAAAAYYYYHHBBWWWWWWYYYYYYYWWWHPPPPPHHHHHHHHHIIIIIIIIILLLLWWWWWWWYYYYYYHHHHHHHHHHHBEEEEEEEEZFZZZFFFFFFZZUUUUPRTTTTTTTTTRRRTTTTTAFAAAAAAAAA
AAAAAAAYYYYHHHHWWWWWWWWYYYYYYHCHHPPPPPHHHHHHHHHIIIIIIIILLLLWWWWWWWWYYYYYHHHHHHHHHHHHBEEEEEEZZZFFFFFFFFFFFZUUUUUSEMMMTTTRRRRRTTTAAAAAAAAAAAAA
AAAAAAYYYYYHHHHHWWWWWWTYYHHHHHHHHHPPPPHHHHHHHHHISSIIIIILLLLLWWWWWWHKKYYHHHHHHHHHHHHHXXXXXEXXZZFFFFFFFFFFFZUUUUUEEEEMERRRRRRRTTTAAAAAAAAAAAAA
AIIIIAYYHHHHHHHWWWWWWYYYYHTHHHHHHHHPPPHHHHHHHHSSSSSSIILLLLWLWWWBBBBBBBBHHHHHHHHHHHHXXXXXXXXXZXFFFFFFFFFFFUUUUUEEEEEEERRRRRRRTTTTAAAAAAAAAAAA
IIIIIAHYHHHHHHHHWWWWWWYYHHHHHHHHHHHHPPBPRRRRRRSSSSSRRSLLLLWWWWWBBBBBBBBBHHHHHHHHHHHHXXXXXXXXXXXFFFFFFFFFFUUUUUEEEEEEEEVRRRRRRTTTAAAAAAAAAAAB
IIIIIHHHHHHHHHHHWWWWWHFYYHHHHHHHHHHHPPBPPRBRRSSSSSSSSSSLLLWWWWWBBBBBBBBBHHHHHHHHHHTHHXXXXXXXXXFFFFFFFFFFFUUUUUUEEEEEEERRRRRRTTTAAAAAAAAAAAAA
IIIIIIHHHHHHHHHHHWWWWHFHHHHHHHHHHHHHHBBBPPBRVSSSSSSSSSLLLLLWWWWBBBBBBBBBHHHHHHHHHHTHXXXXXXXXXXFFFFFFFFFFFUUUUEEEEEEEEEERRRRRTTTCACCAAAAAAAAB
RIIRIHHHHHHHHHHHHHWWWHHHHHHHHHHHHHHHHBBBBBBBSSSSSSSSSSLLLLLWWWWBBBBBBBBBHHHHHHHTTTTTXXXXXXXXXXFFFFFFFFUUUUUUUEEEEEEEEEEEERRRTTTCCCCACCACCCAB
RIRRIHHHHHHHHHHHWWWWWWYYHHHHHHHHHHBHHBBBBBBBSSSSSSSSGGLLLLWWWWWWWWBBBBBMMMMJHHHRRRTTTXXXXXXXXXFFFFFFFFUUUUUUUUEEEEEEEEEEERRRTTTCCCCCCCACCCAA
RRRRHHHHHHHHHHHHWWWWWYYYYHHHHHHHHBBHBBBBBQQQSSSSSSSSSGGWWWWWWWWWWWBMMMMMMMMZZZZZRRTTTXXXXXXXXFFFFFFFFUUUUUUUUUEEEEEEEEEEERRRRTTTTTTTCCCCYYAE
RRRRRHHHHHHHHHHWWWWWWYYYYYEHLHHLHHBBBBBBBQQQBBBSSSSSSHHSWWWWWWWZWWBMMMMMMMMMMZZZRRTTTTWTXXXFFFFFFFFUUUUUUUUUUUEEEEEEEUUEERRRXTTTTTTTCCCCYYYE
KRRRRHHHHHHHHHHWWWWWYYYYVYYZLLLLBBBBBBBBBQQQBBBSSSSSSHHHHEWWWWWWWWBMMMMMMMMMMZZZXXXTXWWWVXXXFIFFFFFUFUUUUUUUUUUUUUECEUUUUAAATTTTTTTTCCCCYYYE
KRRVVHHHHHHHHHHWWWWWWYYYLLLLLLLLBBBBBBBBBQQQBBBSSSSSSHHHHEEWWWBWWWBMMMMMMMMMMXXXXXXXXWWWWXXWWFFFFFFFFUWUUUUUUUUUAUUUUUUUUUAAATTTTTTTTTCYYYYE
KKVVHHHHHHHHHHHHWWWWYYYYLLOLLLLLLLBBBBBBBQQQBBBSSSSSSHHEEEWWWBBWWWWMMMMMMMMMMZXXXXXXXWWWWXXWWWFFFTFFFFWUHHUUUUUUAUUUUUUUUUATTTTTTTTTTCCYYYYE
VKVVFFHHHHHHHWWWWWWWWYYYLLLLLLLLLLNBBBBBBBBBBNWWSWSPHHHHHHHHHWWWWWWMMMMMMMMMMXXXXXXXXHWWWWWWWWWWFTWFFFWUUCCUCUUUUFUUUUUUUAAABBTTTTTTTTCYEEEE
VVVVVVVHHHHWHWWWWWTWTYYNLLLLLLLLLNNBBBBBBBBNNNWWWWWWWHHHHHHHYWMMMMMMMMMMMMMMMXXXXXXXXHHWWWWWWWWWFFWFFWWWCCCCCCUUBBBUUBBBBBBBBBTTTTTTTTTEEEEE
VVVVVVVVVWWWWWWTWTTWTYYNTLLLLLLLLNNNNNNNNNBNNWWWWWWWWWWHHHSSWWMMMMMMMMMMMMMMMXXXXXXXXXXXXXXWWWWWWWWWWWWCCCCCCCUUBBUUUUBBBBBBBBTTTTTTTTEEEEEE
VVVVVVVVWWWWWWWTTTTTTTTTTTTLLLLLLNNNNNNNNNBNWWWWWWWWWWWHSSSSWWMMMMMMMMMMMMMMMZXXXXXXXXXXXXWWWWWWWWWWWWWCCCCCCCCCCBBBBBBBBBBBBBTTTTTTEEEEEEEE
VVVVVVVBWWWWWWWTTTTTTTTTPLLLLLLLLNNNNMMMMMMMMWWWWWWWWWWWSSSSSSMMMMMMMMMMMMMMMZMXXXXXXAXXMWWWWWWWWWWWWWWCCCCCCCCCCBBBBBBBBBBBBBBTTTTTTEEEEEEE
VVVVVVVVWWWWWWTTBTTTTTTTPLLLLLLLLLLLNMMMMMMMMWWWWWWWWWWWSSSSSWMMMMMMMMMMMMMMMNNNXXXXAAAQQQQQWQWWWWWWWWWWCCCCCCCCBBBBBBBBBBBBBBBTTTTTTEEEEEEE
VVVVVVDXWWWWWWWTTTTTTTTTTLLLLLLALLAANMMMMMMMMWWWWWWWWWWSSSSSSSMMMMMMMMZZZGGGGNNNNNNNAAAQQQQQQQWWWWWWWRRWWRCCCCCCBBBBBBBBBBBBBBBTTTTTEEEEEEEE
VVVVVVVXWWWWWNNTTHTTTTTTTTLLLLLAAAAANNIIMMMMMXWWWWWWSSWSSSSSSSMMMMMMMMZZZGGGGGGGNNNNNAAQQQQQQQWTWWXRRRRRRRRCCCCCCCCCBBBBBBBBBBBTTYTTEEEEEEEE
TVVVVVXXWWWWWNNNHHHTTTTTTTTLLLLAAAAAMMMMMMMMMWWBBWIWSSSSSBMMMMMMMMMMMMBZZGGGGGGGNNNAAAAQQQQQQQTTWWRRRRRRRRRCCCCCCCCCBBBBBBBBBBBBTTTEEEEEEEEE
TVWVVVXXXXXONNNHHHNNTTTTTTTLLLLAAAAAMMMMMMMMMWWBBWWXSXSSSSMMMMMMMMMMMMBBBGGGGGGGNNNNAAAQQQQQTTTTTTTRRRRRRRRCCCCCCCCBBBBBBBBBBBBBGTSSEEEEEEEE
TTVVIIXXXXOOOONNHNNNTTTTXATLAAAAAMMMMMMMMMMMMBBBXYXXSXSXSSMMMMMMMBBBWBBBBGGGGGGGNNNNNAAQQQQTTTTTTBBBTRRRRRRRCCCCCCCRBBBBBBBCBBBGGSSSSEEEEEEE
TTTLLXXXLXLLOONGNNNNNTNNAAAAAAAAAMMMMMMMMMMMMBBBXXXXSXXXSSMMMMMMMBBBBBBKBGGGGGGGGGGGNAAAAAQTTTTTTTTTTRRRRRRRRRCCCCRRSBBBBBBSSBBSSSSSEEEEEEEE
TTLLLLLLLXLLLONNNNNNTNNNNAAAAAAAAMMMMMMMMMMMMBBXXXXXXXXSSSSBBBBBBBBBBRRRNGGGGGGGGGGGAAAAAAATTTTTTTTTTTRRRRRRRRRRCRRBBBBBBSSSSSSSSSSEEEEEEEEE
TTLLLLLLLLLLNNNNNNNNNNNNNNNNAAAAAMMMMMMMMMMMMBBBBXXXXXXXXXSSBBBBBBBBBBRRRNGGGGGGGGGGNAAAAAAATTTTTTTRRRRRRRRRRRMMYYRBYYEBBBSSSSSSSSSSEEESSSEE
TLLLLILLLLLLNKNNNNNNNNNNNNNAAAAAAAAJMMMMMMMMMBBBBBXXXXXXXXXSSBBBBBBBBBBRRRGGGGGGGGGGNNNAAAATTTTTTTTTTRRRRRRRRRRRYYYYYYEBSSSSSSSSSSSSSSESSSEE
TLLLLLLLLLLLLLINNNNNNNNNNNNNAAAAAAAJMMMMMMMXBBBBBXXXXXXXXXSSSBBBBBBBBBBBRNGGGGGGGGGGNANAAAATTTTTTTTTTTRRRRRRRRRYYYYYYYSSSSSSSSSSSSSSSSSSSEEE
TLLLLLLLLLLLLLIVNNNONNNNNNNAAAAAAAAAMMMMMMMXFFFBBXXXXXXXXSSSSSBBBBBBBBBBNNNGGGGGGGGGAAAAAATTTTTTTTTTRRRRRRRRRRRYYYYYYSSQSSSSSSSSSSSSSSSSSESS
LLLLLLLLLLLLLLLVVNNONNNNNNNAAAAAAAAYMMMMMMMXFFFBFFXXXXXHHHHSSSSBBBBBBBBBGNNNNNNNANNNAAAAAATTTTTTTTHHRRRRRRRRRRRRYYYYYYSSSSSSSSSSSAAASSSSSSSS
LLLLLLLLLLLLLLXVVNNONNNNNNNHWWAUUAYYYYXXXXXXFFFBFFFFXXXXXHHHSBBBBBBBBBBCNNNNNAANAAAAAAAACCTTTTTTTHHHRRRRRRRRRRRRYYYYYYSSSSSSSSSTSSSSSSSSSSSS
YYLLLLLLLLLLLLHHHHHHHHHHNHHHWAAAZZYYYYYYXXXFFFFFFFFFXXXXXHSSSSBBBWBKKKBBBRNNAAAAAAACAACCCCCCCTTTTHHHRRRRRRKRRRRRRYYYYYSSSSSSSSTTTSSSSSSSSSSS
YLLLLLLLLSSLLLHHHHHHHHHHHHHHHAARZZZYYYYYXFFFFFFFFFFFFXXXHHHSHSSBBWWKKKBBAANAAAAAAAACCCCCCCCCCTHHHHHHHDDDOOKKKRRRRRYYYYSSSSSSSTTTTTSSVSSSSSSS
YYLLSSSLLSSLLLHHHHHHHHHHHHHHHRRRZZZZZYYYXMXXFFFFFFFFFHHHHHHHHSSSSLLKKKBBANNAAAAAAACCCCCCCCCCCTCCHHHHHDDDDKKKKRKKCYYYYSSSSSSSSTTTTTTSVVVVSSSS
YYYLSSSLLSVLLLHHHHHHHHHHHHHHHRRRCCCCCCCCGMMXXFFFFFFFFHHHHHHHHSSLSLLKKKBBAAAAAAAAAACCCCCCCCCCCCCCCHHHHDDDDKKKKKKKKTTYYYYSSSSSTTTTTSSBBBVSSSMS
YYYYSYSSSSVVVVHHHHHHHHHHHHHHHHRRCCCCCCCKMMPMXFFFFOOFFBBHHHHHHSSLLLLKKKAAAAAAAACCCACCCCCCCCCCCCCCCHHHHHDDDDKKKKKKKKTYYYYSSTSTTTTSSSBBBBVSSBBD
YYYYYYSSSSVVVVHHHHHHHHHHHHHHRRRRCCCCCCMMMMMMMMFFFFOFFBBBBHHHHHSSLPPKKKAAVAACCCCCCCCCCCCCCCCCCCCCCCHHDDDDDKKKKKKKKKTTTYYSSTSTTSTSSSBBBBSSBBBD
YYYYYSSSSSVVVVHHHHHHHHHHHHHHRRRRRRCCCCCMMMMMMMFVVVKBBBBBBDDDDDDPLPPLLLAAAAAACCCCCCCCCCCCCCCCCCCCCCCHDDDDKKKKKKKKKTTTYYYTTTTTSSSSSSTBBBBBBBBB
YYYYYYYSSSVVVVHHHHHHHHHHHHHHRRRRCCCCCCCCCMMMMMMMKKKKKKKKDDDDDDBPPPPPPPPPAAAACCCCCCCCCCCCCCCCCCCCCCCHDDDDDKKKCKKKKTTTTTTTTTTTSSSSSDSSBBBBBBBB
YYYYYYSSSSSVVOHHHHHHHHHHHHHHMRRRRCCCCCCCCMMMMMMMKKKKKKKKDRRKDBBPPPPPPPPPAAAAACCCCCCCCCCCICCCCCCCCCCHDDDDDKCCCKKKKKTTTTTTTTTTSSSSSSSSBBBBBBBB
BYYYSSSSSNSSSOOVVHHHHHHHHHHHRRRRCCCCCCCCCMMMMMMMKKKKKKKKRRRRDDPPPPPPPPPPAAAAAACCCCCCCCCIIICCCCCCCCCDDDDSSSCCCKKKKTTTTTTTTTTTSSSSSSSSSBBBBBBB
BBBBSSSSSNNNNOOVVHHHHHHTMMMMRRMMMMCCCCCCCCMMMMMMKKYKKKKKRRRRDPPPPPPPPPPPPAAARACCCCCCCCIIIICCCCCCCCCCXXDSSSSCCCKTKTTTTTTTTTTUSSSSSSSSBBFBBBBB
BBBBBBBSOOOOOOOVVHHHHHHTMMMMMMCMMACMMCCCCCCMMKMMKKKKKKKKRRRRRPPPPPPPPPPPPPAAAAABBCCCCCIIIIICCCCCCCXXXXOSSSSSTTTTKTTTTTTTTTTSSSSSSSSSSFFBBBBB
BBBBBBBBBOWOOOOOOOHHTTTTMMMMMMMMMMMMMCCCCCCMMKKKKKKKKKKKRRRRRQPPPPPPQQPPPEAAAABBBBCCCIIIIIIICICCCCXXSSSSSSSSTTTTTTTTTTTTTTQSQSSSSSSSSFBBBBBB
BBBBBBBBBBOOOOOOOOTTTTTTMMMMMMMMMMMMWCMCCCCCCKKKKKKKKKKKRRRRRQQQQQQQQQQPPPAAPCBBBBBMCZZZZZZZZZZXXXXXSSSSSSSSTTTTTTTTTTTTTTQQQSSQFSSSSFBBBBBB
BBBBBBBBBBOOOOOTOTTTTTTTTMMMMMMMMMMMMMMMCCCCCKKKKKKKKKKRRRRRRQQQQQQQQQQPPPPPPBBBBBBMMZZZZZZZZZZIXXXXSSSSSSSSSSSTTTTTTTTTTTQQQQQQFFFSFFFBBBBB
BBBBBBBBBBOOOOOOOTTTTTTTMMMMMMMMMMMMMMMMMCCCCCTKFKKKKKKKKKKRRHQQQQQQQQQPPPPPBBBBBBBMMZZZZZZZZZZXXXXXXSSSSSSSSSSSTTTTTTTTTTQQFQQFFFSSFFFBBBBB
BBBBBBBBBBBOOOOOOTTTTTTTMMMMMMMMMMMMMMZCCCCCCTTKKKKKKKKKKKKKQQQQQQQQQQQPPPPPPGBBDBBMMZZZZZZZZZZXXXXXXXXSSSSSSSSTTTTTTTTTTVVVFFFFFFFFFFKBEBBE
BBBBBBBBBBOOOOOPPPPTTTTMMMMMMMMMMMMMMZZCCCCCCCTTTKKKKKKKKKKQQQQQQQQQQQPPPPPPPPPPDMMMDZZZZZZZZZZXXXXXXXSSSSSSSSSSTOTTTTTTTVVFFFFFFFFFFFFFEEBE
BBBBBBBBIIIUOOPPPPPPTTTTTMMMMMMMMMMMMZTCCCCCCCTTTTTKKKKKKKKQQQQQQQQQQQPPPPPPPPPPDMMDDDYYZZZZZZIXXXXXSSSSSSSSSSSSOOOTTTVVTVVVVVFFFFFFFFFFFEEE
BBBBBBIIIIIIIPPPPPPTTTTTTMMMMMMMMMMMZZTTTTCCCCTTTTKKKKKKKAAQQQQQQQQRQQPPPPPPPPPDDDMDDDDDZZZZZZXXXXXXSSSSSSSSSSSOOOOTTTTVVVVVVFFFFFFFFFFFFEEE
QBBBBQQIIIIIIIIPPPPTTTTTTMMMMMTTTTTTZZTTTTTCTTTTTTTKKKKAAAAQQQQQQQQQQPPPPPPPPPPDDDDDDDDZZZZZZZXXXXXSSSSSSSSSSSOOOOOOTTTVVVVVFFFFFFFFFFFFFEEE
QQQQQQISIIIIIIIIFTTTTTTTTMMMMMTTTTTTTZTTTTTTTTTTTTTTTTKKAAAAAQQQQQQQPPPPPPPVVPVDDDDDDDDZZZZZZZXXXXSSSSSSSSSSSSOOOOOOOVVVVVVVFFFFFFFFFFFFEEEE
QQQQQIIIIIIIIFFFFFTTTTTTTTMMMMMTTTTTTTTTTTTTTIIIITTIIIIAAAAAAQQQQQQQPPPPPVVVVVVVDDDDDDDZZZZZZZXXXXXXXXXSSSSSSOOOOOOOOVVVVVVVVVFFFFFFFFFFFEEE
QQQQQQQQQIIQFFFFFFTGTTTTTTMVTMMTTTTTTTTTTTTIIIIIIIIIIIIAAAAAAQSQQQQPPPPPPVVVVVVVDDDDDDDZZZZZZZXXXXXXXXXXSSSSOOOOOOOOOOVVVVVVVFFNNNNFFFFFFNNE
QQQQQQQQQQQQFFFFFFTTTTTTTTMVTTTTTTTTTTTTTTTTIIIIIIIIIIIIAAAAPPPPQQQQPPPPPPVVVVVVDDDDDDDZZZZZZZXXXXXXXOOOOOSOOOOOOOOOVVVVVVVVVVVNNNNNNNNFNNNN
QQQQQQQQQQQQFFFFFFFFTTTTTTTTTTTTTTTTTTTTTTTTIIIIIIIIIIIAAAAAPPPPPPPPPPPPPPVVVVVDDDDDDDDZZZZZZZXXXXXOOOOOOOSOOOOOOOOOVVVVVVVVVVVVNNNNNNNNNDDD
QQQQQQQQQQQFFFFFFFFFFFTTTTPPPTTTTTTTTTTTTTTIIIIIIIIIIIIIIAAAPPPPPPPPPPPPPPPPVVDDDDDDDDDZZZZZZZXXXXXXXXOOOOOOOOOOOOOQVLLVEVLVVVVVNNNNNNNNDDDD

View file

@ -0,0 +1,99 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
example1ExpectedOutput = 80
example2ExpectedOutput = 436
example3ExpectedOutput = 1206
example4ExpectedOutput = 236
example5ExpectedOutput = 368
type Line = VU.Vector Char
type Input = V.Vector Line
type Parser = Parsec Void String
parseLine :: Parser Line
parseLine = do
line <- some letterChar <* eol
return $ VU.generate (length line) (line !!)
parseInput' :: Parser Input
parseInput' = do
line <- some parseLine <* eof
return $ V.generate (length line) (line !!)
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Coord = (Int, Int)
type Visited = M.Map Coord ()
type Region = [Coord]
compute :: Input -> Int
compute input = sum $ map (\r -> corners r * length r) regions
where
(regions, _) = V.ifoldl' regions' ([], M.empty) input
regions' :: ([Region], Visited) -> Int -> Line -> ([Region], Visited)
regions' acc y line = VU.ifoldl' (regions'' y) acc line
regions'' :: Int -> ([Region], Visited) -> Int -> Char -> ([Region], Visited)
regions'' y acc@(rs, visited) x c = case M.lookup (x, y) visited of
Just _ -> acc -- already processed
Nothing -> let (r, visited') = flood c ([], visited) (x, y) in (r:rs, visited')
flood :: Char -> (Region, Visited) -> (Int, Int) -> (Region, Visited)
flood c acc@(rs, visited) (x, y) = case M.lookup (x, y) visited of
Just _ -> acc
Nothing -> L.foldl' (flood c) ((x, y):rs, M.insert (x, y) () visited) $ neighbors visited c x y
neighbors :: Visited -> Char -> Int -> Int -> [Coord]
neighbors visited c x y = filter (valid visited c) [ (x-1, y), (x+1, y), (x, y-1), (x, y+1) ]
valid :: Visited -> Char -> (Int, Int) -> Bool
valid visited c (x, y) = case input V.!? y of
Just line -> case line VU.!? x of
Just c' -> c == c'
Nothing -> False
Nothing -> False
corners :: Region -> Int
corners r = sum $ map corners' r
where
inside c = L.elem c r
outside = not . inside
corners' (x, y) = length $ filter id [ outside (x-1, y) && outside (x, y-1) -- top left in
, outside (x+1, y) && outside (x, y-1) -- top right in
, outside (x-1, y) && outside (x, y+1) -- bottom left in
, outside (x+1, y) && outside (x, y+1) -- bottom right in
, inside (x-1, y) && outside (x-1, y-1) && inside (x, y-1) -- top left out
, inside (x+1, y) && outside (x+1, y-1) && inside (x, y-1) -- top right out
, inside (x-1, y) && outside (x-1, y+1) && inside (x, y+1) -- bottom left out
, inside (x+1, y) && outside (x+1, y+1) && inside (x, y+1) ] -- bottom right out
main :: IO ()
main = do
example1 <- parseInput "example1"
let exampleOutput = compute example1
when (exampleOutput /= example1ExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show example1ExpectedOutput)
example2 <- parseInput "example2"
let exampleOutput = compute example2
when (exampleOutput /= example2ExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show example2ExpectedOutput)
example4 <- parseInput "example4"
let exampleOutput = compute example4
when (exampleOutput /= example4ExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show example4ExpectedOutput)
example5 <- parseInput "example5"
let exampleOutput = compute example5
when (exampleOutput /= example5ExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show example5ExpectedOutput)
example3 <- parseInput "example3"
let exampleOutput = compute example3
when (exampleOutput /= example3ExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show example3ExpectedOutput)
input <- parseInput "input"
print $ compute input

View file

@ -0,0 +1,15 @@
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400
Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=12748, Y=12176
Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450
Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=18641, Y=10279

View file

@ -0,0 +1,63 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Either
import qualified Data.Matrix as MTX
import Data.Ratio
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 480
type Pair = (Rational, Rational) -- X Y
type Entry = (Pair, Pair, Pair) -- ButtonA ButtonB Prize
type Input = [Entry]
type Parser = Parsec Void String
parseNumber :: Parser Rational
parseNumber = fromInteger . read <$> some digitChar
parseButton :: Parser Pair
parseButton = (,) <$> (string "Button " *> letterChar *> string ": X+" *> parseNumber)
<*> (string ", Y+" *> parseNumber <* eol)
parsePrize :: Parser Pair
parsePrize = (,) <$> (string "Prize: X=" *> parseNumber)
<*> (string ", Y=" *> parseNumber <* eol)
parseEntry :: Parser Entry
parseEntry = (,,) <$> parseButton
<*> parseButton
<*> parsePrize
parseInput' :: Parser Input
parseInput' = some (parseEntry <* optional eol) <* eof
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
-- ax + bx = c
-- ay + by = d
compute :: Input -> Rational
compute = sum . map compute'
where
compute' ((ax, ay), (bx, by), (px, py)) = let (Right sol) = MTX.rref $ MTX.fromList 2 3 [ ax, bx, px
, ay, by, py ]
x = sol MTX.! (1, 3)
y = sol MTX.! (2, 3)
in if (denominator x == 1 && denominator y == 1) then 3 * x + y else 0
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute input

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,58 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Either
import qualified Data.Matrix as MTX
import Data.Ratio
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
type Pair = (Rational, Rational) -- X Y
type Entry = (Pair, Pair, Pair) -- ButtonA ButtonB Prize
type Input = [Entry]
type Parser = Parsec Void String
parseNumber :: Parser Rational
parseNumber = fromInteger . read <$> some digitChar
parseButton :: Parser Pair
parseButton = (,) <$> (string "Button " *> letterChar *> string ": X+" *> parseNumber)
<*> (string ", Y+" *> parseNumber <* eol)
parsePrize :: Parser Pair
parsePrize = (,) <$> (string "Prize: X=" *> parseNumber)
<*> (string ", Y=" *> parseNumber <* eol)
parseEntry :: Parser Entry
parseEntry = (,,) <$> parseButton
<*> parseButton
<*> parsePrize
parseInput' :: Parser Input
parseInput' = some (parseEntry <* optional eol) <* eof
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
-- ax + bx = c
-- ay + by = d
compute :: Input -> Rational
compute = sum . map compute'
where
compute' ((ax, ay), (bx, by), (px, py)) = let (Right sol) = MTX.rref $ MTX.fromList 2 3 [ ax, bx, px + 10000000000000
, ay, by, py + 10000000000000 ]
x = sol MTX.! (1, 3)
y = sol MTX.! (2, 3)
in if (denominator x == 1 && denominator y == 1) then 3 * x + y else 0
main :: IO ()
main = do
input <- parseInput "input"
print $ compute input

View file

@ -0,0 +1,12 @@
p=0,4 v=3,-3
p=6,3 v=-1,-3
p=10,3 v=-1,2
p=2,0 v=2,-1
p=0,0 v=1,3
p=3,0 v=-2,-2
p=7,6 v=-1,-3
p=3,0 v=-1,-2
p=9,3 v=2,3
p=7,3 v=-1,2
p=2,4 v=2,-3
p=9,5 v=-3,-3

View file

@ -0,0 +1,58 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import qualified Data.List as L
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 12
type Pair = (Int, Int)
type Robot = (Pair, Pair)
type Input = [Robot]
type Parser = Parsec Void String
parseNumber :: Parser Int
parseNumber = read <$> some (digitChar <|> char '-')
parsePair :: Parser Pair
parsePair = (,) <$> parseNumber <* char ','
<*> parseNumber
parseRobot :: Parser Robot
parseRobot = (,) <$> (string "p=" *> parsePair)
<*> (string " v=" *> parsePair)
parseInput' :: Parser Input
parseInput' = some (parseRobot <* eol) <* eof
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
compute :: Int -> Int -> Input -> Int
compute width height input = product $ L.foldl' safety [0, 0, 0, 0] input'
where
mx = width `div` 2
my = height `div` 2
input' = map step input
step ((x, y), (v, w)) = (((x + v * 100) `mod` width), ((y + w * 100) `mod` height))
safety acc@[a, b, c, d] (x, y) | x < mx && y < my = [a+1, b, c, d]
| x > mx && y < my = [a, b+1, c, d]
| x < mx && y > my = [a, b, c+1, d]
| x > mx && y > my = [a, b, c, d+1]
| otherwise = acc
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute 11 7 example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute 101 103 input

View file

@ -0,0 +1,500 @@
p=46,91 v=80,-6
p=89,91 v=-69,68
p=61,39 v=-75,66
p=8,63 v=48,-75
p=58,76 v=-18,19
p=99,14 v=-92,-85
p=80,66 v=-3,-13
p=15,1 v=-11,30
p=52,79 v=93,81
p=81,44 v=24,99
p=6,41 v=-12,61
p=40,14 v=-47,-85
p=53,30 v=-52,-78
p=2,53 v=-97,-33
p=25,75 v=79,44
p=77,17 v=-30,-21
p=41,41 v=93,-99
p=95,98 v=-49,43
p=52,56 v=-88,-55
p=99,20 v=-64,-53
p=9,7 v=-56,-26
p=18,0 v=87,-77
p=90,95 v=-51,72
p=25,81 v=20,-39
p=94,79 v=-12,68
p=58,88 v=-88,6
p=31,99 v=-11,-85
p=99,79 v=33,-46
p=86,25 v=97,-17
p=79,73 v=-35,-4
p=20,52 v=17,63
p=65,65 v=-98,-34
p=34,31 v=33,-49
p=14,21 v=17,54
p=71,16 v=29,42
p=63,53 v=-41,44
p=59,78 v=-44,-92
p=44,96 v=88,93
p=88,70 v=-38,36
p=78,78 v=16,11
p=12,35 v=27,21
p=45,77 v=-65,-10
p=80,87 v=31,89
p=31,2 v=-68,59
p=24,64 v=-6,3
p=28,34 v=54,-98
p=99,61 v=-71,-21
p=11,84 v=-37,60
p=14,14 v=-68,-57
p=97,12 v=-92,58
p=25,69 v=39,-61
p=72,34 v=60,-62
p=15,84 v=-10,14
p=96,57 v=-56,15
p=76,55 v=-33,98
p=23,97 v=56,60
p=34,30 v=-68,76
p=14,2 v=-68,22
p=8,8 v=5,46
p=16,38 v=-71,-21
p=62,91 v=21,72
p=67,75 v=-23,-96
p=28,69 v=-79,31
p=17,71 v=-81,36
p=98,62 v=-43,-59
p=61,92 v=-79,7
p=55,26 v=-81,55
p=97,18 v=66,-32
p=93,33 v=92,-78
p=29,53 v=54,70
p=49,100 v=45,-43
p=63,13 v=52,38
p=13,49 v=9,-64
p=73,37 v=46,7
p=86,56 v=63,-50
p=0,2 v=43,-61
p=57,96 v=-96,74
p=84,63 v=-66,-26
p=25,94 v=-86,68
p=6,72 v=82,40
p=49,5 v=15,-20
p=52,28 v=-28,-63
p=17,99 v=56,-31
p=42,85 v=13,44
p=12,33 v=99,-19
p=97,16 v=19,-69
p=44,29 v=-99,-59
p=30,15 v=36,-81
p=58,42 v=-62,33
p=32,36 v=28,-41
p=34,97 v=-29,2
p=21,61 v=86,-44
p=27,94 v=-49,13
p=60,74 v=-72,85
p=32,81 v=-42,93
p=46,37 v=37,16
p=78,25 v=-49,-8
p=72,76 v=-88,97
p=21,59 v=-2,89
p=1,16 v=-79,-24
p=34,55 v=54,-50
p=34,36 v=46,37
p=99,29 v=-71,-42
p=83,50 v=-24,19
p=51,65 v=-12,13
p=9,41 v=74,70
p=38,34 v=-65,29
p=8,22 v=-79,-66
p=76,77 v=83,-13
p=41,15 v=67,17
p=46,51 v=85,78
p=14,99 v=-33,39
p=49,33 v=-93,-90
p=5,102 v=74,-28
p=27,7 v=22,37
p=80,80 v=-87,-83
p=21,73 v=-76,2
p=59,63 v=-76,-91
p=36,60 v=-34,-46
p=84,89 v=99,-35
p=53,89 v=24,-67
p=17,57 v=39,31
p=86,60 v=-11,-93
p=58,5 v=11,49
p=35,82 v=-91,-10
p=8,38 v=-48,-74
p=69,58 v=34,-38
p=26,17 v=-94,-40
p=66,77 v=-10,64
p=18,7 v=-14,43
p=67,71 v=78,11
p=84,67 v=-7,-1
p=67,54 v=-54,-38
p=38,30 v=-83,82
p=9,19 v=-4,-32
p=34,61 v=-11,65
p=8,60 v=-63,64
p=11,45 v=-75,-29
p=80,26 v=-92,20
p=24,18 v=98,-73
p=63,6 v=86,-53
p=10,60 v=7,69
p=76,47 v=34,-93
p=98,9 v=-17,46
p=65,19 v=11,-73
p=54,51 v=-14,-67
p=74,56 v=-82,40
p=43,74 v=-78,19
p=46,38 v=-83,62
p=51,3 v=28,-19
p=75,47 v=-8,85
p=40,43 v=-94,-42
p=99,48 v=27,-54
p=16,55 v=-48,-62
p=82,79 v=-34,58
p=9,52 v=-53,12
p=53,91 v=34,-48
p=98,68 v=-17,-39
p=30,38 v=-58,17
p=95,87 v=36,-57
p=97,43 v=-69,74
p=70,46 v=65,41
p=14,52 v=30,-21
p=51,77 v=20,-47
p=19,38 v=22,33
p=32,22 v=96,17
p=91,38 v=15,14
p=13,98 v=43,80
p=31,98 v=-1,59
p=14,39 v=40,-29
p=58,32 v=87,-89
p=52,42 v=78,-21
p=24,13 v=-97,-3
p=23,26 v=33,-49
p=6,10 v=-97,-77
p=59,7 v=43,-47
p=89,98 v=-30,6
p=29,65 v=-3,-17
p=85,95 v=94,72
p=54,14 v=80,52
p=85,83 v=-68,65
p=60,22 v=-44,5
p=91,67 v=-25,69
p=90,81 v=-76,99
p=22,92 v=-6,2
p=37,59 v=-73,7
p=37,37 v=-26,-46
p=78,74 v=45,73
p=94,57 v=38,-60
p=62,88 v=-49,56
p=62,29 v=96,37
p=76,71 v=-3,-38
p=6,94 v=-51,8
p=95,64 v=95,50
p=76,90 v=99,-93
p=38,93 v=95,-23
p=62,76 v=-62,60
p=70,61 v=94,-18
p=85,29 v=-61,50
p=11,75 v=-27,56
p=35,51 v=43,13
p=14,74 v=61,52
p=30,15 v=-55,-28
p=18,69 v=-97,-58
p=98,33 v=53,-70
p=30,61 v=-45,-14
p=77,102 v=16,-15
p=93,87 v=92,83
p=23,10 v=20,-98
p=75,48 v=86,-9
p=6,57 v=51,-48
p=39,35 v=80,91
p=84,70 v=63,81
p=5,40 v=-44,-79
p=38,81 v=2,52
p=91,73 v=50,-55
p=55,101 v=95,-22
p=12,13 v=4,-73
p=34,25 v=-39,-37
p=80,5 v=-2,-44
p=85,75 v=-54,65
p=36,37 v=-47,-78
p=7,18 v=79,92
p=79,101 v=-59,-81
p=15,42 v=43,74
p=23,4 v=85,-64
p=95,10 v=-95,30
p=23,96 v=-94,88
p=57,45 v=26,8
p=63,37 v=-91,83
p=73,0 v=-15,10
p=44,3 v=-39,-52
p=17,90 v=94,88
p=63,65 v=17,21
p=9,32 v=58,-66
p=57,37 v=8,-5
p=86,17 v=89,-65
p=65,81 v=-26,73
p=63,56 v=80,9
p=69,33 v=29,-85
p=81,0 v=-92,23
p=97,44 v=45,-63
p=42,85 v=-83,18
p=36,90 v=12,79
p=52,59 v=-75,-83
p=25,72 v=76,83
p=19,81 v=22,77
p=31,35 v=-59,-38
p=59,49 v=18,73
p=52,24 v=31,-8
p=65,34 v=-5,4
p=69,95 v=-41,-93
p=17,94 v=-19,-68
p=90,99 v=-87,-85
p=30,74 v=-94,-96
p=13,40 v=2,13
p=100,3 v=40,-77
p=84,6 v=-72,21
p=51,43 v=-26,74
p=5,82 v=84,89
p=28,63 v=90,-5
p=28,17 v=90,-24
p=98,70 v=40,23
p=39,75 v=82,-19
p=3,56 v=-35,-13
p=46,8 v=-39,-40
p=28,28 v=64,50
p=25,70 v=54,31
p=1,79 v=27,-47
p=35,56 v=90,-5
p=19,23 v=-58,46
p=31,90 v=67,59
p=30,53 v=-89,59
p=56,23 v=-21,-73
p=75,4 v=-72,-23
p=48,1 v=88,-85
p=37,13 v=36,51
p=68,66 v=-41,-67
p=29,2 v=64,-52
p=16,57 v=17,32
p=78,22 v=-10,-40
p=36,52 v=-11,49
p=25,43 v=95,-54
p=11,62 v=87,95
p=67,59 v=91,7
p=30,20 v=77,54
p=31,15 v=33,87
p=75,37 v=72,73
p=95,30 v=-50,38
p=95,54 v=40,49
p=42,93 v=38,85
p=40,78 v=41,-60
p=33,64 v=42,-48
p=36,62 v=72,-55
p=13,29 v=12,-65
p=77,54 v=-10,-54
p=67,70 v=96,-92
p=4,39 v=-69,-9
p=65,97 v=-47,-62
p=40,97 v=26,41
p=21,69 v=35,56
p=100,4 v=-56,13
p=19,57 v=88,-66
p=93,96 v=13,-86
p=14,37 v=-53,4
p=55,58 v=-35,-79
p=35,44 v=10,-27
p=63,65 v=-36,-17
p=69,8 v=60,67
p=0,22 v=66,48
p=13,47 v=-24,16
p=66,17 v=-62,-98
p=93,14 v=-51,1
p=44,45 v=23,33
p=92,10 v=63,-73
p=47,81 v=54,-30
p=64,43 v=90,-92
p=0,23 v=14,4
p=49,57 v=75,61
p=80,42 v=-90,-21
p=61,99 v=-5,-60
p=61,98 v=93,-89
p=79,7 v=-90,-7
p=83,14 v=-20,-53
p=22,72 v=17,35
p=51,56 v=-69,-49
p=76,13 v=25,2
p=55,18 v=47,-3
p=61,93 v=-15,51
p=21,81 v=-45,-6
p=84,42 v=-2,-5
p=20,46 v=-1,57
p=62,62 v=-75,65
p=80,25 v=65,-20
p=20,35 v=64,91
p=78,25 v=68,-45
p=50,21 v=-78,-57
p=47,34 v=-83,-41
p=19,33 v=43,-82
p=42,99 v=-21,-97
p=95,44 v=-90,-66
p=39,62 v=60,-80
p=49,87 v=18,93
p=68,43 v=-83,-98
p=36,64 v=-19,-67
p=88,7 v=14,-77
p=93,32 v=-12,-16
p=59,78 v=-88,56
p=17,87 v=2,-93
p=39,90 v=-22,23
p=58,41 v=-65,54
p=100,47 v=-35,-91
p=10,38 v=-27,74
p=93,90 v=89,85
p=37,64 v=54,77
p=4,5 v=69,-61
p=17,69 v=69,-1
p=91,40 v=-56,-42
p=12,33 v=22,97
p=39,7 v=-57,-15
p=50,25 v=-48,13
p=37,60 v=-79,-47
p=79,26 v=42,-57
p=92,1 v=42,-60
p=65,29 v=-23,-4
p=41,26 v=75,8
p=58,65 v=-83,86
p=54,98 v=-19,36
p=41,18 v=93,13
p=3,81 v=-89,47
p=70,95 v=-36,-1
p=50,24 v=28,-91
p=24,21 v=-19,-42
p=64,20 v=62,62
p=86,52 v=81,53
p=28,24 v=7,-43
p=2,63 v=-97,98
p=91,55 v=14,-79
p=52,92 v=83,31
p=86,93 v=-38,-37
p=70,52 v=12,99
p=14,47 v=-48,23
p=99,58 v=-61,-79
p=20,19 v=74,33
p=33,73 v=-41,80
p=94,12 v=-43,84
p=0,39 v=66,-60
p=76,8 v=-41,-72
p=15,99 v=-97,6
p=13,24 v=93,-21
p=88,96 v=32,-64
p=98,29 v=-74,12
p=20,79 v=48,14
p=69,78 v=36,-66
p=99,25 v=37,-33
p=59,88 v=80,6
p=45,47 v=-83,-25
p=61,15 v=-31,-3
p=83,71 v=-64,-14
p=5,43 v=62,-75
p=98,71 v=84,-10
p=45,72 v=45,31
p=23,34 v=-63,62
p=44,101 v=-52,-57
p=43,99 v=98,-80
p=12,42 v=-71,-25
p=74,99 v=16,-93
p=36,19 v=15,42
p=17,55 v=-22,81
p=91,94 v=50,72
p=81,42 v=11,-83
p=39,33 v=-11,-39
p=78,58 v=81,98
p=62,94 v=-5,-96
p=9,68 v=-21,-15
p=54,84 v=-26,97
p=67,45 v=97,9
p=94,69 v=45,7
p=13,18 v=-97,83
p=33,53 v=67,12
p=49,79 v=67,-22
p=15,90 v=-32,-27
p=89,54 v=50,28
p=11,6 v=87,96
p=89,58 v=19,-59
p=95,1 v=27,-68
p=5,71 v=-6,90
p=36,71 v=-19,-67
p=18,92 v=8,76
p=25,23 v=18,-38
p=81,36 v=-46,-25
p=50,21 v=23,5
p=41,67 v=-52,-44
p=3,50 v=22,41
p=67,47 v=93,23
p=88,79 v=89,10
p=27,35 v=-19,62
p=37,1 v=15,22
p=90,0 v=29,39
p=74,22 v=-33,-57
p=13,95 v=74,-15
p=9,8 v=84,10
p=78,87 v=52,18
p=67,3 v=73,84
p=30,97 v=76,60
p=17,68 v=-65,7
p=72,51 v=7,28
p=85,69 v=-51,81
p=18,98 v=95,-27
p=62,48 v=-52,82
p=37,5 v=-16,-69
p=27,19 v=90,91
p=95,76 v=-97,85
p=55,89 v=-33,-33
p=49,89 v=-39,-19
p=79,76 v=-62,-8
p=29,77 v=-24,97
p=82,53 v=-51,86
p=94,45 v=76,-99
p=91,39 v=-35,-86
p=10,51 v=-97,8
p=10,45 v=52,-10
p=100,17 v=17,22
p=71,50 v=-50,-21
p=10,66 v=-4,98
p=53,13 v=-78,51
p=0,92 v=-5,83
p=70,59 v=-67,-5
p=34,29 v=54,-86
p=99,84 v=-71,-80
p=37,21 v=72,-86
p=98,16 v=69,57
p=81,64 v=37,-10
p=92,22 v=-74,-40
p=27,78 v=51,-18
p=99,63 v=-74,40
p=35,36 v=40,10
p=58,35 v=57,62
p=57,33 v=-34,-53
p=94,72 v=-12,56
p=3,24 v=-49,-25
p=53,87 v=-96,-22
p=26,82 v=-37,48
p=56,31 v=75,25
p=72,99 v=1,82
p=70,60 v=-92,15
p=46,47 v=41,-99
p=8,31 v=74,-66
p=97,71 v=-74,-84
p=8,91 v=4,-93
p=62,20 v=42,17
p=17,83 v=-9,-19
p=18,82 v=-58,-63
p=24,4 v=82,2
p=42,59 v=-21,40
p=94,86 v=-46,80
p=58,62 v=5,-52
p=77,6 v=73,30
p=35,46 v=-78,-66
p=44,59 v=7,-22

View file

@ -0,0 +1,54 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import qualified Data.List as L
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
type Pair = (Int, Int)
type Robot = (Pair, Pair)
type Input = [Robot]
type Parser = Parsec Void String
parseNumber :: Parser Int
parseNumber = read <$> some (digitChar <|> char '-')
parsePair :: Parser Pair
parsePair = (,) <$> parseNumber <* char ','
<*> parseNumber
parseRobot :: Parser Robot
parseRobot = (,) <$> (string "p=" *> parsePair)
<*> (string " v=" *> parsePair)
parseInput' :: Parser Input
parseInput' = some (parseRobot <* eol) <* eof
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
compute :: Int -> Int -> Input -> Int -- the minimum safety score is the answer
compute width height input = fst $ L.foldl' (\acc@(_, a) n@(_, b) -> if a > b then n else acc) (0, 1000000000) safeties
where
safeties = [(i, safety i)|i<-[0..width*height]]
mx = width `div` 2
my = height `div` 2
safety i = product $ L.foldl' score [0, 0, 0, 0] $ map (step i) input
step i ((x, y), (v, w)) = (((x + v * i) `mod` width), ((y + w * i) `mod` height))
score acc@[a, b, c, d] (x, y) | x < mx && y < my = [a+1, b, c, d]
| x > mx && y < my = [a, b+1, c, d]
| x < mx && y > my = [a, b, c+1, d]
| x > mx && y > my = [a, b, c, d+1]
| otherwise = acc
main :: IO ()
main = do
input <- parseInput "input"
print $ compute 101 103 input

View file

@ -0,0 +1,10 @@
########
#..O.O.#
##@.O..#
#...O..#
#.#.O..#
#...O..#
#......#
########
<^^>>>vv<v>>v<<

View file

@ -0,0 +1,21 @@
##########
#..O..O.O#
#......O.#
#.OO..O.O#
#..O@..O.#
#O#..O...#
#O..O..O.#
#.OO.O.OO#
#....O...#
##########
<vv>^<v^>v>^vv^v>v<>v^v<v<^vv<<<^><<><>>v<vvv<>^v^>^<<<><<v<<<v^vv^v>^
vvv<<^>^v^^><<>>><>^<<><^vv^^<>vvv<>><^^v>^>vv<>v<<<<v<^v>^<^^>>>^<v<v
><>vv>v^v^<>><>>>><^^>vv>v<^^^>>v^v^<^^>v^^>v^<^v>v<>>v^v^<v>v^^<^^vv<
<<v<^>>^^^^>>>v^<>vvv^><v<<<>^^^vv^<vvv>^>v<^^^^v<>^>vvvv><>>v^<<^^^^^
^><^><>>><>^^<<^^v>>><^<v>^<vv>>v>>>^v><>^v><<<<v>>v<v<v>vvv>^<><<>^><
^>><>^v<><^vvv<^^<><v<<<<<><^v<<<><<<^^<v<^^^><^>>^<v^><<<^>>^v<v^v<v^
>^>>^v>vv>^<<^v<>><<><<v<<v><>v<^vv<<<>^^v^>^^>>><<^v>>v^v><^^>>^<>vv^
<><^^>^^^<><vvvvv^v<v<<>^v<v>v<<^><<><<><<<^^<<<^<<>><<><^^^>^^<>^>v<>
^^>vv<^v^v<vv>^<><v<^v>^^^>>>^^vvv^>vvv<>>>^<^>>>>>^<<^v>^vvv<>^<><<v>
v^^>>><<^^<>>^v^<v^vv<>v^<<>^<^v^v><^<<<><<^<v><v<>vv>>v><v^<vv<>v^<<^

View file

@ -0,0 +1,109 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Functor
import qualified Data.List as L
import qualified Data.Vector as V
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 2028
example2ExpectedOutput = 10092
data Tile = Wall | Box | Floor | Robot deriving (Eq, Show)
type Line = V.Vector Tile
type Warehouse = V.Vector Line
data Op = N | S | E | W deriving Show
data Input = Input Warehouse [Op] deriving Show
type Parser = Parsec Void String
parseTile :: Parser Tile
parseTile = char '#' $> Wall
<|> char 'O' $> Box
<|> char '.' $> Floor
<|> char '@' $> Robot
parseLine :: Parser Line
parseLine = do
line <- some parseTile <* eol
return $ V.generate (length line) (line !!)
parseOp :: Parser Op
parseOp = char '^' $> N
<|> char 'v' $> S
<|> char '>' $> E
<|> char '<' $> W
parseInput' :: Parser Input
parseInput' = do
line <- some parseLine <* eol
ops <- some (parseOp <* optional eol) <* eof
return $ Input (V.generate (length line) (line !!)) ops
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Coord = (Int, Int)
next :: Coord -> Op -> Coord
next (x, y) N = (x, y-1)
next (x, y) S = (x, y+1)
next (x, y) E = (x+1, y)
next (x, y) W = (x-1, y)
compute :: Input -> Int
compute (Input warehouse ops) = V.ifoldl' scoreBoxes 0 warehouse'
where
scoreBoxes :: Int -> Int -> Line -> Int
scoreBoxes acc y line = V.ifoldl' (scoreBox y) acc line
scoreBox :: Int -> Int -> Int -> Tile -> Int
scoreBox y acc x Box = acc + 100 * y + x
scoreBox _ acc _ _ = acc
warehouse' = fst $ L.foldl' step (warehouse, start) ops
step :: (Warehouse, Coord) -> Op -> (Warehouse, Coord)
step a@(w, r@(x, y)) op | t == Wall = a
| t == Box = case push w r' op of
Just w' -> let line = w' V.! y'
line' = line V.// [(x', Floor)]
w'' = w' V.// [(y', line')]
in (w'', r')
Nothing -> a
| otherwise = (w, (x', y'))
where
r'@(x', y') = next r op
t = w V.! y' V.! x'
push :: Warehouse -> Coord -> Op -> Maybe Warehouse
push w r@(x, y) op | t == Wall = Nothing
| t == Box = push w (x', y') op
| otherwise = Just w'
where
(x', y') = next r op
t = w V.! y' V.! x'
line = w V.! y'
line' = line V.// [(x', Box)]
w' = w V.// [(y', line')]
start = V.ifoldl' findRobot (0, 0) warehouse
findRobot :: (Int, Int) -> Int -> Line -> (Int, Int)
findRobot (0, _) y line = (V.ifoldl' findRobotInLine 0 line, y)
findRobot a _ _ = a
findRobotInLine :: Int -> Int -> Tile -> Int
findRobotInLine 0 x Robot = x
findRobotInLine a _ _ = a
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
example2 <- parseInput "example2"
let example2Output = compute example2
when (example2Output /= example2ExpectedOutput) (error $ "example2 failed: got " ++ show example2Output ++ " instead of " ++ show example2ExpectedOutput)
input <- parseInput "input"
print $ compute input

View file

@ -0,0 +1,71 @@
##################################################
##...O...#OO...O.#....#....#O#O..O..O......O..O..#
#OOOO.#.O.O.....OO#...O.OO.O....O.#..OO....O#OOO.#
#...#.#O..O...OO......O.......#....O..O#.O..OO...#
#.O.....O..#.........O......OO..O..OO.OO....O.O..#
#.....O.OO.O.#.O...O..#.OOOO..#...#.O.OO.O.#.#OO##
#...OO.#..O.O.#.O..OO..O....O...OO.OOO.......O...#
##.O.....O..#O...........O..O.....O.......OO.....#
#...O..O....O...O...O...O..O..O...O......O..OO...#
#.O##.O.OO.....O.O.#....O#.....OO.O.O.#..O....#O.#
#.............#.O........OOO.OO..#.............O.#
#OOO..O.O.........OO....O.#......#.OO.......O..O.#
#.......#...O..#O.OO...O..#O.O...##O#O......O##..#
#O#.O..#........O....O.....O...#O..#......O.O..O.#
#O..O..O#...#.......OO.OO..O.....O..O..O.O.O...O.#
#...O.O...OO.......#O#O...O.##.....#..O.O.....O..#
#.#OOOO..OO..O....O.O....OO.#.OO..O.......O....#.#
#..O...#.....#.....OO..#O....O#.O....O..OOO.O...O#
#.O.......OO.O.#........OO...O..O#..O.#..##...#.O#
#.O..#..........OO.O.O..O..O.......O...O.O.OO....#
#.O..##..........OO..O..O.....#OO#...#..O....O...#
#O.OOOO.O..O........O#.#OO.OO...OO.#OO..OO#O.....#
#..OO..........O...O....O.O.....O.....O...#..O..O#
#.#O..O..O.....#.O...#........O.O.O..O.......#.O.#
#..##..O.....O......O..O@........O....O#.O..OO..O#
#...O..##O.#....#.......O..OO#..O.O.....##O....O.#
#....O.O...O.OOO.O.O#..O..OOOOOOOOOO#.....O...#.O#
#O.....#O..O..#..O....O.O..OOOO.#.O.O#....#.O.O#.#
#..O.O..#O..............O....###..O#.O.....O.#O#O#
#O...O.O.#.#..O......OO.OO#..O...O.O....O#.O...OO#
#..OO.O#.....O##.O##....O..#..#..#O..O.....#....O#
#....#..O..O....O.OO...O.......OO.OO...O.O.....O.#
#....O.O.#O.#OO.......O......O........OOO..O.....#
#..#...##.O......##.....O..O.O#.O...O....O..#.O..#
#...O.O..O....O..O.OOOOOO...#.O...OO.#.....OO.O..#
#O.......O....#.OO.OO...OO...##O......O.O........#
##.O.OO.OO...O..O#......O.O....#.............O.#.#
#O#O...O..O..OO.O.O...OO..O.O..OOOO..O..O...O..O.#
#..OO.O#O..O..#.O..O.#...#..O.....OO..OOO..O...O.#
#.O.O..OO.....O...O.....O..#..O..#.O.#.OOO...O.O.#
#.O..O.......O...OO#.#..O....O...O....O..........#
#....O..O.OO...OO..#....#O.OO.OO##.....O.........#
#..O..O....O...O....OO#.#O..O.#.#O.O..O...#....O.#
#.O.....O.#.O#.O..O.OO.O#............O..........O#
#..O#O.O.........O.#.O#O..#O.O.........O....O..O.#
#..O.....#OO..O..#.#.#....O.O.OO.O.O......O#.#O..#
#.O.O..O.O.O.O...O..O..OO..................#OO...#
#..O....O....O.....OOO...OO..OO.......O....OO....#
#.O....OO.O................OO....O.O#O.O.........#
##################################################
>v>>>^>>v>vv^v^^v^^^<v^vv^vv<<>^v^^^<<<vv<>vv^^>v>v^^><>^<v<v><>>^>^<^^v>v<>^^v<><<^><v>v^v<<^>^>^>^>>vvv>^<<^^^^^><vv>>^>^^>^vv>><v^^v^<<<>^^<<<^^^vv^<^<<<>v<^v<v>^<>v<^>>^v^<>><><<^<>v>^>^>v>>v>vv^><v<v^v>vv>><^^<<>>vv<<^vv>^^vv>>><^v^>>v<<<<v>^<><>^>v^vv>v>><><^vvv>^><<>^<<<vvv^>^vv<<>v^^^>v<>^^vv>vv^<>^<>vvv<vvvv^^^<^vv^<v^<<vv^v<><vvvv^>vv<>><><<v>><^>v<>v<v<v>^v>^<>^v>>><^>>v<<<v^>^v>v>^^>^v<v^v^^<vv^v^><<^^<v^v>>^v>>>>>v<v^>^>^v^>vv^v^><^<v>^^<>^v^>><>>><vv<<>^v<^vvv<v^vvv^>v<<v>>^>><<^v^^v>^^>^<<<>v^^>><<v>^<v^<^>v>>>^^^<<vvv^>vvv>^><v>^>vvv^^^v^^>v^><v>><>^<v<<vv^^>>^^v>><vv>vvv>^>>>vv^><^<v<<<^^v>v^<v^^>^^<<<>v^vv<vvv>^v>v<^^>vv>v<>>vv<><v>v<^^<<^>>v<v^<>^<<v>><<vv^<<<<v^^^v^^<^<^<>v><^<>>v>v>v>v>v><v>>v<<^>>><v^v<v>>v^><^v^>>>^>^<<>>^^v><^<v^vv^<><>>v^^>v<vvv>v<>><<<<<>><<><v<>vv><^^^><vv<v<<>v^>v>>^^v^v^>vvv<v^<>><<<^>vvv><^^v>v<>v><^<v>v<^<<^<>v>>>>^<>^^^>v<v<<vv><v>>>^<^>v^><vv>^<<v<>><<^<>>>^v>><<>v^^v<^>v^v^>vvvv>vv<<>^^^<v>^<<v>>><<>>>vv^<^><><^^^>^v^<><>^<vv<^vv^^v>^<
<^>vv>v>^^>^vvvv<<^><^<>>^<v>v>>^^<v><^<>><<<>^vv<>v<v^>>>^<<^<><<>^^vv^^<<><<vvv>v^^>vv^<v<<>>v><^>v^>>^^v<<<<^v<v<<>>v><v^>vv^<vv^>^v>^^>>><>v<><^v><vvvv^v<<>>^^v><>>vv^>v>v^>^>v<><^v>v^^<<>^v^>^>v<><^v<^^vv<>^^^v^>>><<><<<<v^v^><v<v<^^^><><^<<^^^vv<^^<^<v>v<<v^>>v<>>^<vv<^<v><>^<^v^>^v>>>^v>>v^>^^v^>><<v>>^<v>^vvv<v<<<v>^<>vv<^<v<>^<>v^v^>vv^v>><^>><>^^^<<v<vv^<vv>>v<^^^>vv<^^>vv^^^^<<^<v^>v<v>vvv<v<<^^><v<<^>^^<>v>>v><^v^<v>vv^<v<<v>v>vvv^>v<vv>>>>>^^v<<>^><>v^^^>^^>^>^^vvvv^v<v>>^^^v>>^<v<^^v>>><<>^^><<<^>v^^^v><v<v<v^v^><>^>v<v<^^^>>>vv><<^>><v>><<v<<vv><^^^<<^<>v>^v^v><<<<<<>>vv^<<<><<><><<^<^>^<v<^v>>>^>v^>^v>^v^<^>^v>><<<v>v^^vvv><<^>v^^<><v^>><<v><^^>>v<<<<<^>>><><vv>v<<>>^v<><<^>>v<<<^<^>>^>v^>^v<v>^v>>v<^>><<>><>vvv<<>vv^>v>><><<^><vvv>v><^>^<^v><>>v><v><^v^vv><>^^>>>v<^v^<^v>^v><vv<<v<<v><>>><v<vv<>>v^^>>>vv><v<<<<><v^^>>v>^<v^^>^v<<<><v>v>>^^<vv<v^v>><^<^^<>><v>^<^^<><^^^><>^<v^^^<v<^>>^v>vv^^<^v>><<vv><<v>><v>>>^>>><<<v<<><^vvv^<v>^>vvv^v>>v><<>v><<v<vvvvv^>^>><v^>vv^>>^
vvv^v^><<v<>><><><<<^v>^v^><>^vvv<<^<<v^v<>>v<v^^>>^>v<v>^v<v^v>^<<vvv<^^v<<<<>v^v<<<v<^>><v^vv^vvvv^v><><v<<^>v>v^v^<v<v<^<><^>^vv<^^v<^^>vv<<>^^<>><<<<^^>>>^<^^>vv<>>>^^^^vv^>^v^v^^>^<<<>v^<v>^^^>v<^^<<^<v><^vvv>v>v>v<^>><^<^<>>>^^<<<vv^>>><>>v><>^<>^^<v^><<vv>vv^v<<>^>v><vvv>v^>>v^^^v<<>>^v><^<>^>^<^>^^<vv<>>><v^v^>>>^^>>^v^^^>>^v>v><^^^v<>>vv>>v^^<><^^v>v<^>>v<v^v^v^v^vv^vvv>v^vv>^v>vv<vv<^<<<v^v><<v>v<<^>vvv^^^^>>^>v>^^<>vv<>^^v><v<<^v><><><^<vv^>v^^>>>^^vv>^v>^<>vvv^v<^vv^<<^<^^<>>^<<><vv^>^>^^v^<v><v^>><^^>><<><<<<<<^>^><^v>^v>><v><v<>vvv>^^<^<<>v>>vv<v<><^<<^<>v<v>><><>^v><v<^^^<>>vvv>^^>>>v><v><^^>><<^<v><<^<v<<vv>>^vv<>v>^><><<<<<v>>>v^^v>^<>^<>v^^>>^<>>v^>^<>>>><>><v^v>>v>^<<^v^><<>>^v>><>><>>>><>vv<<>>^>v^v^<vvvvvvv^>v<<<^^<>vvvv^<<><<v^<<vv^^^v^^<<><v>v^^<^^v^^<>^v<>vvv>>^^v^^^<v>v^^vv<^^^<<>^v^>>^^<<^^v^^v<<vv^<<>>>v<>vv<v^v<<>vvv>^<v>v>^v<^^v<>^>^<><<v>v<>v^>v^v>><<><v><>>>>v^<^<^><>^v^<^><<v<^v><>>^v^^^v^><>^v>v<<^v>>^<<v<>v<^<<<<>>^><<<vv<^v^<^>^^><^^vvv^><v<><^^<>^v^>
vvvv^vv^>>^v^v<^<vvv<>v>v>vv>^>^><^vv><v^v>v<><>v^v^>vvvv<<>v<^^^vv<^v><>^>^>v<>^>^vvv<>^>^<^^v^<><<>^>^v><v>^v>v^<v^<>>^^>^>v^>v>>^^<v><^<^vv>^vv^v^>v><^vv>^>v>^><>v>v^^>>v>^<<v^<vvv>>v<v>v^^<>^v^vv^<^^<v>>>v>>^v>vvv^^v^>v<vvv^<><v>v>v<>^^v^^<vv<>v<vvv>>><><<>>v>^^<^^^^><v>^>v<^<^>v^^>v>^>>^><<<^vv>vv^v^><v^<v>vv>^<>^vvvv^>vv>^>v^>v<<v^^<v^<v>>vvv<<v<>>>v^>^vv>^<v<>>^^v<vv<^>v<>^<<^^><>^^v>^v>>^<v>vv^v<<^^>^<v<><v>vv<><vv<>>v<^^^><<^^>^v<>vv<v>><<<v><<>>vv^>>^vvvv^><<v<vv^v<vv<>v<><v<<><v>vvv>>vv^^^<><^v<><v<^<v<v<^>>vv<><<>^^>><<v><^>vvv^>^vvv<>v^^<<^<vv>>v>^>v>^^><<>v<v^>^<<<<vv<<^^^>^>^>v<>>vv^><v<><<><^><><^^vv>>^<^vv<^^v<><<><>vvvv^^^<>v>>v^<vvv<v<vv><<v^v<v>>^v^<<^>>vvvv^v<<^<^vv<v<v>^v<^<^^>vv<v^^^>>^<^><^^v<v^v^>^^^v^v>^>^><^>>^v<v<^^^v^>>^v>vv>^v<>^v^^^v^v^>v>><^^<^v<<v<^v<>v^<>^<>^v<v^^v<^>v<v>^v<<><<<>^v><<<^>vvvvv^v^^^<<v>>v^>>^^<<v^^>vv^^vvvv>^>v^<<<^<>v><<^>^v^<^>><<<v<vv>vv<<^>^<^^><>>^^v>vvv^<^>^^^^<^v<<>^<>^>>v>^<><><>>^^vv^<<>><^<v><>^v^vvv<<>>^<>^>v<<^><<^>^<^>^<<><
<<^<^>><<<vv>v<v<^<>>>v^>vv><>>vvvv<<^><<<>v<>v^v^<>v>v<^^<<v<vv^<<<vv>^<>^^vv<><v<<^v^v<^<v>>vv>><^^^><v<^>v<vvv^v<^<>vv^>v<>>>^vv<<<<<^><>^>^<vv<><^>v<vvv>^v<>><>><>>>>^vv^v^><^^v<vv<<v<>^<^<v<><<>v>^^^vvv>v<<<^^<^>v^^v><>><^^^^<>vv^^v^vv>><v<v>>v^<v>vvv>><v<>v>^>v>^^<v^^<<^<v^<v^v^><>^vv^vvvv^^v<>^><v^^<>>>^vv>v^^^^<v<<^>>>>v>>^>v^^^>><^^vv^v^vv<v<vv^<><^^>v>^vv>>^<v^v><^^^>^<<<^>vv<<>^v>^>v^>>^v<<>^^>vv^v>^v<>vv>v<>v>vvvv><<^^<>^<<v><^v<<<^><^<><>>><v>v<^^vv<^^^v<<>^>>>vv>^<<^<>v<^vv<v<^^><<>^v^v>^v<><<^<<v>>^<^v<>v>^>v>>v>><>v>><v>v^vv<v<^<vv<v><^<><><>^>^><^>>^<^vvv>v<v<<<>><^v<>^>><>^^^^>>v><v^^v^><v^v<^v>><>>^<^^^^v>^^^^>v>v^^vv^^>^^v<<<^>>><^^^^<^^^><^><>^^^vv>vv<>>v^>>>v^<><>^^><v>><><<^<v>>v>>^><vv<^>>^v<vv>>^>v>vvv^>v^^>>^vv^<<<>>^vvvvv<v>vvv^>>v^<>vv^<<<^v><v<<>v<>v^v<<v<<<vv^><>v>>^>vv>v^^<<v^>^><>vv>^^>>>><<<><>v><vv>>>v^<>>>^vv>vv<v^^v>vvvv<v<vv^>v^^<vv<>^<><<>>>v<>v>>v^^>^><<<<>>^<v>v<^^><>>>vv>v>>>^<>^v<v<<<vvv<^v^<v^v<<^^>vv>>vv^>v<<>^^v^>v<^<>>^<>vv^>v<<^v^<v>v<vvv^
<>vvv^<v^vv>v<>^v>>>^v<^^>v>>v>>^^<^<^v<^v^^>^>>>>^^>><<><^^^^>^^v<>^^v>>v<^v<><^<^vv>v>v^^<<^v>>vv>>v<v<<^<v^<^>^v^^<^<<><^<>>^^>v>v<>>^<^<<>^vvv<>^<><^<v^>v<v<v><^vvv^^<^<^<^v>^^^<>vvvv>>>v^<v<><^^v>>^>v^<v><<><>>>^vv<>>vv>^^^v<^^>vv>v^>>>^^><v>><^>v<><>^^<^>^^^v>^^^<vv><v^^>v<<<^<>><<>^^^vv>>>^^v^^<v^<>v<<^>^^<^<>vv<vv>>^vvv<v<<>v<<<v>v>^v>^>^<vv<^<v^^<^>^<^>^>>^<<>v<<v>vv<><vv^>^^>^^<>^^<^<><<^>v^^^>^<^>v^v^<^vv>v>v<>>v<>v>>>^<<<<^^>><>v<v>^^>v<^^>v>v^v^>>><>>><<^>vv><<vv<<v>^vv<^<>>><v<^>>>^>^><<^<<v<<<>>>vvv<v<>vvvv><><^<><v^v>^v<<<^vvv>v^^><>v^><^<vv>^>>^v>^<^v<<^^<<^v<^><^^^v>v<<^^>v>vvv^v>>><^>v<<^<vv^>^>vv^><^^^><v<^^vv<vv^^v^>vvv^v^<>^>>>><>v^>>^>v<v^^^<<<<v^<vv^>v><^^<vv><v><^<^<^^><v>>><>v<^vv>^^<>^<<><v^^<>v^v<>^>^<>v>>^<>>>v^v^<<<^v<vv^^>><^>v<><^<^>>>>v<^>>>vv<^>v>>>>v^^vv>^^^<v^vv<><^<>>^v>^v^^v<>>v<^>^<v^^^^>>v^v><>^<^>^vv<v^^<<<vv<v<><vv^<v^vv>v>^>>><vv^v^><<^>^v><<><>vv^>^v^^v>^<v^<>v<^<<<v^<><<vv><v>vv<v>>vv<<><vv^v<v<<vvvv>>><^<>>^<^vvv^>v<<<>><^v<>vv^vv<^<v>>^v<v
v>>><>v>>^^<v>^<v<<v<>^<^<>>vv<^^>vv<<^<^v^<v^v<^^^>>v<vvv>>^>v^v>><<v>vvv<^v^v<>vv>^<^>>>^<v^vvv^vv^v^^>v^vv<>v>^<<<v^^v>v>v>v<>>^v><v^^^><v<^^<^<v^^^>>v>>^>^v><v^>v<>^<vv>^^>v><<vv^<v<vv^>>^<<<v<^v>>^v><^>^>>><<<^<v^^v^^v<^>>>>^>vvvvv<>>v>^v^^v>v>>^<v>^>v<^>>v<<v>^^<^v>v<<<<><^v^<>^<^<><vv^<v^vv<^>^v>>>v<<>v><^><<>>^>^<><^^^^<^^><><<<v<>^>^vvvvv><v><>vv><>v^<>^vvv>>>^><<<><<<v<^<v<<^<vv>>v^>>vv^><><>^<^^<>><v<v^<>>><<v^v^^^vv<>v<^>>v^<><^><v<<<v>v><v><v<^<^vv><^>v<<v^^<^<^><>>v^v>^>>>>v^^v<>^v^v>v><>^v>^v>^vv^<<^^^vvv>><<<vvv<<^>v^v^v<vvvv>^>v<v>^>^v>>v^>^v^><<^><^>>^<>^<^^<^^^vvvvv<>^v^>v><<><^v^v^>^<<>^^><v^v^^><v>^v<><<^vv<>^<>><^>^^>v>^v>>^v>vvv>>^^v<^v>vv><^>>>><^v^<>^>>^<^><><<vv<<>v>^<>><>v^>v>^^<<v<><>>^^<>>>v<v>>><<v<^v^><>>><^^<><<^v>v^>^^<>>vvv^<<<v<<vvvvvvv<^<^v<v^^<<^v<v<v^<^><^v<v>v>>^>v>>vv^<>vv>>v>>v><<<v><<<vv>^<<><^>^v^v^v^>^<^v>><<>v<<^<>v><v<<<<<v<<<<^^v>v<^^^<v^v<<v<^vv<^<<>>^v<<<v>^><>^^<>>v<v^v>^^<<<v^v^v>v^<>vvv<>><<v>v<^<^<v^v^>v<vv<^>>v^>^>vv<^v<v<^<^v^>v>v^
<>^>vv>^>^vv>v<^<<<v<vvv<v^>>^^<>>><^<v>^v>v><^^^^<^vv<<v^v>v>^vvv<<>><>v>v>v^<><>>v^^>>^v>^^<v^><<><vvv^v>v^<^v^><><<>><^>v<v><<><<v^<>^>^^>v<>>v>vv<^<^v^^<v>^v<<<^>><><v>>^<>^v^>><><<>v>v>>^^v<<^<<^^>^^><>^><v^^>>><v^^<^v^<<>>>^^><^v>><^<><><>^^>>v<><>>>^vv^>^v>vv>^>v^^^<<<>^vvvv>v<^v^^v<>^^<>>v>v<>^>>^^<^>>v<v<>^>><^^>v^v<^^>^^v>^vv>>>vv<vv>^>v^^v>>>>^^>^vv>^>^>><>>>^v>v>><vv>vv>vv<v<v>>^^^<>v^<<v^v>^^vv>^v>>><<<<v^^><v>^vv^^<>^v^<^v^v<vv>>v>^v^vv^vv<^<vv^<>v><<<vv><<<^^^v<^>^^><>vvv>v^>^^>^vv>vv>>^<^v>vv^<v<^><>v^^v>>v^<^vv^v^^<v<><vvvvv<<>vvvv^<vvv<><<^>vvv>v>v><<>>^>v>^<<^vv^<v^v<v^^v<^^^><>vvv<><v<^^>>>^<<>^<<^^>^v><v<<<>^<v^<<<v<^>>^^<<^v>>><^>v>>>^v^>v^>^<^v>^^<^^<^<<v^><vv>^^v<>v^^<^<v><>^^<>v<v><vv<^<<v^^><^v><>^<>^<>v^<<^v>^>vv>>^^v^^><>><<v^><^<v>><>^^vvvvvv^^<^vv<<v<<>^^>^v><v><>^v><^<<^^vv^>v^<^<^^^vv><>^vv<^^v^<><v^v>^v^v>^^^v^<<><vvv<<>>^vv<>^<><^>v>^<v^>^><>^>v^^<<<<><><<>^<<<>><^^<v<<^<<v<<v<^>v<<<^^>>v^v^v^<^><vv^>v^<v^<^^>v^>v>^^^^vv^^<v<><^<<<<v<v<v<^v^v>vv<>^^^^<
^<<^<<><<<^<>^<<><^<^v><v>^<<v^<^vv<>^><^^<<<^<<vv>^v^><^>>v^vv>v^v^v<^vv<^<v^^<<<^^^v><<v^<>^><^<><><>v>v><<vv>>>vv>v<>v>^<<v<^^vvvv^^v>vv^><vv^<><<<^v^^vv<v<<>v^v<><^^v^^^<<v<v<^<<^<<>>^v<vv>^^vv<vvv>^^v<^^v<v<><^><^v^>^<^^^v>^<v>v<^v><>>>>>^<<><<v^>><>><<^^<v<<>^^v<^<<<><>>v<>^<<^^vv><^vvv>^v>^<>><^><>>^^^^^v<><<v><<^>^<^>v>v>^^>v^v>v>^>^<<<<<v^>^<<v^v>><v>v<^>vvv<^<>>^<v^^v^vv<^vvv>v<>v^<vv<^>>><^^^^>>^><vvv^v<v>>^vv<<^><>>^^vvvv<><>>^><<<v^>v><>>^vv<>v>^>^v>^<>^<<<v>v<v>>^v<>v<<>><^>^^^<>^^v><>^<v^<>>>v^<^>vv<>^<>^v<v<><v<v>v<<<^>^<<>^<>^^>^^>^^><<<<v<^^^^<>><^<>><<^>v>^^v<v<<^v<v^>>^^v<^^>^vv<<>v^<^<><>>^<>v^<^v^<<<>><v<^^^<<^^<v<<v^>v>v^>>v^>v^v^<v<v>>v^^^v^<><vv<<<v<<>^v<<>>^v<<<>><<<<<v^>v>v><><<v^^^^v^<>vv^<vv>^>><v>^<<v<>>v>><>>v^^^>vv^>>><^>^>^>^<<v^^^<><^>^<<v<^^<^^^^<>v^^v><^<^><>>^<vv>^^<><^vv^v^<<^^v<vv^<^v^vv<>>>^vv<^v<v><<^^vv><v<^<>^^<><<>>v^<<>^^>vv>>^>^>>^vv<^><vvv^<vv>v<v^><<><>v>v>vv>^>v<>v^^>^<<>v<v>v>vv>vv^^v<<^v>><v^<<>v^><<<^^>^>><v>>>^<>^<<>><v>^^^^v>^^^^vvv
^>^><v>v^^v^^<vv<<<><^^<<>v>v^^^<v>><<>v><<<>^^^^<v>^^^v<<>v<v^>^v<v<^vvv<>v^v>>>v<>v<>><^v^<^v<^<<vv><v>>>>v<><>><^vvv^v^><>>>vv<>v><v>^<<>v<<^>v>v<>>>v<^>v<^><<>>>><>><><v<<>vv<v<^vv^vv>v>^v<^^v<v><<^^<<><v^><^<<>v>>>^^<<<<<v>v<>v>v>v<^<>^v<>>v>^<<^<vv<<^v>><^>>>vv><>v<^<<<vvv^v<><<vv^^vv^>^<>^^^<^<>>v<^>>vvv<<>>><^><>^vv<v<<<<>^>v<v>^<<v<<>vvv><>^>>^<<>v>^<<><<^^^<v^vv>><>><vv>>^^<^>>v<<<<<vv^<^<^^<<<^v<^^^v<>>v^>v^vv^v^v<>v>vv<v<^^v<<<v>><>vvv^v>v^v^>><><<<>^>>^<v><>vv<<<v><<v<vvv><^vvv^<v>v^v^^><<^<v>v^vvv>vv^^v^<><>>^^v<>>>><^<<<>>>v>><>>^v^<<^v<v>>^v>>>v><v<>>^^v^^>^vvv<^^vv><v<<v<><><<>v^<><<>>>v<<^v>v^<<>v>^<^^>>v^vv><vv^vv>v^v>v>v>v>v>v><v^<v>^^<<><<vv<^<<><>^vv><<vv><^^^^>vvv>>><><v^vvv^<<>><<><^^v^><><><<v>><>v>^<^<>vvv^>>v^v>>^<<v^<^^v>^^>><>>^v^v>v^^v^^>^<^<<^^v^^^<<^>^^><>vv^^><<v^<>>^^^v^vv<^^^>v^^v^<>>^<v<<^>><^>>>^>>>>^v>>^vv<>v^><>^^^><^<>^<^v<vvv<<<<><v^^^><v><v^<><^^>>>^<^v^<^^>^v<>>v^vv^>>>v><>v<><^<<<>>v>v<>>v^^><<vv><v>^>><^>v><^>v^<<v><v<<^vv>^^>>>v^v^<>v^<v^^^
^^^v>>^^>>><v>v^<^>v^^<v^v^v>vv<v<<>v<<<>v^v<<^^vv<v>vv<<^^^>v>vv><^>v^<>v><<<v<vvv<v<>>v<^^<<^>^^^^><^^^<<>>v>v<>>>^>>>>vvv^<<>v<>>>>^vv><>>^v<v^<>><^<^v>v^^<vvvv<>vv<^>^>^<<<>v^^>><>v<v<<v>>>v>v>>>>^<>>^^>v>v>v<^>v^v><v>>^^><vv>>^v>^^<^<<>>^v^<<<^>>vv^>^<<>>>v><^<>^^>v^v>v><^<^v<<v><>>>^>><^>v<^<v^<><^><<<<^vv^>v>>^^^>>>^>v<^vv^>v>^<<<v<v<<v<>vv>>^<^<>v>><<<^<v<^^<<v<<^>><<>v<vv><vv^v<<<v^v^>v<><>v<^^<>v<v<><>>v<>v<v<>^v<v<v<^><<^^v>v>>^vv>^^vv^><^v^^>^^<><>^>^>^^<v^^<<v<^>v><v>^<vv>^>v>><<^<^><>^^^<v^v^>v>^^>^^^vvv<<v^vvvv^v^^^v<>>v>>v<^<>>>>>v<>^><^v<^><<<>v>v<vv><<><>v<^v^><>^><>^^v^^^><^^vv^<^^^^^vv<^^^v^>><<^^><^vv>^<^<^<vvv^>vvv<>^>>vv><^><>v^^<>>>^>>>>^v^>v><>^vv><><<<^v<>v<^<v^v>v<><>v^vv^>>^^^^>v>v<>^^<v^^>>>v<^>v>^^<<v><vv<v>>>^<^v^><^>^<<^v<v>^v>^v^^v<^>><<vv<>^<<<<>>v<<^>>^vv>v^^<>v<<v>^<<><<^<>vv^v^vv>^^<>^<>v<>>v^>>^>^><<<^<<>>v><^><<>^^><v^^><^>>^v<^><<<><<<<^v><>>vv<>^^^>>>^<v<^vv^^>v<<vv><^<v^><^v^^^^^<^<^<^><>^>^<v^v>v<><vvv>v<>v<^^<<<<^>>>>vv^><^>>>v>^>^<v^<<<^<>^v
v^>>^^v<^^vv>^>^>v<v>v^<>>v<^<<><^>>>vv<<v<<^^><<>^>>><<<vvv^v^<^>v<vv>v>^<>>v<<v^<<^vvv^^^^<<^v>^<>^vv><<<<><<>>>^v^>^<v<^<^<>>><^^<<vv<<<v<><v^>>vv><^v<>vvvvvvvv><v^>>^^^^>vv>^><<vv><<^>^^v<<<>>><<^^v<^<^^^v>vv^v>^v^^<^^<>v>^^^<>><^v<<<>vv^<v>^^^v<>^v<>>^^<>>v<<<vv><<<vv^^<vv<<^vv<<>v^^v>>><^<<>>^>>^v>v>^^<v<v^>v><v<vvvv<<<^<^v^>vv^^>v>>v^>^>v<<>>>^v>v^v^v<<v^v<<>v^vv>><><>><v<^vv>>^vvv^>^vv^<v<>^<^^>^v<v^v^>v><^<^>vv<v^<^^^<>^v>v><vv>v^vv>>^<>>>^>>^>^^^^><<v>v^^<>v>>^^^^>>vv>>v^<^v>^<<>><<^v<v<^v><>>^^><<>^><>^v<>>v>^<^<v>>^vvv><>^^><>vv>v<^v<vv^<>^>^^v>v<>^>vv<<v^^><><^<<^>v^v^^>><<^<<><^<v^>>><<<><v<<><<^v<^>v>>v>>><^^<<><^>v>^vv^^vvvv>^v^><>v^^>>v^<><><vvv>v>>^^^^>^<v^^<^v>^><^<<<v>v<><^v<>^<^v^>^>>v<vv<><^^>>>>>>>^v<v^v>><<<v<<>><v^v<<v<>>^^><v>vv>^><>^><<<vv^<<^>>v^v^vvv><v^^><<vv<^<><v^>><<v<^v<^>>><^<^^>^v^^^>vv^>^^^v^v<v<vv>^vvvv^v^<>^<^<<>v><v^v>^^>>><^>vv^<^<<^<^^<<^><v^><v<<<<^^<v><vvv>v>^^><v<v^<<^><v>><>^<vvv^>v>vvv^<><<^^<>^<<>^vv<>v^v>><>^v>><v<^v><><v<v<^<^^<^vv^^>^>
v^vvv^^>^><<v^>^<<v^>v>v<>>>>>>v^<^<v^v^>>^>^><>><<^v^v>>>^^<vv^<<^>>^v^v<v^>>vvv><vv^^^<vv><vv><<v><>vv^<>^<v<^^>>v>^<v<^<^v<>v<v><>v^^<v<<^<<vv>vvvv^>vv^<>^<vv>^<^v<>>^v><v^<<v<<>^^>v^^v><^<vvv^>vvv^>>^>v^^<<v<<>^vv<^^><v<<<>>^^>>^<^v^^^v<v>v^v>>>v<^v>^v<vv<v<<<<^<<^^<<><<v^<v<<<>><^>^>><>><v><v<^>>v^<<v<>v<v>>>v<^^<^>^<v>v^<<v<><>v<^<v><^>v^^<<^^^<^v^>^<v><>v>>^<><<v>v^<^^>v^^<v^<^^<v^<vv^>>>vv>v<^<^<>v^v<<v<<vv^<>>^^>vv><v<>><v^v^^v<v<<>>>v<>>v^<<<>v^^^<<^^^v<>v^v<^v<v>^>^<v<^v<^^>>v^v<<v^<v<vv>>^><vv>>v<<>^>v>><v^v>><^vv^>^v^^<vv<vv<^^<^<><<<^>><v<<v<<>^>^^^<<<<<v><^v^v<v^vv<<v<><^^^<vv>vv^<v<><v>v<vvv><^^v<<<<<<<v<^<<^^^v<<vv^v><<^^^>>>^>v>^vv<>vv>>^<<<>>>^^<^><vv<>v<vv>v^v<<<<^<>^v<>^^v^^^<>>v^<^>^vv^v<^^<v^v^<v>v<^>vvvvv>^<><v>vv<^<>><<v>^^>^>^^>><<^>><^v^^vvv^vv^>v>^v>v^v>v><>^<v<<>v<>^<<v<vv^v^vv<^>v^vvv>^v>v>^^^<>>v^v<^vv>v<<^<^<v><v>vv>v^v><><^>v^<^>v^vv^v>>^v^v<>^^>><>v<vv^>vv<v>><<>^>^^v<v>^>v>^><v^^^v<^<^v<><>v><^v>><^^>>^><><v^v>v><><v^<><^<<>v^<<vv>>><^<>vv<v<<<^v<<v<v
<v^v>vv><v<<^v^>>>>v^^^^^^>v<v^>>>><<<v<^vv<^<v^^><^vv>^<><>>>>v^<vv^<>v<^^>>><>^^vv>v^v<>>v>vv>v<v>>>>v>^v^^<<>>><>v^<>><>^v<><>^v^^v>><><><<<>>^><>^^v>^v<v^^>^<v^>^^v^<v><vv>vvv<<vvvv^>v<>>>^>>><^><>vv^>>>^^>v^<<v^v^><><vv^^<v<<>><vv>v^^<vv>><<>^^>v>>v^>^v^^v^v<<>vv^>>^^><<v^^<v^vv^v>>^<<v>^^<v>>v><vv><<>^<v^^>>vv>>v<<^v><v^^>vv^>>^<^v^^>v^<vvvv>>>>>^<^><v^v<v><><v^^>>vv<^>v>>>v>v^v<<<vvv<>v>><^vv>v<^<^><<v<<vv^<^><<>^^^^v>>vv<^><^>vv>>>vv^^<><v>^^^<>^v>><^>>v<^v>>^v^><v<><>v<v>^>>>><v>vv>v>^^^^^>^><>^v>><v<v^>>>v^>><><vvv>v<<<>^^vv^v^<v><<><v>>><<<>^<v^<>>v^^<<^v>^<<>^<v^v<>>^>>^>^>v>vv^v>^<><^^<<<^<^^^<>v^v<v<^^>>^>^v^<v^^^v<>vv>>^^v>><<<^v><>>vvvv<<vvvv<^^>^^v^^^v^<>^v>v><>v><<<^^^><^^v><vvvv>vvv<<v>^>^<^<v><v^<>>vv^<v<><><><<^<<^><><vv<^>v^>^v^<>>^<^>^>>>>vv<><>^>v>>v>vv><<^vv<>><v^v<>^v>v>>v^^v>vv<^vv^>>v<<v<<>v><><>v^^><^>>><>v>>v>v^^<v<vv<>><^><<vv<<v^^^^^^<v^><<^vv<^<<<>v><<<>v>^v><<v>^<^>^^^>v>vv><<>>^<>>^^^^^^^<>v>^<vvvvv^v>^^v^v<^>vv<<<^>>><<>>v<^^v^<>^<vv<<v>>>^vv^v^^>v<>
vv><v^>>v>>^<<>><<>^^<<^>^><v>>>><<>v<v^>>><<v^<>>v>><<v^>vv^>^><<><>^<<^^<<<<v<>v<>><>^>^^<v>^v^^>v^<vv^^v<^<^<<><vv<^>v<>>vv^><>><v<><vv>v<^vvvv^<v><v<>>v<<>v<<^^<<vvvv^>^>>>v>v<^vvv^>^<<<vv<<>^<^v<^^^>>>>^^^<^^<<v<^<>>^<v<>^><><v^v<v<>v<>^v^v<^^^^^<^v<>^v<^^>v<>>v<<<>v<>v<>v<^^v>><>>v>^^v>v^>v^^<><<v<<<vvv><v^><>^^^>><^<<<<v<v^<v<v^v><>v<v<^v><<^>>vv<<>^^^vvv<<^>vvv<^v>>><>^v<^><<^<<v>v<v^><^>><v<>^<^><vv<^^^<v>><<vv<<<v<v<>v^<vv><<>vvv^v^>v^>v<v><^<v<<<<v^v^vv^>>^>v<v^^vv^<>vv>v^>^^v<><><<^v^>>vv<^^^^<v><<<v>vv<<>^^^<^v<^<v^^^v<<<><^>^v<v^<>v<v<vv<v>^<^>>><^>^>v<vv>vv>^vv<<vv>>^vvvv<>v^^v^v<>vvv<>v<<v^>v^<v><<<v^^^>>v<>vv^>>><<v^^<^><^>>>^^^><>v<^v^^vv>v><^<>>^>v><v^<<>v<v^>v^<v><^v<><<^^<^<<v>v<^^>^v<^<<>><v>vvv>v^<<<^>^>^^vv^vv^^<<v<<v<>^v^<>^<<v^^^>vv>^^^>vv><^<<>>v<^^v<^>^>>^>v<<<>vv^^<>^^^^^>vv^<<<>v^v^v<>^>>v<>>^<><<v<><v<v>v^<>><<^<<>>v><^>v^^<>v^^<>^<><vv<v<^^><^>>v><^><<vv>><<<^^>v^<<v>v^<v>v>^^<<vv^>><<vv^v^v^^>>>v^^>><<^v>vv<<<<vv^v<<^>v<>^>>><>>^vv><^^^<<v><^v<>v><<^^^>
><^>><^vv<^v<^>^<<>v^>vv<vv<>^^v^>v<^><<><vv^<vvvvv<<^v><^^>v^>v<^vvv^>^<v<<<^><<^v<<>>><^^^vvv<<^vv^v<<>v<>>^^>^>>v<^^><>^vv>v^<^v<v>^^^^<vv<<>^<^^^>>^<v>^v>^<v<>>>>^>^<v^^>^^^>^v><^><v^v<vvvvv<>>^<<v<<<>^>>v^v^<^<>^<>^^<<>>>v^<^<<>v<><><^><^><v><v>v>v^^<^^v<v<>>^>v><^>^<^>^^<^^>>vv>vv>v>>^v^v>^<<v^^><^<>v>>v^^v><^v<<<^^v>><<v^>^v>v>^^<<^<><>>>vvv<^><<^vv<>v<><^^^^<<^<<^<^^>v^><<vvv^>vvv>v><>^v<<v>vv<v^<vvvvv>^<v^><^v^>v^><^<<>><^^^^^<<<>^<<^><^<v^^^^vv^v<<v>v^<v<v^>v<^^><^v<^^>v<<v>^v>^vv^<^vv^^^v>>>>>^>^^>^><^>vv>>vv^<<<<>^v^>^^>^>>^>^v><v>v<<v^><<>v<>>><v><v><v<v^^^^v<vv>^<><vv>^<v<^^v^^<vv<>>>^<v<v>v>^v<^^><^>vv>^vv^v<^<vv><><v<<<<<<^^vv>>><<^v><v><^vv<>v^^^<><<^^>vv<^^v>v<vv<^v><v^v^^v^><^^^<^<<^vvv<>vv^vvv^^>v^v^^v<<v>v<<^<>v^>v<<v^<>vv^<>>^v^^>><>vv<>^^<^<v^<>>^^<<><<v^<<v^v>^><>v<^^^><^v<^v>^v<>>>^^v<v><<<<v>^<^>^<>><<>>><>^v>v>v>><^<<v<v><v>^<<<vv>^<v^<>v^v>v^<<>v<vvv>^^^v<^>^<>^><^<<vvvv<<><><^>>><^<^>v><>>v><>v>v^v<<^<>>^<v<v><^^^^^<v^v^^v>>>vv<v^^<v<<vv^v>^v<><<>>v<^^>><^<
v>><<v^^>>>vv<>><>^vv^<<<><<<v><vv<v^^^<<<^>>^^><v<<>^<^>v<vv><v><v>v^^<vvv>vv>>>v>^<<v^v<v>v>vvv^>^vv^<<<>^^>v^>^<v<<v<v><><v^^vv<^vv<<v^<>>^^<>v><<v<>>>>^<v^v>>^v^^>>><v^v^><^v^>^^v^v>^^>^<^v^<^v^<><v>>v^^^><v^<<^^><><<>vv^^^v^^<><>vv<v^<v<>><>>^^><v^<^v^<^>>v^v<>v^<v>v>vv<^><vvv>><^><v^<^v<>><><>>v^><<<<^v^>^>v><v^><v>^><<v^^v>><v><^>>v>v^^<>>v<>^<>^<<v<>><^v<>v^>><^v><><v>^^^<v<<v><v>v<<vv^<v>^<<v>v<>>vv><>><<>><>v^v>^><v^>>>vv>v^>><vvv<^^<^>^vv<>^<<v<<^>vv>^>v^v<^vvv^<<v>><vv^v<^v<v>v><<^>>^^vvv<<^>>^<<<<v<v>>v^><<<^^<>^<<>v^>vv^>v<^^<^vvv^vv<v><^^>v<<><^^<>>^<^^<vv^v^vvvvv^v<<<<>>vv>vv>>v<^^<<^<<<<v<<vvv^^<v<v<<^^><<><><>^v^^>v^<<><^vv>>^>v<><>v<<^v>v<v<<^<<^^vv<>v>^<<><^<^<^^<v<>v^>v^><vvv>>><<v<>><>v>^<<vv>>^>>>v<<>^><<v<>>^><>><>^^>^^v>vvvv^>^<><<v^><^vvv^>^vvv<<>>v^<>>^^>vvv^<^v>v^<<><v>^>>>>><v<v><>^<^^vv><<v<><vv>vvvvvvv^>>>>><v>^<>v>^>^^>v^^<<<vv<<>^>v<^v^>>v^^^^^^>v^vv>v>>v<><^vv^>vvv<^v>v<>^><^v<^v^<<^<vvv^^vvv>v>^<v^<>v<<>^v^>vv^>v<v^<<vvv<<>^>v>^^>>^vvv^v<<<^v>><^<>^<^
vv><^^^v>v>>>>><>>^<vv^v^^>^v^<>^<<<<>^v>vv<>><^v<<>v<>>>^^v<^v^<<>>^<>vv<<>^^v^^><<<v>>vv>^><>^<^><><><^v>>>vv<^>^<^>vvv><<^v^^^^<vvvv>>^^^>vv<^vv>>^<^v^^v^>^<v^>^<>vv<v^>>^>^<<>^>^<vv<<>^>v><vvv><<^><><<<<^v><^<v<^vv><v^>v<v<^v<<<>v<<^><^>^v^>v>vv<<v<<<>^v>^^v<v<^>>>><>v>^^<^v>vv^v<>v>^vvvv^v><vvvvv><^<^^^<v^v<vvv^v<v>^<<><>^^>vv<vvv^>v<><^vv<<<^<>>>^>>v^<<^v^>v>v^^>>>^><^<^<>>vv^<^<<v><>>vvv<<><<>v^<<<>>^vvv^>>>vv^^v>v<v>><<v>vv^v>^v^v^<>><^<<><^v^<>>^^><v^^^^vvv^^><<>^><v<^v<^v<<v^v>^<>^>v^><<v^v>^^>>^^>>^^^>^^v><>v^^v>^>><>>^^^v^v^<vvv<v>^^^>v<>^^>>>^<<><v<^^>>v<^vv><^^vv^<v>^v<v<<<<^<>^>^^>v><<v<^^<><>vv^v^<>>v><><^v>v^>^>v>^<v^<v<>v<>^vvv<v>^><><^>v^<>^v>>v>^<vv>>>^v^^^>>^vv^<>^>^^v^v>>><<>^v<^>v^<<<>^vvv<<v<<<<>^^>v^^^v<^^v^vv<v>^vv<v^><><^>>>vv<<>^<<^v>v>><>vv>^v^<>v>^vv>^v<^>>>>>><^>^v>>^>^^v^^^vvv>^<>><>^vvv<<<>^>v<<>vvv<^<<v^v^>v>v>>^^<><>v>>^><>>^>v>^>>v<^<vvv^>vv<>^><vv^^>v<vv<>v<>v><v^^v^^<<^><^v<<v^v>^>>^^v^^^vv>><v^^<^<>>>^^^^^v<^^^<^^vvvvvvv^v<^^<^^v^>>v>>>><v^^v<v<>^
<>>>^v<>><<<^><v^v<<>>>^<><<^^<>v^v^>^<<<vv>^<^><<<><><>>>^v>>v<<v^>^^>>>><v>>v<v<<^^v>v<<vv^<<^>^<<^v><v<vv^v>v<v^^^^<^^^v>^v<^v<^<>v^^v^v<><<v>v<<v<>^>>v><><^^>><>^>^^^><^<<>>>v^v^^<v<><v<<<<vv<><<<vv^v<<<<v<<<>v<^^vv<<v^>^>v<^><><vv^>^^v>v>v^^^^v^v<<^v<v^>><>>^^v<><>>v>v>^^^^^>v^v^^>^v>vv^<>>>^^^^v<^vv<v<<^v^<vvv<^><<><<<<<^^v^^<v<<>v>^>vv<^>v<<^vvv<^<^>^>^^><^<><vv^<<>v>>>>^^<v<^v<vv^vv>v><>v<^v^<v<>>^<>>><>v<^<<^>>v<^<<<>^^v<^<^v<><^v<^><<<v^^^^^v^v>vv<^v<^>>^^^v><v^v<^^>^<<^>^^<v^<<^v><v<<vv>^v>^<<>^<v^>v<v>v><<^<<>v^<^v^>>v^>^^><v>^<<>v<^v^^<v<^^<v>>^^v><>>^^v>v><vv^<^<<<>^<^^>v>vv<^vvv<^v<<>^v^<v<^>v<v<v<<<v^>>v<<v>^<<v<<v><>^^>^<v<>^>>><v<>>>^v^^^^^v><v^^^>^<^<^^<v><v<<>^<v^v>vv^^<v^v<v^^v>v<><<^v<>v^^<><vv^vv<<<><>^^v^>>>v><><^<>><v<<v^><<>^>v^^<^v<^>>v^>^>^^^v><>v^^<><<^^v^vv>vv^vv<<><>^^v^><><^<<>v^v^<vv<^v<<v>v^<v^<^<><<^<>v^<^><>^^^v<^>^<<><<>^><^vv<>^^>v<v>v>vvv^^>>^^^>^>^^>><vv<vv><<^^<><>vv>^v<<>>^v<v^<^vv>>v>^^^^<v<<^<^^vv>v><v<^vvv<v^v^<>>v^v><vv^vv^^<v><>>><v<v><^<>
^^>v<<v^^<>><v>^v<>^<>><v><vv<<vvv^^^^>v<>>v^<<>v>vv>vv^<v^v>v<^<v>^>><^<><^><>><^^<^vvvv<^><^v<^>v<<^^>v<^>>v>><v^<^<>^<vv>v<^^v>v<>v>><^v>^^v^>><^v^<vv^<>><v<^^<v><><^^^<^v<>^v><>>^^<><vv^>v>v^>v<^<^^^>>v<^<v<<v<<^<vvv^vv^><<<v<<^vv^<v^^v<^v<vv<<<<v^><^<^vv^><<>^^>>>v>>v<<vvv^^^v<vv>^v<><<<v><^>^^<<<>>>v^v^<^<^<>^>^<<>v<^vv^v^<<v><v<>^^>^vv^vv^v^v<<v^<>>>>v^v>vv^^v>v^>v<<v^v>>>>v^^^>><^<<<^>v^^v<<<^^v>v^^^<><<>v<^v<<><v<<vv<<v<^<^v><<^v^^>>>><^^>^^<<v^<<<v^^>>>^^><<v><>^<^>^^^vv^<<>v^^v<^<vv^>^v<^<vv<^vv<^><^>>>><^^v<>>>><<>^v>^<^<v<v^v<^<^vv<v><^vv<><v>><<^>v^<vv>^>>>^>>v^^^v>vv^<>>^>>>^^vvv<vvvv>^v<^><^>>>^v^>>>^v^^^^^^<>v^vv<^^v^><<v>v^<<<>v><<v<vv^><<v^^v>^v>vv^^^><>vv>>vv<^>v><<>>>v<<>>>^<><<v><<v<<^<^>>v>>^>^v>><><>^<<<^v<<<v><^^v<>vv<<<<<><vv<^<>v<^^>^^v<v^v^>><>v>^v>^<<<v><^v^v<v<^<<>><^vv>^>><>vv<><>^^>><><v^<><vv<<<^v<<>vvvv^><v^><<^v<>><^<^>^^<<v>>>^>^>^v^^v<>^^^^><>>v<^><v<^v^<^^>v<>v<<^<v^^><<>>^^v<vv>>v<>><^>>>>^<<>^^>v^v^>^><v^<<<^<v>>vv^^>^><<v^>^^<>v<<>v><^v^v<^><^^v

View file

@ -0,0 +1,164 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Functor
import qualified Data.List as L
import qualified Data.Vector as V
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 9021
data Tile = Wall | Box | Lbox | Rbox | Floor | Robot deriving (Eq, Show)
type Line = V.Vector Tile
type Warehouse = V.Vector Line
data Op = N | S | E | W deriving (Eq, Show)
data Input = Input Warehouse [Op] deriving Show
type Parser = Parsec Void String
parseTile :: Parser Tile
parseTile = char '#' $> Wall
<|> char 'O' $> Box
<|> char '.' $> Floor
<|> char '@' $> Robot
parseLine :: Parser Line
parseLine = do
line <- some parseTile <* eol
return $ V.generate (length line) (line !!)
parseOp :: Parser Op
parseOp = char '^' $> N
<|> char 'v' $> S
<|> char '>' $> E
<|> char '<' $> W
parseInput' :: Parser Input
parseInput' = do
line <- some parseLine <* eol
ops <- some (parseOp <* optional eol) <* eof
return $ Input (V.generate (length line) (line !!)) ops
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Coord = (Int, Int)
next :: Coord -> Op -> Coord
next (x, y) N = (x, y-1)
next (x, y) S = (x, y+1)
next (x, y) E = (x+1, y)
next (x, y) W = (x-1, y)
showWarehouse :: Warehouse -> String
showWarehouse w = V.foldl' showOne [] w
showOne acc line = acc ++ (V.foldl' showTile [] line) ++ "\n"
showTile acc Wall = acc ++ "#"
showTile acc Lbox = acc ++ "["
showTile acc Rbox = acc ++ "]"
showTile acc Floor = acc ++ "."
showTile acc Robot = acc ++ "@"
showTile acc Box = acc ++ "O"
compute :: Input -> Int
compute (Input warehouse ops) = V.ifoldl' scoreBoxes 0 warehouse''
where
scoreBoxes :: Int -> Int -> Line -> Int
scoreBoxes acc y line = V.ifoldl' (scoreBox y) acc line
scoreBox :: Int -> Int -> Int -> Tile -> Int
scoreBox y acc x Lbox = acc + 100 * y + x
scoreBox _ acc _ _ = acc
warehouse'' = fst $ L.foldl' step (warehouse', start) ops
step :: (Warehouse, Coord) -> Op -> (Warehouse, Coord)
step a@(w, r@(x, y)) op | t == Wall = a
| t == Lbox = case push w r' op of
Just w' -> (w', r')
Nothing -> a
| (op == N || op == S) && t == Rbox = case push w (x'-1, y') op of -- we want to always push boxes from their left side to reduce push cases
Just w' ->(w', r')
Nothing -> a
| t == Rbox = case push w (x', y') op of
Just w' -> (w', r')
Nothing -> a
| otherwise = (w, (x', y'))
where
r'@(x', y') = next r op
t = w V.! y' V.! x'
push :: Warehouse -> Coord -> Op -> Maybe Warehouse
push w r@(x, y) op | t == Wall = Nothing
| (op == N || op == S) && tr == Wall = Nothing
| (op == N || op == S) && t == Lbox = case push w (x, y') op of -- pushing a boxes that matches ours
Just w' -> let l1 = w' V.! y
l1' = l1 V.// [(x, Floor), (x+1, Floor)]
l2 = w' V.! y'
l2' = l2 V.// [(x, Lbox), (x+1, Rbox)]
in Just (w' V.// [(y, l1'), (y', l2')])
Nothing -> Nothing
| (op == N || op == S) && t == Rbox = case push w (x-1, y') op of
Just w' -> if tr == Lbox then case push w' (x+1, y') op of -- are we pushing two boxes?
Just w'' -> let l1 = w'' V.! y
l1' = l1 V.// [(x, Floor), (x+1, Floor)]
l2 = w'' V.! y'
l2' = l2 V.// [(x, Lbox), (x+1, Rbox)]
in Just (w'' V.// [(y, l1'), (y', l2')])
Nothing -> Nothing
else let l1 = w' V.! y -- or just one on our left
l1' = l1 V.// [(x, Floor), (x+1, Floor)]
l2 = w' V.! y'
l2' = l2 V.// [(x, Lbox), (x+1, Rbox)]
in Just (w' V.// [(y, l1'), (y', l2')])
Nothing -> Nothing
| (op == N || op == S) && tr == Lbox = case push w (x+1, y') op of -- or just one on our right
Just w' -> let l1 = w' V.! y
l1' = l1 V.// [(x, Floor), (x+1, Floor)]
l2 = w' V.! y'
l2' = l2 V.// [(x, Lbox), (x+1, Rbox)]
in Just (w' V.// [(y, l1'), (y', l2')])
Nothing -> Nothing
| (op == N || op == S) = let l1 = w V.! y -- free space
l1' = l1 V.// [(x, Floor), (x+1, Floor)]
l2 = w V.! y'
l2' = l2 V.// [(x, Lbox), (x+1, Rbox)]
in Just (w V.// [(y, l1'), (y', l2')])
| t == Lbox || t == Rbox = case push w (x', y) op of -- East-West movements are simpler
Just w' -> let l = w' V.! y
l' = l V.// [(x, Floor), (x', to)]
in Just (w' V.// [(y, l')])
Nothing -> Nothing
| otherwise = let l = w V.! y -- free space
l' = l V.// [(x, Floor), (x', to)]
in Just (w V.// [(y, l')])
where
(x', y') = next r op
t = w V.! y' V.! x'
tr = w V.! y' V.! (x'+1)
to = w V.! y V.! x
start = V.ifoldl' findRobot (0, 0) warehouse'
findRobot :: (Int, Int) -> Int -> Line -> (Int, Int)
findRobot (0, _) y line = (V.ifoldl' findRobotInLine 0 line, y)
findRobot a _ _ = a
findRobotInLine :: Int -> Int -> Tile -> Int
findRobotInLine 0 x Robot = x
findRobotInLine a _ _ = a
wideWidth = 2 * V.length (warehouse V.! 0)
warehouse' = V.map widen warehouse
widen line = V.ifoldl' widenOne (V.replicate wideWidth Floor) line
widenOne acc x Wall = acc V.// [(2*x, Wall), (2*x+1, Wall)]
widenOne acc x Box = acc V.// [(2*x, Lbox), (2*x+1, Rbox)]
widenOne acc x Robot = acc V.// [(2*x, Robot)]
widenOne acc _ _ = acc
main :: IO ()
main = do
example <- parseInput "example2"
let exampleOutput = compute example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute input

View file

@ -0,0 +1,17 @@
#################
#...#...#...#..E#
#.#.#.#.#.#.#.#.#
#.#.#.#...#...#.#
#.#.#.#.###.#.#.#
#...#.#.#.....#.#
#.#.#.#.#.#####.#
#.#...#.#.#.....#
#.#.#####.#.###.#
#.#.#.......#...#
#.#.###.#####.###
#.#.#...#.....#.#
#.#.#.#####.###.#
#.#.#.........#.#
#.#.#.#########.#
#S#.............#
#################

View file

@ -0,0 +1,90 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Functor
import qualified Data.Heap as H
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Vector as V
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 11048
data Tile = Wall | Floor | Start | End deriving (Eq, Show)
type Line = V.Vector Tile
type Input = V.Vector Line
type Parser = Parsec Void String
parseTile :: Parser Tile
parseTile = char '#' $> Wall
<|> char '.' $> Floor
<|> char 'E' $> End
<|> char 'S' $> Start
parseLine :: Parser Line
parseLine = do
line <- some parseTile <* eol
return $ V.generate (length line) (line !!)
parseInput' :: Parser Input
parseInput' = do
line <- some parseLine <* eof
return $ V.generate (length line) (line !!)
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Cost = Int
data Heading = N | S | E | W deriving (Eq, Show)
type Coord = (Int, Int)
data Position = Position Coord Heading Cost deriving Show
instance Ord Position where
compare (Position _ _ c1) (Position _ _ c2) = c1 `compare` c2
instance Eq Position where
(Position _ _ c1) == (Position _ _ c2) = c1 == c2
type Visited = M.Map Coord Int
type Candidates = H.MinHeap Position
compute :: Input -> Int
compute input = walk M.empty $ H.singleton (Position start E 0)
where
walk :: Visited -> Candidates -> Int
walk v h | t == End = c
| otherwise = walk v' $ H.union h' $ H.fromList $ nexts v' $ Position p d c
where
([(Position p@(x, y) d c)], h') = H.splitAt 1 h
t = input V.! y V.! x
v' = case M.lookup p v of
Just c' -> if c < c' then M.insert p c v else v
Nothing -> M.insert p c v
nexts :: Visited -> Position -> [Position]
nexts v p = L.filter (valid v) $ candidates p
valid :: Visited -> Position -> Bool
valid v (Position p@(x, y) _ c) = input V.! y V.! x /= Wall && case M.lookup p v of
Just c' -> c < c'
Nothing -> True
candidates :: Position -> [Position]
candidates (Position (x, y) N c) = [ Position (x-1, y) W (c+1001), Position (x+1, y) E (c+1001), Position (x, y-1) N (c+1) ]
candidates (Position (x, y) S c) = [ Position (x-1, y) W (c+1001), Position (x+1, y) E (c+1001), Position (x, y+1) S (c+1) ]
candidates (Position (x, y) E c) = [ Position (x, y-1) N (c+1001), Position (x, y+1) S (c+1001), Position (x+1, y) E (c+1) ]
candidates (Position (x, y) W c) = [ Position (x, y-1) N (c+1001), Position (x, y+1) S (c+1001), Position (x-1, y) W (c+1) ]
height = V.length input
width = V.length (input V.! 0)
start = (1, height - 2)
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute input

141
2024/16-Reindeer_Maze/input Normal file
View file

@ -0,0 +1,141 @@
#############################################################################################################################################
#.........#...........#.................#.......#.............#.....#.#...#...........#.....#.....#...#.......#.....#...........#.......#..E#
#.#######.#.#.#######.###.#########.###.#######.#.#.#.###.#.#.###.#.#.#.#.#.#####.#.###.#.#.#.#.#.#.#.#.#.#.#.#.###.#.#####.###.#.#####.###.#
#.#.....#.#.#.#.....#...............#.#.#.....#...#...#.#.#.......#...#.#.#.....#.#.#...#.....#.#.#.#...#.#.....#.#.........................#
#.#.###.#.#.#.###.#######.###########.#.#.###.#.#######.#.#.#########.#.#.#.#####.###.#####.###.#.#.#####.#######.#.#.#.#.#.#.#.###.#.#.#.###
#...#.#.#...#...#...#.....#...........#.#...#.#.#.......#.#.........#.#.#.#.#.....#...#.........#.#.....#.......#.#.#.#.....#.......#...#...#
#.#.#.#.#######.###.#.###.#.#########.#.###.#.#.#####.#.#.#.###.###.###.#.#.#.#.#.#.###.###.#####.#.#######.###.#.#.#####.#.#########.###.#.#
#.#...#.......#...#...#...#...#.#.....#...#.#.#.....#.#.#...#...#...#...#...#...#.#.#...#.........#.#.....#.#...#.#...#...#...#.......#.....#
#.#.#.#######.###.#####.#.###.#.#.#######.#.#.#####.###.###.#.###.###.#########.###.#.###.#.#######.#.###.###.###.###.#.#.#.#.#######.#.#.###
#.#.#.......#.#.#.#...#.#.......#.......#.....#...#...#...#...#.#.....#...#.....#...#.#.....#...#...#...#...........#.#.#.#.#.#.....#...#...#
#.#.###.#####.#.#.#.#.#.#.#########.###.#####.###.###.#.#.#####.#######.###.#####.###.#####.#.#.#######.#.#.#####.###.#.#.#.#.#.###.###.#.#.#
#...#.#.........#...#.#...........#...#.....#...#...#...#.#.........#.....#.#.....#.#.....#.#.#.......#.#...#...#.......#.#.#...#.#.#.....#.#
#.#.#.###############.#.#.#.#####.#####.###.###.#.#.#####.#######.#.#.###.#.#.#####.#####.#.#.#######.#.###.#.#.###.#####.#.#.###.#.#.#.#.#.#
#.#...#.....#.#...#...#.#...#...#.....#...............................#...#.............#...#...#.................#.#...#...#.....#.....#...#
#.#.#.###.#.#.#.#.#.#####.###.#.#####.#.#.#.###.###.#######.#.#####.###.#.#########.#####.#.###.#####.###.###.###.#.#.#.#.#.###########.#.#.#
#.#.#...#.#.....#...#.....#...#.#...#.#...#.#...#...#.......#.#...#.....#...#.............#...#.....#.#...#...#...#.#.....#.......#.......#.#
#.#.###.#.###.#.#####.#####.###.#.###.#####.#.###.#.#.#######.#.#.###.#######.#############.#.#.###.#.#.#.#.###.#.###.###.#.#####.#.###.#####
#...#.#...#...#...#...#.....#...#.#...#...#.#.#...#.#.#.......#.#.#...#.......#.....#.........#...#.#...#.#.#.#.#.#...#.#.........#...#.#...#
#.###.#####.#####.#.#######.#.#.#.#.###.#.#.#.###.###.#.#####.#.###.#.#.#######.###.#.###########.#.#######.#.#.#.#.###.#.#####.#.###.#.#.#.#
#...#.......#...#.........#.#.....#.....#.#.#.#...#...#.#...#.#.....#...#.....#.#...#.#...#.....#.#.......#.#.#.#.#.....#.#.....#.#...#...#.#
#.#.#.#######.###########.#.#####.#######.#.#.#.###.#####.#.#.#######.#.#.#.###.#.#.#.#.#.#.###.#.#.#####.#.#.#.#######.#.#.###.#.#.###.#.#.#
#.#...........#...#.....#.#...#.......#...#...#...#.#.....#...#.......#...#.....#.#.#.....#.#.#...#...#...#...........#.#...#...#.#.......#.#
#.###########.#.#.###.###.###.#########.#.#.###.#.#.#.###.#####.#######.#########.#####.#.#.#.#######.#.###.#####.###.#.#####.#.#.#.###.#.#.#
#.......#.....#.#.............#.........#.#.#...#.#.#...#.#...#.....#.#.#...#...#.......#.#...#.....#.#.....#...#...#.....#...#...#.........#
#.#####.#######.###.#.#######.#.#########.#.#.###.#.###.#.#.#.#.###.#.#.#.###.#.###.#.#.#.###.###.#.#.#######.#.#######.#.#.###.#######.#.#.#
#...#.#...#.....#...#.....#.#.#...#...#...#.....#.......#.#.#.#...#.#...#.#...#...#.#...#...#.....#.......#...#.......#.....#.#.#.......#.#.#
###.#.###.#.#####.#####.#.#.#.###.#.#.#.#######.#.#########.#.#.###.#.###.#.#####.###.#####.#############.#.#######.#.#####.#.#.#######.#.#.#
#...#.......#...#...#...#.#.....#...#.#.....#...#.#.........#.#.#...#.#...#.#.........#.....#...........#.#.#.#.............#.#.....#.....#.#
#.#.#####.#.###.###.#.###.#######.#.#.###.#.#.###.#.###.#####.#.#.###.###.#.###########.#####.#########.###.#.#.#############.#.###.#.#.#.#.#
#.#.....#.........#...#.#.......#.#.#...#.#.#.#...#.....#.....#.#...#.....#...#.........#.....#.......#.....#...............#...#.#.#.....#.#
#.#.###.#.###.#########.#######.#.#.###.###.#.###.#####.#.#########.###.#.###.#.###########.###.#.#######.#.#####.#.#.#####.#.#.#.#.#.#.#.#.#
#...#...#...#.#...............#.#...#.#.#...#...#.....#.#.#.......#.#.......#.#...#.........#...#.#.......#.......#.#.#.#...#.#...#.#.#...#.#
#####.###.#.###.#########.###.#.###.#.#.#.#####.#######.#.#.#####.#.#######.#.###.#####.#####.#####.#############.###.#.#.###.#.###.###.#.#.#
#.....#...#.....#...#...#...#.#.#...#.#.#...............#...#...#.#.....#...#...#.........#...#.....#.......#.........#.#...#.........#...#.#
#.#####.#.#######.#.###.###.#.#.#.###.#.#####.###############.###.#.###.###.#.#.#####.#.#.#.#.#.#####.#.#.#.#.###.#.###.###.###.#####.###.###
#...#.#.......#...#.....#...#.#.#.#...#.#.............#.......#...#...#...#.#.#.#.#...#.#.#.#.#.#.....#...#...#...#.....#.#.................#
###.#.###.###.#.#######.#.#.###.#.#.###.#.#####.#######.#.#####.###.###.#.#.#.#.#.#.###.#.#.#.#.###.#####.#####.#######.#.#########.###.###.#
#...#.#.....#.#.#.......#.#.#...#...#...#.#.....#.......#...#...#.....#.#.#.#.....#.....#.#...#...#.....#...#...#...#...#...#.....#.#.......#
#.###.#.#.#.#.#.#.#######.#.#.###.###.###.#.#####.#####.###.#.###.###.###.###.###.###.###.#.#.###.###.#####.#.###.#.#.###.#.#.#.###.#########
#.........#.#...#.#.....#.#.#.#...#...#...#.#.....#.....#.#...#.#...#.....#...#.....#.....#.#...#...#.#.....#...#.#.#.#...#.#.#...#...#.....#
#.#.#.#.#.#######.###.###.###.#####.###.#####.#####.#.#.#.#####.#.#.#######.###############.#.#.###.###.#######.#.#.#.#.###.#.###.###.#.###.#
#.#.#...#.#.....#...#.#...#...#.....#.......#.....#...#.#.........#...#.................#...#.#...#...#.#...#.....#.#.#.#.#.#.#...#.#...#...#
#.#.#####.#.#.#####.#.#.###.###.#####.#####.#####.#.###.#.###########.#.#####.#######.#.#####.###.###.#.#.#.#######.#.#.#.#.###.#.#.#####.#.#
#.#.....#.#.#.....#.#.#.........#...#.#...#.....#...#.#.#.........#...#.#.......#...#.#.......#.#...#.#...#.#...#...#...#.#.....#.......#.#.#
#.#####.#.#.###.###.#.#####.###.#.###.#.#######.#####.#.###########.###.###.###.#.#.#.#########.#.###.#.###.#.#.#.#######.#############.#.#.#
#...#.#.#.#.#.#.#...#.#...#.....#...#.#.......#.#.....#.#...........#.#...#.#...#.#.#...#...#.....#...#...#...#.#.#.............#...#...#...#
###.#.#.#.#.#.#.#.###.#.#.#########.#.###.###.#.#.###.#.#.#######.###.###.#.#.###.#.#.#.#.#.###.###.#########.#.###.#.#########.#.#.#.#####.#
#.....#.#.#.#.#.#.....#.#...#.....#.#.#...#...#.....#.#...#.......#.........#.....#...#.#.#...#.#...#.......#.#.....#.#.......#...#.#.....#.#
#.#####.#.#.#.#.#####.#.###.#.###.#.#.#.###.#########.#####.#####.#.###############.###.#.###.###.###.#####.#.#######.###.#########.#####.#.#
#.#.....#.#...#.......#...#.#.#...........#.#...........#...#.#...#.#.#.......#...#.#...#.#.#.....#.....#.#.#.#...#...#...#.........#.....#.#
#.#.#####.###.###########.#.#.#######.###.###.#.#########.###.#.###.#.#.#####.#.#.#.#.###.#.###########.#.#.#.#.#.#.###.#.#.#######.#.#####.#
#.#...#.....#...#.........#.#.......#.....#...#.#.........#...#.......#.#...#.#.#...#.....#.........#...#...#.#.#...#...#.#.#.....#.#.#...#.#
#.###.#####.#.###.#########.###.###.#####.#.###.#.#########.#.#######.#.#.###.#####.#.#.#.#####.###.#.###.#####.#####.#.###.#.###.###.###.#.#
#...#.....#.......#.......#.#.....#.....#.#.#...#...#.......#.........#.#.....#...#.#.#.....#...#...#...#.#.....#...#.#...#.#.#.#.........#.#
#.#####.#.#.#.#.###.#####.#.#.###.###.###.#.#######.#.#.#######.#####.#.#.#####.#.#.#.#####.#.###.###.#.#.###.###.###.###.#.#.#.###########.#
#.#...#.#.#.#.#...#.#.....#.#.#.#...#.....#.......#.#...........#.....#.#.#.....#.#.#...#.#...#.#...#.#.#.....#.....#.#...#.#.#...#...#...#.#
###.#.###.#.#.###.#.#.#####.#.#.###.#.###########.#.#######.#.###.###.#.#.#.#####.###.#.#.#####.###.###.###.#####.#.#.#.#.#.#.#.###.#.#.#.#.#
#...#.....#.#...#...#...#.#...#.....#.........#.#.#.........#.#...#.#.#.#...#...#...#.#...#.....#.#...#.#.......#.#.#...#...#.......#.#.#.#.#
#.#########.###.###.###.#.#######.#.#########.#.#.###.#.#####.###.#.#.#.#####.#####.#.###.#.#.#.#.###.#.#####.#.###.###.###.#.#.#.###.#.#.#.#
#.....#.......#.#.....#...#.......#...#...#.....#...#.#.#...#...#.#.........#...#.....#...#.#.#.....#.#.#.....#...#.....#.......#.#.....#...#
#####.#.###.###.#.###.#.#.###.###.###.#.#.#.#####.#.#.#.###.###.#.#######.#.#.#.#.#########.#.#######.#.#.#######.#######.#######.#########.#
#.....#.#.#...#.#...#.........#.....#.#.#.#.#...#.#.....#...#.....#.....#.#...#.#...#...#...#.........#.#.#.....#.#.......#.#...#.#...#...#.#
#.#####.#.###.#.#.#.###########.#####.#.#.#.#.#.#####.###.###.#####.###.#.###.#.#.###.#.#.#####.#######.#.#.#.#.#.#.#.#####.#.#.#.#.#.#.#.#.#
#...#.......#.#.#.#.......#.....#.....#.#...#.#.#.....#.......#...#.....#...#.#...#...#.....#.........#...#.#.#.#...#.......#.#...#.#...#.#.#
#.#.#####.###.#.#######.###.###.#.###########.#.#.###.#.#####.#.#.###.#.###.#.#####.###.###.#.#.#####.#.###.#.#.#######.###.#.#####.#####.###
#.#...#.#.#...#...#...#...#.......#...........#.....#.#.#...#.#.#.....#.#...#.#.......#...#.#.#...#...#...#.#.#...#...#...#.................#
#.###.#.#.#.#####.#.#.###.###.#.###.#####.###########.###.#.###.#######.#.#.###.#########.#.###.#.#######.#.#.###.#.#.#####.###########.###.#
#.#...#...#.....#.#.#.#.....#.#.#...#.....#.....#...#...#.#.....#.....#...#.#...#...#.........#.#.#.....#.#.#...#.#.#.......#...........#...#
#.#.#.#########.#.#.#.#.###.#.#.#.#####.###.###.#.#.###.#.#####.#.###.#.#.#.#.###.#.#.#######.#.#.#.###.#.#.###.#.#.###.###.#####.#.#####.#.#
#.#.#.#.......#.....#...#.#.#.#.........#...#.#...#.....#...#...#...#...#.#.#...#.#.#.........#.#.....#.#.#.#...#.#.......#.......#.#.....#.#
#.#.#.#.#####.###########.#.#.#########.#.###.#########.#.#.#.#.#.#.#.#.#.#####.###.#######.###########.#.###.###.#######.#########.#.#####.#
#.#.......#...#.........#...#...#.#...#.#...#.#...........#...#.#.#.#.#.#.......#.......#...............#.....#...#.....#.#.............#...#
#####.###.#.#.#.#######.#.###.#.#.#.#.#####.#.#.###.#######.#.#.###.###.#.#######.#####.###.#.###.#####.#######.###.###.#.#####.#######.#####
#.....#.....#.#.....#...#.....#.#.#.#.......#...#.......#.....#...#.............#.....#.....#...#.#...#.#.....#...#...#.#.#...#.#...........#
#.###.#.#.#########.#.#######.#.#.#.#############.#####.#.###.###.#############.#.###.#######.#.#.#.#.#.#.###.###.###.#.#.#.#.###.#.#.#.#.#.#
#.#.#.#.............#.......#.#...#...............#...#...#.....#.#.........#...#...#.......#.#.#...#.....#.....#...#.#...#.#...#.#.#...#.#.#
#.#.#.###.#################.#.###.###.#.#############.#####.###.#.#.#######.#.#############.#.#.###############.###.#.#####.###.#.#.###.#.#.#
#.#...#.....................#...#...#.#.#.....#.......#.....#.#.#...#.....#.#.#.....#.......#.#...#...........#...#.#...#...#.#.#.#...#...#.#
#.#.#.#.#.#######.###############.###.#.###.#.#####.#.#.#####.#.#####.#.###.#.###.#.#.#######.###.#.#########.#.###.#.#.#.###.#.#.###.#.###.#
#.#.....#...#...#.#.......#.......#...#.#...#.#.....#.#.#...#...#...........#...#.#...#.......#...#.#.......#.#...#.#.#.#...#...#.#.#.......#
#.###.#.#.#.###.#.#.#####.#.#######.###.#.###.#.#####.#.#.#.#####.#############.#.#####.###.###.#.#.###.###.#.#.#.#.###.#.#.#.###.#.###.###.#
#.#...#.#.#.......#...#.#...#.....#.....#...#...#...#.#...#.......#.......#...#.#.#...#.#...#.#.#.#...#...#.#...#...#.....#.#.....#.#.......#
#.#.#.###.#.#.###.###.#.#####.###.#########.#####.###.#############.#####.###.#.#.#.#.#.#.#.#.#.#.###.###.#.#########.#.#.#.#######.#.#.###.#
#...#...#...#...#...#.#...#.....#.#.......#.....#.....#.....#.....#...#.#.....#.#...#.#.#.#.#.#.#...#.#...#.........#.#...#.#.....#...#.....#
#.###.#.###.###.#####.###.#.###.#.#.###.#.#.###.#.#######.#.#.#.###.#.#.###.###.#.###.#.#.#.#.#.#####.#####.#####.#.#.#.###.#.#.###.###.#####
#.#...#.....#...#.....#...#.#.#.#.#.#...#.#...#.#.#.......#.#.#.......#.....#...#.#.#.#.#.#...#.#...#.....#.....#.#.#.#.#...#.#.....#.......#
###.#.#######.#.#.#####.###.#.#.###.#.###.#####.#.#####.#####.#######.#######.###.#.#.#.#.###.#.#.#.#####.###.###.#.#.#.###.#.#######.#.###.#
#...#...#.....#.#.....#.#.....#.....#.#.........#...#...#.....#.....#.#.....#.#.....#.....#...#...#.....#...#.#.......#...#.....#.....#...#.#
#.###.#.#.#####.#####.#.#.###.#######.#.###########.#.###.#####.#.###.#.###.#.#.#################.###.#.###.#.#.#####.###.#####.#.#####.#.#.#
#.#.......#.#.......#...........#.#...#...#.......#.#...#.......#.....#.#.#...#.#.#.............#.#.#.#.#.#.#.#...#.#.#.#...#.#.#.....#...#.#
#.###.#####.#.#####.#.#########.#.#.###.#.#.#######.###.#.#.#####.#####.#.#####.#.#.###.#######.#.#.#.#.#.#.#.###.#.#.#.###.#.#.#####.#.###.#
#.#...#...#...#.....#...#...#.....#.....#.#...#.....#...#...#.....#.....#.....#.#.#...#.....#...#...#.#...#.#.#...#.......#.#.#...#...#...#.#
#.#.#.#.###.###.#.#.###.#.#.#########.###.###.#.#####.###.###.#.###.#####.#####.#.###.#.#.#.#.#######.###.#.###.###.#######.#.###.###.###.#.#
#...#.#.....#.#.#.#.#.#...#.....#...#.#.#...#...#.....#...#...#.....#.#.........#...#.#.#.#.#.....#...#.#.#.....#...#.....#.#...#...#.#...#.#
#####.#.#####.#.#.#.#.#####.###.#.#.#.#.###.#.###.#####.###.###.#####.#.#########.#.#.#.#.#.#####.#.###.#.#######.###.###.#.#.#####.#.#.###.#
#.....#.#.....#.#.#.......#...#.#.#.#...#...#.....#...#...#.....#.#...#.#.........#.#.#.#.#...#.#.#...#.........#...#.#.....#.#.....#.#...#.#
#.#.###.#.#####.#.#####.###.#.#.#.#.###.#.#.#######.#.###.#######.#.#.#.#.#.#######.#.#.#.###.#.#.###.#############.#.#######.#.#######.#.###
#.....#...#.....#.#.....#...#...#.#.#.....#.........#.....#...#.....#.#.#.#.#...#...#.#.#.#.#.#.#.#...#.............#.....#.......#...#.#...#
#.#.#.#####.#####.#######.#######.#.#.###.###.#############.#.#.#####.#.#.###.#.#.###.###.#.#.#.#.#.#.#.###############.#.#######.#.#.###.#.#
#...#.#.....#.#...#.......#.......#...#.#.#...#.#...#.......#.#.#...#...#.#...#.#...#...#.......#...#.#...#...........#.#...#...#...#...#.#.#
###.#.#.#####.#.###.#######.###.#######.#.#.###.#.#.#.#.#####.#.###.#####.#.###.#######.#.#######.#######.#.#########.###.#.#.#.#######.###.#
#.....#...#...#.#...#.....#.#.#.....#.....#.#.....#...#.#.....#...........#.#.#...#.....#.#.......#.......#...#.....#.....#...........#.....#
#.#.#####.###.#.#.###.###.#.#.#####.#.#####.#.#########.#.#########.#.#.###.#.#.#.#.#.#.#.#.#######.#########.#####.###.###.#####.#.#.#####.#
#.#.....#.....#.#.#...#.#.#...#.#...#.#.....#.#.........#...#.........#.#...#...#...#...#...#...#...#...#...#...#.....#...#.#...#.#.#.....#.#
#.#.###.#####.#.#.#.###.#.###.#.#.#.###.#####.#.#.#.#######.###########.#.#####.###.#.#######.#.#.###.#.#.#.###.#.###.###.#.#.#.#.#.###.###.#
#...#.............#...#...#...#...#.#...#.....#.#...#.....#.......#.....#.#.......#.#.......#.#.#.#...#.#.#...#.#...#.#...#.#.#...#...#.....#
#.#.#.#####.#.#######.#.#####.#.#.#.#.#########.#######.#.#######.#.###.#.###.#.###.#.#####.#.#.#.#.###.#.#.###.#.#.#.#.###.#.#############.#
#...#.#.....#...#.....#.....#...#.#.#.....#.....#.......#.#.....#.#.#...#...#.#.#...#.#...#...#...#.#.....#.#...#...#.#...#.#...#...#.....#.#
#.#.#.#.#######.#.#########.#####.#.#####.#.#.###.###.#####.###.#.#.#.#.###.#.#.#.###.#.#.#########.###.###.#.###.#.#####.#####.#.#.#.###.#.#
#.#...#.#.....#.#.......#.#.#.....#.#.......#.#.......#.....#.....#.#.#.#...#.#.#.#...#.#.#.......#.......#.#.#...#.......#.....#.#...#...#.#
#.#.#.###.#.#.#.#######.#.#.#.#.#####.#.#####.#.#.###.#.#####.###.#.#.#.#.###.###.#.#####.#.#.###.###.#.#.#.#.#.###########.#####.#####.#####
#.#...#...#.#.#.........#.....#.#.....#.........#...#.#.#...#...#.#.#.#...#...#...#.....#...#.#...#...#.#...#.#.#...........................#
###.#.#.###.#########.#.#######.#.#################.###.#.#####.#.#.#.#####.###.#######.#####.#.###.#.#.#.###.#.#######.#.#################.#
#.....#...#.......#...#.........#.#.#.............#.....#.....#.....#.#...#.....#.#.....#.........#.#.#.#.....#.....#...#.#...............#.#
#.#.#.###.#######.#.#####.###.###.#.#.###.#.###############.#.#######.#.#.#####.#.#.#####.#######.#.###.###########.#.#.###.#############.#.#
#.........#.....#.#.#...#...#.#.#.#.#.#...#.#...........#...#.........#.#.....#...#.....#.#.....#.#...#.#.#.......#.#.#...#...#...#.....#...#
###.#.###.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#####.###.#####.#.#####.#######.#####.#########.#.#.#.#.#.###.#.#.#.###.#.#.#.###.###.###.#.###.###.#
#...........#.#.#...#.#.#.#.#...#.#...#.....#.#...#...#.#.#.....#...........#.............#.#.........#.#.#...#.#.#...#.#.....#...#.#.#...#.#
#.###.#.#.###.#.#.#.#.#.###.#.###.#.#######.#.#.###.#.#.#.#.#####.#########.#####.#########.#########.#.#.###.#.#######.#######.###.#.###.#.#
#.#.......#.....#...#.#.....#.#...#...#...#...#...#.#.#...#...#...#...#...#.#...#.#.....#...#.....#...#.#.#...#.......#...#.....#...#.#...#.#
#.#.#.#.#.#.#########.#######.#.#####.#.#.#######.#.#.###.#####.###.#.#.#.###.#.###.###.#.###.###.#####.#.#.#######.#.#.#.#.###.#.###.#.###.#
#.#.....#...#.........#.....#.#...#.#...#.......#.#.#.#...#...#.#...#...#.#.........#...#...#...#.#.....#.#...#...#.#.#.#.#.#...#.....#.....#
#.#####.#.###.###.#####.###.#.###.#.###.#.#######.#.#.#####.#.#.#.#######.#.#.#######.#####.###.#.#.###.#.###.#.#.#.#.###.#.#.###.###.#######
#.#...#...#.....#.#.#.....#.#...#.#.....#.......#...#.#.....#.#.#...#.......#.......#...#.....#.#...#.........#.#.#.#...#.#.#.....#.....#...#
#.###.#.#.#.#####.#.#.#####.###.#.#.#####.#.###.#####.#.#####.#.###.#####.###.#####.###.#######.#####.###.#####.#.#.###.#.#.#######.###.###.#
#.....#.#...#.....#...#...#.....#.#.....#.#.............#...#.....#.#...#.#...#...#...#.....#...#...#.#...#.....#.#...#...#.#.....#.#.#.#...#
#####.#.#.###.#####.###.#.#.#####.#####.###.###.#####.###.#########.#.#.#.#.#.###.#.#######.#.###.#.#.#.#.###.###.#.#.###.#.#.#.#.#.#.#.#.#.#
#.#...........#.....#...#.#.#...#.#...#.#...#.........................#.#.........#.......#.#...#.#.#...#.#...#.....#.#...#.#.#.#...#.#.#.#.#
#.#.#######.#.#.#####.###.#.#.#.#.#.#.#.#.#.#.###.#.#####.#.#########.#.#.#############.#.#.###.#.#.#####.#.#.#####.#.#.###.###.#####.#.#.###
#.......................#.#...#.#...#.#...#.......#...#...#.........#.#.#.....#...#...#.#.#.....#.#...#.#.#...#.......#...#.....#...#...#...#
#.#####.#####.#########.#.###.#.#####.###.#.#.#######.#####.#######.#.#.#.###.#.#.#.#.#.#.#.#####.###.#.#.###.#.###.#####.#######.#.#.###.#.#
#.#.....#...#.#.......#.#...#.......#.#...#.#...#...#.............#...#...#.#...#...#.#.#...#...#...................#.....#.......#.#.#...#.#
###.#.###.#.#.#.#####.#.###.#####.###.#.###.#.#.#.#.#####.#######.#######.#.#########.#.###.#.#.#.#.#####.#.#######.###.###.#####.###.#.###.#
#...#.....#.#.#...#...#.#.#.#...#.#...#...#...#.#.#.....#.#...............#.........#.#...#...#...#.....#.#.......#.......#.#...#.....#.#...#
#.#########.#.###.#.###.#.#.###.#.#.#####.###.#.#.###.###.#.#############.#######.###.###.#############.#.#.#.###.#.###.#.#.#.#.#######.#.###
#.....#.........#.#...#...................#.....#...#...#.#...#.........#.......#...#.#...#.....#...#...#.#.#.#.#.......#...#.#.#...#...#...#
#.###.#.#########.###.###.###.#.#####.#.#.#.#.#####.###.#.#####.#######.#.#####.###.#.#.###.###.###.#.###.###.#.###.###.#####.###.#.#.#####.#
#...#.#.....#.....#...#...#...#...#...#...#...#.#...#.#...#.....#.....#...#...#.....#.#.......................#.....#...#.........#.........#
#.#.#.#######.#####.###.###.#######.#########.#.#.###.#####.#####.#######.#.#.#######.#######.###.#.#####.#.###.###.#.#.###################.#
#S..#.............#.......#...................#.............#...............#.........#...........#.........#...............................#
#############################################################################################################################################

View file

@ -0,0 +1,94 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Functor
import qualified Data.Heap as H
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Vector as V
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 64
data Tile = Wall | Floor | Start | End deriving (Eq, Show)
type Line = V.Vector Tile
type Input = V.Vector Line
type Parser = Parsec Void String
parseTile :: Parser Tile
parseTile = char '#' $> Wall
<|> char '.' $> Floor
<|> char 'E' $> End
<|> char 'S' $> Start
parseLine :: Parser Line
parseLine = do
line <- some parseTile <* eol
return $ V.generate (length line) (line !!)
parseInput' :: Parser Input
parseInput' = do
line <- some parseLine <* eof
return $ V.generate (length line) (line !!)
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Cost = Int
data Heading = N | S | E | W deriving (Eq, Ord, Show)
type Coord = (Int, Int, Heading)
type Path = S.Set Coord
data Position = Position Coord Cost Path deriving (Eq, Show)
instance Ord Position where
compare (Position _ c1 _) (Position _ c2 _) = c1 `compare` c2
type Visited = M.Map Coord Int
type Candidates = H.MinHeap Position
compute :: Input -> Int
compute input = S.size $ S.map (\(x, y, _) -> (x, y)) $ walk infinity M.empty $ H.singleton (Position start 0 S.empty)
where
walk :: Int -> Visited -> Candidates -> S.Set Coord
walk l v h | H.size h == 0 = S.empty
| c > l = walk l v' h'
| t == End = S.union s' $ walk c v' h'
| otherwise = walk l v' $ H.union h' $ H.fromList $ nexts v' $ Position p c s'
where
([(Position p@(x, y, d) c s)], h') = H.splitAt 1 h
t = input V.! y V.! x
v' = case M.lookup p v of
Just c' -> if c < c' then M.insert p c v else v
Nothing -> M.insert p c v
s' = S.insert p s
nexts :: Visited -> Position -> [Position]
nexts v p = L.filter (valid v) $ candidates p
valid :: Visited -> Position -> Bool
valid v (Position p@(x, y, _) c _) = input V.! y V.! x /= Wall && case M.lookup p v of
Just c' -> c <= c'
Nothing -> True
candidates :: Position -> [Position]
candidates (Position (x, y, N) c s) = [ Position (x-1, y, W) (c+1001) s, Position (x+1, y, E) (c+1001) s, Position (x, y-1, N) (c+1) s ]
candidates (Position (x, y, S) c s) = [ Position (x-1, y, W) (c+1001) s, Position (x+1, y, E) (c+1001) s, Position (x, y+1, S) (c+1) s ]
candidates (Position (x, y, E) c s) = [ Position (x, y-1, N) (c+1001) s, Position (x, y+1, S) (c+1001) s, Position (x+1, y, E) (c+1) s ]
candidates (Position (x, y, W) c s) = [ Position (x, y-1, N) (c+1001) s, Position (x, y+1, S) (c+1001) s, Position (x-1, y, W) (c+1) s ]
height = V.length input
width = V.length (input V.! 0)
start = (1, height - 2, E)
infinity = maxBound :: Int
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute input

View file

@ -0,0 +1,5 @@
Register A: 729
Register B: 0
Register C: 0
Program: 0,1,5,4,3,0

View file

@ -0,0 +1,66 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Bits
import Data.Functor
import qualified Data.List as L
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = "4,6,3,5,6,3,5,2,1,0"
type Register = Int
type Op = Int
data Input = Input [Register] [Op] deriving Show
type Parser = Parsec Void String
parseNumber :: Parser Int
parseNumber = read <$> some digitChar
parseRegister :: Parser Register
parseRegister = string "Register " *> (char 'A' <|> char 'B' <|> char 'C') *> string ": " *> parseNumber
parseInput' :: Parser Input
parseInput' = Input <$> some (parseRegister <* eol) <* eol
<*> (string "Program: " *> some (parseNumber <* optional (char ',')) <* eol <* eof)
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Pointer = Int
type PState = (Pointer, [Register], [Int])
compute :: Input -> String
compute (Input start ops) = L.intercalate "," . L.reverse . map show . (\(_, _, s) -> s) $ step (0, start, [])
where
end = length ops
step :: PState -> PState
step ps@(p, [a, b, c], _) | p == end = ps
| otherwise = step $ i ps co
where
i = [adv, bxl, bst, jnz, bxc, out, bdv, cdv] L.!! (ops L.!! p)
co = [0, 1, 2, 3, a, b, c] L.!! (ops L.!! (p+1))
adv (p, [a, b, c], acc) n = (p+2, [a `div` (2 ^ n), b, c], acc)
bxl (p, [a, b, c], acc) n = (p+2, [a, xor b n, c], acc)
bst (p, [a, b, c], acc) n = (p+2, [a, n `mod` 8, c], acc)
jnz (p, [0, b, c], acc) n = (p+2, [0, b, c], acc)
jnz (p, [a, b, c], acc) n = (n, [a, b, c], acc)
bxc (p, [a, b, c], acc) _ = (p+2, [a, xor b c, c], acc)
out (p, [a, b, c], acc) n = (p+2, [a, b, c], (n `mod` 8) : acc)
bdv (p, [a, b, c], acc) n = (p+2, [a, a `div` (2 ^ n), c], acc)
cdv (p, [a, b, c], acc) n = (p+2, [a, b, a `div` (2 ^ n)], acc)
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute input

View file

@ -0,0 +1,5 @@
Register A: 37283687
Register B: 0
Register C: 0
Program: 2,4,1,3,7,5,4,1,1,3,0,3,5,5,3,0

View file

@ -0,0 +1,76 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Bits
import Data.Functor
import qualified Data.List as L
import Data.Maybe
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
type Register = Int
type Op = Int
data Input = Input [Register] [Op] deriving Show
type Parser = Parsec Void String
parseNumber :: Parser Int
parseNumber = read <$> some digitChar
parseRegister :: Parser Register
parseRegister = string "Register " *> (char 'A' <|> char 'B' <|> char 'C') *> string ": " *> parseNumber
parseInput' :: Parser Input
parseInput' = Input <$> some (parseRegister <* eol) <* eol
<*> (string "Program: " *> some (parseNumber <* optional (char ',')) <* eol <* eof)
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Pointer = Int
type PState = (Pointer, [Register], [Int])
compute :: Input -> Int
compute (Input start ops) = minimum $ findA 0 (tail $ L.reverse $ L.tails ops)
where
findA :: Int -> [[Int]] -> [Int]
findA a [] = [a]
findA a (l:ls) = concatMap (\next -> findA next ls) nexts
where
candidates :: [Int]
candidates = [a*8..a*8+7]
steps :: [PState]
steps = map (\x -> step (0, [x, 0, 0], [])) candidates
outputs :: [[Int]]
outputs = map (\(_, [_, _, _], x') -> reverse x') steps
valids :: [Int]
valids = L.elemIndices l outputs
nexts :: [Int]
nexts = map (candidates L.!!) valids
end = length ops
step :: PState -> PState
step ps@(p, [a, b, c], _) | p == end = ps
| otherwise = step $ i ps co
where
i = [adv, bxl, bst, jnz, bxc, out, bdv, cdv] L.!! (ops L.!! p)
co = [0, 1, 2, 3, a, b, c] L.!! (ops L.!! (p+1))
adv (p, [a, b, c], acc) n = (p+2, [a `div` (2 ^ n), b, c], acc)
bxl (p, [a, b, c], acc) n = (p+2, [a, xor b n, c], acc)
bst (p, [a, b, c], acc) n = (p+2, [a, n `mod` 8, c], acc)
jnz (p, [0, b, c], acc) n = (p+2, [0, b, c], acc)
jnz (p, [a, b, c], acc) n = (n, [a, b, c], acc)
bxc (p, [a, b, c], acc) _ = (p+2, [a, xor b c, c], acc)
out (p, [a, b, c], acc) n = (p+2, [a, b, c], (n `mod` 8) : acc)
bdv (p, [a, b, c], acc) n = (p+2, [a, a `div` (2 ^ n), c], acc)
cdv (p, [a, b, c], acc) n = (p+2, [a, b, a `div` (2 ^ n)], acc)
main :: IO ()
main = do
input <- parseInput "input"
print $ compute input

25
2024/18-RAM_Run/example Normal file
View file

@ -0,0 +1,25 @@
5,4
4,2
4,5
3,0
2,1
6,3
2,4
1,5
0,6
3,3
2,6
5,1
1,2
5,5
2,5
6,5
1,4
0,4
6,4
1,1
6,1
1,0
0,5
1,6
2,0

75
2024/18-RAM_Run/first.hs Normal file
View file

@ -0,0 +1,75 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Functor
import qualified Data.Heap as H
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Vector as V
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 22
type Coord = (Int, Int)
type Input = [Coord]
type Parser = Parsec Void String
parseNumber :: Parser Int
parseNumber = read <$> some digitChar
parseCoord :: Parser Coord
parseCoord = (,) <$> parseNumber <* char ','
<*> parseNumber <* eol
parseInput' :: Parser Input
parseInput' = some parseCoord <* eof
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Cost = Int
data Position = Position Coord Cost deriving Show
instance Ord Position where
compare (Position _ c1) (Position _ c2) = c1 `compare` c2
instance Eq Position where
(Position p1 _ ) == (Position p2 _ ) = p1 == p2
type Visited = M.Map Coord Cost
type Maze = M.Map Coord ()
type Candidates = H.MinHeap Position
compute :: Int -> Int -> Input -> Int
compute size cutoff input = walk (M.singleton (0, 0) 0) $ H.singleton (Position (0, 0) 0)
where
walk :: Visited -> Candidates -> Int
walk v h | x == size && y == size = c
| otherwise = walk v' $ H.union h' $ H.fromList n
where
([pos@(Position p@(x, y) c)], h') = H.splitAt 1 h
n = nexts v pos
v' = L.foldl' (\acc (Position a b) -> M.insert a b acc) v n
nexts :: Visited -> Position -> [Position]
nexts v (Position p c) = L.filter (valid v) . map (\p' -> Position p' (c+1)) $ candidates p
valid :: Visited -> Position -> Bool
valid v (Position p@(x, y) c) = x >= 0 && x <= size && y >= 0 && y <= size && not (M.member p maze) && case M.lookup p v of
Just c' -> c < c'
Nothing -> True
candidates :: Coord -> [Coord]
candidates (x, y) = [ (x-1, y), (x+1, y), (x, y-1), (x, y+1) ]
maze = M.fromList $ zip (take cutoff input) (L.repeat ())
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute 6 12 example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute 70 1024 input

3450
2024/18-RAM_Run/input Normal file

File diff suppressed because it is too large Load diff

84
2024/18-RAM_Run/second.hs Normal file
View file

@ -0,0 +1,84 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Functor
import qualified Data.Heap as H
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Vector as V
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = (6, 1)
type Coord = (Int, Int)
type Input = [Coord]
type Parser = Parsec Void String
parseNumber :: Parser Int
parseNumber = read <$> some digitChar
parseCoord :: Parser Coord
parseCoord = (,) <$> parseNumber <* char ','
<*> parseNumber <* eol
parseInput' :: Parser Input
parseInput' = some parseCoord <* eof
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Cost = Int
data Position = Position Coord Cost deriving Show
instance Ord Position where
compare (Position _ c1) (Position _ c2) = c1 `compare` c2
instance Eq Position where
(Position p1 _ ) == (Position p2 _ ) = p1 == p2
type Visited = M.Map Coord Cost
type Maze = M.Map Coord ()
type Candidates = H.MinHeap Position
compute' :: Int -> Int -> Input -> Bool
compute' size cutoff input = walk (M.singleton (0, 0) 0) $ H.singleton (Position (0, 0) 0)
where
walk :: Visited -> Candidates -> Bool
walk v h | H.isEmpty h = False
| x == size && y == size = True
| otherwise = walk v' $ H.union h' $ H.fromList n
where
([pos@(Position p@(x, y) c)], h') = H.splitAt 1 h
n = nexts v pos
v' = L.foldl' (\acc (Position a b) -> M.insert a b acc) v n
nexts :: Visited -> Position -> [Position]
nexts v (Position p c) = L.filter (valid v) . map (\p' -> Position p' (c+1)) $ candidates p
valid :: Visited -> Position -> Bool
valid v (Position p@(x, y) c) = x >= 0 && x <= size && y >= 0 && y <= size && not (M.member p maze) && case M.lookup p v of
Just c' -> c < c'
Nothing -> True
candidates :: Coord -> [Coord]
candidates (x, y) = [ (x-1, y), (x+1, y), (x, y-1), (x, y+1) ]
maze = M.fromList $ zip (take cutoff input) (L.repeat ())
compute :: Int -> Int -> Int -> Input -> Coord
compute size n m input | mid == n = input L.!! n
| valid = compute size mid m input
| otherwise = compute size n mid input
where
mid = (n + (m - n) `div` 2)
valid = compute' size mid input
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute 6 12 (length example) example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute 70 1024 (length input) input

View file

@ -0,0 +1,10 @@
r, wr, b, g, bwu, rb, gb, br
brwrr
bggr
gbbr
rrbgbr
ubwu
bwurrg
brgr
bbrgwb

View file

@ -0,0 +1,42 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Functor
import qualified Data.List as L
import Data.Maybe
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 6
type Input = ([String], [String]) -- patterns, designs
type Parser = Parsec Void String
parseInput' :: Parser Input
parseInput' = (,) <$> some (some letterChar <* optional (string ", ")) <* eol <* eol
<*> some (some letterChar <* eol) <* eof
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
compute :: Input -> Int
compute (stripes, designs) = length . filter id $ map compute' designs
where
compute' :: String -> Bool
compute' [] = True
compute' design = or $ map compute' $ catMaybes $ map (\s -> L.stripPrefix s design) stripes
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute input

402
2024/19-Linen_Layout/input Normal file
View file

@ -0,0 +1,402 @@
wubr, uwbu, ugwru, wwgrgwbu, brwwuuwb, wgu, rw, rgb, ugr, gwuurww, rrb, ugwg, wwgb, rwr, wuw, wwbb, wwgrwuw, gruggu, ggb, wrrgww, gwuu, bwb, wbbubwb, urwgggg, bubwu, wbb, rurrgwgg, rub, urr, uwrgrgwu, gwgb, wbwb, gur, brw, bg, gugrwb, ub, ugwgu, wubbg, bubgrw, wgb, wgruu, bgg, bbuubbr, rbbw, ww, grgrb, urw, rug, wbwrgw, brr, bbgrguw, rwb, bbguu, gwbbg, bubg, wwuwwb, urggwu, bbwg, bbbwbbr, wwb, brgwbuw, wwrr, bwu, urbu, wguuw, grb, urbrbbu, rwg, urguw, wbg, uuru, uburw, bbbwrb, urwbur, guu, rbg, gwgwwrr, rbwu, r, wbw, gb, wgwg, ubw, bb, rbgru, rrbuwg, uwb, wuub, uurrub, wuu, bub, uwww, wug, grwguwu, bwgggbrw, uwu, wb, rrbgwubw, wubu, urbrg, wrbw, gruw, rrgwg, bbrub, ugu, gbu, gburu, wgbru, ubwu, brggw, wurr, bgwwgu, wggw, ugbgur, gwruww, wuwww, rbbbrug, wgw, gggu, rgrww, wgwwrg, wuugbw, rggb, brurrg, rbuu, ruu, wrrb, wwwb, gbguuuu, ruubur, gbwrw, gbgu, rbw, ubbb, wr, buwug, grw, wrbu, guwwwur, guw, urggurbu, uwg, grrwwwr, gbb, ruuw, ugww, guurw, grguu, gwrwrr, uwrwr, ubrb, wrrw, burbru, gugg, ubg, rwbu, rruwbru, ugbwu, gbr, ggwwg, rubbugg, wuwb, rrgw, rrbuu, rggbu, gbguu, ggr, wwwbgu, gbrw, bbbug, wrwwbb, wrg, buu, gwub, brrgugw, brg, rwggg, wuuuuugb, guwu, wgbbb, urur, wrr, wugwggu, uubgg, gbg, wgub, grru, uu, gbgbw, wubrg, wwrb, urrgb, wbuurrb, bw, bbw, rugbuw, bwbu, wbu, rrgwgbru, ggurrrb, grr, rrgug, rgw, rr, gbwbbww, ubbru, uuw, ruwbwwr, gwu, ugw, gbw, ruw, grww, ubbwrgrg, wgg, rwwr, ggwur, buuru, bbg, ruwgg, ururu, wrb, b, wbbubwgr, uub, brgr, wbbrrb, bru, wbbub, ggbbrg, wgrwbwr, gwrg, ubwruw, rurrb, brug, wu, bug, wwrruuu, uuu, wurgbu, u, bbr, wwrwu, wru, wbgr, ru, rwgguw, wwu, ggbg, ggrgu, wgwurw, ruwrwu, ggg, wggggbu, rbugggg, wwbbu, w, rwru, bgr, gr, bwwb, uggwbwuw, grg, uur, wbwrrugb, wbwg, ggww, wwg, rbwg, gub, bbb, gugbu, ugg, rurrg, brb, guggww, bugb, ubrwww, bbwr, ur, wwr, uru, uuurrw, wgwwbb, bgbbr, gugu, bwrrgrrw, bgw, gbgw, ubgrgr, wrw, grug, ugggww, wbbwg, rbwb, ubr, wgwb, brbwbgwu, gubwgr, bruugggg, wgggu, rgr, ugwwgbgr, bgrurr, wgr, gwb, gwgrr, ggw, gurrb, wuwubw, brbbgw, ububrbw, ubbrw, ububu, ubrbub, bggu, rwrgb, burwg, wrru, rg, rrbww, rrww, wrwb, uuwwu, bwuwr, gwbr, urruwrg, rubgbr, gwgbw, rbru, wrrubw, bgwugbr, uguurg, wwrg, bwr, rwrr, uwugr, uug, wwgu, wwrububg, www, bgb, urg, wg, gu, rwu, rbb, gwgw, grggguuw, rbuwrru, gwug, bgu, burgb, bwrubu, uww, wur, rurr, rrr, wwbrr, wwbbrw, urww, buwugwr, rbuurb, wub, bbbw, gwr, wwbgru, ubu, uugrg, rbu, rrg, gggg, gww, ubgbb, wbr, ururbwu, wugr, uugub, br, bgbb, grbgrw, gru, bgur, bbu, rru, ug, wwgugub, uuwgg, wguubw, urwbruw, gbbb, wrwuw, wguw, gbwgrbw, rwwwu, brgru, bu, rur, rbr, wrguugu, bbrr, wbgb, ugwbwu, wrbuwr, ubgr, uwbw, uwwuwrrb, gwugr, ggrr, uurgru, brbrb, brwbrr, bbru, ruwub, rrwgu, buw, ggu, rggbbr, brgw, bguwr, wwbgu, rgu, bur, urrgbu, uw, uwrbuw, wrubbw, wubw, bww, gubgb, rww, bbuwggg, bwgr, brwb, rgg, rb, urb, bgrw, wgurgrr, bgwuur, bbbu, wbwrgg, uwr, ugb, rwbg, gbubbuw
guuggwbugbrrwgwgrwuburuggwwguwbgrrbbguugrbgwugu
gwguggrrbbwwgwugugwbrbwbgwuuuuwwrbwrbbbgrwwrwwbbwbgww
gwgggggwwwbuwwburbbrrguugrgruurggwburgruruguurwwuruguggr
gwggwuwwwwbuwrubbwrbwgrggruwgbuuwwbbgwrubwbrgu
gggbgrbuguwwgrggbrrwrrgburgbrubgbubrrbrbgguurgwburggrwwbub
gwggbbrrbbwrrwbbubwgrrbwbwbbburrrgurrggwrrr
gbuwrwrrgruurwuwwwrgurbbubgururbbuuwbbgggrwrgb
gwgggwrggrrwbwrwwgbbrgbbwggwwgurrubrrrwggbuwrrrrwrugrbw
brurbrgbubuugbwrrubwwwbgbwbuurwurgrggrrbrbuuwbbw
gwgrwbbwrwbuurrgubrgbrrgbwwugrwgrwgwuwrbruwwbwgugrbbbbbrgwb
wruubwrwwbbrugbwwbbrbbrrbubwrbggwrbugburbggubuu
bwgrbbuwwugggwgrrwwwrgwuwwgbbwbggububbrugwbbruubggrb
gwggbrgrburwbbwurrbuugwbgbgrbrwurrbuurgwbgugbrbbgr
gbwguuuuwrbwwgwgwuurwbrugrbrgugrrgrgwrwgwrwurgg
gwgruugubrbwbruwbbruwbgrbugubbbwrwurgbgbburwguw
gwgrggwgbwbuuwubgrggbguurrruwuururuubbbguwuwrbbruguu
rwrwbrubbbbrrrwrwgrgwuwbgrrbbwbrubggwubrwwguwb
gwguuubuwwbbubggugrugwubbbrbwgbugbwgwbbruuwwuwgugbbwwwwrugr
ggrgwggrwuggwwrbrggbbrurwguwuubrubrwwguburbbrubgwubgg
gugbrggrrrguuwubgbwrwbrgbrrugwwrruruuggurrgbrwrwru
bwuwgugbgrwgurbbgrgbrrgubbguwbburrwwwbgguwwgrggwwrbgwuwbww
gwggbwwubbbbbrgrgwgrbburgrwgbbruubgrgwgwwugwbbrubggwgbb
bbburbgugrguurubwwwwurbuubrgwwuururuuwbbuurwubrggrwbuubw
gggbrrwwurwubrrgrburgruwwuwrrguurbruwrugrwbuwrwrggguwrggw
rgbrguurrrbrgguurwrbbwuubwgrbguwgbugbwuwbbgg
gwgubbruwwgwugrwuugwuruuwrwbbubugugguwwguurrruruwbg
bbgwugurbuwgburbrrrrgrwwrrggggwuwbgbwrguwwgurgwuggrburrwgg
gwrrgbwgugugrgrrggggrwugwbwgrrgwugurbwrbbwwrwggubrwbur
rrwgrgwwwbbugrgwrbubuguwgggrgwguugurgurwrggburguwugr
gwgugbrguwrbbuggrgbrwubgwubwwwrwrrrbbgbbw
ruwgwuwugrrbrgwbgbbgbwugwuggruwuwurgbuubbruwubburbguw
rwrugrgwbwuwgbwrbbwrrruubgubbwrugggugbwggbgrbuuwruwrrrgbuu
wuwbgwgwggwwrbgrbuwbwrbugwgbrugrggggrggwuwuggwgubgu
rbrgrwwrubuubuwuwwrgubggubrbrgggwrwrwrgwuu
gwgururwgbwruwwggbwuwwwggugwwwwrgwbuwrrbbbgrgbgbrwurwbrwgw
bgbrbgbwguwgrubggugrwrbwrgrwgubgruggrbburrbgwubwuguuw
rguggurbgwrgurwurggwwgrwugbwgwbbbrbrurwggg
gwgrgrgbbwrbgrwubwbbuwruuwurwgwwrwuruubrwgburbgwgbu
uuubwbgruwbrwrubwguwbugbgggwguggrwubgbbbuurrguu
gwgggwrbbgbrgbrwrbrwggrbrrwbuububwgrrrrggru
gwgguwgurrrrbwwwrwrgwbbgurrwurrbubwbgbruw
uwrwubgwuwbwggbgrgugbbwrwwbbbubwgrwbrubuuggggrwrrwwgrb
grrwruuguuurgurwgwwgbrwwburwbuubrbggggrbrgu
urgrruurbgurubrrbbrrrrgwrbbwguwrrbrgburwwrbwbrgugbugbgg
rggbbrbbbgbburwrwrguwrwbwruwubrbgugrgugwbwbrwuggbgwbr
wurbgbwbbwgubbburbrgbuugugguwbgrwggrruburugrb
gwggubbgbgggwbbwurburwwguwbwbrggbubuuggwwr
wrbrrbwrburbrgrubbwubbrgbbbuwrurrrrurubrbuuwwwubrbrrbr
buggburbubbwrbbrbbwwwgwgrbugguuuugbgguuwrrgwrrbbrrgrwwgbru
gwgugubwgbgrururgbbuguwwwbwrrugbbgrubrwrwuuwb
buwrugurwgrbguwwrwgruwrgbbbwwruubugrubrbbwuub
rwgwwbugbbrgwwrwrrrrrwgrugrbruurrgrggrrgbbruub
ubguwwrgurguwwgbbbbbwwbburrurbuwwrgbwbbgrgbwwrbubbggbr
urgwwrbbwggrwguugguurgugbuurrubrgbbuwbrwgwrwbuwuuw
gwguwbgrggwugrrgrwbwrbugwgwgbubguurggrbrurugub
ubgrbuwgguwgrbgrbguruwrgrgwuwgggrgurbwggbgbg
wrgugrgggubbuwgggwbgubwwrwbgbuwgwgbbwguubgbwbr
bwgguuuggrguwrubbruwbrbrgburrguwrrbrggwwbb
gwggwggbrrgwgbruubwruwguwbugwrwrwrrwbwwu
ugbuwrrwgwbruwurubbgruuuwrrwgbgwugbuubgwwugbu
gwgugrgrrurrwgburbwbbwuugwruwrubrrbgbrrrrrrbguugbwb
wubrrbuubugwrbburrrbbwwbgrwgbuuururgrruwbgrguwbwubgbu
wurbruwuwrwggwuwrubrggwbbuwbgbggbbrwwwbuugbwrguwugwuugggub
grrubugurbbbuuwrrrugggrbggurbbuuwrwbggubuugugwgrbguggggbw
buwgrgwuugguurbubrwurgugbbwrgwgguubwgwgwwbu
uggrwgggwgwwugbbrrgrurgbggwbgrbwwgugrwwgwr
bbggrugwrbwggggbgbbwwrwbbgwgwwugugwbuwrugbg
bubugwbwguwububwwwuwguwurbwwbbgurugwwuwurwbbbugbwrrgggb
bggurgwbgggwbguubgwurubgrwbrwuwwgwubwbrguwwwuuuug
rubguugrwrubwguuwrgwurbguuugurgbburrruwwrgwrggbggwruubwr
wbbbruuwuwubbwrburugguurbggwwgbbrwwwbrggggwwu
gwggrwbrbgrrbuwwgwuubrwgrwguruwrrgrbrbruwrgrgwu
gggrbwrruuuuwruubgrgubrgrgwuwgbrwbrwgurgugbgugbruubrrgwwb
bbwbbubgguwrbwbwubwgrbwurrbuwgurrwuuubggrbwwrwgbrwbuwrbuub
gbggguuruugwrbuuuwgbwbububwbwrrwwubrrrwwbubrbwugbrug
buuwgggurgbgbguwrruubruubbuwugbrggbrbruubwgb
brwbrrrwrgurwgbugurubbguubbuwubrgbuwrgwbbgbwrbbwwg
rbgwbuwuugbruurrbwbggrurguuwwgwbbubwgrgugbbwburbuggbwuwrru
uggbruuuwwrurrwurwbwgbgwugwbgbwuwrwrwuuwubbrwruguug
rrrwguwuwbbgrgrrgggwubbwrgrggrrwrrbgwbbrwgruugbgwrwwuugwr
gwwbbwbgbrurgwbwwggurwrwgwbbrwugugubwwuwwbwbw
wbgrwbbgwuuruwbbrurubgruwgwggbruggggbrrubggrwgbrgwuuwuwrbb
gwggbbwgggwgrwubrguugugrururrwurrwuwbwuubuwrwuwuurgrbuub
ubuggrwbubrrbggbgrbubbburgrugwurbbuwgwbwrwwgbwugubgwuu
urgubgwwwwrubwwuuuwbbwwgwwrgwwwwwuuwbrgruugwrrrwuggw
bwuwruurgrrgbbgrugrwrugbrbburbrwbugrbgrbrgug
gwgugrrgbuwuwgrbrurbbuwgrububbrurrrwrugbbbrrruubuw
gwrrbwwwburubbrgbwbugbuubuwwbwgwgubrburruruwgbbgurbgb
gwguruwwuwrrbwggrbubbubwrurbwggwgurrbbubgbbggbr
uwgubbwuggwubwbbwbwwrburbuuururuuwrrugwgurwrrrrbrbwwuubuw
wbrbbbgwrgrurbrugrgwgggrgbggrruggbggwbwbwruggrurwu
urgrbbwggrguurgrwwugbrrbwruwgwbbuwbuuwggwbgrguurgbwrgwb
gwguwwrrrwgrgubbgrgbbbruuwgbugggbggurgrbwwwrrb
gwgrgrwurrwggwwgbwubwburwbgubbwrgwurrwgwbruubburwbrwrwwww
gwgubwugwugguwbrgwwbggguruburggrugwwgruurbrgrwwrwbrbgbwgw
rbuurbuwurwrrggrbbburwwuugwbwrbbwgwbuwrrbu
uuubrbwrguwuwubwgrrgrrubuwbrwwbbrrburwrbwgbwuwbru
wbubuwbrgwubggbrrgwugwwuwbgwrrrgwgbruuwgggwgggurgrgr
gwbgwggrgbbgwwwwgbrbwguurwbwgwgugrwrrrgrbwrgggbgr
urrwurrwrurrgbwrbwguwbgbrrrububgbguuubbbwb
uuwwrbbubruwuwrwwwrubrrbbrbbwwbuwbburbgbgrgrrbuwburuwbugr
rrwggurbubbwbugwuuwuwggugwwwwugrrbgwbrwrbgburgbbrwu
bwwgrugurwwbuwrrggubgrurgrwbwrrbggurgugwgrrguubwugw
bwbbubbgbbruwrwuwrwugwbrrwgbgrbrruruubwuwwggg
gwgrbwgwbuggbwbbggububbuwbuuuwrrurwwbbgrb
gwgugwgrbbgwbbrwwbbwurguwwrgubuwbbbgrrurugbbw
gwgrwbbbgbbbwgrrubrurbuurgbgggububurbwbrrgggwwr
gwggbgrurgugwwburgwwrububguurwurrwuwwwbgwguruggbgwwrw
rggwbwgbugrbwbwbwwburruwrurubuggwubrurbbguguwrwuwrg
uurrggwugrrbuubwgwwgbrbuuuwugggguubuwbbwgggrrburggruwg
gwggggrgbwwwrrrgwbgrbggwbwrgbrurgwgbwgbwwuwgrbgrwugbg
wuurgrrgguuwbgugubrwwubuurbbuburrwgwugugwggbwrggurrurrb
rwgwwgbgbwbbrggrwwrwgbuuuugbwbururgugwurwrubuuuuw
gwgguurruuugbbrguuggbrgwgrbgbgbwrrurruwwwurggrg
brurruwgwgrugbgruwgrrwwbrbuugugrrbgrwrburggurrwuuruubrwbu
buurbrbgrrbrgwrgwrrwguugubrwwuuwbgwgruwuwgurrwurbrrwb
gwguwbgwbuwrbggbururbrbuwugwwguwrurgwgbgbgrbruur
ggguwuruwuwgggwwbrbbwuugrwgggbrgwbwwburrbbbuwuwbgwgw
gwgubbrrgrrwgurggbwbgbbbrwggwgwruuwbwgggbrwgwwrrurbwgbgg
rrgwubrurrrrwuurrrwuubrwrwgbgrwbgwubwwwbbbwgrwwrwb
gwguwuuugbgbgugbbwgruruwbugrgwbrwbuwbuuggggwrwrurbbrgrbu
gwgurggbwrrgbwwguggwugrurgugrurgwggbuubbwr
uwurgugguwbbrugwrguugrwuwwgrgwguuggrbuwrbwgww
gbruwggubuwrwrgubugrgbuwgubrgrugwbbwbwbbuwgrgrgwwbrub
wbbgubguubwbbguwrwrbruuwbguwbubbruuggrubbwurbrbbguggb
guguwbgbbrugbugwbbbuwrrugubwrwwrgguruwrgggrgurrbu
uguggugbugwurrrbgurbbugrgwrwbwrrwwbuuggbrubrgbrrr
wgurguwrgrrrwgbbgrbgbrbubrwbgbbbgguwrrwgbbrgbw
bugbwburwrbuuurgwrubgbwurwrruurbgwgbwgwgwbruuruu
gwguruwwwgbwrgrbrgubbrguugrgrgugggrurbbwubrwwuwwguggr
ugbwbgbwubrwwgbwrbwrgwrgbwbrrrburgwggggruwb
gwgugwgbwrugrugugwwuwwugwrrwbuugbwbbgbbggwuubrgwgw
wwwrrbwuuuwurrrrgbgruwgbburgrrrrrbrbrrwrrwbgrgburw
bbrgwgruguwgwwbrgruubbrrwbgburrrubgguubrubbwgb
wbuuuubwggbbggwuggbwwrbubgrrurrwbugrwgbbubgrbrwbrgwbgwru
grbgggbgbubgubggrrubugggrrugrbbubruwgrrbub
gwggbubggrwrbgrwbrguugrggguuwggwgrwuubwggrw
gwgguruggggwbbbrubgbwwbbgurggrurugrruguuuwuu
rbbgwwuurgurwbbbrbbwrwbwwbwbbbrruuwruwwbbwgubgbrrwuugrw
gurbwuggwgurbuwwggugwbgbwrrubgbbbrgbwwrbwurwburburruwgb
gwgruuwugugwugwbbbgrwwwbrgugbgrwuwggguggugwwgbgrr
grbrbbwbwugruugbrubggubguruubuurgwwbwbwrrugbbbguw
bggbbuugruggrgwgurugrurugbgubbgrbbugbrwuururwruugwbrrbr
gwbgwguugwggbrrbgugbuwwbwbuwururwgurrrgurrug
bggrggbguguugbrwuuwuuwburubgwrbbrbbgbbruwww
bgwwgbggurbbrbwrbbwuurrurbggubrrwubwbbwgwwrrur
burwugwwbwruwrubgbwbuubbbbrbrgwgugruwrubwrur
gwgggrrwbrbrbgguugbuwgruwgugwgbruuggggwuuuwwrwgrbggubu
brwuguubburburubrubrugbbbgurwubugrugwwgwbrgrg
ruugurrbbbbwrbrwurbbbuwwbgrggwuwwwubrgwuggggwbwuwgwrrrbgb
wgurggurbububbgrgguwguurruwbbbbgbggwburgbgrgwrwgbrurr
bwubrrbuwbrbbwbwgwwgwrrubwwbbwbbwwbwugrgwuwu
wbwrbgbwwrwburwgububrwgbbbwwgbwuwbwgbwgbwb
wurgrurrwrbgrwbbrrrgbwuwugububugrbugwggbbrguu
uurgwrrgrgbrwwbugurubwwwrgbrwrrwuuugrbrbgruguugbgbbbub
brrrrrguurrwgbbuwrgbwubwgrgbgrbbwgwbwbruguwu
rggubgrgwwgggggwurrbgbrwgbubrwbbrbwubgbuggggrbw
ugbbwbrruburbwgubbwbwwwrugbgwugwubrbururgubugrbbrrbggwrb
wrgbgugrgburuugugbrbrruurwbbbbwuuguwugrwrubgwbwubwwguguubr
wgbuurbwgrgwwuubwbbgggbburbwbrbgrrrwgbwbbwrgu
gwguwrwwbbugbbgbbwubuugruurbuuruuwgugwrrguu
wwubburgwurbrrbrbwuguugwrrwurrgrrwwuubrwubuuwgbbb
guuwrgrwbugbwubrbubrgrrbwuwburbrugrbuggugwwrbgrwwr
brrgurrugwbrbruuurwubwbgrbbrbrbwbuwuugwuuwgwurururgu
buwgurgbrrrwbgwbbbrrbrurwuwrbbbgrrbbgwwgrrbw
bbuwbwgbuurugbbwgurwwbbwguggbrguwrwggbubuwuggwrwugbwburwwu
wrrrruwuwrbuugbwgguugbrurgrgwbuwbbbbgggrgwuwgruggwgubgwr
brgbguuugwwrwugbwbrbwrurwbuubbrbbgruubgrrgg
ubgwgggwbuugrbwgwrgbwwrgbrbrrgbrrgburbbrurrubrugbgwu
gbubwgbgbruwrgububrbwbwgggbrwrrbbrgbrggwwuwbbbgww
rwwrrubwrrrbgbrbbbgrgbbbuggubbwburugbwbwubbgwggg
gwgruuguguggruugwrwbugwbrgrwbwwbubbwuwbgb
gwgurrgrwgwgbrgwgrgwgubwbwrwguwbggwgwrwggbwrgwwuuuububgwgb
rbrrwwbbuwgrbrgwrwbbgbugbrgggguwrrrrugwbwgurrgu
bgbwggwuwrrrubbbgbwrrgrrwrurrgwwwrrrbwrubuubbbrg
wggwbugbrrrwggwgbwwugugrwggwwwguugwruggwbwuwggrrrwrwub
ubrurgbgwubbrwwruubuuwbwgrruwwwubguwugwwgbgrgubrgw
ruggbwbubgubugugwggububuurrwgrwuwbuwwugurbu
guburggbwgwuggrbbbguwgurbguwrrrwguwwwgrbwgubrg
bbbgbbbrrrrbwrgbuuguwrgrwwbbgrbuububrggguwrgr
buwgrrwgubwugrwwrbbgbbwrbwbbrubuwbbbgwbbgbru
bbrrbuguwwbbbrgwuugrguuwwwggwrwgbbguurwwbuugurwurgbubgbu
gwggguburgrrwrgwbgurbbbrwwuuwbubbguwwuugrugbg
bwbwrbuwwrruuuurrubbrubwrggruuugwururwwgbwbuwrbgbwuwwgb
gwgugbrurggbbwurwwburgrbuwgbbwugrgwuuwgbrrurgbwrwurgwgbuwwb
wgggrgbwgrubguuubrwurrrwwbrugbbbubrgbgrrwgb
wbrrgbgrgrugwwgugbrbgbugrwgrwwgguwwgrgwuruwrgu
rwugrbrgurbrubburbbgwugwwubguurrruwbuurgrgurgwgrwggub
urrwguwrrrbrrrgrrruuwuwubrgbrbbwwburgwrwrbruugggggb
ruugbwwbwbgguuuugurwbbrrwruugwgrwwbrgwuugb
gwgrbguugwbururbwuwurbuubrurgwrwgurwwugrubbwbuwbgwgubrrrrb
wwwwwgbbugurggrubbububwugbwbguwrgbbgrwrrrbbrbrbrruwwrr
gwgrgrbrbwrwuuugbuwrwuuwwwrwbubwrbwwgbuwbbrbbrrubugb
gwgruggbrrrbgwubwwggbgurgwruuuurrrgrgurrrbrrrgggrr
rugggwgrbubgwgrgguugwgbbggugwrbbbwgbgwburrwggbbbbg
gggrrugwbbgruubgbwrrwrubwrggwgrrubgwwwuurwubwwrurrw
gwgurrrggrggrguguurgubgrgwrbbrbrugggwubgruggburwrb
urrugbrgbubrrgbbugggguuwwgbruuwuubgubbrbrwrbbrbwbb
gwgugubwrgbrubbbggubbgwrrbwuggwububrurgw
rurgwwwrgwruubwurbuggwugburrrgwrburbgbrbubwu
gwgrwgruwgrbwwurrwgggruwbbrrurgwgubwburbgrugrwgbwruuwguurugw
rwrwuwruguwgbwubwuugwggguwrgruwgrubwwrrwrbbuwrgguubwg
buwuwgurwuruubguwgugbwbgggbrurwwggrgubbuwuggrbu
rbrbgwrrgbbwwwwrgwbwrurwbrrruwurburgrrwgbwrwwurbrrbbg
wwgbwrbggguwwwwwbgwruruubgrwurgbuugurruwbwrrg
rrbrwbwrwugubrrgbuwbrggrgrrwrgrrwwbubguggrugggrw
gwbuubguwgurwbbwwgbgruwgwwgwwrggbrrbgubrubwgbggu
gwguugrbggwuwwgbrwugubbgwrrrgwbwrrruuwrugguubgwbrggwgwb
rgwuuubrgurbwbrgwubbuububgurwgubgguruuggbwbg
bbguruwrruggwuwuguwrgrbwugguwuwrrrrrwuwgurrwrruwwbrbu
ruuuwwwrugbuwuwurbubrwrugwbubbubwruguggrbrrwguwrwugwugbbw
wrwgbbwrgwgwrwwbgbruuggugrwgwwrbwgbuguuwbbg
wwbwurrgwugrbrbgrgwugbugrbbbubrgugwrggwwug
ububggururwrubwrguwruwuwbrwuwurrwrwwgwrguwwgwgur
gugwggbwgbgrrwwwrgbggwrwgugbuuwbgrburrgrbgrwwbbrwbrbwurgw
gwgurwbgbrguwgbrwrwbwuwgrwrurwguubbrrbwrbwgru
wuubbugguugrwwgwrggwbubwugggurwruguwgbrubgwwwbwggubuub
grwrwrbugbgbwwbbbuuwrrggwwwubbbgbuguwwbuugrbrwbu
ggugbgbwbgbuwbburubrrgbwrwbuugurgwuwbrrubrrrrbbbwruruwwwwr
rbgrwbugwurwbgbuwrgggwubuwwrwwwguuggrugwuruwgbg
rrwugwbbwbbwubgbubwbgbgbgbbwggwbwgrurrgwggub
bgwgrwuruuwbrrrwwwwggguwubwggwrrrwgruwuwuu
rwuwwwwwuuwwrggrbrrgugwubuggwwwrbbbubgurbur
uubrgurbgbruuguwwbbgwbrrgrrruuwrugrubwwgguwu
bguugbbgbguwbggwubggugugrrgrubwrgwwwwurrrw
wwwrwrbruburwrrwgugwwrbuubguwuwgubuwwuwrrbgbrbw
grgwuubrgbruwuwrrguuuwuwggbwrrrgurgrbgrbww
gwgrbuburuurrbuwggrrgrbgurbbwggrwuurwggbggwgwgrgrwugurrwrgu
rwwwbbuwwwbrgggguubbwuggwgwubbwwbwwwgbuwrrruwrbrrug
gwggugwubbwrgrgwrugbrbbrurubwbbrgrwrbwggbggrgrru
grrrwwbggrgwgbgurgwrggwwwrgrggwuuggbbgguugw
gwgurbuubwwbbrwbgbggrrwrubwrbgwbbwgruurgguugwggrrrwbburugrbg
gwgggggggwbwguuuwgggggwgwbuggwburburrgwrbu
ugbruwuwrgurbgbwrrgugwrbbrubggubbwwwbgwgbugurbgbrg
rbrgwggbwrugbbrrruggbwuruwgwbgbwruurgwwwgbwg
gwgrbbgwubwwgbbuubrwwuwugbggwbbbuubrbggu
gwrubwgbgwwububrrgruggbgwbuwgwuwuggwbbrrbgguwrrgrrubuwuu
bgububbrgrrurbugbgwggbwrwugurrrbburbbgggbwubwbubgwrwuuuub
rguuuggbbrrurrbrgburrggwguuwbrruggrrbggrwgwgrgwgwuw
uwrrrgubgbgrubuurbwbruuurrbrwggwwgrwrguubgrww
rwwuuuuguwwbuwbgrggubbgwbbguguururrubwwgggruuwgwwgbg
rurrbububwwrgurrbgggurggggbbuggbbbrbgruwrbwbubuuwbwg
rwugugugugruburbubwrrgrgugbrbgburrrgrbbwgwuwu
ubgbwrwbrbwrggrubbbgbbuwrgurwwbrwwgrgwbuwwrgrggggb
ubbbbggwgwguruwrbbwrwwrbrubbwgwwbgrgwgwgrubbrurugbwrgrrrww
gwgubggbuwbgwrwrrruugbbwrbbbwbruwbwubrgrgwbwu
gwgurwrwrruwbwgwrbrrubbgbrwbgugbgugwrrgwrubgwbguuwbw
rrbwurbrrwwrurrugwbugwbuuggbwbwugrwguurwrwrurgbgg
ubbgwubuurgwwwuuwugrgwwbbwubwbrbbrbrguburgbrbggrg
gwgrwrwwggwgggubbuurrugwubbwugrrbrwwrruuwbuubugwrgrg
wrbgbgrrbuwrwrwbgurrwuugurgbwubgrgurgwgwgb
rbgbgbrwubuwggrwwwbrgubbruwwbbwbrbuwwgrbuwgwwur
wubwwguwgrbrwwgrgwwwubgwrgggubwruwgrbgbrrbwbwbbuwuu
uubrwbbubwbbguwgbububrgbrbuwrbruruuguuggbwu
ruwgbrbbwwbwbuuwwbuwuwugggrbwggwwwbrrrrgubugggurrbwrbbugu
gwguuruburgubgggrgrrwururubbwbgbwgrwrwrrggg
uuwgrrbrurwrgbwwbbrbbwwrwubgrwwrububgbbuuuruwgrwruur
ugggwrubgbubuubwwbbbbuuubbbuuubgurbburuubrrruwrwuw
gwggbbuubwbrubwubbwruurrgugbubuurrrrgbgrbguubu
burbrwwrrbwrrgruurggbwggrwwbbggwbbuururbrrguwbwbwrbuwbgrrg
rurguwggbrgubwbbrruugubgburwbgrwruggurgugguurwrrrwuwguruww
ggwgwggwggwwrbuwgrbuurbruggrrrwgubuggbrrrbggwbrggrwbbgrb
gwggbuuwwwbgurgbgubgwrrrbrbgwrbbbbgrbruuww
gwgurrrrrrwurbgbubgbbrbrwwggbubbbwguwwgguu
gwggurrwbbbugguwbrwgwrwgubruruuggwbwggwwrrbuwwurwwbrbu
bubuurbgrurwwuwwgubgurwwrgggrgbuurgbwuruwbugbgwbu
gwgruwggrgurwrruwburuwgbbgrwbubggrrwrgbwwwgruwr
gugwgubbbruggwbrgwurgrgrggrrbwgruwwwuggurbggbbrbburubuububu
rrburugbgwgugbgwgbbgwggrggguuwurggubrbggwub
bruuuwbrbwbgwugwgurubwgbwbrugrrrbgurggwburwrwurwuwrbbuwr
brruuwugrgrgrbwwgugbwruwrwugugugrbuubugburwbwur
ubbwbbwbuurbrugubgrwwruwbwurrbbgrgbwrbuuubw
rrubbubwrbbbgbrwgbuguwbuwwrbwbbwwugubrugbwwbbrbuwwu
gwgggbubrrwwbrwbbuwrguwuwuwrwuwbrrgrwwur
gugwbgwguurbbrwwgruuguugbuwrwrwuggwbwuwbbwuuuggrwgurugwuuru
gbwuurggurbuuguurwbgbgubugggwubgwgruggubbbwgguurwubbwrg
gguwugurgbbuuwrbggwrugugwrguwbugwgurrwrrwrub
ubgwrwrgbuwrrrurbrbwrbbgrrwgbwrbgugwwuuwguu
bwurburrwrgrgwbbwrrbgggwrurggwgbwrubwbrwbuwgbbubr
grggubbwwrwrbbburgwguubrwurgugwurbuurgbugr
ruurrguwgbwwuwuurrbrbggbgwgrubugwwbbrgwrwrrw
grububbgruwrbgrbrgrbwwbuuuwrbbwruuuggwbbbgwugbwb
gwgubbrrubugrgwgbbuwbwwurbuuugubuwgubbubruw
gwguwurgbguuruurbugubwrgrrrbuubguwggbruburrwwwbgw
bubbrwwburwwwbwbbrurrwugwrugbuuwwwuwbwbgrbggrbwwurgurwww
gwggburwgwguuuguugrbgwrrubbwwwwrurwrrgwubrbrwuwububwg
gwggbbwbbrwgrugrurrgwggggggrwugguruwbgrwgrwwgbbrburub
gwggbwrbwbwuggbbbwrbgubgwwbgubruwrururgbruwrgbuwrubwrwuwwug
gwguuwwgrwrwubbgrgrrwuurbgburrururguuwgrwugubggubrbugug
uggurbbwwggbgwwrbrwuwwrwwrrwrgrurggubrguuruwuuwrgruubw
ugwrbbwgggwuwbgrrwwwggrwbgbgwrwgrbubrwubgburggugw
gwgugwgwbbrrwbrubuuuurwuuuuugbbbrgwwgugwruwrrwg
gugwgrgbwuurbggwrwurrbrrgrrwrgrrwrruguwuwb
wbgrrgwuwrrwbgwbbbwgrwrbrrgugbgbgbugurggrbrrgrwrugbbbr
wrbguubwwwrgrgugrrbwbbwwurugrrwurubguurrrgruuwr
gugwgurbwrrgrgbrurrurwgrurbbrrgwuguugwrgrgrg
gwgruugrrbbrguwubuwuwwgbggubgurbwwbgrbgrrrg
ugrugrbrwbgubbwbbguurwwuuwbubgrwggbgrrwwburu
ggrggubrrbgruuwurwbbbbrbubrrrgbbgubwbwwgbwuwurbbrruug
gwggggrwguuwgwubgrwwurgurgguwwbrrrwwbrgwguwrugwwrugggwrbrw
wrwuuburuwwggbrwgubgwgrwrgwgwwrwwruwbuwgrbuurburgubwurbw
uugugwbgbuuwubguggwbugbwwguuwggrrggurbwggugbbugggururwgwuu
uwrbbugggwgurbugubbggwurwbbbwggbgrrgrgbgrbuwgbruwugubrw
gwgggurrurrburgugguuruuuuguuwbuguuuwrbbu
brgbwruurrggbrwguwbgrwwurwwrbwbwrrgwrwwwrrguuwubwubr
rubugwrurrgwgwbbrrrgguwguuwwgubrubuuuwrggwwwrbbrgrbgu
bwruuwwgruubgurbgbrgwrgwbugruwrbbwbrrugrww
gwguuubwwurbbrubbbrggwwwruguruurwuurwbgbuwwbwwguwg
rrbgrrugbrrwwgbruggbrrrguubbrgwwgguurgrwrrgu
wruwwuwrwgruuggwgbbuuwwgbrugbrwwbwbuwuggwwuuuu
ubgbwrwgrrrbwrrrwrbuwgruwgbrurrwrrurgbbwwrubg
gugwgguwwrrwrbggwrgggbwuwubrbuuggrubuggrwrggbbwbgbgwrbuu
ugbwbbrbgbbgburrwrgbwbwugwwbubggruwuwrurwgrbrbbw
gwguwrwgrubwgbwbrubguwwurrugrwurrgburrbuguuruuwbbwrwu
buugwwwbugwrrrgubwwbwgguwurwuuwwrbwrubggwgrrugw
gwgrbgwwgurgurgbgruwuuwwwbrbubburggggwbr
gwgrbrrruuugrggwbrbrbburgbugwrrgurbuggbubrrbrrubgwbguug
ubuwgwuggbgrrubguwbbwwrwggrbrwrggwwubguuwur
gwggwbwrrgrrwgrggurrugwbwbguubwbwgbuwbwurrwur
wbrrwubuwbuubgurbuububbbbwwuwwuubuubgwbugubrwbwrrugwgrb
gwgrwwgwubggruwrggwbrbwrwbwrbbuwwbuuwgrrguurrwgu
bguguwrbuuubwugggrwrwbgrbgbbgbwbrubgwubgwuurwwuugwgggwuu
gwuurubuwrgbgrubwwrrwbbwrguubwrrwrwwrbggrguwugg
gwgugwrgrgggbruwbrwwguwbwrbbbruwgwbrwubwwwwrrgurbwwwwbbbgrw
bguugbwbrbwwwbbuwuwruwgbgbbwrbwwgbrurrurwuwg
gwguwbwwgubrrurbubrurgrbbrrggrrgwubruurburwbrwurubbubwbwb
rwwwururrbwubgurbgbgbbgrrwgwuuuuugbwbbrubwrrbgwbbu
gwgrgrurrrurgbrwubgurgwwbggbwwurwguwggugugg
gwguuuwguwwubruwubbugwwuwwrubrururgbrguwgr
urrbuwurwbggugrwrwgurbgggwuuwbrrrububguwruuuwrruwrbgbu
gwgubgrguubbbbrbrguwgbwrbbubggbwwuubrbugrgbgrbwuwgbuwrgbrgu
ggwgwgbgwgrgbbuggrubbbgugbrgrgwrbrgurwurggwu
gruuugrbbbwwrrubgguwbwgrrurggrubrbbuwbugbguwrrw
gwguwrbbubrrgwggrrbuguwbwrrgbwgggggrgbwwgrgb
urrrugrbugwwurwuuwwwgbbbbgrgbuwbgguwugrwrubr
gwggwubgrwrrgbwurwrgwwggurrburgwbuurgbruuuubgbuwrugrwruwr
brbbrbwwrruguruuwrburrwuubbrbwurwgbggbgbuugwrgbw
gwggbwbbugwgwgrwwuggbbugwwgubbuwugbrgbbuurg
gwrrguuguuggbbbwuwrrwwwrwuwrwwgbuwbbrbgrwwgurubrubrrbuuw
gwgubugrbbrbuwugwwubrrwwbwgugbuwwgguurruurbwbbugr
wgbwwgbuwurggurrgbrrurwwbgwbugrgbwubgggbrbbruwg
ugwgrrggwbugwbrugrggwubbbggrrruggwuuuggwrwugbuubuubuwrugr
rbubguguubuwgwgwgbuwurwburuwwwguwbubbruguwuu
gwgurugbrugggrurrburgrgubguwbwwgbrgrbruguguuubwwrgur
bwwrrbwrruwgbgwgrubruugwrrwgrrbruwwwuwbuwuuwuwr
gwggwwbggruurbuwbbugrrwwgrgrrrububgrbbgr
gwggubggbwgwubruubgubugurrrrrurubwrruuuwuurugrubr
gwgggurrrggbgruggrbgwuwrguwrgwbbgwrubwuuwrgguurwwwrbbgbgbur
bwurgbbbgwguruugwurgrrbwggbwrrwrburugurbur
wbggwubggwwwbugwgrggwbuwubwgrwggbbgbuwbbwb
grurwgbgruggguguwbrugggwubbugrgbugrbbgbguruwwrbgbgwwggbrbb
wrguuggubwwurwuububgruwubggwburbwgwuubbwwgrrgbgrbwubrwgbg
uwrrwurrugwbrgwbuwbwwrwggbwwbuguwbwbbwwgrw
wbwwurwrgbrugbbwbubuwbwwwgrbbwugbguggwgwggww
wbwgbgbgbbbgrbgurwgurwwrggbbwuwbgrwubwbgwgr
rurrwuwugbgwbrwwguuuurrwgbuwbbwbubwburgwruwurggwbrr
uwubrbgubruuubruurbbwwrwgwuuwrbwguwgubrrrgruubw
rwruubbuuwwbbbbbwggwgbwuguuuuwwuuubuubgggbgbbrguwuwg
gwguubrwuuuwwgugugbgbuwbuwgwrbrbuuuwgrgbgubbr
rwrrugugubwbbgugrbwurgbwguwrbuggrwbubbrugruggrbbbrubrgwgwr
gwgurwrwrubuwgrwwugugguwgrwbgggwrubbrbwwgbrgrur
wubguuwwgrggbrwwbgrgugugrguwrubggugwwuwrbrggwwww
gwgrwwwrbgrrbwgrbgrugbbggbbbgugbbwwwgbuggr
gwgrubrrugrwwgurbbububurrbbbwrgwwrguuugbuuwwbuwwbbbgbbwurgrb
gwgrbuugugbgwurgwrruwbuguububuwgbbbwrbgrwbbrurwbbrbuwrr
gwggwuuuuurrrurwwurugwwwgggwurbgbbrwrgwgwug
rwbguuwgggbwwuwwwugurwrwuwbrwwgbgwwwbbuubrw
gwgurggurbugrwrwguwugwbwguubggruurwurwurubuurwgwbwuwg
grwgwrbwbgwrbrgwuururwurbbubrubrwwwgbrbrbbw
gwgrugurwguwwrgurwugwurbruuwbuuuwurbrgwwuuwgbg
wrwgwgrwwwwrrggugbbwwbgwwbgbbwgrbgugurbwguw
bbubrbrrubwggurruwrggwuurgwgwbwbrbububwbwurrrwbggbur
wwrwwbrgrrrgburwuwwgurubrwguwbgurbwrrwbwwgwwrbbwrrwwww
uruuurgbgbuwuwgwgbubbrgrwggbbgrbwuwgubrgurgrgburrwrgb
gwggrgwbgrrugugwugwgwguuwwuuwwgrgwbuurrgw
gwgubgwguwwbugbgwgrurrgurgwwggbggbugrrgwrbwwwwguugbgubrbwgb
wggbrubwuurbrggwgwwuurggwbubggrbggrgwwwuug
gwggbburgbbrwwbrrbuuuwwbrugbbwwrrwrguwwubuwwuurruru
uwgggwgrwruwwgburrwwbggwgbrurrrgubrrwrrwbbuuuwuwugrgg
gwrggwwrrbwrrubbwrurbgwrwuwuwggrbbbbgrbubg
gwburgrgugwwuurrwuuwuuuuburbbwgrruuubruururgwruubrubrugu
wbwwbubwburwgbbgwgbubuubrguwgbwwggbuwbguurgurbbwuwbugrrb
gwgurwrurggwwguburuwgbgrrrgruwwggrruruwruuwrggrrbu
gugwgrggburwgbwbwbgbuuwwbbwrwgwbwurwgrbbbu
gwgrrwgugbubrrrgrwwbrrggwrrrgurgwgrbbuggwru
wbruwbbgbuwbrwwwbrrrwuwugwbggrrbuuwgubwrrwuwurggruurrgw
gwguubbuuubgrwbuubwbuwgwwgwgubrrrbburggubwwugr
ggrrguggbbbrggbgwwuubbwrrrrrbwruguuggrbbggrbgwr
rgbubuguwggwrrwgwugrgggwuwwbwbwubbruubrgru
ggggrrwgubrbrwuggbrubbrwwuugbuwrwrurgwgwwbbwugbrurbg
ggbggbrwrurrurubrruuggurwwguwrguurrbgrrgru
gwgrwuugbgwrbwbgrwwrgurrruwgbbrggwrrrruruug
gwggrgbbwwrwrrggbbbgggburuubbbbguruurbgwbrbrwgg
gwguuwuubuurwuububbgubwugurrgurrwurwubgbrugbwbwrbuwwrwrurg
wguwwwrrrwguwrrbuguuubguurggrwbbbwrugggruuggrbu
rrwgwgbugbwbrbbgrbbbbrgbbuuugruwbgbwwbrwwrw
rwggbggwbrruwruubwrgrwrwuggubuwwbbubrbwbrwbuuurgggggburb
gwggugbguwubgrwruwwuuuggbrbbubbububbwrbwbggguruwbru
uuuurbuurwbgwuuuuuurwuuugwugrgwwrrbrrwbrrgbgwbuwbggw
ugburrwuwbggrwuuruuwbrrrgbrubwguguwbugwbuwbbbgru

View file

@ -0,0 +1,48 @@
-- requires cabal install --lib megaparsec parser-combinators heap vector
module Main (main) where
import Control.Monad (void, when)
import Data.Functor
import qualified Data.List as L
import qualified Data.Map as M
import Data.Maybe
import Data.Void (Void)
import Text.Megaparsec
import Text.Megaparsec.Char
exampleExpectedOutput = 16
type Input = ([String], [String]) -- patterns, designs
type Parser = Parsec Void String
parseInput' :: Parser Input
parseInput' = (,) <$> some (some letterChar <* optional (string ", ")) <* eol <* eol
<*> some (some letterChar <* eol) <* eof
parseInput :: String -> IO Input
parseInput filename = do
input <- readFile filename
case runParser parseInput' filename input of
Left bundle -> error $ errorBundlePretty bundle
Right input' -> return input'
type Memo = M.Map String Int
compute :: Input -> Int
compute (stripes, designs) = snd $ L.foldl' compute' (M.empty, 0) designs
where
compute' :: (Memo, Int) -> String -> (Memo, Int)
compute' (memo, c) [] = (memo, c + 1)
compute' (memo, c) design = case M.lookup design memo of
Just c' -> (memo, c + c')
Nothing -> let (memo', c') = L.foldl' compute' (memo, 0) $ catMaybes $ map (\s -> L.stripPrefix s design) stripes
in (M.insert design c' memo', c + c')
main :: IO ()
main = do
example <- parseInput "example"
let exampleOutput = compute example
when (exampleOutput /= exampleExpectedOutput) (error $ "example failed: got " ++ show exampleOutput ++ " instead of " ++ show exampleExpectedOutput)
input <- parseInput "input"
print $ compute input