**Dustin Swan**2 years ago

**2 changed files**with

**1078 additions**and

**0 deletions**

`@ -0,0 +1,78 @@` |
|||

`(* Common util. Should probably put this in a module or something.. *)` |
|||

`let get_one_line file =` |
|||

` try Some (input_line file) with` |
|||

` End_of_file -> None` |
|||

```
``` |
|||

`let get_lines file =` |
|||

` let rec input lines =` |
|||

` match get_one_line file with` |
|||

` Some line -> input (line :: lines)` |
|||

` | None -> List.rev lines` |
|||

` in input []` |
|||

```
``` |
|||

`let read_file file =` |
|||

` let channel = open_in(file) in` |
|||

` get_lines channel` |
|||

```
``` |
|||

`let (<<) f g x = f(g(x))` |
|||

`let (>>) f g x = g(f(x))` |
|||

```
``` |
|||

`let rec take n (x :: xs) = (* take the first n elements *)` |
|||

` match n with` |
|||

` | 0 -> []` |
|||

` | n -> x :: (take (n-1) xs)` |
|||

```
``` |
|||

`let rec drop n l = (* drop the first n elemnts *)` |
|||

` match n with` |
|||

` | 0 -> l` |
|||

` | n -> drop (n-1) @@ List.tl l` |
|||

```
``` |
|||

`let sub_list start length = (* sub list from start *)` |
|||

` take length >> drop start` |
|||

```
``` |
|||

`let list_sum = List.fold_left (+) 0` |
|||

```
``` |
|||

`let list_max l = List.fold_left (fun acc x -> if x > acc then x else acc) (List.hd l) l` |
|||

`let list_min l = List.fold_left (fun acc x -> if x < acc then x else acc) (List.hd l) l` |
|||

```
``` |
|||

`let range start len = (* makes a new list from start with length len *)` |
|||

` List.init len (fun x -> x + 0) |> List.map (fun x -> x + start)` |
|||

```
``` |
|||

`let flip f x y = f y x` |
|||

```
``` |
|||

`(* --- *)` |
|||

```
``` |
|||

`let has_adders l target = (* do any 2 elements of l add up to target *)` |
|||

` match List.find_opt (fun x ->` |
|||

` match List.find_opt (fun y -> x != y && x + y = target) l with` |
|||

` | Some _ -> true` |
|||

` | None -> false` |
|||

` ) l with` |
|||

` | Some _ -> true` |
|||

` | None -> false` |
|||

```
``` |
|||

`let rec first_without_adders pre lines =` |
|||

` let x :: xs = lines in (* match out the head and tail *)` |
|||

` let cur = List.nth lines pre in (* grab the first row after the preamble *)` |
|||

` let sub = take pre lines in (* grab the preamble sublist *)` |
|||

` if has_adders sub cur (* chechk for adders *)` |
|||

` then first_without_adders pre xs (* if it has adders, recurse with the tail of the original list *)` |
|||

` else cur (* no adders! return this one *)` |
|||

```
``` |
|||

`let rec all_sub_lists = function (* all combinations of sub-lists *)` |
|||

` | [] -> []` |
|||

` | xs ->` |
|||

` range 0 (List.length xs)` |
|||

` |> List.map (fun len' -> sub_list 0 len' xs)` |
|||

` |> flip List.append (all_sub_lists @@ List.tl xs)` |
|||

```
``` |
|||

`let () =` |
|||

` let lines = read_file "day9.txt" |> List.map int_of_string in` |
|||

```
``` |
|||

` let first = lines |> first_without_adders 25 in` |
|||

` Printf.printf "first without 2 adders %i\n" first;` |
|||

```
``` |
|||

` let all_subs = all_sub_lists lines in` |
|||

` let our_range = List.find (fun l -> list_sum l = first) all_subs in` |
|||

` let our_sum = (list_max our_range) + (list_min our_range) in` |
|||

` Printf.printf "sum %i\n" our_sum;` |

####
1000
day9.txt
File diff suppressed because it is too large
View File

File diff suppressed because it is too large

View File
Write
Preview

Loading…

Cancel

Save

Reference in new issue