diff --git a/lib/day4/day4.ex b/lib/day4/day4.ex index 072fc3a..c439ce3 100644 --- a/lib/day4/day4.ex +++ b/lib/day4/day4.ex @@ -1,5 +1,4 @@ defmodule Day4 do - defmodule Timestamp do defstruct [:year, :month, :day, :hour, :minute] @@ -9,7 +8,7 @@ defmodule Day4 do month: m |> String.to_integer(), day: d |> String.to_integer(), hour: h |> String.to_integer(), - minute: min |> String.to_integer + minute: min |> String.to_integer() } end @@ -17,10 +16,11 @@ defmodule Day4 do first.minute..second.minute end end - + def parse_event(line) do res = Regex.run(~r/\[(\d+)-(\d+)-(\d+) (\d+):(\d+)\] (.+)/, line) [_line, y, m, d, h, min, event | _tail] = res + { Timestamp.create(y, m, d, h, min), event @@ -53,10 +53,12 @@ defmodule Day4 do _id -> {:cont, Enum.reverse(acc), [event]} end end + after_fun = fn [] -> {:cont, []} acc -> {:cont, Enum.reverse(acc), acc} end + events |> Enum.chunk_while([], chunk_fun, after_fun) |> Enum.reject(fn @@ -65,11 +67,14 @@ defmodule Day4 do end) |> Enum.reduce(%{}, fn [begin_shift | events], acc -> guard_id = parse_guard(begin_shift) - ranges = events - |> Enum.chunk_every(2) - |> Enum.map(fn [{sleep, _}, {wake, _} | []] -> - Timestamp.range(sleep, wake) - end) + + ranges = + events + |> Enum.chunk_every(2) + |> Enum.map(fn [{sleep, _}, {wake, _} | []] -> + Timestamp.range(sleep, wake) + end) + Map.update(acc, guard_id, ranges, &(&1 ++ ranges)) end) |> Enum.reject(fn @@ -81,38 +86,48 @@ defmodule Day4 do def get_max_sleep_time(guards) do guards |> Enum.map(fn {id, times} -> - total = times - |> Enum.map(fn a..b -> b - a end) - |> Enum.sum() - {minute, _count} = times - |> Enum.flat_map(&Enum.to_list/1) - |> Enum.reduce(%{}, fn minute, acc -> - Map.update(acc, minute, 1, &(&1 + 1)) - end) - |> Enum.max_by(fn {_minute, count} -> count end) + total = + times + |> Enum.map(fn a..b -> b - a end) + |> Enum.sum() + + {minute, _count} = + times + |> Enum.flat_map(&Enum.to_list/1) + |> Enum.reduce(%{}, fn minute, acc -> + Map.update(acc, minute, 1, &(&1 + 1)) + end) + |> Enum.max_by(fn {_minute, count} -> count end) + {id, total, minute} end) |> Enum.max_by(fn {_id, total, _minute} -> total end) end def range_containing(ranges) do - first = Enum.reduce(ranges, Enum.at(ranges, 0).first, fn first.._, acc -> - min(first, acc) - end) - last = Enum.reduce(ranges, Enum.at(ranges, 0).last, fn _..last, acc -> - max(last, acc) - end) + first = + Enum.reduce(ranges, Enum.at(ranges, 0).first, fn first.._, acc -> + min(first, acc) + end) + + last = + Enum.reduce(ranges, Enum.at(ranges, 0).last, fn _..last, acc -> + max(last, acc) + end) + first..last end def get_most_frequent_sleep_time(guards) do guards |> Enum.map(fn {id, times} -> - {minute, count} = range_containing(times) - |> Enum.map(fn minute -> - {minute, Enum.count(times, fn range -> minute in range end)} - end) - |> Enum.max_by(fn {_minute, count} -> count end) + {minute, count} = + range_containing(times) + |> Enum.map(fn minute -> + {minute, Enum.count(times, fn range -> minute in range end)} + end) + |> Enum.max_by(fn {_minute, count} -> count end) + {id, minute, count} end) |> Enum.max_by(fn {_id, _minute, count} -> count end) @@ -124,21 +139,24 @@ defmodule Day4 do end def part1() do - {id, _total, minute} = parse_input() - |> parse_events() - |> sort_events() - |> get_sleep_times() - |> get_max_sleep_time() + {id, _total, minute} = + parse_input() + |> parse_events() + |> sort_events() + |> get_sleep_times() + |> get_max_sleep_time() + String.to_integer(id) * minute end def part2() do - {id, minute, _count} = parse_input() - |> parse_events() - |> sort_events() - |> get_sleep_times() - |> get_most_frequent_sleep_time() + {id, minute, _count} = + parse_input() + |> parse_events() + |> sort_events() + |> get_sleep_times() + |> get_most_frequent_sleep_time() + String.to_integer(id) * minute end - -end \ No newline at end of file +end diff --git a/lib/day5/day5.ex b/lib/day5/day5.ex index 124c6c9..7af3082 100644 --- a/lib/day5/day5.ex +++ b/lib/day5/day5.ex @@ -1,5 +1,4 @@ defmodule Day5 do - @doc """ Compares two codepoints for opposite case. @@ -18,6 +17,7 @@ defmodule Day5 do else [c | s] end + c, [] -> [c] end) @@ -76,6 +76,7 @@ defmodule Day5 do s = <> str = String.replace(input, s, "") str = String.replace(str, String.upcase(s), "") + input |> String.replace(s, "") |> String.replace(String.upcase(s), "") @@ -87,7 +88,7 @@ defmodule Day5 do end def parse_input() do - File.read!("lib/day5/input.txt") + File.read!("lib/day5/input.txt") end def part1() do @@ -101,5 +102,4 @@ defmodule Day5 do parse_input() |> min_length() end - -end \ No newline at end of file +end diff --git a/lib/day6/day6.ex b/lib/day6/day6.ex index 6fb0e08..d0fe9a3 100644 --- a/lib/day6/day6.ex +++ b/lib/day6/day6.ex @@ -1,5 +1,4 @@ defmodule Day6 do - @doc """ Parses a node from a string. @@ -11,6 +10,7 @@ defmodule Day6 do """ def parse_node(s) do [x, y] = String.split(s, ", ") + { x |> String.to_integer(), y |> String.to_integer() @@ -39,7 +39,7 @@ defmodule Day6 do nil """ def nearest_node(point, all) do - nearest = + nearest = all |> Enum.map(fn other -> {other, distance(point, other)} end) @@ -58,9 +58,11 @@ defmodule Day6 do 0..grid_size |> Enum.reduce(acc, fn x, {areas, infinite_area_nodes} -> pt = {x, y} + case nearest_node(pt, nodes) do nil -> {areas, infinite_area_nodes} + nearest -> if x == 0 or y == 0 or x == grid_size or y == grid_size do { @@ -102,9 +104,11 @@ defmodule Day6 do 0..grid_size |> Enum.reduce(acc, fn x, acc -> pt = {x, y} + cond do total_distances(pt, nodes) < max_dist -> [pt | acc] + true -> acc end @@ -128,5 +132,4 @@ defmodule Day6 do |> region_near_most() |> Enum.count() end - -end \ No newline at end of file +end diff --git a/test/day4_test.exs b/test/day4_test.exs index 74e0e60..db8f2ad 100644 --- a/test/day4_test.exs +++ b/test/day4_test.exs @@ -4,11 +4,15 @@ defmodule Day4Test do alias Day4.Timestamp test "parse event" do - assert Day4.parse_event("[1518-11-01 00:00] Guard #10 begins shift") == {%Timestamp{year: 1518, month: 11, day: 01, hour: 0, minute: 0}, "Guard #10 begins shift"} + assert Day4.parse_event("[1518-11-01 00:00] Guard #10 begins shift") == + {%Timestamp{year: 1518, month: 11, day: 01, hour: 0, minute: 0}, + "Guard #10 begins shift"} end test "parse guard" do - event = {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 00}, "Guard #10 begins shift"} + event = + {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 00}, "Guard #10 begins shift"} + assert Day4.parse_guard(event) == "10" end @@ -17,17 +21,19 @@ defmodule Day4Test do {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 05}, "falls asleep"}, {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 55}, "wakes up"}, {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 25}, "wakes up"}, - {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 00}, "Guard #10 begins shift"}, + {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 00}, + "Guard #10 begins shift"}, {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 30}, "falls asleep"} ] assert Day4.sort_events(events) == [ - {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 00}, "Guard #10 begins shift"}, - {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 05}, "falls asleep"}, - {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 25}, "wakes up"}, - {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 30}, "falls asleep"}, - {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 55}, "wakes up"} - ] + {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 00}, + "Guard #10 begins shift"}, + {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 05}, "falls asleep"}, + {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 25}, "wakes up"}, + {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 30}, "falls asleep"}, + {%Timestamp{year: 1518, month: 11, day: 01, hour: 00, minute: 55}, "wakes up"} + ] end test "get sleep times" do @@ -52,9 +58,9 @@ defmodule Day4Test do ] assert Day4.get_sleep_times(events) == [ - {"10", [5..25, 30..55, 24..29]}, - {"99", [40..50, 36..46, 45..55]} - ] + {"10", [5..25, 30..55, 24..29]}, + {"99", [40..50, 36..46, 45..55]} + ] end test "get max sleep time" do @@ -79,5 +85,4 @@ defmodule Day4Test do assert Day4.get_most_frequent_sleep_time(guards) == {"99", 45, 3} end - -end \ No newline at end of file +end diff --git a/test/day5/day5_test.exs b/test/day5/day5_test.exs index 4237006..336f317 100644 --- a/test/day5/day5_test.exs +++ b/test/day5/day5_test.exs @@ -1,4 +1,4 @@ defmodule Day5Test do use ExUnit.Case doctest Day5 -end \ No newline at end of file +end diff --git a/test/day6_test.exs b/test/day6_test.exs index 51a7be2..3ea86bb 100644 --- a/test/day6_test.exs +++ b/test/day6_test.exs @@ -1,4 +1,4 @@ defmodule Day6Test do use ExUnit.Case doctest Day6 -end \ No newline at end of file +end