Mercurial > lbo > hg > aoc22
changeset 35:e66716229c5e
Remove superfluous subdirectory
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sat, 02 Dec 2023 14:02:37 +0100 |
parents | 6f2c271c91da |
children | 326aec2bdce6 |
files | 2023/aoc23/.ocamlformat 2023/aoc23/aoc23.opam 2023/aoc23/bin/day01.ml 2023/aoc23/bin/dune 2023/aoc23/bin/main.ml 2023/aoc23/day01.ml 2023/aoc23/dune 2023/aoc23/dune-project 2023/aoc23/lib/dune 2023/aoc23/test/aoc23.ml 2023/aoc23/test/dune 2023/day01.ml |
diffstat | 10 files changed, 4 insertions(+), 188 deletions(-) [+] |
line wrap: on
line diff
--- a/2023/aoc23/aoc23.opam Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -# This file is generated by dune, edit dune-project instead -opam-version: "2.0" -synopsis: "A short synopsis" -description: "A longer description" -maintainer: ["Maintainer Name"] -authors: ["Author Name"] -license: "LICENSE" -tags: ["topics" "to describe" "your" "project"] -homepage: "https://github.com/username/reponame" -doc: "https://url/to/documentation" -bug-reports: "https://github.com/username/reponame/issues" -depends: [ - "ocaml" - "dune" {>= "3.10"} - "base" - "core" - "stdio" - "odoc" {with-doc} -] -build: [ - ["dune" "subst"] {dev} - [ - "dune" - "build" - "-p" - name - "-j" - jobs - "@install" - "@runtest" {with-test} - "@doc" {with-doc} - ] -] -dev-repo: "git+https://github.com/username/reponame.git"
--- a/2023/aoc23/bin/day01.ml Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -
--- a/2023/aoc23/bin/dune Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -(executable - (public_name aoc23) - (name main) - (libraries aoc23)) -
--- a/2023/aoc23/bin/main.ml Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -let () = print_endline "Hello, World!"
--- a/2023/aoc23/day01.ml Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -open Stdio -open Base - -let input () = In_channel.stdin - -(* Part 1 *) -module Part1 = struct - let calibration_value_of_string s = - let digits = String.filter s ~f:Char.is_digit in - let first, last = (String.prefix digits 1, String.suffix digits 1) in - Int.of_string (String.concat [ first; last ]) - - let process ch = - let f lines line = calibration_value_of_string line :: lines in - List.rev @@ In_channel.fold_lines ch ~init:[] ~f - - let _part1 () = - let r = process (input ()) in - Out_channel.printf "%d\n" (List.fold ~init:0 ~f:( + ) r) -end - -(* Part 2 *) - -module Part2 = struct - let folder ix acc x : (int * int) option = - match (ix, acc, x) with - | ix, None, d -> - let i = Int.of_string_opt (String.of_char d) in - Option.map i ~f:(fun i -> (ix, i)) - | _, Some d, _ -> Some d - - (* Return the (index, value) of the first digit in the string *) - let find_first_digit s = String.foldi ~init:None ~f:folder s - - (* Return the (index, value) of the last digit in the string *) - let find_last_digit s : (int * int) option = - let%map.Option ix, v = find_first_digit (String.rev s) in - (String.length s - ix - 1, v) - - let digits = - [ - (1, "one"); - (2, "two"); - (3, "three"); - (4, "four"); - (5, "five"); - (6, "six"); - (7, "seven"); - (8, "eight"); - (9, "nine"); - ] - - (* generate a counting sequence *) - let count_seq (from : int) (upto : int) : int Sequence.t = - let f c = - if Int.equal c upto then None - else Some (c, if upto > from then c + 1 else c - 1) - in - Sequence.unfold ~init:from ~f - - (* try to find number string `number` with value `value` in string `s`, from the beginning if `fwd`. *) - let find_number ~fwd s value number : int option * int = - let ixs = - if fwd then count_seq 0 (String.length s) - else count_seq (String.length s - 1) 0 - in - let check pos = String.is_substring_at s ~pos ~substring:number in - (Sequence.find ixs ~f:check, value) - - (* find any number word in the string, from the beginning if `fwd` or from the end otherwise. *) - let find_any_number ~fwd s : (int * int) option = - let f (value, number) = find_number ~fwd s value number in - let found = List.map digits ~f in - let compare (ix1, _) (ix2, _) = - match (ix1, ix2) with - | Some a, Some b -> Int.compare a b * if fwd then 1 else -1 - | Some _, None -> -1 - | None, Some _ -> 1 - | None, None -> 0 - in - (* sort by index *) - let sorted = List.sort found ~compare in - match List.hd_exn sorted with Some ix, d -> Some (ix, d) | None, _ -> None - - (* Process line `line`, and return numeric result. *) - let handle line : int = - let maybe_first_dig = find_first_digit line in - let maybe_first_wrd = find_any_number ~fwd:true line in - let maybe_last_dig = find_last_digit line in - let maybe_last_wrd = find_any_number ~fwd:false line in - let match_num ~fwd (dig : (int * int) option) (wrd : (int * int) option) = - match (dig, wrd) with - | Some (ix1, d1), Some (ix2, d2) -> - if (fwd && ix1 < ix2) || ((not fwd) && ix1 > ix2) then d1 else d2 - | Some (_, d), None | None, Some (_, d) -> d - | None, None -> assert false - in - let first_dig = match_num ~fwd:true maybe_first_dig maybe_first_wrd in - let last_dig = match_num ~fwd:false maybe_last_dig maybe_last_wrd in - (10 * first_dig) + last_dig - - let process ch = - let f lines line = handle line :: lines in - List.rev @@ In_channel.fold_lines ch ~init:[] ~f - - let part2 () = - let r = process In_channel.stdin in - Out_channel.printf "%d\n" (List.fold ~init:0 ~f:( + ) r) -end - -let () = Part2.part2 ()
--- a/2023/aoc23/dune Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -(executable - (name day01) - (libraries base core) - (preprocess (pps ppx_let)) - )
--- a/2023/aoc23/dune-project Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -(lang dune 3.10) - -(name aoc23) - -(generate_opam_files true) - -(source - (github username/reponame)) - -(authors "Author Name") - -(maintainers "Maintainer Name") - -(license LICENSE) - -(documentation https://url/to/documentation) - -(package - (name aoc23) - (synopsis "A short synopsis") - (description "A longer description") - (depends ocaml dune base core stdio) - (tags - (topics "to describe" your project))) - -; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project
--- a/2023/aoc23/lib/dune Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -(library - (name aoc23))
--- a/2023/aoc23/test/dune Sat Dec 02 13:53:44 2023 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -(test - (name aoc23))
--- a/2023/day01.ml Sat Dec 02 13:53:44 2023 +0100 +++ b/2023/day01.ml Sat Dec 02 14:02:37 2023 +0100 @@ -58,6 +58,7 @@ in Sequence.unfold ~init:from ~f + (* try to find number string `number` with value `value` in string `s`, from the beginning if `fwd`. *) let find_number ~fwd s value number : int option * int = let ixs = if fwd then count_seq 0 (String.length s) @@ -66,6 +67,7 @@ let check pos = String.is_substring_at s ~pos ~substring:number in (Sequence.find ixs ~f:check, value) + (* find any number word in the string, from the beginning if `fwd` or from the end otherwise. *) let find_any_number ~fwd s : (int * int) option = let f (value, number) = find_number ~fwd s value number in let found = List.map digits ~f in @@ -80,7 +82,8 @@ let sorted = List.sort found ~compare in match List.hd_exn sorted with Some ix, d -> Some (ix, d) | None, _ -> None - let handle line = + (* Process line `line`, and return numeric result. *) + let handle line : int = let maybe_first_dig = find_first_digit line in let maybe_first_wrd = find_any_number ~fwd:true line in let maybe_last_dig = find_last_digit line in