refactoring in playground, use zip file for web
This commit is contained in:
132
playground/samples/aoc2024/Day6.newt
Normal file
132
playground/samples/aoc2024/Day6.newt
Normal 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"
|
||||
Reference in New Issue
Block a user