AoC 2025 - Day 1

This commit is contained in:
2025-12-01 08:46:49 -08:00
parent aa0a12f402
commit 940d1ae8b1
8 changed files with 128 additions and 0 deletions

36
aoc2025/Aoc.newt Normal file
View File

@@ -0,0 +1,36 @@
module Aoc
import Prelude
-- `by` is the first argument for use in `map`
nums' : String String List Int
nums' by s = map stringToInt $ filter (_/=_ "") $ split (trim s) by
nums : String List Int
nums s = map stringToInt $ filter (_/=_ "") $ split (trim s) " "
indexOf? : a. {{Eq a}} a List a Maybe Nat
indexOf? {a} z xs = go Z z xs
where
go : Nat a List a Maybe Nat
go ix z Nil = Nothing
go ix z (x :: xs) =
if z == x then Just ix else go (S ix) z xs
-- TODO move to Aoc library
Point : U
Point = Int × Int
instance Add Point where
(a,b) + (c,d) = (a + c, b + d)
instance Sub Point where
(a,b) - (c,d) = (a - c, b - d)
-- instance Ord Point where
-- (a,b) < (c,d) = a < c || a == c && b < d
-- instance Eq Point where
-- (a,b) == (c,d) = a == c && b == d

1
aoc2025/Data Symbolic link
View File

@@ -0,0 +1 @@
../src/Data

54
aoc2025/Day1.newt Normal file
View File

@@ -0,0 +1,54 @@
module Day1
import Prelude
import Node
parseLine : String Maybe Int
parseLine s = case unpack s of
('L' :: rest) => Just $ 0 - stringToInt (pack rest)
('R' :: rest) => Just $ stringToInt (pack rest)
_ => Nothing
parse : String List Int
parse text = mapMaybe parseLine $ split (trim text) "\n"
part1 : List Int Int
part1 xs = go 0 50 xs
where
go : Int Int List Int Int
go acc pos Nil = acc
go acc pos (x :: xs) =
let pos = mod (x + pos) 100
acc = if pos == 0 then acc + 1 else acc
in go acc pos xs
-- This is uglier than I'd like
part2 : List Int Nat
part2 xs = go Z 50 xs
where
go : Nat Int List Int Nat
go acc pos Nil = acc
go acc pos (0 :: xs) = go acc pos xs
go acc pos (x :: xs) =
if x == 0 then go acc pos xs
else if x <= -100 then go (S acc) pos (x + 100 :: xs)
else if 100 <= x then go (S acc) pos (x - 100 :: xs)
else if x + pos < 0 then go (if pos == 0 then acc else S acc) (x + pos + 100) xs
else if x + pos == 0 then go (S acc) (x + pos) xs
else if 100 <= x + pos then go (S acc) (x + pos - 100) xs
else go acc (x + pos) xs
run : String IO Unit
run fn = do
printLn fn
text <- readFile fn
let xs = parse text
let p1 = part1 xs
printLn "part1 \{show p1}"
let p2 = part2 xs
printLn "part2 \{show p2}"
main : IO Unit
main = do
run "aoc2025/day1/eg.txt"
run "aoc2025/day1/input.txt"

12
aoc2025/DayXX.newt Normal file
View File

@@ -0,0 +1,12 @@
module DayXX
import Prelude
import Node
import Aoc
run : String IO Unit
main : IO Unit
main = do
run "aoc2025/dayXX/eg.txt"
run "aoc2025/dayXX/input.txt"

7
aoc2025/Node.newt Normal file
View File

@@ -0,0 +1,7 @@
module Node
import Prelude
pfunc fs : JSObject := `require('fs')`
pfunc getArgs : List String := `arrayToList(String, process.argv)`
pfunc readFile uses (MkIORes) : (fn : String) -> IO String := `(fn) => (w) => Prelude_MkIORes(require('fs').readFileSync(fn, 'utf8'), w)`

1
aoc2025/Prelude.newt Symbolic link
View File

@@ -0,0 +1 @@
../src/Prelude.newt

10
aoc2025/day1/eg.txt Normal file
View File

@@ -0,0 +1,10 @@
L68
L30
R48
L5
R60
L55
L1
L99
R14
L82

7
aoc2025/mkday Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/zsh -e
day=$1
if [ ! -d day${day} -a ! -z "$1" ]; then
echo Make Day ${day}
mkdir day${day}
sed "s/XX/$day/g" DayXX.newt > Day$day.newt
fi