refactoring in playground, use zip file for web

This commit is contained in:
2024-12-08 20:19:55 -08:00
parent 0f5a909cce
commit d6aaaaabf1
47 changed files with 1932 additions and 88 deletions

View File

@@ -0,0 +1,132 @@
module Day6
import Prelude
import Node
import Aoc
import SortedMap
Point : U
Point = Int × Int
instance Eq Point where
(a,b) == (c,d) = a == c && b == d
instance Ord Point where
(a,b) < (c,d) = a < c || a == c && b < d
Grid : U
Grid = SortedMap Point Char
loadData : String Grid
loadData text = go (unpack text) 0 0 EmptyMap
where
go : List Char Int Int SortedMap Point Char SortedMap Point Char
go Nil r c map = map
go ('\n' :: cs) r c map = go cs (r + 1) 0 map
go (x :: xs) r c map = go xs r (c + 1) $ updateMap (r,c) x map
data Dir : U where North East South West : Dir
instance Show Dir where
show North = "N"
show East = "E"
show South = "S"
show West = "W"
instance Ord Dir where
a < b = show a < show b
instance Eq (Point × Dir) where
(a,b) == (c,d) = a == c && show b == show d
instance Ord (Point × Dir) where
(a,b) < (c,d) =
if a < c then True
else if a /= c then False
else b < d
Done : U
Done = SortedMap (Point × Dir) Unit
turn : Dir Dir
turn North = East
turn East = South
turn South = West
turn West = North
instance Cast Dir Char where
cast North = '^'
cast East = '>'
cast South = 'v'
cast West = '<'
step : Dir Point Point
step North (r, c) = (r - 1, c)
step East (r, c) = (r, c + 1)
step South (r, c) = (r + 1, c)
step West (r, c) = (r, c - 1)
bad : Point Bool
bad (x,y) = x < 0 || y < 0
-- third is
walk : Dir Point Grid Grid
walk dir pos grid =
let grid = updateMap pos 'X' grid in
let pos' = step dir pos in
case lookupMap pos' grid of
Just (_, '#') => walk (turn dir) pos grid
Nothing => grid
_ => walk dir pos' grid
checkLoop : Grid Done Dir Point Bool
checkLoop grid done dir pos =
let (Nothing) = lookupMap (pos,dir) done | _ => True in
let done = updateMap (pos, dir) MkUnit done
pos' = step dir pos
in case lookupMap pos' grid of
Nothing => False
Just (_, '#') => checkLoop grid done (turn dir) pos
Just _ => checkLoop grid done dir pos'
part2 : Dir Point Grid Done List Point List Point
part2 dir pos grid done sol =
let done = updateMap (pos, dir) MkUnit done
grid = updateMap pos 'X' grid
turnDir = turn dir
turnPos = step turnDir pos
pos' = step dir pos in
case lookupMap pos' grid of
Nothing => sol
Just (_, '#') => part2 (turn dir) pos grid done sol
Just (_, 'X') => part2 dir pos' grid done sol
Just (_, '.') => if checkLoop (updateMap pos' '#' grid) done turnDir pos
then part2 dir pos' grid done (pos' :: sol)
else part2 dir pos' grid done sol
Just x => part2 (trace ("WAT " ++ debugStr x) dir) pos' grid done sol
lookupV : a. Char List (a × Char) Maybe a
lookupV _ Nil = Nothing
lookupV needle ((k,v) :: rest) =
if v == needle then Just k else lookupV needle rest
run : String -> IO Unit
run fn = do
putStrLn fn
text <- readFile fn
let grid = loadData text
let (Just pos) = lookupV '^' (toList grid) | _ => putStrLn "no guard"
let grid' = walk North pos grid
let xs = filter (\ x => 'X' == snd x) $ toList grid'
let part1 = length xs
putStrLn $ "part1 " ++ show part1
let cands = part2 North pos grid EmptyMap Nil
-- debugLog $ length cands -- turns out nub isn't needed for these cases, but we'll leave it in
putStrLn $ "part2 " ++ show (length $ ordNub cands)
printLn $ length $ toList grid
main : IO Unit
main = do
run "aoc2024/day6/eg.txt"
run "aoc2024/day6/input.txt"