diff options
author | Brian Chu <brianmchu42@gmail.com> | 2022-01-27 13:43:15 -0800 |
---|---|---|
committer | Brian Chu <brianmchu42@gmail.com> | 2022-01-27 13:43:15 -0800 |
commit | facc9b10d3df43354e684882505fd07a3bc0985f (patch) | |
tree | dc951c96a7c7466d4cb7cb1f670c043fddb6cb7a | |
download | AdventOfCode2017-facc9b10d3df43354e684882505fd07a3bc0985f.tar.gz |
solutions up to day 4
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | day1.ml | 39 | ||||
-rw-r--r-- | day2.ml | 39 | ||||
-rw-r--r-- | day3.ml | 24 | ||||
-rw-r--r-- | day4.ml | 38 |
5 files changed, 141 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2211df6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.txt diff --git a/day1.ml b/day1.ml new file mode 100644 index 0000000..6e95cfb --- /dev/null +++ b/day1.ml @@ -0,0 +1,39 @@ +#use "topfind";; +#thread;; +#require "core";; +#require "stdio";; + +open Core +open Stdio + +let captcha = In_channel.read_all "day1.txt" + |> String.strip + |> String.to_list + |> List.map ~f:(fun x -> Char.to_int x - Char.to_int '0') + +let rec last = function + | [] -> assert false + | [x] -> x + | x::xs -> last xs + +let rec init = function + | [] -> [] + | [x] -> [] + | x::xs -> x::(init xs) + +let rotate_once l = (last l)::(init l) + +let rec rotate n l = + match n with + | 0 -> l + | _ -> rotate (n-1) (rotate_once l) + +let neighbor_sums n l = + let rotated = rotate n l in + Caml.List.combine l rotated + |> List.map ~f:(fun (x, y) -> if x = y then x else 0) + |> List.fold_left ~f:(+) ~init:0 + +let () = + neighbor_sums 1 captcha |> Printf.printf "%d\n"; + neighbor_sums ((List.length captcha) / 2) captcha |> Printf.printf "%d\n" diff --git a/day2.ml b/day2.ml new file mode 100644 index 0000000..2843dcd --- /dev/null +++ b/day2.ml @@ -0,0 +1,39 @@ +#use "topfind";; +#thread;; +#require "core";; +#require "stdio";; +#require "csv";; + +open Core +open Stdio + +let spreadsheet = Csv.load ~separator:'\t' "day2.txt" + |> List.map ~f:(List.map ~f:int_of_string) + +let minmax = List.fold_left + ~init:(Int.max_value, Int.min_value) + ~f:(fun (lmin, lmax) x -> (min x lmin, max x lmax)) + +let part1 l = List.map ~f:minmax l + |> List.map ~f:(fun (lmin, lmax) -> lmax - lmin) + |> List.fold_left ~f:(+) ~init:0 + +let rec dividend row = + let divisible a b = + a mod b = 0 || b mod a = 0 in + let divide a b = + if a mod b = 0 then a/b else b/a in + + match row with + | [] -> 0 + | h::t -> + match List.find t ~f:(divisible h) with + | Some x -> divide h x + | None -> dividend t + +let part2 l = List.map ~f:dividend l + |> List.fold_left ~f:(+) ~init:0 + +let () = + Printf.printf "%d\n" (part1 spreadsheet); + Printf.printf "%d\n" (part2 spreadsheet) diff --git a/day3.ml b/day3.ml new file mode 100644 index 0000000..bcca156 --- /dev/null +++ b/day3.ml @@ -0,0 +1,24 @@ +open Float + +let input = 265149 + +let coordinates n = + let k = int_of_float (ceil (((sqrt (float_of_int n)) -. 1.) /. 2.)) in + let t = 1 + (2 * k) in + let m = int_of_float ((float_of_int t) ** 2.) in + let t = t - 1 in + if n >= m - t then + (k - (m - n), -k) + else if n >= m - (2 * t) then + (-k, -k + (m - n)) + else if n >= m - (3 * t) then + (-k + (m - n), k) + else + (k, k - (m - n - t)) + +let () = + let (x, y) = coordinates input in + Printf.printf "%d\n" (Int.abs x + Int.abs y) + + +(* Part 2 is listed on OEIS *) diff --git a/day4.ml b/day4.ml new file mode 100644 index 0000000..e058aec --- /dev/null +++ b/day4.ml @@ -0,0 +1,38 @@ +#use "topfind";; +#thread;; +#require "core";; +#require "stdio";; + +open Core +open Stdio + +let passphrases = In_channel.read_lines "day4.txt" + |> List.map ~f:(fun x -> String.strip x |> String.split ~on:' ') + + +let passphrase_set_lengths p = + let toSet strings = + List.fold ~f:Set.add ~init:(Set.empty (module String)) strings in + List.map ~f:toSet p |> List.map ~f:Set.length + +let passphrase_lengths = List.map ~f:List.length + +let rec has_anagram passphrase = + let string_to_set = + String.fold ~f:Set.add ~init:(Set.empty (module Char)) in + let anagram a b = + Set.equal (string_to_set a) (string_to_set b) in + match passphrase with + | [] -> false + | h::t -> + match List.find t ~f:(anagram h) with + | Some x -> true + | None -> has_anagram t + +let () = + let pairs = List.zip_exn (passphrase_set_lengths passphrases) (passphrase_lengths passphrases) in + let valid_count = List.fold ~f:(fun acc (x, y) -> if x = y then acc+1 else acc) ~init:0 pairs in + Printf.printf "%d\n" valid_count; + + let anagram_count = List.fold ~f:(fun acc x -> if has_anagram x then acc else acc + 1) ~init:0 passphrases in + Printf.printf "%d\n" anagram_count |