commit 262c7b7e1e632a6fdc9d5e297936abbacbbbe243 Author: Matthew Gretton-Dann Date: Sun Dec 1 09:10:51 2024 +0000 2024 day 1 solutions diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69fa449 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +_build/ diff --git a/bin/day2401.ml b/bin/day2401.ml new file mode 100644 index 0000000..3e1fe43 --- /dev/null +++ b/bin/day2401.ml @@ -0,0 +1,71 @@ +(** [nums_from_string s] takes a string of space separated integers and gives + back a list of the integers. *) +let nums_from_string s = + List.map int_of_string (Str.split (Str.regexp " +") s);; + +(** [pair_nums_from_string s] takes a string of two numbers separated by + whitespace and returns the pair of the numbers *) +let pair_nums_from_string s = + match (nums_from_string s) with + | h :: h' :: [] -> (h, h') + | _ -> raise (Invalid_argument "pair_nums_from_string") + +(** [unzip lst] takes a list of pairs and returns a pair of lists. *) +let unzip lst = + let rec impl acc acc' = function + | (h, h') :: t -> impl (h :: acc) (h' :: acc') t + | _ -> (acc, acc') + in + impl [] [] lst + +(** [pairs_from_channel ch] returns the list of pairs given on the channel + *) +let pairs_from_channel ch = + let rec impl acc = + try (impl ((input_line ch) :: acc)) with + | End_of_file -> acc + in + impl [] |> List.map pair_nums_from_string + +(** [pairs_from_file fname] returns the list of pairs given in the file *) +let pairs_from_file fname = + try + let ch = open_in fname in + pairs_from_channel ch + with + | _ -> failwith "pairs_from_file" + +(** [distance a b] returns the absolute difference between [a] and [b]. *) +let distance a b = + abs (a - b) + +let day2401a fname = + let (a, b) = unzip (pairs_from_file fname) in + let d = List.map2 distance (List.sort Int.compare a) (List.sort Int.compare b) in + List.fold_left ( + ) 0 d + +(** [count lst n] counts the number of times [n] appears as an element in [lst]. + *) +let count lst n = + List.fold_left (fun acc x -> if x = n then (acc + 1) else acc) 0 lst + +let day2401b fname = + let (a, b) = unzip (pairs_from_file fname) in + List.map (count b) a |> + List.map2 ( * ) a |> + List.fold_left ( + ) 0 + +let _ = try + begin + match Sys.argv with + | [|_; fname|] -> + Printf.printf "Part 1 = %d\n" (day2401a fname); + Printf.printf "Part 2 = %d\n" (day2401b fname); + | _ -> + Printf.printf "Usage: day2401 \n"; + exit 1 + end +with +| e -> + Printf.printf "An error occured: %s\n" (Printexc.to_string e); + exit 1 \ No newline at end of file diff --git a/bin/dune b/bin/dune new file mode 100644 index 0000000..f5aa6c5 --- /dev/null +++ b/bin/dune @@ -0,0 +1,4 @@ +(executables + (public_names day2401) + (names day2401) + (libraries str)) diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..eca6dbf --- /dev/null +++ b/dune-project @@ -0,0 +1,25 @@ +(lang dune 3.16) + +(name aoc) + +(source + (github matt-gretton-dann/ocaml-aoc)) + +(authors "Matthew Gretton-Dann") + +(maintainers "Matthew Gretton-Dann") + +(license LICENSE) + +(documentation https://url/to/documentation) + +(package + (name aoc) + (synopsis "Implementation of AoC competitions in OCaml") + (description + "Implementation of solutions to various Advent of Code exercises written in OCaml") + (depends ocaml dune) + (tags + (topics "to describe" your project))) + +; See the complete stanza docs at https://dune.readthedocs.io/en/stable/reference/dune-project/index.html