This commit is contained in:
ryan 2023-09-21 18:17:39 -07:00
commit 2eae917f47
13 changed files with 4955 additions and 0 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
eval $(opam config env)

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.DS_Store
_build/

2
.ocamlformat Normal file
View File

@ -0,0 +1,2 @@
profile = janestreet
version = 0.26.0

31
aoc.opam Normal file
View File

@ -0,0 +1,31 @@
# 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"}
"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"

5
bin/dune Normal file
View File

@ -0,0 +1,5 @@
(executable
(public_name aoc)
(name main)
(libraries aoc stdio re)
(preprocess (pps ppx_regexp)))

2253
bin/input1.txt Normal file

File diff suppressed because it is too large Load Diff

2500
bin/input2.txt Normal file

File diff suppressed because it is too large Load Diff

131
bin/main.ml Normal file
View File

@ -0,0 +1,131 @@
let lines_of_file filename = Stdio.In_channel.(with_file filename ~f:input_lines)
let rec print_int_list = function
| [] -> ()
| e :: l ->
print_int e;
print_string " ";
print_int_list l
;;
let day1_part1 lines =
let rec most_calories most current lines =
match lines with
| [] -> most
| "" :: lines -> most_calories (max most current) 0 lines
| line :: lines ->
let calories = int_of_string line in
most_calories most (current + calories) lines
in
most_calories 0 0 lines
;;
let day1_part2 lines =
let accum_calories elves calories =
match elves, calories with
| elves, "" -> 0 :: elves
| elf :: elves, calories -> (elf + int_of_string calories) :: elves
| elves, _ -> elves
in
let calories_per_elf = List.fold_left accum_calories [ 0 ] lines in
match List.sort (fun x y -> y - x) calories_per_elf with
| x1 :: x2 :: x3 :: _ -> x1 + x2 + x3
| _ -> failwith "wtf"
;;
type move =
| Rock
| Paper
| Scissors
type outcome =
| Win
| Lose
| Draw
let parse_move = function
| "A" | "X" -> Rock
| "B" | "Y" -> Paper
| "C" | "Z" -> Scissors
| char -> failwith @@ Printf.sprintf "Char %s does not correspond to a move" char
;;
let parse_outcome = function
| "X" -> Lose
| "Y" -> Draw
| "Z" -> Win
| char -> failwith @@ Printf.sprintf "Char %s does not correspond to an outcome" char
;;
let participation_score = function
| Rock -> 1
| Paper -> 2
| Scissors -> 3
;;
let match_score = function
| Win -> 6
| Draw -> 3
| Lose -> 0
;;
let beats = function
| Rock -> Paper
| Paper -> Scissors
| Scissors -> Rock
;;
let loses_to = function
| Rock -> Scissors
| Paper -> Rock
| Scissors -> Paper
;;
let match_outcome = function
| them, me when me = beats them -> Win
| them, me when me = them -> Draw
| _, _ -> Lose
;;
let day2_part1 lines =
let parse_line line =
match Re.Pcre.(split ~rex:(regexp {|\s+|}) line) with
| them :: me :: _ -> parse_move them, parse_move me
| _ -> failwith @@ Printf.sprintf "line `%s` contains more than two moves" line
in
List.fold_left
(fun total_score line ->
let them, me = parse_line line in
total_score + participation_score me + match_score (match_outcome (them, me)))
0
lines
;;
let day2_part2 lines =
let parse_line =
function%pcre
| {|(?<them>\w)\s*(?<outcome>\w)|} -> parse_move them, parse_outcome outcome
| line -> failwith @@ Printf.sprintf "line `%s` doesn't match re" line
in
List.fold_left
(fun total_score line ->
let them, outcome = parse_line line in
let me =
match outcome with
| Win -> beats them
| Draw -> them
| Lose -> loses_to them
in
total_score + participation_score me + match_score outcome)
0
lines
;;
let () =
(* print_int @@ day1_part1 @@ lines_of_file "input1.txt"; *)
(* print_int @@ day1_part2 @@ lines_of_file "input1.txt"; *)
print_int @@ day2_part1 @@ lines_of_file "input2.txt";
print_newline ();
print_int @@ day2_part2 @@ lines_of_file "input2.txt";
print_newline ()
;;

26
dune-project Normal file
View File

@ -0,0 +1,26 @@
(lang dune 3.10)
(name aoc)
(generate_opam_files true)
(source
(github username/reponame))
(authors "Author Name")
(maintainers "Maintainer Name")
(license LICENSE)
(documentation https://url/to/documentation)
(package
(name aoc)
(synopsis "A short synopsis")
(description "A longer description")
(depends ocaml dune)
(tags
(topics "to describe" your project)))
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project

2
lib/dune Normal file
View File

@ -0,0 +1,2 @@
(library
(name aoc))

0
lib/test.ml Normal file
View File

0
test/aoc.ml Normal file
View File

2
test/dune Normal file
View File

@ -0,0 +1,2 @@
(test
(name aoc))