From 940d1ae8b117b3cbeec3ed7ec640a843034124cb Mon Sep 17 00:00:00 2001 From: Steve Dunham Date: Mon, 1 Dec 2025 08:46:49 -0800 Subject: [PATCH] AoC 2025 - Day 1 --- aoc2025/Aoc.newt | 36 +++++++++++++++++++++++++++++ aoc2025/Data | 1 + aoc2025/Day1.newt | 54 ++++++++++++++++++++++++++++++++++++++++++++ aoc2025/DayXX.newt | 12 ++++++++++ aoc2025/Node.newt | 7 ++++++ aoc2025/Prelude.newt | 1 + aoc2025/day1/eg.txt | 10 ++++++++ aoc2025/mkday | 7 ++++++ 8 files changed, 128 insertions(+) create mode 100644 aoc2025/Aoc.newt create mode 120000 aoc2025/Data create mode 100644 aoc2025/Day1.newt create mode 100644 aoc2025/DayXX.newt create mode 100644 aoc2025/Node.newt create mode 120000 aoc2025/Prelude.newt create mode 100644 aoc2025/day1/eg.txt create mode 100755 aoc2025/mkday diff --git a/aoc2025/Aoc.newt b/aoc2025/Aoc.newt new file mode 100644 index 0000000..691a15c --- /dev/null +++ b/aoc2025/Aoc.newt @@ -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 diff --git a/aoc2025/Data b/aoc2025/Data new file mode 120000 index 0000000..e57d8b9 --- /dev/null +++ b/aoc2025/Data @@ -0,0 +1 @@ +../src/Data \ No newline at end of file diff --git a/aoc2025/Day1.newt b/aoc2025/Day1.newt new file mode 100644 index 0000000..1da1edf --- /dev/null +++ b/aoc2025/Day1.newt @@ -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" diff --git a/aoc2025/DayXX.newt b/aoc2025/DayXX.newt new file mode 100644 index 0000000..d96e409 --- /dev/null +++ b/aoc2025/DayXX.newt @@ -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" diff --git a/aoc2025/Node.newt b/aoc2025/Node.newt new file mode 100644 index 0000000..98bcdb8 --- /dev/null +++ b/aoc2025/Node.newt @@ -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)` diff --git a/aoc2025/Prelude.newt b/aoc2025/Prelude.newt new file mode 120000 index 0000000..bb92875 --- /dev/null +++ b/aoc2025/Prelude.newt @@ -0,0 +1 @@ +../src/Prelude.newt \ No newline at end of file diff --git a/aoc2025/day1/eg.txt b/aoc2025/day1/eg.txt new file mode 100644 index 0000000..53287c7 --- /dev/null +++ b/aoc2025/day1/eg.txt @@ -0,0 +1,10 @@ +L68 +L30 +R48 +L5 +R60 +L55 +L1 +L99 +R14 +L82 diff --git a/aoc2025/mkday b/aoc2025/mkday new file mode 100755 index 0000000..66bdc73 --- /dev/null +++ b/aoc2025/mkday @@ -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