Skip to content

Commit

Permalink
feat(aoc2024): day5 (#53)
Browse files Browse the repository at this point in the history
* feat(aoc2024): day5 part1

* feat(aoc2024): day5 part2
  • Loading branch information
vipentti authored Dec 5, 2024
1 parent 015b3c8 commit 2d99878
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 3 deletions.
4 changes: 2 additions & 2 deletions aoc2024.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ param (
[switch] $All,
[switch] $NoBuild,
[ValidateSet(
"day1", "day2", "day3", "day4"
# , "day5", "day6", "day7", "day8", "day9"
"day1", "day2", "day3", "day4", "day5"
#, "day6", "day7", "day8", "day9"
# , "day10", "day11", "day12", "day13", "day14", "day15", "day16"
# , "day17", "day18", "day19", "day20", "day21", "day22"
# , "day23", "day24", "day25"
Expand Down
15 changes: 14 additions & 1 deletion visp/examples/aoc2024/common.visp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,15 @@
(fn EnumerateSpanSplitLines ([text: string])
(.EnumerateSplitSubstrings text [| #\lf #\cr |] commonSplitOptions))

(fn EnumareteSpanSplitChars ([ch: array<char>] [text: ReadOnlySpan<char>])
(fn EnumerateSpanSplitLinesWithoutEmpty ([text: string])
(.EnumerateSplitSubstrings text [| #\lf #\cr |] (bor StringSplitOptions.TrimEntries StringSplitOptions.RemoveEmptyEntries)))

(fn EnumerateSpanSplitChars ([ch: array<char>] [text: ReadOnlySpan<char>])
(.EnumerateSplitSubstrings text ch commonSplitOptions))

(fn EnumerateSpanSplitCharsWithoutEmpty ([ch: array<char>] [text: ReadOnlySpan<char>])
(.EnumerateSplitSubstrings text ch (bor StringSplitOptions.TrimEntries StringSplitOptions.RemoveEmptyEntries)))

(fn EnumerateSpaceSeparated ([text: ReadOnlySpan<char>])
(.EnumerateSplitSubstrings text [| #\space |] (bor StringSplitOptions.TrimEntries StringSplitOptions.RemoveEmptyEntries)))

Expand All @@ -32,6 +38,13 @@
(printfn "file: %s" filepath)
(System.IO.File.ReadAllText filepath))

(syntax-macro Macro_ReadWhile
([_ (id enu) body ...]
(while (.MoveNext enu)
(let id (+Current enu))
(begin body ...)
)))

(syntax-macro Macro_ReadWhileNotEmpty
([_ (id enu) body ...]
(while (.MoveNext enu)
Expand Down
161 changes: 161 additions & 0 deletions visp/examples/aoc2024/day5.visp
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@

;; Copyright 2024 Ville Penttinen
;; Distributed under the MIT License.
;; https://github.com/vipentti/visp-fs/blob/main/LICENSE.md
;;
;; for basic syntax highlighting
;; vim: set syntax=clojure:

;;
;; day5
;;
;; Include common utlities
(include "./common.visp")

;; Functions & types
(record Rule
[before: int32]
[after: int32])

(typedef PageUpdate list<int32>)
(typedef Rules Map<int32, Set<int32>>)

(record PageOrder
[rules : Rules]
[updates: list<PageUpdate>]
)

(fn ParseFile ([text: string])
(mut lines (EnumerateSpanSplitLinesWithoutEmpty text))

(mut reading_first_section true)

(let rules (new ResizeArray<_>))
(let updates (new ResizeArray<_>))

(mut new_rules Map.empty)

(Macro_ReadWhile [line lines]
(let index (.IndexOf line #\|))

(if (> index -1)
(begin
(mut parts (EnumerateSpanSplitCharsWithoutEmpty [|#\||] line))
(let f (span->int32 (Macro_ReadNext parts)))
(let s (span->int32 (Macro_ReadNext parts)))

(up! new_rules
(Map.change f #(
match %1
[(Some its) (Some (Set.add s its))]
[_ (Some (Set.singleton s))])
))

;; (printfn "%A %A" f s)
;; (.Add rules {| [before f] [after s] |})
)
(begin
(mut parts (EnumerateSpanSplitCharsWithoutEmpty [|#\,|] line))
(let arr (new ResizeArray<_>))
(Macro_ReadWhile [part parts]
(.Add arr (span->int32 part)))

;; (printfn "%A" arr)

(.Add updates (->> arr Seq.toList)))
)
;; Read contents here
())

{|
[rules new_rules]
[updates (->> updates Seq.toList)]
|}
)

(fn rec Rules_IsBeforeAllOf [(before: int32) (rest: PageUpdate) (rules: Rules)]
(match (Map.tryFind before rules)
[(Some afters)
;;
(->> rest
(List.forall #(begin
(or (Set.contains %1 afters)
(not (Rules_IsBeforeAllOf %1 (| before |) rules)))
)))
]
[None
;; (printfn "here? %A %A" before rest)
(->> rest
(List.forall #(
not (Rules_IsBeforeAllOf %1 (| before |) rules)
)))
]))

(fn UpdateInCorrectOrder [(upd: PageUpdate) (rules: Rules)]
(fn rec loop ([up: PageUpdate] [rules: Rules] (correct: bool))
(cond_
[(not correct) correct]
[_
(match up
[(cur :: rest) (loop rest rules (Rules_IsBeforeAllOf cur rest rules)) ]
[[] correct]
)]))
(loop upd rules true))

(fn Update_PickMiddle [(upd: PageUpdate)]
(let len (/ (List.length upd) 2))
;; (printfn "valid %A %A" upd len)
(List.item len upd))

(fn Update_Fix [(rules: Rules) (upd: PageUpdate)]
;; (printfn "valid %A %A" upd len)
(fn rec loop ([up: PageUpdate] [rules: Rules] [fixed: PageUpdate])
(match up
[[] (List.rev fixed)]
[(cur :: [])
(-> (cons cur fixed) (List.rev))
]
[(cur :: next :: rest)
(cond_
[(Rules_IsBeforeAllOf cur (cons next rest) rules)
(loop (cons next rest) rules (cons cur fixed))
]
[(Rules_IsBeforeAllOf next (cons cur rest) rules)
(loop (cons cur rest) rules (cons next fixed))
]
[_ (loop (List.concat (| rest (| cur next |)|)) rules fixed)]
)
]
)
)

(loop upd rules (||)))

(fn Part1 (parsedInput)
;; (printfn "%A" parsedInput)
;; Implement part1
(->> (+updates parsedInput)
(List.filter #(UpdateInCorrectOrder %1 (+rules parsedInput)))
(List.map Update_PickMiddle)
(List.sum)))

(fn Part2 (parsedInput)
;; Implement part2
(->> (+updates parsedInput)
(List.filter #(not (UpdateInCorrectOrder %1 (+rules parsedInput))))
(List.map (Update_Fix (+rules parsedInput)))
(List.map Update_PickMiddle)
(List.sum)))

;; Implementation

(let parsed (-> (ReadInput "day5") ParseFile))

;; Expected results
(let PART1_EXPECTED_RESULT (if IS_EXAMPLE 143 4637))
(let PART2_EXPECTED_RESULT (if IS_EXAMPLE 123 6370))

(WriteResult "part1" (-> parsed Part1) PART1_EXPECTED_RESULT)
(WriteResult "part2" (-> parsed Part2) PART2_EXPECTED_RESULT)

()
28 changes: 28 additions & 0 deletions visp/examples/aoc2024/inputs/day5_example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13

75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

0 comments on commit 2d99878

Please sign in to comment.