Skip to content

Commit

Permalink
More stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
drewolson committed Oct 26, 2023
1 parent f9c8941 commit b9efec0
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 121 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ opam install . --deps-only --with-test
## Run

```
dune exec aoc -- --help
dune exec aoc -- --day 1 --part 1
dune exec aoc -- -d1 -p1
dune exec aoc -- -help
dune exec aoc -- -day 1 -part 1
dune exec aoc -- -d 1 -p 1
```

## Build
Expand Down
2 changes: 1 addition & 1 deletion aoc.opam
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ depends: [
"dune" {>= "3.10"}
"angstrom"
"core"
"cmdliner"
"core_unix"
"ppx_jane"
"re"
"odoc" {with-doc}
Expand Down
2 changes: 1 addition & 1 deletion aoc.opam.locked
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ homepage: "https://github.com/drewolson/aoc-ocaml"
bug-reports: "https://github.com/drewolson/aoc-ocaml/issues"
depends: [
"angstrom" {= "0.15.0"}
"cmdliner" {= "1.2.0"}
"core" {= "v0.16.2"}
"core_unix" {= "v0.16.0"}
"dune" {= "3.11.1"}
"ocaml" {= "5.1.0"}
"ppx_jane" {= "v0.16.0"}
Expand Down
5 changes: 4 additions & 1 deletion bin/dune
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
(name main)
(libraries
core
cmdliner
core_unix.command_unix
runner)
(preprocess
(pps
ppx_jane))
(flags
-open Core))
59 changes: 31 additions & 28 deletions bin/main.ml
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
module Arg = Cmdliner.Arg
module Cmd = Cmdliner.Cmd
module Term = Cmdliner.Term

let ( & ), ( $ ) = Arg.(( & )), Cmdliner.Term.(( $ ))

let year =
let doc = "Year to run" in
Arg.value & Arg.opt Arg.int 2022 & Arg.info [ "y"; "year" ] ~docv:"YEAR" ~doc
let year_arg =
Command.Arg_type.create (fun year_str ->
match Int.of_string_opt year_str with
| Some year when year = 2022 || year = 2023 -> year
| _ -> failwith "Year must be [2022, 2023]")
;;

let day =
let doc = "Day to run (1 - 25)" in
let days = List.map ~f:(fun d -> Int.to_string d, d) (List.init 25 ~f:Int.succ) in
Arg.required
& Arg.opt (Arg.some & Arg.enum days) None
& Arg.info [ "d"; "day" ] ~docv:"DAY" ~doc
let day_arg =
Command.Arg_type.create (fun day_str ->
match Int.of_string_opt day_str with
| Some day when 1 <= day && day <= 25 -> day
| _ -> failwith "Day must be between 1 - 25")
;;

let part =
let doc = "Part to run (1 or 2)" in
let parts = [ "1", 1; "2", 2 ] in
Arg.required
& Arg.opt (Arg.some & Arg.enum parts) None
& Arg.info [ "p"; "part" ] ~docv:"PART" ~doc
let part_arg =
Command.Arg_type.create (fun part_str ->
match Int.of_string_opt part_str with
| Some part when part = 1 || part = 2 -> part
| _ -> failwith "Part must be 1 or 2")
;;

let aoc_t = Term.const Runner.run $ year $ day $ part

let cmd =
let doc = "Run aoc solution" in
let info = Cmd.info "aoc" ~version:"1.0.0" ~doc in
Cmd.v info aoc_t
let command_param =
let open Command.Let_syntax in
let module P = Command.Param in
let%map year =
P.flag
"year"
(P.optional_with_default 2022 year_arg)
~doc:"int year to run (default: 2022)"
~aliases:[ "y" ]
and day =
P.flag "day" (P.required day_arg) ~aliases:[ "d" ] ~doc:"int day to run (1 - 25)"
and part =
P.flag "part" (P.required part_arg) ~aliases:[ "p" ] ~doc:"int part to run (1 or 2)"
in
fun _ -> Runner.run year day part
;;

let () = Stdlib.exit (Cmd.eval cmd)
let () = Command_unix.run (Command.basic command_param ~summary:"Run aoc solution")
2 changes: 1 addition & 1 deletion dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@

angstrom
core
cmdliner
core_unix
ppx_jane
re))
3 changes: 3 additions & 0 deletions lib/runner/dune
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
core
year2022
year2023)
(preprocess
(pps
ppx_jane))
(flags
-open Core))
3 changes: 0 additions & 3 deletions lib/util/list.mli

This file was deleted.

27 changes: 17 additions & 10 deletions lib/util/parser.ml
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
module A = Angstrom
include Angstrom

module Syntax = struct
module Let_syntax = A.Let_syntax.Let_syntax
module Let_syntax = Angstrom.Let_syntax.Let_syntax

let ( let+ ) = A.( let+ )
let ( and+ ) = A.( and+ )
let ( let* ) = A.( let* )
let ( let+ ) = ( let+ )
let ( and+ ) = ( and+ )
let ( let* ) = ( let* )

let ( >>| ), ( *> ), ( <* ), ( <|> ), ( <$> ) =
A.(( >>| ), ( *> ), ( <* ), ( <|> ), ( <$> ))
( >>| ), ( *> ), ( <* ), ( <|> ), ( <$> )
;;

let ( $> ) p a = p >>| const a
let ( <$ ) a p = p >>| const a
end

open Syntax

let integerP =
let integer =
let open Syntax in
let%map tokens =
A.take_while1 (function
take_while1 (function
| '0' .. '9' -> true
| _ -> false)
in
Int.of_string tokens
;;

let parse_exn parser input =
input |> parse_string ~consume:Prefix parser |> Result.ok_or_failwith
;;

let parse_all_exn parser input =
input |> parse_string ~consume:All parser |> Result.ok_or_failwith
;;
20 changes: 0 additions & 20 deletions lib/util/parser.mli

This file was deleted.

21 changes: 9 additions & 12 deletions lib/year2022/day04.ml
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
module P = Util.Parser
module A = Angstrom
open P.Syntax

type range =
{ start : int
; stop : int
}

let rangeP =
let%map start = P.integerP <* A.char '-'
and stop = P.integerP in
let range_p =
let%map start = P.integer <* P.char '-'
and stop = P.integer in
{ start; stop }
;;

let rangePairP =
let%map a = rangeP <* A.char ','
and b = rangeP in
let range_pair_p =
let%map a = range_p <* P.char ','
and b = range_p in
a, b
;;

let rangePairsP = A.sep_by (A.char '\n') rangePairP
let range_pairs_p = P.sep_by (P.char '\n') range_pair_p

let is_subset a b =
(a.start <= b.start && a.stop >= b.stop) || (b.start <= a.start && b.stop >= a.stop)
Expand All @@ -31,16 +30,14 @@ let is_overlapping a b =

let part1 input =
input
|> A.parse_string ~consume:Prefix rangePairsP
|> Result.ok_or_failwith
|> P.parse_exn range_pairs_p
|> List.filter ~f:(fun (a, b) -> is_subset a b)
|> List.length
;;

let part2 input =
input
|> A.parse_string ~consume:Prefix rangePairsP
|> Result.ok_or_failwith
|> P.parse_exn range_pairs_p
|> List.filter ~f:(fun (a, b) -> is_overlapping a b)
|> List.length
;;
35 changes: 16 additions & 19 deletions lib/year2022/day05.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module P = Util.Parser
module A = Angstrom
module IntMap = Map.Make (Int)
open P.Syntax

Expand All @@ -16,21 +15,21 @@ type instructions =
; crates : crate list IntMap.t
}

let dropLineP = A.skip_while (fun c -> not (Char.equal c '\n')) <* A.end_of_line
let noCrateP = None <$ A.string " "
let yesCrateP = Option.some <$> A.char '[' *> A.any_char <* A.char ']'
let crateP = noCrateP <|> yesCrateP
let crateLineP = A.sep_by1 (A.char ' ') crateP
let crateLinesP = A.sep_by1 A.end_of_line crateLineP <* A.end_of_line
let drop_line_p = P.skip_while (fun c -> not (Char.equal c '\n')) <* P.end_of_line
let no_crate_p = None <$ P.string " "
let yes_crate_p = Option.some <$> P.char '[' *> P.any_char <* P.char ']'
let crate_p = no_crate_p <|> yes_crate_p
let crate_line_p = P.sep_by1 (P.char ' ') crate_p
let crate_lines_p = P.sep_by1 P.end_of_line crate_line_p <* P.end_of_line

let moveP =
let%map n = A.string "move " *> P.integerP
and from = A.string " from " *> P.integerP
and to' = A.string " to " *> P.integerP in
let move_p =
let%map n = P.string "move " *> P.integer
and from = P.string " from " *> P.integer
and to' = P.string " to " *> P.integer in
{ n; from; to' }
;;

let movesP = A.sep_by1 A.end_of_line moveP
let moves_p = P.sep_by1 P.end_of_line move_p

let pad_crates crates =
let max = crates |> List.map ~f:List.length |> Util.List.max_int in
Expand All @@ -48,10 +47,10 @@ let to_stacks crates =
|> IntMap.of_alist_exn
;;

let instructionsP =
let%map crateLines = crateLinesP <* dropLineP <* dropLineP
and moves = movesP in
let crates = to_stacks crateLines in
let instructions_p =
let%map crate_lines = crate_lines_p <* drop_line_p <* drop_line_p
and moves = moves_p in
let crates = to_stacks crate_lines in
{ moves; crates }
;;

Expand All @@ -63,9 +62,7 @@ let move_crate f crates { n; from; to' } =
;;

let find_crates f input =
let { moves; crates } =
input |> A.parse_string ~consume:Prefix instructionsP |> Result.ok_or_failwith
in
let { moves; crates } = P.parse_exn instructions_p input in
moves
|> List.fold ~init:crates ~f:(move_crate f)
|> Map.data
Expand Down
36 changes: 14 additions & 22 deletions lib/year2022/day07.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module P = Util.Parser
module A = Angstrom
open P.Syntax

type cmd =
Expand All @@ -12,32 +11,32 @@ type fs =
| File of string * int
| Dir of string * fs list

let nameP =
A.take_while (function
let name_p =
P.take_while (function
| 'a' .. 'z' | '.' | '/' -> true
| _ -> false)
;;

let cdP =
let%map dir = A.string "$ cd " *> nameP in
let cd_p =
let%map dir = P.string "$ cd " *> name_p in
Cd dir
;;

let lsP = Ls <$ A.string "$ ls"
let ls_p = Ls <$ P.string "$ ls"

let dirItemP =
let%map dir = A.string "dir " *> nameP in
let dir_item_p =
let%map dir = P.string "dir " *> name_p in
DirItem dir
;;

let fileItemP =
let%map size = P.integerP <* A.char ' '
and file = nameP in
let file_item_p =
let%map size = P.integer <* P.char ' '
and file = name_p in
FileItem (size, file)
;;

let cmdP = A.choice [ cdP; lsP; dirItemP; fileItemP ]
let cmdsP = A.sep_by1 A.end_of_line cmdP
let cmd_p = P.choice [ cd_p; ls_p; dir_item_p; file_item_p ]
let cmds_p = P.sep_by1 P.end_of_line cmd_p

let build_fs cmds =
let rec build_nodes nodes = function
Expand Down Expand Up @@ -71,22 +70,15 @@ let sizes fs =

let part1 input =
input
|> A.parse_string ~consume:Prefix cmdsP
|> Result.ok_or_failwith
|> P.parse_exn cmds_p
|> build_fs
|> sizes
|> List.filter ~f:(fun x -> x <= 100000)
|> Util.List.sum_int
;;

let part2 input =
let ns =
input
|> A.parse_string ~consume:Prefix cmdsP
|> Result.ok_or_failwith
|> build_fs
|> sizes
in
let ns = input |> P.parse_exn cmds_p |> build_fs |> sizes in
let goal = 30000000 - (70000000 - List.hd_exn ns) in
ns |> List.tl_exn |> List.sort ~compare |> List.find_exn ~f:(fun n -> n >= goal)
;;

0 comments on commit b9efec0

Please sign in to comment.