let usage args = let err = Format.sprintf "usage: %s %s" Sys.argv.(0) args in print_endline err; exit 1 let usage_default day = usage (string_of_int day ^ " ") let main day mains = function | [part; input] -> mains.(int_of_string part - 1) input | _ -> usage_default day type 'a monoid = {id: 'a; op: 'a -> 'a -> 'a; op_name: string; pp: Format.formatter -> 'a -> unit} let mult = {id = 1; op = ( * ); op_name = "*"; pp = Format.pp_print_int} let add = {id = 0; op = ( + ); op_name = "+"; pp = Format.pp_print_int} let print_fold mon xs = let res = List.fold_left mon.op mon.id xs in let rec go fmt = function | [] -> Format.fprintf fmt "%a" mon.pp mon.id | [x] -> Format.fprintf fmt "%a" mon.pp x | x::xs -> Format.fprintf fmt "%a * %a" mon.pp x go xs in Format.printf "%a = %a\n" go xs mon.pp res let print_prod = print_fold mult let print_sum = print_fold add