Zulip Chat Archive
Stream: general
Topic: Advent of Code 2024 - Day 1
James Sully (Dec 03 2024 at 11:46):
Here's my solution. Feedback appreciated, and please post your own solution!
import Batteries.Data.HashMap
def String.lines (s : String) : List String := s.split (· == '\n')
structure Input where
l1 : List Nat
l2 : List Nat
def parseLine (s : String) : Option (Nat × Nat) := do
let ns : List Nat ← s.splitOn " " |>.mapM (·.toNat?)
match ns with
| [n1, n2] => .some (n1, n2)
| _ => .none
def parseInput (input : String) : Option Input := do
let pairs ← input.lines.mapM parseLine
let (l1, l2) := pairs.unzip
.some ⟨l1, l2⟩
def part1 (input : Input) : Nat :=
let (sortedl1, sortedl2) := (input.l1.mergeSort, input.l2.mergeSort)
let differences := List.zipWith Int.subNatNat sortedl1 sortedl2
|>.map Int.natAbs
differences.sum
-- definitely missing haskell's Map.alter or rust's entry api
open Batteries (HashMap)
def counts (ns : List Nat) : HashMap Nat Nat :=
ns.foldl (init := ∅) λ map n ↦ match map.find? n with
| .some count => map.insert n (count + 1)
| .none => map.insert n 1
def part2 (input : Input) : Nat :=
let l2_counts := counts input.l2
input.l1.map (λ n ↦ n * l2_counts.findD n 0) |>.sum
def Day01.main : IO Unit := do
let input ← IO.FS.readFile "input.txt"
let .some parsed := parseInput input | do
IO.println "error parsing input"
let result1 := part1 parsed
let result2 := part2 parsed
IO.println s!"Part 1: {result1}"
IO.println s!"Part 2: {result2}"
Kim Morrison (Dec 03 2024 at 12:10):
docs#Std.HashMap.alter and docs#Std.HashMap.modify
Kim Morrison (Dec 03 2024 at 12:11):
(more generally, I'd advise using Std.HashMap
instead of Batteries.HashMap
now.)
James Sully (Dec 03 2024 at 12:12):
Nice, thanks. I thought Batteries was a renaming of Std, is this something different?
Kim Morrison (Dec 03 2024 at 12:13):
Std was renamed to Batteries to make room for the new Std, which is packaged as part of the language distribution.
James Sully (Dec 03 2024 at 12:13):
Gotcha. Awesome
James Sully (Dec 03 2024 at 12:30):
slightly nicer counts
:
open Std (HashMap)
def counts (ns : List Nat) : HashMap Nat Nat :=
ns.foldl (init := ∅) λ map n ↦ map.alter n λ
| .none => .some 1
| .some count => .some <| count + 1
Jared Corduan (Dec 03 2024 at 19:01):
does anything have to be added to the lake config files in order to use Std
? I get the error:
invalid field 'mergeSort', the environment does not contain 'List.mergeSort'
when I do this:
import Std
#eval ([] : List Nat).mergeSort
(I'm using lean4:stable
)
Edward van de Meent (Dec 03 2024 at 19:05):
what does #eval Lean.versionString
say?
Edward van de Meent (Dec 03 2024 at 19:06):
btw, afaict List.mergeSort
doesn't even live in Std
, it's in Init
(and therefore shouldn't need any imports, i think)
Jared Corduan (Dec 03 2024 at 19:14):
4.11.0
Jared Corduan (Dec 03 2024 at 19:17):
oh, maybe I'm behind, I'll do an update and see if being on 4.14.0
helps. thanks!
Jared Corduan (Dec 03 2024 at 19:20):
that was it!
JJ (Jan 01 2025 at 22:55):
decided to delay advent of code by a month this year to focus on finals... i'm going to try to do every day in lean this january! here's my day 1 for those interested, stylistic feedback much appreciated
def solution (input : String): String :=
let input := input.stripSuffix "\n"|>.splitOn "\n"
let l1 := input.map <| fun x => x.splitOn " " |>.get! 0 |>.toInt!
let l2 := input.map <| fun x => x.splitOn " " |>.get! 1 |>.toInt!
let p1 :=
List.foldl (· + ·) 0 <|
List.zipWith (fun a b => (a - b).natAbs) l1.mergeSort l2.mergeSort
let p2 :=
List.foldl (· + ·) 0 <|
List.map (fun a => a * List.count a l2) l1
s!"{p1}, {p2}"
JJ (Jan 01 2025 at 22:58):
today taught me about ·
simple lambda notation and a good number of list helpers. something i don't know yet is how to get!
the last element of a list, and generally how to use the module system... would like to be able to run lake exe aoc Day⟨num⟩
and run different modules in my Solutions/
folder while keeping initial input parsing in Main.lean
, but i haven't yet figured out how to set up that structure yet. i think i'm going to try and scoure other people's solutions for interesting syntax sugar after solving each day...
JJ (Jan 01 2025 at 23:01):
also important note: (· + ·)
looks like a little happy face
Last updated: May 02 2025 at 03:31 UTC