123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- (* open IntInf; *)
- fun read file =
- let
- val inStream = TextIO.openIn file
- in
- (* TextIO.inputAll returns a TextIO.vector, which is a string. *)
- TextIO.inputAll inStream
- end;
- val newline_tokenizer = String.tokens (fn c => c = #"\n");
- fun sum_lists (nil, nil) = []
- | sum_lists (nil, l2) = []
- | sum_lists (l1, nil) = []
- | sum_lists (alst as (a::arest), blst as (b::brest)) =
- (a + b)::sum_lists(arest, brest);
- fun string_to_ints str =
- map (fn c =>
- case c of
- #"1" => 1
- | #"0" => 0
- | _ => raise Fail "unrecognized bit value")
- (String.explode str);
- fun invert 0 = 1
- | invert 1 = 0
- | invert _ = raise Fail "unrecognized bit value";
- fun invert_list lst = map invert lst;
- fun make_list (0, _) = []
- | make_list (len, fill) =
- fill :: make_list (len - 1, fill);
- fun calc_rates lines =
- let
- fun iter (nil, sum, count) = (sum, count)
- | iter (remaining_lines as (line::rest_lines), sum, count) =
- let
- val ints = string_to_ints line;
- val acc = sum_lists (sum, ints);
- in
- iter (rest_lines, acc, count + 1)
- end;
- in
- let
- val zero = make_list (length (String.explode (hd lines)), 0);
- val (sums, len) = iter (lines, zero, 0);
- val gamma_rate_bits =
- map (fn sum => if sum > (len div 2)
- then 1
- else 0)
- sums;
- val epsilon_bits = invert_list gamma_rate_bits;
- in
- (gamma_rate_bits, epsilon_bits)
- end
- end;
- fun int_expt (0, _) = 0
- | int_expt (1, _) = 1
- | int_expt (base, 0) = 1
- | int_expt (base, 1) = base
- | int_expt (base, exponent) =
- base * int_expt (base, exponent - 1);
- fun bit_to_decimal (bit, ind) =
- bit * int_expt (2, ind);
- fun bits_to_decimal bits =
- List.foldli (fn (ind, bit, acc) =>
- acc + bit_to_decimal (bit, ind))
- 0
- (rev bits);
- val str = read "input";
- val lines = newline_tokenizer str;
- val (gamma_rate, epsilon_rate) = calc_rates lines;
- val solution = (bits_to_decimal gamma_rate) * (bits_to_decimal epsilon_rate);
- solution;
|