|
1 | 1 | open Utils |
2 | 2 |
|
| 3 | +let parse input = |
| 4 | + let (ops, numbers) = String.split_on_char '\n' input |
| 5 | + |> List.rev |
| 6 | + |> function |
| 7 | + | [] -> failwith "bad input" |
| 8 | + | x::xs -> x ^ " ", List.rev xs |> List.map (fun s -> s ^ " ") |
| 9 | + in |
| 10 | + let (s1, s2, _, _, _) = fold_range (fun (s1, s2, op, vers, hors) i -> |
| 11 | + let op = match op with |
| 12 | + | Some op -> Some op |
| 13 | + | None -> (match ops.[i] with |
| 14 | + | '*' -> Some (List.fold_left ( * ) 1) |
| 15 | + | '+' -> Some (List.fold_left (+) 0) |
| 16 | + | _ -> None) in |
| 17 | + let n_vers = List.fold_left (fun a -> function |
| 18 | + | '0'..'9' as c -> a * 10 + (int_of_char c - int_of_char '0') |
| 19 | + | _ -> a) 0 (List.map (fun l -> l.[i]) numbers) in |
| 20 | + let hors = List.map2 (fun a l -> match l.[i] with |
| 21 | + | '0'..'9' as c -> a * 10 + (int_of_char c - int_of_char '0') |
| 22 | + | _ -> a) hors numbers in |
| 23 | + if List.for_all (fun l -> l.[i] = ' ') numbers then |
| 24 | + let op = Option.get op in |
| 25 | + (s1 + op hors, s2 + op vers, None, [], List.map (fun _ -> 0) numbers) |
| 26 | + else |
| 27 | + (s1, s2, op, n_vers :: vers, hors) |
| 28 | + |
| 29 | + ) (0, 0, None, [], List.map (fun _ -> 0) numbers) 0 (String.length ops - 1) |
| 30 | + in |
| 31 | + s1, s2 |
| 32 | + |
3 | 33 | let day06 input = |
4 | | - ("TODO", "TODO") |
| 34 | + let input = trim_end_nl input in |
| 35 | + let part1, part2 = parse input in |
| 36 | + (string_of_int part1, string_of_int part2) |
5 | 37 |
|
6 | 38 |
|
0 commit comments