From bd4acc8f171c8cbb1a07802a4368a49eda66dc17 Mon Sep 17 00:00:00 2001 From: Adam Millerchip Date: Sun, 26 Dec 2021 22:10:19 +0900 Subject: [PATCH] Add 2018 --- 2018/day1/input | 995 +++++++++++++++++++++++++++++++ 2018/day1/part1.exs | 5 + 2018/day1/part2.exs | 27 + 2018/day10/day10.exs | 91 +++ 2018/day10/input | 374 ++++++++++++ 2018/day11/day11.exs | 93 +++ 2018/day12/day12.exs | 101 ++++ 2018/day12/input | 34 ++ 2018/day13/day13.exs | 179 ++++++ 2018/day13/input | 150 +++++ 2018/day13/test | 6 + 2018/day13/test2 | 7 + 2018/day14/day14.exs | 155 +++++ 2018/day2/input | 250 ++++++++ 2018/day2/part1.exs | 33 ++ 2018/day2/part2.exs | 30 + 2018/day3/day3.exs | 57 ++ 2018/day3/input | 1317 ++++++++++++++++++++++++++++++++++++++++++ 2018/day4/day4.exs | 97 ++++ 2018/day4/input | 1106 +++++++++++++++++++++++++++++++++++ 2018/day5/day5.exs | 41 ++ 2018/day5/input | 1 + 2018/day6/day6.exs | 118 ++++ 2018/day6/input | 50 ++ 2018/day7/day7.exs | 125 ++++ 2018/day7/input | 101 ++++ 2018/day8/day8.exs | 52 ++ 2018/day8/input | 1 + 2018/day9/day9.exs | 102 ++++ 2018/day9/input | 1 + 30 files changed, 5699 insertions(+) create mode 100644 2018/day1/input create mode 100644 2018/day1/part1.exs create mode 100644 2018/day1/part2.exs create mode 100644 2018/day10/day10.exs create mode 100644 2018/day10/input create mode 100644 2018/day11/day11.exs create mode 100644 2018/day12/day12.exs create mode 100644 2018/day12/input create mode 100644 2018/day13/day13.exs create mode 100644 2018/day13/input create mode 100644 2018/day13/test create mode 100644 2018/day13/test2 create mode 100644 2018/day14/day14.exs create mode 100644 2018/day2/input create mode 100644 2018/day2/part1.exs create mode 100644 2018/day2/part2.exs create mode 100644 2018/day3/day3.exs create mode 100644 2018/day3/input create mode 100644 2018/day4/day4.exs create mode 100644 2018/day4/input create mode 100644 2018/day5/day5.exs create mode 100644 2018/day5/input create mode 100644 2018/day6/day6.exs create mode 100644 2018/day6/input create mode 100644 2018/day7/day7.exs create mode 100644 2018/day7/input create mode 100644 2018/day8/day8.exs create mode 100644 2018/day8/input create mode 100644 2018/day9/day9.exs create mode 100644 2018/day9/input diff --git a/2018/day1/input b/2018/day1/input new file mode 100644 index 0000000..f89e583 --- /dev/null +++ b/2018/day1/input @@ -0,0 +1,995 @@ +-4 ++9 ++6 ++8 ++3 ++14 ++11 ++7 +-12 ++4 +-15 ++2 +-12 +-4 ++15 +-8 +-16 +-4 ++14 +-11 +-19 +-2 ++15 +-4 +-5 +-1 ++15 +-8 ++1 ++10 ++7 ++18 ++1 ++10 ++11 ++17 +-16 ++4 +-12 ++14 ++9 ++6 ++7 ++10 ++14 ++7 ++6 +-3 ++19 ++18 ++4 ++16 ++17 ++11 ++9 ++7 +-8 +-1 +-5 +-12 +-7 ++4 +-5 ++2 ++4 ++3 ++20 +-19 ++18 ++12 ++14 ++5 +-14 ++7 +-19 +-20 ++6 +-3 ++7 ++15 ++12 ++11 ++15 ++2 ++3 +-17 +-18 ++1 ++13 +-3 ++14 +-1 +-8 +-9 +-12 ++15 +-8 ++10 ++11 ++15 ++4 ++6 ++16 ++1 ++3 ++13 +-6 ++14 +-3 +-12 +-12 ++14 ++6 +-10 ++20 ++5 ++18 ++11 ++3 ++17 ++2 +-9 +-17 +-14 ++2 ++9 ++11 +-2 ++14 ++5 +-7 ++18 +-6 +-9 +-9 +-10 +-12 +-16 +-1 ++14 +-15 +-9 +-2 +-6 +-11 +-14 +-11 +-19 ++11 +-12 +-18 +-5 ++11 ++18 ++17 +-5 +-19 ++14 ++11 +-2 +-14 ++17 ++8 ++3 ++12 +-9 ++1 ++23 ++7 +-12 ++24 ++10 +-2 ++6 ++20 +-16 +-17 ++19 +-7 ++11 ++14 ++21 +-18 ++1 ++4 ++8 +-2 +-5 +-12 +-13 ++7 ++19 ++2 ++8 ++9 ++8 ++2 ++17 ++15 ++18 ++18 ++18 +-2 +-13 +-18 +-12 +-1 ++17 +-14 +-15 ++8 ++20 ++9 +-7 ++11 +-15 +-16 +-11 +-9 ++11 ++19 ++15 ++4 ++15 ++9 +-3 ++5 +-18 ++6 ++17 ++15 +-8 +-13 ++16 ++8 ++17 ++2 ++18 ++2 ++2 ++4 +-10 ++11 +-3 ++8 ++2 ++3 +-12 ++6 ++12 +-1 ++21 +-13 +-17 +-10 ++13 +-6 +-18 +-4 +-6 +-5 ++18 +-20 +-6 +-7 +-17 +-6 +-18 ++9 ++16 ++14 ++10 ++16 ++1 +-4 ++1 ++15 +-9 +-5 +-4 +-7 +-7 +-1 ++13 +-15 +-1 +-22 +-19 ++10 +-8 +-5 ++16 +-12 ++17 ++7 ++4 +-7 ++4 ++6 ++5 +-2 +-1 ++20 +-8 +-3 ++7 +-47 +-10 ++19 +-27 +-3 ++13 +-26 ++1 ++8 +-30 +-14 ++3 ++17 +-16 +-2 +-11 ++14 +-8 +-7 +-10 +-8 ++20 ++23 ++26 ++12 +-25 +-88 ++4 ++1 +-29 +-5 ++16 +-19 ++15 ++19 +-27 +-8 +-18 +-9 +-12 +-10 ++14 +-13 +-14 +-10 +-21 +-14 ++6 +-1 ++21 ++14 ++6 ++21 +-2 ++17 ++20 +-5 ++17 +-4 +-14 +-9 +-11 +-14 ++17 ++20 ++10 ++20 +-80 ++15 +-27 +-42 ++7 +-18 ++14 +-4 +-16 +-3 ++10 +-8 +-25 +-14 +-3 ++24 ++3 ++18 +-35 ++54 ++29 +-35 ++63 ++4 +-119 +-24 +-57508 ++1 +-10 +-10 +-17 +-8 +-9 ++4 +-7 ++19 ++2 ++19 ++8 +-16 +-19 +-2 ++5 ++2 ++10 ++11 +-6 +-18 ++11 +-17 +-17 ++12 ++4 +-2 +-17 +-5 ++7 +-18 +-14 +-3 +-18 +-16 ++18 +-1 +-10 +-8 +-13 ++12 +-4 +-9 ++6 ++11 +-5 ++9 ++13 ++16 ++15 +-5 ++10 ++13 +-19 +-16 +-13 ++5 +-12 ++8 ++1 ++14 ++23 +-1 ++17 +-15 +-19 +-9 ++8 +-2 ++19 +-13 +-15 ++2 ++12 +-15 +-16 +-20 +-2 ++14 ++6 +-1 +-1 +-3 +-9 +-3 +-15 ++6 ++4 +-8 ++9 +-14 +-10 ++9 +-15 +-16 +-3 +-18 +-9 ++18 +-8 +-16 +-18 ++14 ++17 ++9 ++12 +-7 ++2 ++15 ++12 +-7 +-11 ++13 ++8 ++5 ++2 ++10 +-19 +-12 +-20 ++10 ++7 ++19 +-8 +-7 ++19 +-18 +-15 +-9 +-12 +-18 ++2 ++12 ++10 +-5 ++7 +-15 ++1 +-11 +-18 +-8 +-16 +-16 ++13 +-19 +-10 +-5 +-5 +-18 ++13 ++3 ++16 ++17 ++15 ++19 +-11 ++15 +-12 ++2 ++17 ++17 +-16 +-15 ++5 ++20 +-12 ++5 ++2 ++7 ++15 +-6 +-17 ++18 +-20 +-8 +-15 +-18 +-1 +-20 +-5 ++18 +-11 +-15 ++2 +-15 +-15 ++8 +-18 ++1 ++1 ++5 ++5 ++11 ++5 ++15 ++16 ++19 +-4 +-7 +-5 ++8 +-2 +-19 ++7 +-6 ++19 ++17 ++9 ++2 ++1 +-15 +-2 +-6 +-12 ++19 +-16 +-9 ++4 +-3 ++21 ++6 ++27 ++14 +-22 ++18 ++12 ++18 ++13 +-10 ++8 +-13 +-6 ++10 +-12 +-17 +-38 ++21 +-19 ++18 +-23 +-7 ++17 ++8 ++59 ++3 +-19 ++22 ++17 ++15 ++5 ++24 ++13 ++15 ++8 ++18 +-17 ++16 ++16 ++20 ++1 ++7 +-16 +-15 ++2 +-18 +-9 ++1 ++13 ++5 +-17 ++22 +-13 +-21 +-12 +-4 ++20 +-31 +-12 +-34 ++10 ++2 ++20 ++22 +-28 +-19 +-19 +-2 ++133 ++17 +-10 ++18 +-10 ++6 ++20 +-10 ++3 ++11 ++14 +-5 ++3 ++20 ++11 +-9 +-12 +-1 +-3 +-19 ++12 ++14 ++8 ++12 ++2 ++18 ++7 +-19 ++11 +-22 ++13 +-9 ++15 +-13 ++1 ++20 ++14 +-9 ++11 +-18 ++13 +-21 +-20 +-16 ++7 +-14 ++12 +-1 ++8 +-16 +-16 +-13 ++7 +-3 ++19 +-22 +-10 ++6 ++1 ++16 ++4 +-1 +-12 +-16 +-10 ++29 ++8 ++18 +-9 ++11 ++18 +-6 +-2 ++4 +-3 +-8 +-9 ++21 ++13 +-23 +-26 +-22 +-9 +-24 +-11 ++2 +-18 +-42 ++13 ++46 +-96 +-7 +-9 +-131 +-6 +-21 ++11 +-18 ++14 ++28 +-18 +-11 +-18 +-48 ++7 ++69 ++9 +-24 +-15 ++46 +-10 ++137 +-57522 ++5 ++4 ++3 ++16 +-3 +-18 ++3 +-9 +-10 ++11 ++12 +-8 +-18 +-18 +-4 ++18 ++19 +-4 +-19 +-19 ++4 +-15 ++3 +-16 +-2 ++12 ++16 ++9 ++10 ++13 ++1 ++21 ++17 ++18 ++5 +-4 +-2 ++15 ++13 ++2 ++7 +-19 ++1 +-16 +-7 +-10 ++18 ++12 +-21 +-7 ++3 ++16 ++14 +-13 ++17 ++2 ++7 +-2 +-10 +-17 ++9 +-5 ++14 ++13 ++7 ++15 +-13 ++1 +-13 ++16 +-2 +-5 +-7 ++15 ++13 +-8 +-1 ++18 ++16 +-15 +-7 ++11 ++10 ++16 +-12 ++15 +-16 +-14 ++8 +-16 +-4 +-4 +-19 +-17 +-4 ++18 ++1 ++14 +-9 +-15 ++19 ++8 ++19 ++14 ++20 +-14 ++1 +-18 ++4 +-3 ++2 +-20 ++10 +-2 ++1 +-3 +-2 +-3 ++12 ++6 ++6 ++11 ++17 +-7 ++20 +-16 ++5 ++6 +-39 +-26 +-31 +-29 ++2 +-19 ++18 +-6 +-16 ++14 ++4 +-19 ++18 +-14 +-1 +-10 +-4 +-17 ++6 ++17 ++1 ++1 +-12 ++21 +-12 ++16 +-12 ++16 +-27 ++22 +-2 ++30 ++1 +-3 ++7 ++23 +-9 ++20 ++34 +-142 +-7 ++5 ++16 +-23 +-9 ++7 +-2 ++12 +-15 +-4 +-19 +-16 ++15 ++13 ++4 ++4 +-16 +-7 ++10 ++17 +-6 +-15 ++11 +-5 +-8 +-18 ++115524 diff --git a/2018/day1/part1.exs b/2018/day1/part1.exs new file mode 100644 index 0000000..e9e3249 --- /dev/null +++ b/2018/day1/part1.exs @@ -0,0 +1,5 @@ +File.stream!("input") +|> Stream.map(&String.trim/1) +|> Stream.map(&String.to_integer/1) +|> Enum.sum() +|> IO.puts() diff --git a/2018/day1/part2.exs b/2018/day1/part2.exs new file mode 100644 index 0000000..8376acc --- /dev/null +++ b/2018/day1/part2.exs @@ -0,0 +1,27 @@ +defmodule Part2 do + def mark_seen(change, {prev_freq, seen}) do + freq = prev_freq + change + + marked_freq = {freq, MapSet.member?(seen, freq)} + acc = {freq, MapSet.put(seen, freq)} + + {[marked_freq], acc} + end + + def run do + File.stream!("input") + |> Stream.map(&String.trim/1) + # Trying to work out why can't cycle over the stream + # Can't reproduce with this + # Stream.cycle([1]) |> Stream.transform(0, fn one, prev -> {[prev + one], prev + one} end) |> Enum.find(fn x -> x == 25 end) + # So maybe it's because a combination of the accumulator in the stream and Enum.find + |> Stream.map(&String.to_integer/1) + |> Stream.cycle() + |> Stream.transform({0, MapSet.new([0])}, &mark_seen/2) + |> Enum.find(fn {_freq, seen} -> seen end) + |> elem(0) + |> IO.puts() + end +end + +Part2.run() diff --git a/2018/day10/day10.exs b/2018/day10/day10.exs new file mode 100644 index 0000000..cc0621f --- /dev/null +++ b/2018/day10/day10.exs @@ -0,0 +1,91 @@ +defmodule Star do + defstruct [:pos_x, :pos_y, :vel_x, :vel_y] + + def move_all(stars, secs) do + Enum.map(stars, &move(&1, secs)) + end + + def move(star, secs) do + %Star{star | pos_x: star.pos_x + star.vel_x * secs, pos_y: star.pos_y + star.vel_y * secs} + end +end + +defmodule Day10 do + @input_pattern ~r/=< ?(-?\d+), ?(-?\d+)>.*=< ?(-?\d+), ?(-?\d+)>/ + + def parse_line(line) do + [pos_x, pos_y, v_x, v_y] = + Regex.run(@input_pattern, line, capture: :all_but_first) + |> Enum.map(&String.to_integer/1) + + %Star{pos_x: pos_x, pos_y: pos_y, vel_x: v_x, vel_y: v_y} + end + + def init do + File.stream!("input") + |> Enum.map(&parse_line/1) + end + + # Start with the first star, then compare all the others to find the extremities + def bounding_box([%Star{pos_x: x, pos_y: y} | _] = stars) do + Enum.reduce(stars, {x, y, x, y}, fn star, {min_x, min_y, max_x, max_y} -> + { + min(star.pos_x, min_x), + min(star.pos_y, min_y), + max(star.pos_x, max_x), + max(star.pos_y, max_y) + } + end) + end + + def draw(stars) do + starfield = MapSet.new(stars, fn star -> {star.pos_x, star.pos_y} end) + + {min_x, min_y, max_x, max_y} = bounding_box(stars) + + grid = + for y <- min_y..max_y, x <- min_x..max_x do + eol = if x === max_x, do: "\n", else: "" + char = if MapSet.member?(starfield, {x, y}), do: "#", else: " " + char <> eol + end + + Enum.join(grid) + end + + def aligned?(stars) do + starfield = MapSet.new(stars, fn star -> {star.pos_x, star.pos_y} end) + Enum.all?(stars, &aligned?(&1, starfield)) + end + + def aligned?(star, starfield) do + neighbours = [ + {star.pos_x - 1, star.pos_y - 1}, + {star.pos_x - 1, star.pos_y}, + {star.pos_x - 1, star.pos_y + 1}, + {star.pos_x, star.pos_y - 1}, + {star.pos_x, star.pos_y + 1}, + {star.pos_x + 1, star.pos_y - 1}, + {star.pos_x + 1, star.pos_y}, + {star.pos_x + 1, star.pos_y + 1} + ] + + Enum.any?(neighbours, &MapSet.member?(starfield, &1)) + end + + def wait_for_alignment(stars, count) do + if aligned?(stars) do + {stars, count} + else + stars |> Star.move_all(1) |> wait_for_alignment(count + 1) + end + end + + def go do + {stars, count} = init() |> wait_for_alignment(0) + IO.puts(draw(stars)) + IO.puts("#{count} seconds") + end +end + +Day10.go() diff --git a/2018/day10/input b/2018/day10/input new file mode 100644 index 0000000..41ce6a2 --- /dev/null +++ b/2018/day10/input @@ -0,0 +1,374 @@ +position=<-20620, -41485> velocity=< 2, 4> +position=<-51844, 41770> velocity=< 5, -4> +position=<-51817, -20670> velocity=< 5, 2> +position=< 21000, 52179> velocity=<-2, -5> +position=< 21051, 31360> velocity=<-2, -3> +position=< 41859, -41487> velocity=<-4, 4> +position=< 41830, 31361> velocity=<-4, -3> +position=<-51817, -51895> velocity=< 5, 5> +position=<-51836, -41484> velocity=< 5, 4> +position=< 21032, -51887> velocity=<-2, 5> +position=<-31003, -41482> velocity=< 3, 4> +position=< 52261, -51890> velocity=<-5, 5> +position=<-51836, 10547> velocity=< 5, -1> +position=< 10614, -10259> velocity=<-1, 1> +position=<-10194, 41776> velocity=< 1, -4> +position=<-10186, 10550> velocity=< 1, -1> +position=< 31431, -51892> velocity=<-3, 5> +position=<-51804, 52175> velocity=< 5, -5> +position=< 10601, 52183> velocity=<-1, -5> +position=<-51812, 10548> velocity=< 5, -1> +position=< 10633, 20959> velocity=<-1, -2> +position=<-41417, -41480> velocity=< 4, 4> +position=< 10628, 31360> velocity=<-1, -3> +position=<-10160, -20666> velocity=< 1, 2> +position=<-51793, -20673> velocity=< 5, 2> +position=<-41430, -41485> velocity=< 4, 4> +position=< 21032, -20670> velocity=<-2, 2> +position=<-30987, -51891> velocity=< 3, 5> +position=< 52280, -31080> velocity=<-5, 3> +position=<-30995, -10266> velocity=< 3, 1> +position=<-10177, -51888> velocity=< 1, 5> +position=<-30995, 10551> velocity=< 3, -1> +position=< 21028, 20961> velocity=<-2, -2> +position=< 31412, -51895> velocity=<-3, 5> +position=< 31467, -10260> velocity=<-3, 1> +position=< 31407, -51895> velocity=<-3, 5> +position=< 10636, 41773> velocity=<-1, -4> +position=< 31418, -51892> velocity=<-3, 5> +position=<-20620, 41773> velocity=< 2, -4> +position=<-10163, -10265> velocity=< 1, 1> +position=<-20594, -10264> velocity=< 2, 1> +position=< 52266, -10262> velocity=<-5, 1> +position=< 52223, 52178> velocity=<-5, -5> +position=< 21019, -20666> velocity=<-2, 2> +position=<-20620, 20958> velocity=< 2, -2> +position=< 21016, 20960> velocity=<-2, -2> +position=< 10593, -10259> velocity=<-1, 1> +position=< 21045, 31365> velocity=<-2, -3> +position=< 10609, 10548> velocity=<-1, -1> +position=< 21016, -20666> velocity=<-2, 2> +position=< 10598, -10265> velocity=<-1, 1> +position=<-41394, 20955> velocity=< 4, -2> +position=<-20612, -10262> velocity=< 2, 1> +position=<-30987, -41489> velocity=< 3, 4> +position=< 52261, 31361> velocity=<-5, -3> +position=< 31408, 31364> velocity=<-3, -3> +position=<-10181, -31076> velocity=< 1, 3> +position=<-20625, -10268> velocity=< 2, 1> +position=< 41846, 10551> velocity=<-4, -1> +position=<-20588, -31074> velocity=< 2, 3> +position=<-41407, 31364> velocity=< 4, -3> +position=<-20577, 41767> velocity=< 2, -4> +position=< 21040, 31361> velocity=<-2, -3> +position=<-20586, -51892> velocity=< 2, 5> +position=<-41386, 31364> velocity=< 4, -3> +position=< 21001, 20953> velocity=<-2, -2> +position=<-51797, -20671> velocity=< 5, 2> +position=<-20620, -41484> velocity=< 2, 4> +position=< 31433, -51887> velocity=<-3, 5> +position=< 10617, 31363> velocity=<-1, -3> +position=< 10598, 52175> velocity=<-1, -5> +position=<-41413, -51891> velocity=< 4, 5> +position=<-41386, -10260> velocity=< 4, 1> +position=<-51846, -20671> velocity=< 5, 2> +position=< 52273, -51892> velocity=<-5, 5> +position=<-51836, -51896> velocity=< 5, 5> +position=<-20596, 20959> velocity=< 2, -2> +position=< 41814, 31360> velocity=<-4, -3> +position=< 10620, -31073> velocity=<-1, 3> +position=<-41438, 31360> velocity=< 4, -3> +position=< 21060, 31361> velocity=<-2, -3> +position=<-20628, -41487> velocity=< 2, 4> +position=<-10185, -51896> velocity=< 1, 5> +position=<-31022, -20671> velocity=< 3, 2> +position=< 31407, 10551> velocity=<-3, -1> +position=< 41830, -51887> velocity=<-4, 5> +position=< 52263, 52177> velocity=<-5, -5> +position=<-41413, -10267> velocity=< 4, 1> +position=< 10653, -10260> velocity=<-1, 1> +position=<-20628, -31074> velocity=< 2, 3> +position=< 41830, -51892> velocity=<-4, 5> +position=<-51822, 20953> velocity=< 5, -2> +position=< 52221, 52181> velocity=<-5, -5> +position=<-20583, -41488> velocity=< 2, 4> +position=<-51813, -31082> velocity=< 5, 3> +position=< 41822, 52175> velocity=<-4, -5> +position=<-41442, -41482> velocity=< 4, 4> +position=<-10172, -31078> velocity=< 1, 3> +position=<-10178, -10263> velocity=< 1, 1> +position=<-51797, 31360> velocity=< 5, -3> +position=< 10650, 31364> velocity=<-1, -3> +position=<-51798, 10550> velocity=< 5, -1> +position=< 31444, -51893> velocity=<-3, 5> +position=< 21008, -51888> velocity=<-2, 5> +position=<-51792, -31078> velocity=< 5, 3> +position=<-30991, 20960> velocity=< 3, -2> +position=< 10606, -10263> velocity=<-1, 1> +position=<-41429, 31363> velocity=< 4, -3> +position=< 41843, 20960> velocity=<-4, -2> +position=< 31423, -51896> velocity=<-3, 5> +position=<-20586, 20957> velocity=< 2, -2> +position=< 21002, -20675> velocity=<-2, 2> +position=< 21056, 20953> velocity=<-2, -2> +position=< 31420, 10549> velocity=<-3, -1> +position=< 21029, 31365> velocity=<-2, -3> +position=< 21048, 20955> velocity=<-2, -2> +position=< 31463, -10264> velocity=<-3, 1> +position=<-31007, -41489> velocity=< 3, 4> +position=<-20595, -20675> velocity=< 2, 2> +position=<-51849, -20673> velocity=< 5, 2> +position=< 41856, -10264> velocity=<-4, 1> +position=<-31011, -20671> velocity=< 3, 2> +position=<-31033, 41767> velocity=< 3, -4> +position=<-10165, 20956> velocity=< 1, -2> +position=<-41418, -20667> velocity=< 4, 2> +position=< 21024, 41775> velocity=<-2, -4> +position=<-20572, 10547> velocity=< 2, -1> +position=<-41383, 52181> velocity=< 4, -5> +position=<-31022, 20956> velocity=< 3, -2> +position=< 31415, -51889> velocity=<-3, 5> +position=<-10184, -51887> velocity=< 1, 5> +position=<-41418, 10548> velocity=< 4, -1> +position=< 52238, 10555> velocity=<-5, -1> +position=<-41439, 10546> velocity=< 4, -1> +position=< 21013, -51887> velocity=<-2, 5> +position=< 52247, 41767> velocity=<-5, -4> +position=<-20599, -51895> velocity=< 2, 5> +position=< 41823, 31364> velocity=<-4, -3> +position=<-41394, 41773> velocity=< 4, -4> +position=<-41394, 10547> velocity=< 4, -1> +position=<-31027, -51893> velocity=< 3, 5> +position=< 31420, 10554> velocity=<-3, -1> +position=< 52258, -10267> velocity=<-5, 1> +position=< 52277, -20672> velocity=<-5, 2> +position=< 10601, -41488> velocity=<-1, 4> +position=< 52258, 31362> velocity=<-5, -3> +position=<-31031, -31078> velocity=< 3, 3> +position=<-30987, -31073> velocity=< 3, 3> +position=<-30990, 41775> velocity=< 3, -4> +position=< 31432, -41489> velocity=<-3, 4> +position=<-31001, 41767> velocity=< 3, -4> +position=<-20588, -20675> velocity=< 2, 2> +position=<-20591, 41769> velocity=< 2, -4> +position=<-31003, 20953> velocity=< 3, -2> +position=<-51793, 52178> velocity=< 5, -5> +position=<-41410, 31361> velocity=< 4, -3> +position=<-20580, 31369> velocity=< 2, -3> +position=<-20594, 31360> velocity=< 2, -3> +position=< 41855, -41487> velocity=<-4, 4> +position=<-10173, 20954> velocity=< 1, -2> +position=< 21016, 20954> velocity=<-2, -2> +position=< 41843, -51888> velocity=<-4, 5> +position=< 52241, -51887> velocity=<-5, 5> +position=<-51816, -31082> velocity=< 5, 3> +position=<-31035, -20666> velocity=< 3, 2> +position=< 41857, 31366> velocity=<-4, -3> +position=< 41814, -51896> velocity=<-4, 5> +position=< 31439, 20957> velocity=<-3, -2> +position=< 21036, 31366> velocity=<-2, -3> +position=<-20615, -41488> velocity=< 2, 4> +position=< 10634, -20674> velocity=<-1, 2> +position=< 52269, 20958> velocity=<-5, -2> +position=<-41441, -20671> velocity=< 4, 2> +position=<-30995, -20670> velocity=< 3, 2> +position=< 41872, -20672> velocity=<-4, 2> +position=< 52222, 31364> velocity=<-5, -3> +position=<-41434, 20956> velocity=< 4, -2> +position=< 41814, 10554> velocity=<-4, -1> +position=< 41833, -41480> velocity=<-4, 4> +position=<-31007, 31368> velocity=< 3, -3> +position=< 10609, -41481> velocity=<-1, 4> +position=<-51844, 41769> velocity=< 5, -4> +position=< 41814, 31361> velocity=<-4, -3> +position=< 41818, 20957> velocity=<-4, -2> +position=< 41859, -51888> velocity=<-4, 5> +position=< 31455, -20667> velocity=<-3, 2> +position=< 21045, 10549> velocity=<-2, -1> +position=< 10609, 10550> velocity=<-1, -1> +position=<-20628, 10552> velocity=< 2, -1> +position=<-41431, -20671> velocity=< 4, 2> +position=< 41858, 52181> velocity=<-4, -5> +position=< 10595, 20953> velocity=<-1, -2> +position=<-10208, 20960> velocity=< 1, -2> +position=<-51817, 10553> velocity=< 5, -1> +position=<-20568, -31074> velocity=< 2, 3> +position=< 52241, 10555> velocity=<-5, -1> +position=< 31452, 41774> velocity=<-3, -4> +position=< 41865, -41485> velocity=<-4, 4> +position=< 10638, -31080> velocity=<-1, 3> +position=<-20571, 31364> velocity=< 2, -3> +position=<-41394, 31363> velocity=< 4, -3> +position=< 31407, 10546> velocity=<-3, -1> +position=< 41870, 31366> velocity=<-4, -3> +position=< 21040, -31074> velocity=<-2, 3> +position=< 10614, -20666> velocity=<-1, 2> +position=<-51801, 52182> velocity=< 5, -5> +position=<-31027, 41767> velocity=< 3, -4> +position=< 31415, -20671> velocity=<-3, 2> +position=<-51817, -41481> velocity=< 5, 4> +position=< 31452, 52177> velocity=<-3, -5> +position=< 21027, -20675> velocity=<-2, 2> +position=<-31035, 20957> velocity=< 3, -2> +position=<-51814, -31077> velocity=< 5, 3> +position=<-20569, 41769> velocity=< 2, -4> +position=< 21013, -51889> velocity=<-2, 5> +position=< 21033, -51892> velocity=<-2, 5> +position=<-10173, -20669> velocity=< 1, 2> +position=<-20596, 41770> velocity=< 2, -4> +position=< 21027, 52183> velocity=<-2, -5> +position=<-41418, -31076> velocity=< 4, 3> +position=< 52264, 52179> velocity=<-5, -5> +position=< 21048, 10551> velocity=<-2, -1> +position=< 52221, 20956> velocity=<-5, -2> +position=<-51793, 20954> velocity=< 5, -2> +position=<-30999, 10550> velocity=< 3, -1> +position=< 41827, -31075> velocity=<-4, 3> +position=<-41423, 10555> velocity=< 4, -1> +position=< 52272, 41771> velocity=<-5, -4> +position=< 21008, 52180> velocity=<-2, -5> +position=<-20595, -31078> velocity=< 2, 3> +position=<-10178, -51890> velocity=< 1, 5> +position=< 21013, 10548> velocity=<-2, -1> +position=<-51793, -41483> velocity=< 5, 4> +position=<-51808, 10547> velocity=< 5, -1> +position=< 21050, -41489> velocity=<-2, 4> +position=<-20599, -41481> velocity=< 2, 4> +position=<-51833, 31367> velocity=< 5, -3> +position=<-51817, -31082> velocity=< 5, 3> +position=<-30995, 31364> velocity=< 3, -3> +position=< 31455, 10546> velocity=<-3, -1> +position=< 31433, 41776> velocity=<-3, -4> +position=<-30995, -10264> velocity=< 3, 1> +position=<-51849, -51889> velocity=< 5, 5> +position=<-31026, 20957> velocity=< 3, -2> +position=< 31468, 31360> velocity=<-3, -3> +position=< 31449, -51893> velocity=<-3, 5> +position=<-41397, 20959> velocity=< 4, -2> +position=<-10181, 10549> velocity=< 1, -1> +position=< 10638, -10268> velocity=<-1, 1> +position=< 41843, -10262> velocity=<-4, 1> +position=<-10189, 52183> velocity=< 1, -5> +position=< 41859, -51893> velocity=<-4, 5> +position=< 41819, -51893> velocity=<-4, 5> +position=< 31431, -10263> velocity=<-3, 1> +position=<-51793, 52179> velocity=< 5, -5> +position=< 10593, -10263> velocity=<-1, 1> +position=< 21040, 31369> velocity=<-2, -3> +position=< 10649, -10267> velocity=<-1, 1> +position=< 41875, -10268> velocity=<-4, 1> +position=<-20600, 10554> velocity=< 2, -1> +position=< 31468, 20953> velocity=<-3, -2> +position=<-31019, 20958> velocity=< 3, -2> +position=<-20624, -51892> velocity=< 2, 5> +position=< 41842, 20953> velocity=<-4, -2> +position=<-20599, -41480> velocity=< 2, 4> +position=< 10645, -51896> velocity=<-1, 5> +position=<-10216, 52175> velocity=< 1, -5> +position=< 21024, 31363> velocity=<-2, -3> +position=< 41870, 10551> velocity=<-4, -1> +position=<-20572, -20672> velocity=< 2, 2> +position=<-20583, 31369> velocity=< 2, -3> +position=<-20586, 31363> velocity=< 2, -3> +position=<-20596, 10549> velocity=< 2, -1> +position=< 31436, 41772> velocity=<-3, -4> +position=<-41418, 20960> velocity=< 4, -2> +position=<-10205, -51889> velocity=< 1, 5> +position=< 10649, -31074> velocity=<-1, 3> +position=< 10622, 20959> velocity=<-1, -2> +position=< 52274, -10268> velocity=<-5, 1> +position=< 52222, -51896> velocity=<-5, 5> +position=< 52266, -31077> velocity=<-5, 3> +position=< 41854, -10259> velocity=<-4, 1> +position=< 31463, -20670> velocity=<-3, 2> +position=< 21045, 10552> velocity=<-2, -1> +position=<-10197, 20955> velocity=< 1, -2> +position=< 31431, -51892> velocity=<-3, 5> +position=< 52250, -10262> velocity=<-5, 1> +position=< 41830, -20672> velocity=<-4, 2> +position=<-20596, -51887> velocity=< 2, 5> +position=<-10203, -41480> velocity=< 1, 4> +position=< 41850, 52174> velocity=<-4, -5> +position=< 10628, 52179> velocity=<-1, -5> +position=<-30986, 31360> velocity=< 3, -3> +position=<-20591, -31074> velocity=< 2, 3> +position=< 52234, -51887> velocity=<-5, 5> +position=<-20604, -51891> velocity=< 2, 5> +position=< 10593, 41768> velocity=<-1, -4> +position=< 31439, 31362> velocity=<-3, -3> +position=< 41859, -51892> velocity=<-4, 5> +position=<-10205, 31369> velocity=< 1, -3> +position=<-31027, 10548> velocity=< 3, -1> +position=< 10633, 10548> velocity=<-1, -1> +position=< 21028, 20953> velocity=<-2, -2> +position=< 21016, 20959> velocity=<-2, -2> +position=< 31434, -10263> velocity=<-3, 1> +position=<-10192, 10555> velocity=< 1, -1> +position=< 52234, 31366> velocity=<-5, -3> +position=< 41822, 31363> velocity=<-4, -3> +position=< 41838, -51895> velocity=<-4, 5> +position=<-31007, 20958> velocity=< 3, -2> +position=<-41402, 31362> velocity=< 4, -3> +position=< 52229, 41769> velocity=<-5, -4> +position=< 10641, -41482> velocity=<-1, 4> +position=<-51804, -41484> velocity=< 5, 4> +position=< 41827, 20962> velocity=<-4, -2> +position=<-10208, -31080> velocity=< 1, 3> +position=< 41826, 41771> velocity=<-4, -4> +position=< 21041, -10266> velocity=<-2, 1> +position=<-51808, -51895> velocity=< 5, 5> +position=<-51841, 41774> velocity=< 5, -4> +position=<-20596, 41774> velocity=< 2, -4> +position=< 41866, 31364> velocity=<-4, -3> +position=< 31407, -20672> velocity=<-3, 2> +position=< 10643, -20671> velocity=<-1, 2> +position=< 41865, 10546> velocity=<-4, -1> +position=<-51792, 10551> velocity=< 5, -1> +position=<-30977, -10262> velocity=< 3, 1> +position=< 31436, 41775> velocity=<-3, -4> +position=< 31443, 20960> velocity=<-3, -2> +position=<-30977, 10549> velocity=< 3, -1> +position=<-31022, -31082> velocity=< 3, 3> +position=<-41434, -41488> velocity=< 4, 4> +position=<-20604, -31074> velocity=< 2, 3> +position=< 52261, 31367> velocity=<-5, -3> +position=< 21029, 20960> velocity=<-2, -2> +position=< 10625, 52174> velocity=<-1, -5> +position=<-41433, 41771> velocity=< 4, -4> +position=< 52269, 20954> velocity=<-5, -2> +position=< 10625, 41768> velocity=<-1, -4> +position=< 41830, 20959> velocity=<-4, -2> +position=< 31431, -10266> velocity=<-3, 1> +position=<-20572, 41774> velocity=< 2, -4> +position=< 52265, -20668> velocity=<-5, 2> +position=< 10595, -41485> velocity=<-1, 4> +position=<-20580, -10264> velocity=< 2, 1> +position=< 52270, -10268> velocity=<-5, 1> +position=<-31019, 31362> velocity=< 3, -3> +position=< 31439, -10262> velocity=<-3, 1> +position=<-20618, 20957> velocity=< 2, -2> +position=<-41407, 31364> velocity=< 4, -3> +position=< 41814, -31080> velocity=<-4, 3> +position=<-10208, -20673> velocity=< 1, 2> +position=< 31412, -20673> velocity=<-3, 2> +position=< 31463, 52183> velocity=<-3, -5> +position=<-30983, -51896> velocity=< 3, 5> +position=< 31447, 10553> velocity=<-3, -1> +position=< 41843, -51895> velocity=<-4, 5> +position=< 31447, -10259> velocity=<-3, 1> +position=<-41438, -31082> velocity=< 4, 3> +position=< 10593, -31078> velocity=<-1, 3> +position=<-30985, 10546> velocity=< 3, -1> +position=<-31027, -41487> velocity=< 3, 4> +position=< 21026, 52174> velocity=<-2, -5> +position=<-51809, 52178> velocity=< 5, -5> +position=<-41429, -10267> velocity=< 4, 1> +position=< 52256, 10551> velocity=<-5, -1> +position=< 52277, 41769> velocity=<-5, -4> +position=<-31000, 41767> velocity=< 3, -4> +position=<-20583, -51887> velocity=< 2, 5> +position=<-20594, 10550> velocity=< 2, -1> +position=<-41393, 20953> velocity=< 4, -2> +position=< 21002, -20671> velocity=<-2, 2> +position=<-10200, 41776> velocity=< 1, -4> +position=< 52258, 31369> velocity=<-5, -3> diff --git a/2018/day11/day11.exs b/2018/day11/day11.exs new file mode 100644 index 0000000..bab29bc --- /dev/null +++ b/2018/day11/day11.exs @@ -0,0 +1,93 @@ +defmodule Day11 do + @serial 7511 + @size 300 + + def hundreds(lvl) when lvl < 100, do: 0 + + def hundreds(lvl) do + [_units, _tens, hundreds | _] = Integer.digits(lvl) |> Enum.reverse() + hundreds + end + + def power_level(x, y, serial) do + rack_id = x + 10 + rack_id |> Kernel.*(y) |> Kernel.+(serial) |> Kernel.*(rack_id) |> hundreds() |> Kernel.-(5) + end + + def grid(serial \\ @serial) do + for x <- 1..@size, y <- 1..@size, into: %{} do + {{x, y}, power_level(x, y, serial)} + end + end + + def total_power(x, y, grid) do + for x <- x..(x + 2), y <- y..(y + 2) do + grid[{x, y}] + end + |> Enum.sum() + end + + def find_largest_3x3(grid) do + for x <- 1..(@size - 2), y <- 1..(@size - 2) do + {{x, y}, total_power(x, y, grid)} + end + |> Enum.max_by(fn {_, power} -> power end) + end + + def part1 do + {{x, y}, power} = grid() |> find_largest_3x3() + "#{x},#{y} (total power #{power})" + end + + # Entry point + def largest_total_power_at(x, y, grid) do + size = 1 + power = grid[{x, y}] + largest_total_power_at(x, y, grid, size, power, size, power) + end + + # Terminating condition, square size has reached the edge of the grid + def largest_total_power_at(x, y, _grid, size, _power, max_size, max_power) + when x + size > @size or y + size > @size do + {x, y, max_size, max_power} + end + + # Calculate extra power for square of size + 1 and take the max of the two + def largest_total_power_at(x, y, grid, size, power, max_size, max_power) do + new_x = x + size + new_y = y + size + new_row = for row_x <- x..new_x, do: grid[{row_x, new_y}] + # Minus 1 to avoid counting the corner twice + new_col = for col_y <- y..(new_y - 1), do: grid[{new_x, col_y}] + new_power = Enum.sum([power | new_row ++ new_col]) + new_size = size + 1 + + {max_size, max_power} = + if new_power > max_power do + {new_size, new_power} + else + {max_size, max_power} + end + + largest_total_power_at(x, y, grid, new_size, new_power, max_size, max_power) + end + + # Still very slow, managed to avoid recalculating larger squares, but still recalculates + # smaller squares that are a subset of a larger square we already calculated. + # Could fix it, but 300x300 completes in a few mins.. maybe will come back to this + # I Wonder if replacing all the comprehensions with reduce would have a strong effect + def part2 do + grid = grid() + + {x, y, size, power} = + for x <- 1..@size, IO.inspect(301 - x), y <- 1..@size do + largest_total_power_at(x, y, grid) + end + |> Enum.max_by(fn {_x, _y, _size, power} -> power end) + + "Part 2 Answer: #{x},#{y},#{size} (power: #{power})" + end +end + +IO.puts(Day11.part1()) +IO.puts(Day11.part2()) diff --git a/2018/day12/day12.exs b/2018/day12/day12.exs new file mode 100644 index 0000000..3e9e807 --- /dev/null +++ b/2018/day12/day12.exs @@ -0,0 +1,101 @@ +defmodule Day12 do + defmodule Parser do + def parse(filename) when is_binary(filename) do + File.open!(filename, [:utf8], &parse/1) + end + + def parse(file) do + IO.read(file, String.length("initial state: ")) + state = file |> IO.read(:line) |> String.trim() |> String.to_charlist() |> Enum.with_index() + IO.read(file, :line) + {state, parse_spec(file)} + end + + def parse_spec(file), do: parse_spec(file, IO.read(file, :line), %{}) + def parse_spec(_file, :eof, spec), do: spec + + def parse_spec(file, line, spec) do + [pattern, <>] = ~r/(.{5}) => (.)/ |> Regex.run(line, capture: :all_but_first) + + parse_spec( + file, + IO.read(file, :line), + Map.put(spec, String.to_charlist(pattern), result) + ) + end + end + + def evolve(input, _spec, 0, _previous), do: input + + def evolve(input, spec, generations, previous) do + next = generation(input, spec) + IO.inspect("#{generations}: #{next |> visualise}") + + if stable?(next, input) do + # Stable state, so we can just add the remaining generation count to the index numbers and finish early + next = Enum.map(next, fn {pot, idx} -> {pot, idx + generations - 1} end) + evolve(next, spec, 0, input) + else + evolve(next, spec, generations - 1, input) + end + end + + def stable?(next, prev), do: visualise(next) === visualise(prev) + + def generation(input, spec) do + input |> pad |> propagate(spec) |> strip + end + + def propagate([a, b, c, d, e | rest], spec) do + {_, pot} = c + pattern = visualise([a, b, c, d, e]) + [{Map.get(spec, pattern), pot} | propagate([b, c, d, e | rest], spec)] + end + + def propagate(rest, _spec) when length(rest) == 4, do: [] + + # Pads with 4 empty pots. If the spec contained ..... => #, would need to pad with 5 + def pad(list) do + list |> Enum.reverse() |> pad_rear |> Enum.reverse() |> pad_front + end + + def pad_front([{?., _}, {?., _}, {?., _}, {?., _} | _] = done), do: done + def pad_front([{_, i} | _] = list), do: pad_front([{?., i - 1} | list]) + + def pad_rear([{?., _}, {?., _}, {?., _}, {?., _} | _] = done), do: done + def pad_rear([{_, i} | _] = list), do: pad_rear([{?., i + 1} | list]) + + # Removes leading and trailing empty pots + def strip([{?., _}]), do: [] + def strip([{?., _} | list]), do: strip(list) + def strip([{?#, _} | _] = list), do: strip_tl(Enum.reverse(list)) + def strip_tl([{?., _} | list]), do: strip_tl(list) + def strip_tl(list), do: Enum.reverse(list) + + def visualise(input) do + Enum.map(input, fn {x, _i} -> x end) + end + + def part1 do + {input, spec} = Parser.parse("input") + + evolve(input, spec, 20, []) + |> Enum.filter(fn {plant, _} -> plant === ?# end) + |> Enum.map(fn {_, pot} -> pot end) + |> Enum.sum() + end + + def part2 do + {input, spec} = Parser.parse("input") + + evolve(input, spec, 50_000_000_000, []) + |> Enum.filter(fn {plant, _} -> plant === ?# end) + |> Enum.map(fn {_, pot} -> pot end) + |> Enum.sum() + end +end + +part1 = Day12.part1() +part2 = Day12.part2() +IO.puts("part 1: #{part1}") +IO.puts("part 2: #{part2}") diff --git a/2018/day12/input b/2018/day12/input new file mode 100644 index 0000000..a0e8bc4 --- /dev/null +++ b/2018/day12/input @@ -0,0 +1,34 @@ +initial state: #.##.##.##.##.......###..####..#....#...#.##...##.#.####...#..##..###...##.#..#.##.#.#.#.#..####..# + +..### => . +##..# => # +#..## => . +.#..# => . +#.##. => . +#.... => . +##... => # +#...# => . +###.# => # +##.## => . +....# => . +..##. => # +..#.. => . +##.#. => . +.##.# => # +#..#. => # +.##.. => # +###.. => # +.###. => # +##### => # +####. => . +.#.#. => . +...#. => # +#.### => . +.#... => # +.#### => . +#.#.# => # +...## => . +..... => . +.#.## => # +..#.# => # +#.#.. => # diff --git a/2018/day13/day13.exs b/2018/day13/day13.exs new file mode 100644 index 0000000..b01338f --- /dev/null +++ b/2018/day13/day13.exs @@ -0,0 +1,179 @@ +defmodule Day13 do + defmodule Cart do + defstruct dir: nil, turn: :left + end + + defmodule Parser do + # track pieces + # | - / \ + + # Carts + # ^ v < > + # Inital cart = straight track underneath + # Sample input: + # /->-\ + # | | /----\ + # | /-+--+-\ | + # | | | | v | + # \-+-/ \-+--/ + # \------/ + def parse_file(filename) do + rows = + File.read!(filename) + |> String.split("\n") + |> Enum.map(&String.to_charlist/1) + + {_, track, carts} = + Enum.reduce(rows, {0, %{}, %{}}, fn row, {row_idx, track, carts} -> + {_, _, track, carts} = Enum.reduce(row, {row_idx, 0, track, carts}, &parse_char/2) + {row_idx + 1, track, carts} + end) + + {track, carts} + end + + defp parse_char(?\s, {row_idx, col_idx, track, carts}) do + {row_idx, col_idx + 1, track, carts} + end + + defp parse_char(cart, args) when cart in '^v<>', do: parse_cart(cart, args) + defp parse_char(track, args) when track in '|-/\\+', do: parse_track(track, args) + + defp parse_cart(?^, {row_idx, col_idx, track, carts}) do + carts = Map.put(carts, {row_idx, col_idx}, %Cart{dir: :up}) + parse_track(?|, {row_idx, col_idx, track, carts}) + end + + defp parse_cart(?v, {row_idx, col_idx, track, carts}) do + carts = Map.put(carts, {row_idx, col_idx}, %Cart{dir: :down}) + parse_track(?|, {row_idx, col_idx, track, carts}) + end + + defp parse_cart(?<, {row_idx, col_idx, track, carts}) do + carts = Map.put(carts, {row_idx, col_idx}, %Cart{dir: :left}) + parse_track(?-, {row_idx, col_idx, track, carts}) + end + + defp parse_cart(?>, {row_idx, col_idx, track, carts}) do + carts = Map.put(carts, {row_idx, col_idx}, %Cart{dir: :right}) + parse_track(?-, {row_idx, col_idx, track, carts}) + end + + defp parse_track(char, {row_idx, col_idx, track, carts}) do + track = Map.put(track, {row_idx, col_idx}, <>) + {row_idx, col_idx + 1, track, carts} + end + end + + # Plan: + # Build a giant coordinate map containing what piece of track is at a coordinate + # (spaces with no track can be skipped) + # Build a separate map of carts + # Carts should contain their location, dir, and next turn + # -> Sort the map each tick to determine cart order + # For a tick, go through each cart and update it's location (key), dir, and next turn + # - if there's a collision, we can stop early and return the location + + def sort(carts) do + Enum.sort(carts, fn {{row1, col1}, _}, {{row2, col2}, _} -> + cond do + row1 < row2 -> true + row1 == row2 -> col1 <= col2 + row1 > row2 -> false + end + end) + end + + def next_pos(row, col, %Cart{dir: :up}), do: {row - 1, col} + def next_pos(row, col, %Cart{dir: :down}), do: {row + 1, col} + def next_pos(row, col, %Cart{dir: :left}), do: {row, col - 1} + def next_pos(row, col, %Cart{dir: :right}), do: {row, col + 1} + + def turn(cart, track) when track in ["-", "|"], do: cart + def turn(%Cart{dir: :left} = cart, "/"), do: %Cart{cart | dir: :down} + def turn(%Cart{dir: :right} = cart, "/"), do: %Cart{cart | dir: :up} + def turn(%Cart{dir: :up} = cart, "/"), do: %Cart{cart | dir: :right} + def turn(%Cart{dir: :down} = cart, "/"), do: %Cart{cart | dir: :left} + def turn(%Cart{dir: :left} = cart, "\\"), do: %Cart{cart | dir: :up} + def turn(%Cart{dir: :right} = cart, "\\"), do: %Cart{cart | dir: :down} + def turn(%Cart{dir: :up} = cart, "\\"), do: %Cart{cart | dir: :left} + def turn(%Cart{dir: :down} = cart, "\\"), do: %Cart{cart | dir: :right} + def turn(%Cart{dir: :left, turn: :left}, "+"), do: %Cart{dir: :down, turn: :straight} + def turn(%Cart{dir: :left, turn: :straight}, "+"), do: %Cart{dir: :left, turn: :right} + def turn(%Cart{dir: :left, turn: :right}, "+"), do: %Cart{dir: :up, turn: :left} + def turn(%Cart{dir: :right, turn: :left}, "+"), do: %Cart{dir: :up, turn: :straight} + def turn(%Cart{dir: :right, turn: :straight}, "+"), do: %Cart{dir: :right, turn: :right} + def turn(%Cart{dir: :right, turn: :right}, "+"), do: %Cart{dir: :down, turn: :left} + def turn(%Cart{dir: :up, turn: :left}, "+"), do: %Cart{dir: :left, turn: :straight} + def turn(%Cart{dir: :up, turn: :straight}, "+"), do: %Cart{dir: :up, turn: :right} + def turn(%Cart{dir: :up, turn: :right}, "+"), do: %Cart{dir: :right, turn: :left} + def turn(%Cart{dir: :down, turn: :left}, "+"), do: %Cart{dir: :right, turn: :straight} + def turn(%Cart{dir: :down, turn: :straight}, "+"), do: %Cart{dir: :down, turn: :right} + def turn(%Cart{dir: :down, turn: :right}, "+"), do: %Cart{dir: :left, turn: :left} + + def crashed?(pos, unmoved_carts, moved_carts) do + Map.get(unmoved_carts, pos) || Map.get(moved_carts, pos) + end + + def tick([], _unmoved_carts, moved_carts, _track), do: {:tock, moved_carts} + + def tick([{{row, col}, cart} | sorted_carts], unmoved_carts, moved_carts, track) do + # This cart is no longer unmoved (so it can't crash into itself) + unmoved_carts = Map.delete(unmoved_carts, {row, col}) + + next_pos = next_pos(row, col, cart) + + if crashed?(next_pos, unmoved_carts, moved_carts) do + {:boom, next_pos} + else + next_track = Map.fetch!(track, next_pos) + moved_cart = turn(cart, next_track) + tick(sorted_carts, unmoved_carts, Map.put(moved_carts, next_pos, moved_cart), track) + end + end + + def find_collision(track, carts) do + case tick(sort(carts), carts, %{}, track) do + {:tock, carts} -> find_collision(track, carts) + {:boom, {row, col}} -> "#{col},#{row}" + end + end + + def part1 do + {track, carts} = Parser.parse_file("input") + find_collision(track, carts) + end + + # Part 2. + # Instead of stopping on a crash, we should instead remove the two carts that crashed. + # Terminating condition is when there is only one cart left. + + def tick2([], _unmoved_carts, moved_carts, _track), do: moved_carts + + def tick2([{{row, col}, cart} | sorted_carts], unmoved_carts, moved_carts, track) do + unmoved_carts = Map.delete(unmoved_carts, {row, col}) + next_pos = next_pos(row, col, cart) + + if crashed?(next_pos, unmoved_carts, moved_carts) do + unmoved_carts = Map.delete(unmoved_carts, next_pos) + moved_carts = Map.delete(moved_carts, next_pos) + # Could have deleted an unmoved, so need to re-sort the remaining carts to process + tick2(sort(unmoved_carts), unmoved_carts, moved_carts, track) + else + next_track = Map.fetch!(track, next_pos) + moved_cart = turn(cart, next_track) + tick2(sorted_carts, unmoved_carts, Map.put(moved_carts, next_pos, moved_cart), track) + end + end + + def find_last_cart(track, carts), do: find_last_cart(track, carts, sort(carts)) + def find_last_cart(_track, _carts, [{{row, col}, _cart}]), do: "#{col},#{row}" + + def find_last_cart(track, carts, sorted_carts) do + find_last_cart(track, tick2(sorted_carts, carts, %{}, track)) + end + + def part2 do + {track, carts} = Parser.parse_file("input") + find_last_cart(track, carts) + end +end diff --git a/2018/day13/input b/2018/day13/input new file mode 100644 index 0000000..af5a7aa --- /dev/null +++ b/2018/day13/input @@ -0,0 +1,150 @@ + /--------------------------------------------------------------------------------------------------------\ + | /--------------------------------------------------\ /----------------------------+\ + | | | | /------------------------++-----\ + /-------------------------\ | /+--------------------------------------------------+----\ | | || | + | /---------------------+--+----++-\ /------------------------------------+----+-------------+---+--------------------\ || | + | | /+--+----++-+-----------+-----\ /+----+-------------+--\| /------------+---++----\| + | /+--------------------++--+----++-+-----------+----\| || | | || /-----+------------+-\ || || + /------+--++--------------------++\ | || | /----+----++-----------------------------++----+-------------+--++\| | | | || || + | | || /----------------+++-+----++-+------+----+----++--------------------\ || | | |||| | | | || || + | | || | ||| | || | | | || /----------+--------++----+-------------+--++++-----+---------\ | | || || + | | || | ||| | || | | |/---++---------+----------+--------++----+-------------+--++++-----+---------+--+-+-++--\ || + |/-----+--++---+---\ ||| | || | | || || /-----+----------+--------++----+-------------+--++++-----+----\ | | | || | || + || | || | | ||| | /--++-+------+----++---++---+-----+----------+--------++--<-+-------------+--++++-----+--\ |/---+--+-+-++--+\|| + || | || | | ||| | | \+-+------+----++---++---+-----+----------+--------++----/ | |||| | | || | | | || |||| + || | || | | ||| | | | | | /-++---++---+-----+----------+--------++----------------\ | |||| | | || | | | || |||| + || | || | | ||| | | | | | | || || | | /+--------++----------------+-+--++++-----+--+-++--\| | | || |||| + || | || /+---+------------+++-+-+---+\| | | || || | | ||/-------++----------------+-+--++++---\ | | || || | | || |||| + || \--++--++---+------------+/| | | ||| | | || || | | ||| || | | |||| | | | || || | | || |||| + || || || | | | \-+---+++------+--+-++---++---+-----+---------+++-------++----------------+-+--++++---+-+--+-++--++--+-+-/| |||| + || /----++--++---+------------+-+---+---+++------+--+-++---++---+---\ | /-------+++-\ || | | |||| | | | || || | ^ | |||| + || | || || | \-+---+---+++------+--+-++---+/ | | | | ||| | \+----------------+-+--/||| | | | || || | | | |||| + || | || || | /---------+--\| ||| | /+-++---+----+---+-+-+-------+++-+------+----------------+-+---+++---+-+-\| || || | | | |||| + || | || || | | | /++---+++---\ | || ||/--+----+---+-+-+-------+++-+------+------------\ | | ||| | | || |\--++--+-+--+--+/|| + || | || || | | | ||| /+++---+--+-++-+++--+\ | | | | ||| | | | | | ||| | | || | || | | | | || + || | /--++--++---+----+---------+-+++--++++---+--+-++-+++--++---+---+-+-+-------+++-+------+----\ | | | ||| | | || | || | | | | || + || | | || || |/---+---------+-+++--++++---+--+-++-+++--++-\ | | | | ||| | | | | | | ||| | | || | || | | | | || + || | | || |\---++---+---------+-+++--++++---+--+-++-+++--++-+-+---+-+-+-------+/| | | | | | | ||| | | || | || | | | | || + || | | || | || | /--+-+++--++++---+--+-++-+++--++-+\| | | | | | | /--+----+-------+---+-+---+++---+-+\|| | || | | | | || + || \-+--++--+----++---+------+--+-+++--++++---+--+-++-+++--++-+++---/ | | /--+-+-+---+--+-\ | | | \---+++---+-++++-+---++--+-+--/ | || + || | || /+----++---+------+--+-+++--++++---+--+-++-+++--++-+++-----+-+----+-\| | | | | | | | | ||| | |||| | || | | | || + || | || || || | | | ||| |||| | | || ||| || ||| | | | || | | | | | | /-----+---+--\ ||| | |||| | || | | | || + || | || || || | | | ||| |||| | | |^ ||| || ||| | | | || | | | | | | | v | | ||| | |||| | || | | | || + || | || || /-++---+------+--+-+++--++++--\| | || ||| || ||| | | | || | | | | | | | | | | ||| | |||| | || | | | || + || | || || | || | | | ||| |||| || | || ||| ||/+++-----+-+----+-++-+\| | |/+--+-+-----+\ | | ||| | |||| | || | | | || + || | || || | || | | | ||| |||| || | || ||| |||||| \-+----+-++-+++---+--+++--+-+-----++--+--+--+++---+-++++-+---+/ | | | || + ||/----+--++-++--+-++\ | | | ||| |||| || | || ||| |||||| | | || ||| | ||| | | || | | ||| | |||| | | | | | || + ||| | || || | ||| | | | ||| |||| || | || ||| |||||| | | || ||| | ||| | | v| | |/-+++---+-++++-+---+---+-+-----+\|| + ||| | || || | ||| | | | ||| |||| || | || ||| |||||| | | || \++---+--+++--+-+-----++--+--++-+++---/ |||| | | | | |||| + ||| | || || v ||| | | | ||| |||| || | || ||| |||||| | | || || | ||| | | || | || ||| |||| | | | | |||| + ||| | || || | ||| | | | ||| |||| || | || ||| |||||| /---+----+-++--++---+--+++--+-+--<--++--+--++-+++-\ |||| | | | | |||| + ||| | || || | ||| | | | |||/-++++--++--+-++-+++--++++++---+---+----+-++--++---+--+++--+-+-----++-\| || ||| | |||| | | | | |||| + ||| | || || | ||| | | | |||| |||| || | || ||| /++++++---+---+----+-++--++---+--+++--+-+---\ || || || ||| | |||| | | | | |||| + ||| | || || | ||| | | | |||| |||| || | \+-+++-+++++++---+---+----+-++--++---+--+++--+-+---+-++-++--++-+++-+---++/| | | | | |||| + ||| | \+-++--+-+++--+------+--+-++++-++++--++--+--+-+++-+/||||| | | /-+-++--++---+--+++--+-+---+-++-++--++-+++-+---++-+-+-<-+---+\| |||| +/+++----+---+-++--+-+++--+------+--+-++++-++++--++--+--+-+++-+-+++++---+---+--+-+-++--++---+--+++--+-+-\ | || || || ||| | || | | | ||| |||| +|||| | | || | ||| | | | |||| |||| || | | ||| | ||||| | | | | || || | ||| | | | | || || || ||\-+---++-+-+-<-+---++/ |||| +|||| | | \+--+-+++--+------+--+-++++-++++--++--+--+-+++-+-+++++<--+---+--+-+-/| || | ||| | | | | || || || || | || | | | || |||| +||||/---+---+--+--+-+++--+------+-\| |||| |||| ||/-+--+-+++-+-+++++---+---+--+-+--+--++---+--+++--+-+-+-+-++-++--++-++--+---++-+-+---+---++--\ |||| +|||||/--+---+--+--+-+++--+------+-++-++++-++++--+++-+\ | ||| | ||||| /-+--<+--+-+--+--++--\| ||| | | | | || || || || | || | | | || | |||| +|||||| | | | | ||| | | || |||| |||| ||| || | ||| | ||||| | | | | | | || |\--+++--+-+-+-+-++-++--++-++--+---+/ | | | || | |||| +|||||| | \--+--+-+++--+------+-++-++++-+++/ ||| || | |\+-+-+++++-+-+---+--+-+--+--++--+---+++--+-+-+-+-++-++--++-++--+---+--+-+---+---++--+---/||| +|||||| | | /+-+++--+------+-++-++++-+++---+++-++-+-+-+-+-+++++-+-+---+--+-+--+--++--+---+++\ | | | | || || || || | | | | | || | ||| +|||||| | | || ||| | | ||/++++-+++---+++-++-+-+-+-+-+++++-+-+---+--+-+--+--++--+---++++-+-+-+-+-++-++--++\|| | | | | | || | ||| +|||||| | | || ||| | | ||||||| ||| ||| || | | | \-+++++-+-+---+--+-+--+--++--+---++++-+-+-+-//++-++--+++++\ | | | | | || | ||| +|\++++--+------+-++-+++--+------+-+/||||| ||| ||| || | | | ||||| | | \--+-+--+--+/ | |||| | | | ||| || |||||| | | | | | || | ||| +| |||| | | || ||| | | | ||||| ||| ||| || | | | ||||| | | /----+-+--+--+---+---++++-+-+-+--+++-++\ |||||| | | | | | || | ||| +| |||| | | || ||| | |/+-+++++-+++---+++-++-+-+-+---+++++-+-+-+---\| | | | | |||| | | | ||| ||| |||||| | | | | | || | ||| +| |||| | | || ||| | ||| ||||| |\+---+++-++-+-+-+---+++++-+-+-+---++-+--+--+---+---/||| | | | ||| ||| |||||| | | | | | || | ||| +| |||| | | || ||| | ||| ||||| |/+---+++-++-+-+-+---+++++-+-+-+---++-+--+--+---+----+++-+-+-+\ ||| ||| |||||| | | | | | || | ||| +| ||||/-+------+-++\||| | /--+++-+++++-+++-\ ||| || | |/+---+++++-+-+-+---++-+--+--+---+----+++-+-+-++-+++-+++-++++++-+---+--+-+---+---++--+-\ ||| +| ||||| | | |||||| | | ||| ||||| ||| | ||| || | ||| ||||| | | | || | | | | ||| |/+-++-+++-+++-++++++-+---+--+-+-\ | || | | ||| +|/+++++-+------+-++++++--+---+--+++-+++++-+++-+-+++-++-+-+++---+++++-+-+-+---++-+--+-\| | ||| ||| || ||| ||| |||||| | | | | | | || | | ||| +||v|||| | | |||||| | | ||| |||||/+++-+-+++-++-+-+++---+++++-+-+-+---++-+--+-++---+----+++-+++-++-+++-+++-++++++-+---+--+-+-+-+---++-\| | ||| +||||||| \------+-++++++--+---+--+++-+++++++++-+-+++-++-+-+++---+++++-+-+-+---++-+--+-++---+----+++-/|| || ||| ||| |||||| | | | | | | || || | ||| +||||||| | |||||| | | ||| ||||||||| | ||| || | ||| /-+++++-+-+-+---++-+--+-++--\| |||/-++-++-+++\||| |||||| | | | | | | || || | ||| +||\++++--------+-+++/|| | | ||| ||||||||| | ||| \+-+-+++-+-+++++-+-+-+---++-+--+-++--++----++++-++-++-+++++++-++++/| | | | | | | || || | ||| +|| |||| /------+-+++-++--+---+--+++-+++++++++-+-+++--+-+-+++-+-+++++-+-+\| || | | || || |||| || || ||||||| |||| | | | | | | | || || | ||| +|| |||| | | ||| || | | ||| ||||||||| | ||| | | ||\-+-+++++-+-+++---++-+--+-++--++----++++-++-++-+/||||| |||| | | | | | | | || || | ||| +|| |||| | | ||| || | | ||| ||||||||| | ||| | | || | ||||| | ||| || | | || || |||| || || | ||||| |||| | | \--+-+-+-+---++-++-+--+/| +||/++++-+------+-+++-++--+---+--+++-+++++++++-+-+++--+-+-++--+-+++++\| ||| || | | || ||/---++++-++-++\| ||||| |||| | | | | | | || || | | | +||||||| | | ||| || | | ||| |||||||||/+-+++--+-+-++--+-+++++++-+++---++-+--+-++--+++--\|||| || |||| ||||| |||| | | | | | | || || | | | +||||||| | | ||| || | | /+++-+++++++++++-+++--+-+-++--+-+++++++-+++---++-+--+-++--+++--+++++-++-++++-+++++-++++-+-+-\ | | | | || || | | | +||||||| | | |\+-++--+---+-++++-+++++++++++-/|| | | \+--+-+++++++-+++---++-+--+-++--+++--+++++-++-++++-+++++-++++-+-+-+----+-+-+-+---/| || | | | +||||||| | | | | || | | |||| ||||||||||| || | | | | ||||||| ||| || | | || ||| ||||| || |||| ||||| |||| | | | | | | | | || | | | +||||||| | | | | || | | |||| ||||||||||| || | \--+--+-+++++++-+++---++-+--+-++--+++--+++++-++-++++-+++/| |||| | | | | | | | | || | | | +|||||||/+------+-+-+-++\ | | |||| ||||||||||| || | | | ||||||| ||\---++-+--+-++--+++--+++++-++-++++-+++-/ |||| |/+-+----+-+-+-+----+-++-+-\| | +||||||||| | | | ||| | | |||| ||||||||||| || | | | ||||||| || || | | || ||| ||||| || |||| ||| |||| ||| | | | | | | || | || | +||||||||| | | | ||| | /+-++++-+++++++++++--++--+----+--+-+++++++-++----++-+--+-++--+++--+++++-++-++++-+++---++++-+++-+----+-+\| | | || | || | +||||||||| | | | ||| | || |||| ||||||||||| || | | | ||||||| || || \--+-++--+++--++/|| || |||| ||| |||| ||| | | ||| | | || | || | +||||||||| | | | ||| | |\-++++-++++++++++/ || | /--+--+-+++++++-++----++----+-++--+++--++-++-++-++++-+++---++++-+++-+----+-+++-+-\ | || | || | +||||||||| | | | ||| | | |||| |||||||||| || | | | | ||||||| || || | || ||| || || || |||| ||| |||| ||| | | ||| | | | || | || | +||||||||| | | | ||| | | |||| |||||||||| || | | | | ||||||| \+----++----+-++--+++--++-++-++-++++-+++---++++-++/ | | ||| | | | || | || | +||||||||| | | | ||| | | |||| |||||||||| ||/-+-+--+--+-+++++++--+----++----+-++--+++\ |\-++-++-++++-/|| |||| || | | ||| | | | || | || | +||||||||| | | | ||| | | |||| |||||||||| ||| | | | | ||||||| | || | || |||| | || || |||| || |||| || | | ||| | | | || | || | +||||||||| | | | ||| | | |||| |||||||||\---+++-+-+--+--+-+++++++--+----++----+-++--++++-/ || || |||| || |||| || | | ||| | | | || | || | +||||||||| | | | ||| | | |||| ||||||||| ||| | |/-+--+-+++++++--+-\ || | || |||| || || |||| || |||\-++--+----+-+++-+-+--+-++-+-++-/ +||||||||| | | | ||| |/-+--++++-+++++++++----+++-+-++-+--+-+++++++--+-+--++--\ | || |||| || || |||| || ||| || | | ||| | | | || | || +||||||||| | | | ||| \+-+--++++-++/|||\++----+++-+-++-+--+-/|||||| | | || | | || ||||/---++-++-++++--++---+++\ || | | ||| | | | || | || +||||||||| | | | ||| | |/-++++-++-+++-++----+++-+-++-+--+--++++++--+-+--++--+-+-++--+++++---++-++-++++--++---++++-++--+\ | ||| | | | || | || +||||||||\------+-+-+-+++--+-++-++++-++-+++-++----+++-+-++-+--+--++++++--/ | || | | || ||||| || || |||| || /++++-++--++---+-+++-+-+--+-++\| || +|||||||| /---+-+-+-+++--+-++-++++-++-+++-++----+++-+-++-+--+--++++++----+--++--+-+\|| ||||| || || ||^| || ||||| || || | ||| | | | |||| || +|||||||| /+---+-+-+-+++--+-++-++++-++-+++-++----+++-+-++-+--+\ |||||\----+--++--+-++++--+/||| || || |||| || ||||| || || | ||| | | | |||| || +|||||\++--++---+-+-+-+++--+-++-++++-++-+++-++----+++-/ || |/-++-+++++-----+--++--+-++++--+-+++---++-++-++++--++--+++++-++\ || | ||| | | | |||| || +||||| || || | | | ||| | || |||| || ||| || ||| || || || ||||| | || | \+++--+-+++---++-++-++++--++--+++++-+++-++---+-+++-/ | | |||| || +||||| || || | |/+-+++--+-++-++++-++-+++\|| ||| || || || ||||| | || | ||| | ||| || \+-++++--++--+++++-+++-++---+-++/ | | |||| || +||||| || || | ||| ||| | || |||| || |||||| ||| || || || ||||| | || | ||| | ||| /-++--+-++++--++--+++++-+++-++--\| || | | |||| || +||||| || || | ||| ||| | || |||| || |||||| |\+---++-++-++-+++++-----+--++--+--+++--+-+++-+-++--+-++++--++--+++++-+++-++--++-++----+--+-+/|| || +\++++-++--++---+-+++-+++--+-++-++++-++-++++++----+-+---++-++-++-+++++-----+--++--+--+++--+-+++-+-++--+-/||| || ||||| ||| || || || | | | || || + |||| \+--++---+-++/ ||| | || |||| || |||||| | | || || || ||||| | || | ||| | ||| | || | ||| || ||||| ||| || || || | | | || || + |||| |/-++---+-++--+++--+-++-++++-++-++++++---\| | || || || ||||| | || | ||| | ||| | || | ||| || ||||| ||| || || || | | | || || + |||| || || | || ||| | || |||| || |||||| || | || || || ||||| | |\--+--+++--+-+++-+-++--+--+++--++--+++++-+++-++--++-++----+--/ | || || + |||| || || | || ||| | || |||| || |||||| || | || || || ||||| | | | ||| | ||| | || | ||| || \++++-+++-++--++-++----+----+-/| || + |||| || || | || ||| | || |||| || |||||| || | || ||/++-+++++-----+--+---+--+++--+-+++-+-++--+--+++--++---++++-+++\|| || || | | | || + |||| || || | || ||| | |\-++++-++-++++++---++-+---++-+++++-+++++-----+--+---+--+++--+-+++-+-++--+--+++--++---++++-+++++/ || || | | | || + |||| || || | || ||| | | |||| || |||||| || | || ||||| ||||| | | | ||| | ||| | || | ||| || |||| ||||| || || | | | || + |||| || || | || ||| | | |||| || ||||\+---++-+---++-+++++-+++++-----+--+---+--+++--+-+++-+-++--+--/|| || |||| |\+++---++-++----+----+--+-/| + |||| || || | || ||| | | |||| |\-++++-+---+/ | /-++-+++++\||||| | | | ||| | ||| | || | || || |||| | ||| || || | | | | + |||| || |\---+-++--+++--+-+--++++-+--++++-+---+--+-+-++-+++++++++++-----+--+---+--/|| | ||| | || |/--++--++\ |||| | ||| || || | | | | + |||| || | | || ||| | | |||| | \+++-+---+--+-+-++-+++++++++++-----+--+---+---++--+-+++-+-++--++--++--+++--++++-+-+++---+/ || | | | | + |||| || | | || ||| | | |||| | ||| | | | | || \++++++++++-----+--+---+---++--+-+++-+-++--++--++--+++--++++-+-+++---+--++----+----+--/ | + |||| || | | || ||| | | |||| | \++-+---+--+-+-++--++++++++++-----+--+---+---++--+-+++-+-++--++--++--+/| |||| | ||| | || | | | + |||| || | | || ||| \-+--++++-+----++-+---+--+-+-++--++++++++++-----+--+---/ || | ||| \-++--++--++--+-+--++++-+-+++---/ || | | | + |||| || | | || ||| | ||||/+----++-+---+--+-+-++--++++++++++-----+--+-------++--+-+++---++--++--++-\| | |||| | ||| || | | | + |||| || \----+-++--+++----+--++++++----++-+---+--+-+-++--+++/|\++++-----+--+-------+/ | ||| || || || || | |||| | ||| || | | | + |||| || | || ||| | |||||| || | | | | || ||| | |||| | | | | ||| || || || || | |||| | ||| || | | | + |||| || | || ||| | |||||| || | | | | || ||| | |||| | | | | ||| || || || || | |||| | ||| || | | | + |||| || | || ||| | |||||| || | | | | || ||| | |||| | | | | ||| || || || || |/-++++-+-+++------++----+----+\ | + |||| || | || ||| | |\++++----++-+---+--+-+-++--+++-+-+/|| | | | | ||| || || || || || |||| | ||| || | || | + |||| || \-++--+++----+--+-++++----++-/ | | | || ||| | | \+-----+--+-------+---+-+++---++--++--++-++-++-++++-+-+++------/| | || | + |||| || || ||| | | |||| || | | \-++--+++-/ | | | | | | ||| || || || || || |||| | ||| | | || | + |||| || || /+++----+--+-++++----++-----+--+---++--+++---+--+-\ | | |/--+-+++---++--++--++-++-++-++++-+-+++-------+----+----++-\ | + |||| || || |||| | | |||| || | | || ||| | | | | | || | ||\>--++--++--++-++-++-+++/ | ||| | | || | | + |||| || || |||| | | ||\+----++-----+--+---++--+++---+--+-+---+--+-------++--+-++----++--++--++-/| || ||| | ||| | | || | | + |||| || || |||| | | || | || | | \+--+++---+--+-+---+--+-------++--+-++----++--++--++--+-++-+++--+-+++-------+----/ /--++-+--+\ + |||| || || |||| | \-++-+----++-----+--+----+--+++---+--+-+---+--+-------++--+-++----++--++--++--+-++-+++--+-++/ | | || | || + |||| || || |||| | ||/+----++-----+--+----+--+++---+--+-+---+--+------\|| | || || || || | || ||| | || | | || | || + |||| || || |\++----+----++++----++-----+--+----+--+++---/ | | | | ||| | || || || |\--+-++-+++--/ || | | || | || + |||| || || | || | |||| || | | | ||| | | | | ||| | || || || | | || ||| || | | || | || + |||| || |\-+-++----+----++++----+/ | | | ||| | | | | ||| |/++----++--++--+---+-++-+++----++--------+-\ | || | || + ||\+--++--------+--+-/| | |||| /--+-----\| | | ||| | | | | ||| |||| || || | | || ||| || | | | || | || + || | || | | | | |||| | | || | | ||| | | | | ||| |||| || || | | || ||| || | | | || | || + || | || | | | | /--++++-+--+-----++--+----+--+++------+<+---+\ | ||| |||| || || | | |\-+++----++--------+-+----+--+/ | || + || | || v | | | | \+++-+--+-----++--+----+--+++------+-+---++-/ ||| |||| || \+--+---+-+--/|| || | | | | | || + \+-+--++--------+--+--+----+-+---+++-+--+-----++--+----+--+++------+-+---++--------+/| |||| || | | | | || || | | | | | || + | | || | | | | | ||| | | || | | ||| | | || | | ||\+----++---+--/ | | || || | | \--+--+--+/ + | | |\--------+--+--+----+-+---+++-+--+-----+/ \----+--+++------+-+---++--------+-+--++-/ || | | | || || | | | | | + | | | | | | | | ||\-+--+-----+--------+--+++------+-+---++--------+-+--++------++---+------+-+---+/ || | | | | | + | | | | | | | | || | \-----+--------+--+++------+-+---++--------+-+--++------++---+------+-+---+-----++--------+-+-------/ | | + | | | \--+--+----+-+---++--+--------+--------+--+++------+-+---++--------+-+--++------/| | | | | || | | | | + | | | | | \-+---++--+--------+--------+--+++------+-+---++--------+-+--++-------+---+------+-+---+-----++--------/ | | | + | | | | | \---++--+--------+--------+--+++------+-+---+/ | | || | \------+-/ | || | | | + | | | \--+----------++--+--------+--------+--+++------+-/ | | | || | | | || | | | + | | | | || | | | \++------+-----+---------+-+--++-------+----------+-----+-----/| | | | + \-+--+---------------+----------++--+--------+--------+---++------/ | | | || | | | | | | | + \--+--------------<+----------/\--+--------+--------+---++------------+---------/ | || | | \------+----------+----------+--/ + | | | | \---++------------/ \--++-------+----------+------------+----------+----------/ + | | \--------/ || || \----------/ | | + | | \+---------------------------++-------------------------------/ | + \---------------/ | || | + \---------------------------/\------------------------------------------/ diff --git a/2018/day13/test b/2018/day13/test new file mode 100644 index 0000000..45af070 --- /dev/null +++ b/2018/day13/test @@ -0,0 +1,6 @@ +/->-\ +| | /----\ +| /-+--+-\ | +| | | | v | +\-+-/ \-+--/ + \------/ diff --git a/2018/day13/test2 b/2018/day13/test2 new file mode 100644 index 0000000..ecf7adf --- /dev/null +++ b/2018/day13/test2 @@ -0,0 +1,7 @@ +/>-<\ +| | +| /<+-\ +| | | v +\>+/ diff --git a/2018/day14/day14.exs b/2018/day14/day14.exs new file mode 100644 index 0000000..5b465e6 --- /dev/null +++ b/2018/day14/day14.exs @@ -0,0 +1,155 @@ +defmodule Day14 do + # Cyclical linked list + # Use a map, with a ref as the key. + # Each element contains the value, and next pointer + # Keep two pointers for the current recipies + defmodule Recipe do + defstruct ~w/score next/a + end + + defmodule State do + defstruct ~w/recipes first_elf second_elf last target count target_count last_seq desired_sequence/a + end + + def init(target_count) do + desired_sequence = + target_count + |> Integer.to_string() + |> String.split("", trim: true) + |> Enum.map(&String.to_integer/1) + |> List.to_tuple() + + last_seq = + (for(_i <- 1..(tuple_size(desired_sequence) - 2), do: nil) ++ [3, 7]) + |> List.to_tuple() + + first_elf = System.unique_integer() + second_elf = System.unique_integer() + + %State{ + first_elf: first_elf, + second_elf: second_elf, + last: second_elf, + target: nil, + target_count: target_count, + count: 2, + desired_sequence: desired_sequence, + last_seq: last_seq, + recipes: %{ + first_elf => %Recipe{score: 3, next: second_elf}, + second_elf => %Recipe{score: 7, next: first_elf} + } + } + end + + def combine_recipes(a, b) do + (a + b) + |> Integer.to_string() + |> String.split("", trim: true) + |> Enum.map(&String.to_integer/1) + end + + def append_score(score, %{last: prev_last, recipes: recipes} = state) do + last_seq = + state.last_seq + |> Tuple.delete_at(0) + |> Tuple.append(score) + + last = System.unique_integer() + + updated_recipes = + recipes + |> Map.put(prev_last, %Recipe{recipes[prev_last] | next: last}) + |> Map.put(last, %Recipe{score: score, next: recipes[prev_last].next}) + + state = %State{ + state + | last: last, + recipes: updated_recipes, + count: state.count + 1 + } + + state = + if state.count === state.target_count do + %State{state | target: last} + else + state + end + + if state.last_seq === state.desired_sequence do + state + else + %State{state | last_seq: last_seq} + end + end + + def next_recipe(current, 0, _recipes), do: current + + def next_recipe(current, steps, recipes) do + next_recipe(recipes[current].next, steps - 1, recipes) + end + + def next_recipes(%{first_elf: first_elf, second_elf: second_elf, recipes: recipes} = state) do + %State{ + state + | first_elf: next_recipe(first_elf, recipes[first_elf].score + 1, recipes), + second_elf: next_recipe(second_elf, recipes[second_elf].score + 1, recipes) + } + end + + # Set the target pointer when the target count is reached + def set_target(%{count: target, last: last} = state, target), do: %State{state | target: last} + def set_target(state, _target), do: state + + def compute_recipes(%{count: count, target_count: target} = state) when count >= target + 10, + do: state + + def compute_recipes(%{first_elf: elf1, second_elf: elf2, recipes: recipes} = state) do + combine_recipes(recipes[elf1].score, recipes[elf2].score) + |> Enum.reduce(state, &append_score/2) + |> next_recipes() + |> compute_recipes() + end + + def next_ten_scores(_recipes, _current, scores, 10), do: scores + + def next_ten_scores(recipes, current, scores, count) do + next = recipes[current].next + scores = scores <> Integer.to_string(recipes[next].score) + next_ten_scores(recipes, next, scores, count + 1) + end + + def part1 do + state = init(330_121) |> compute_recipes() + next_ten_scores(state.recipes, state.target, "", 0) + end + + # Part 2 + # Produce recipes until the last 6 are the puzzle input + # Then the answer is the count before those 6 + def find_sequence(%{desired_sequence: desired, last_seq: desired, count: count}) do + count - tuple_size(desired) + end + + def find_sequence(%{first_elf: elf1, second_elf: elf2, recipes: recipes} = state) do + if rem(state.count, 100_000) == 0 do + IO.puts((state.last_seq |> Tuple.to_list() |> Enum.join()) <> " (#{state.count})") + end + + combine_recipes(recipes[elf1].score, recipes[elf2].score) + |> Enum.reduce(state, &append_score/2) + |> next_recipes() + |> find_sequence() + end + + # TODO both 1245 and the actual answer are +1. Fix. + def part2 do + IO.puts("tests...") + init(51589) |> find_sequence |> IO.puts() + init(1245) |> find_sequence |> IO.puts() + init(92510) |> find_sequence |> IO.puts() + init(59414) |> find_sequence |> IO.puts() + IO.puts("answer: (after about 20M items)...") + init(330_121) |> find_sequence + end +end diff --git a/2018/day2/input b/2018/day2/input new file mode 100644 index 0000000..9b3bd1a --- /dev/null +++ b/2018/day2/input @@ -0,0 +1,250 @@ +kbqwtcvzgumhpwelrnaxydpfuj +kbqwtcvzgsmhpoelryaxydiqij +kbqwpcvzssmhpoelgnaxydifuj +kbqgtcvxgsmhpoalrnaxydifuj +kbqwtcvygsmhpoelrnaxydiaut +kbqwtcvjgsmhpoelrnawydzfuj +kbqftcvzgsmhpoeprnaxydifus +rbqwtcgzgsxhpoelrnaxydifuj +kbqwtlvzgvmhpoelrnaxkdifuj +kbqwtcvzgsmhpolqrnaxydifub +kbqbtcqzgsmhposlrnaxydifuj +kbqwmcvzgswhpoelxnaxydifuj +kbqwtyvzgsmhkoelrnsxydifuj +khqwtcvzgsmhqoelinaxydifuj +koqwtcvzcsmhpoelrnaxydizuj +kbqwtcvzlsmhpoezrnaxydmfuj +kbqwtcvzdsmhpoelrjaxydifij +kbqwtcvzgsmhpoelrncxyjifuk +kbtwtcvzgsmhpoelonaxydiwuj +kbqwfcrzgsmhpoelrnaeydifuj +kbqutcvkgsmhpoelrnfxydifuj +kbqwtcvzgsmvvoelrnaxydihuj +kbqwtcvzhymhpoelrnaxydifyb +kbqctcvzgumhpoalrnaxydifuj +kuqktcvzgsmhpoelrnaxydieuj +kbqwtcvzgsmvpozlrnaxydifmj +kbqwtcvzgsmhpojlraaxydiouj +kbqwtcvzgmmhpoelknaxydizuj +kbwwtcvzgsmhpoefrnaxydifij +kbqwucvzgsmhpoelvnahydifuj +kbqwtcvzpsmhpgelrqaxydifuj +kblqtcvzgsmhpoeirnaxydifuj +kbqwtcvzgsmhpovlrnabydifum +kbqwwcvzgsmhpoelrnaoydnfuj +kyqwdcvzgsmhpoelrnaxfdifuj +kbqftcvzgsmxpoelknaxydifuj +kbqwtsvzksmhpoelqnaxydifuj +kbqwtcvzgsmhplelrnauydifux +kbqytcvzgsmhpkelrnaxydefuj +kbqwtcvzgsmjjoelrlaxydifuj +kbqvtcvzgsmhpoelnnaxydafuj +kbqwtcvzgsjhioelrnaxpdifuj +kbqptcvpgsmhpoelrnaxydiful +kbqwjcazgimhpoelrnaxydifuj +kbqxtcvzgwmhpaelrnaxydifuj +kbqwtcezgsmhqoelrnaxydifub +kbqwtcvzgsmhooelynaxydifuf +kbqwtwvzgsmkpoelrnaxrdifuj +nbqwtcvugsmhpoelrnzxydifuj +kbvwqcvzgsmhpoelsnaxydifuj +kbqwtcyzjsmhpoelrnaxymifuj +kbqwtcvzgsmhpoclrnaxykzfuj +kbbwtcvzgsmhyodlrnaxydifuj +kbwwtcvzgsmytoelrnaxydifuj +kbmwtcczgpmhpoelrnaxydifuj +ubqwtcvzgsmmpoblrnaxydifuj +kbqwtcvzgrmhpoelrnaxnrifuj +kbqwhcvzgsmhpoelynaaydifuj +kbqwtcvzgsmtpoelrcpxydifuj +kdqwtchzgsmhpoelrmaxydifuj +qbqrncvzgsmhpoelrnaxydifuj +kbqwtcvzghshpoelrnaxodifuj +kbqwhcvzgsmhpoelknaxydiwuj +ebqwtcvzgsmhpoelrotxydifuj +kbqwacvzusmhpoelryaxydifuj +kbqwtcvggsmhpoelrnaxygifyj +kbqwtcvzgsmhpoelrnaxycwfuo +kzqwzcvzgsmhpoelrxaxydifuj +khqwtcvzgsmhpoelrnaxldifyj +kbqwtbtzgsmhpoelrnaxydifud +gbqwtcvzgqmhpoelrnaxydifrj +kbqdtqvzgwmhpoelrnaxydifuj +kbqwscvzgsmhpoelrpaxypifuj +kmqwtcdzgsmhpoelenaxydifuj +klqwtcvvgsmhpoelrfaxydifuj +kbuwtcvzgsmhpoelrtaxyuifuj +kbqwtcvrgomhpoelrnaxydijuj +kbqwtgvzgsmhzoelrnpxydifuj +kbqltcvzgsmhooeljnaxydifuj +kbqwtcvzgbmxpoelrnaxydivuj +kbqdtcmzgsmhpoelrnaxydmfuj +kbqwtcazgsmhpoplrnacydifuj +kbqztcvegsmhpoelrnvxydifuj +kbqwtcvzgsmhpoecrnaxydzfsj +kbqwtcvzgsmepoelrnaqydifuf +kbqwtcqzgsmhpoelrnoxydivuj +kbqwtcvzgsmhpoeylnaxydhfuj +kbqwtcvfgsmhpoelrnaxgdifyj +kbqwtcvzgsmhnbelrnaxyfifuj +kbqwtcvzgsmhpoelrnaxbdffmj +kwqwtcvogtmhpoelrnaxydifuj +kdqwtcvzggyhpoelrnaxydifuj +kbqwtuvzgtmhpoelrnaxydifxj +kbqctdvzcsmhpoelrnaxydifuj +kbqwtcvzgsmhpoblrniyydifuj +kbqwucvzzsmhpoelrnvxydifuj +kbqwtcvzgslzpoelrnaxydiruj +kbqwtdmzgsmhpwelrnaxydifuj +kbqwtcvzgsmhpoilrnaxqiifuj +kbqwtcvzgsmhpgelrnaxydisnj +kbdwtqvzgsmhpoelrnaxydivuj +kbqvtdvzgsmhpoelrjaxydifuj +kfqwtcvzgsmhpoeurnyxydifuj +kbqwtcvzgsmhpoglrnaxqkifuj +kbqwtcvrgsmhpoelrnajydifnj +xbqwpcvzgjmhpoelrnaxydifuj +kbqwtcvzgsmhpoelrdaxvdihuj +kbuwtcvzssmhpoklrnaxydifuj +kbqwtcvzgqmhpoelrnzxydifbj +kbqwtcvzgsmhsoeoknaxydifuj +kfqltcvzgsmhpoelrnaxydifnj +qbqwtsvzgsmhpoelrnaxodifuj +kbqwwevzgsmypoelrnaxydifuj +kbqwtcuzgimhpoelrnaxydffuj +kxqwlcvzgsmhpoelrnaxyrifuj +nbqwtcvzgsmhpoelryaxyiifuj +kbqwtcvzgsmhhoxlreaxydifuj +mbqwtcvzfsmxpoelrnaxydifuj +kbqwttvzgsmhpoeqrnaxidifuj +kbqwtcvzgamhpielrnaxyiifuj +rfqwtcvzgsmhpoelrnaxydifun +kbpwtqvzgsmbpoelrnaxydifuj +kbqwtcvzgsmhpoqlroaxydifua +hbqwtcvzksmhpoelrnaxydbfuj +kaqutcvzgsmhpoelrnaxydiiuj +kbqctcvzgsnhpoelrcaxydifuj +kbqwtnvzgsmhpoelrnaxydqfoj +kbqwtcvzhsmhpoelrnaxydifyb +ubqwtcvcgsmhooelrnaxydifuj +kbqwtcvrgsmhpoelrnaxtdivuj +kbqwtcvzgsmhplelrnmxydifaj +ebqwlcvzghmhpoelrnaxydifuj +hbqwtcvzgsmhpoelrnaqyeifuj +kbqstcvzgsmeprelrnaxydifuj +kbqwtcvogsthpoelrnnxydifuj +ybqwtcvzgdmhpoelrnaxydufuj +kbqutcvzgsmhpoelrnaxydifgx +kbqwtcvzgsmhpozlunadydifuj +kkqwtcvzgsmhpuefrnaxydifuj +kbqrtcvzgsmhpoelrnaxcdifuq +kbqwtcvzjsmupoelrnaxydiluj +kbqwmcvzgsuhpoelrnaxydifhj +kbqwfcvzgsmhpoelrnaxydkzuj +kbqatcvzgsdhpoeyrnaxydifuj +kbtwtcvzusmhpoelrxaxydifuj +kbqwtcwzgsmhpoelrnaxysofuj +kbqqtcvmgsmhpoevrnaxydifuj +kbqwjcvzgsmhpoelrnaxydhuuj +mbdwtcvzgsmhpoelqnaxydifuj +kbqwtcvlgsmhpoelrdaxydifaj +kbqwtcvzgsmmpoelrlaxydnfuj +kbqwtchfggmhpoelrnaxydifuj +kbqqtcvzgsyhpoelrnaxyoifuj +knqwtcvzqsmupoelrnaxydifuj +kdqdtcvzgsmhpoelrnaxydmfuj +kbqwtcvzgsmhptelrnawyhifuj +kbqwtcvzgrmhpoeqrnaxydifuw +kbnxtcvzgsmhpoelrnauydifuj +kbqwacvsgsmhpoelrnaxydifgj +kbqwtcvzgsmhpperrnaxydifuc +gbqwtcvzgsqhxoelrnaxydifuj +kbqwtcvzgsmhpoeljgaxydifwj +kbqktcvzgsmhpotlrnatydifuj +bbqwtcvzgsmhpoilrnaxydjfuj +kbqwecvdgsmhpoelrnaxypifuj +keqwtcvzgemhpotlrnaxydifuj +kbqptcvzgsmvpoelrnaxydixuj +kbqwbctzgsmhpoelrnaxydifup +kbqwtcvzgszhpbelrnzxydifuj +mbqwtcvtgsmhpoeyrnaxydifuj +kbqwtcvzgsmhqcelrhaxydifuj +kbqotcvzgsmhooelrnazydifuj +kbqwtcvzgsmhpoelmpaxyiifuj +kbqwtcvwgsmypoclrnaxydifuj +kbqwtcvsgskhpoelrnaxykifuj +kbqwtcvzgszvpoelrnwxydifuj +kbqwtcvzgsmhpoejonaxydrfuj +kbqwtcvzgsmhkoelrnazyqifuj +kbzwtzvzgsmhptelrnaxydifuj +kbqwtcdzgsmhptelrnaxydiduj +kbqwtcvzgamhpoelrnakyzifuj +kbqwtcvzgsmhpoeonnaxydifxj +kbqwtcvzgsmhpoeranaxydifej +kbqwscvzgsmhpoelunaxydimuj +cbqwtcvzgsmhpoelrdaxydefuj +vbqwtcjzgsmhpoelrnaxydifua +kmqwtcvzksmhpoeljnaxydifuj +kbqwtcvzgsmppojlrnasydifuj +kaqwtcvfgsmhpoelrnaxydiauj +khqwccvzgsmhpoelrnaxydifud +vbqwtcvzrsmhpoelrhaxydifuj +kuqwtcvzgsmhpoelgnaiydifuj +kbqwtcvzdsmhpbelvnaxydifuj +kbowtcvzgnmhpoelrfaxydifuj +kbqwtcvsgsmhfoejrnaxydifuj +kbqwtcvzgskhtoelrnxxydifuj +kbqwtcvzgtmhpoevrnaxydivuj +bbqptcgzgsmhpoelrnaxydifuj +kbqwtpvzgsmnpoelhnaxydifuj +kbqwtovzgsmmpoelrnaxydifuw +kbqwtcvzgsihpwelrnaxydsfuj +kbqwtcvzggmhpollrnaxydifsj +kbqwtcjzgsmhpoelrnaxyxifub +ebqwtcvzgsmzpoelrnaaydifuj +kbqwtcvzusmhpoelrnqxydijuj +obqwtcvzgsghpoelrnaxydifkj +kbrwtcvzmdmhpoelrnaxydifuj +kbqwtcvzxsmhpoblrnhxydifuj +kbqwacvzgsahpoelrnaxydiguj +kyqwtcvzgsmipoelrnlxydifuj +kbbwtcvzgsmhboelpnaxydifuj +kbqwtcvzgsmhpoelrnaxhdosuj +kbqwtgvzgxmhpoelrnaxyrifuj +pbqwtsvzgsmhpoelrnabydifuj +kbqrtcvzgsmhpsblrnaxydifuj +kbqwtcvzgsmhpoexrnaaycifuj +kbqxtcvzgsjhkoelrnaxydifuj +kbqwtcvzgsmhpxelrnaxydifby +lbxwtcvzgsmdpoelrnaxydifuj +kbqwtcczgsmhpoklrnzxydifuj +zbqwtcvzgsmhpoelrbaxydifui +krqwtcvzbsmhpoelrjaxydifuj +kbkwtcvzgsmhpoelrnaxydiacj +kbqwtcvzgszhpseprnaxydifuj +kbxwtcvzxsmhpoesrnaxydifuj +kbqwdcvzgsmhpoelrbaxygifuj +kbqwthkzgsmhhoelrnaxydifuj +klqwtchzgamhpoelrnaxydifuj +obqwtcvzgsvcpoelrnaxydifuj +kblwtcvzgsmhpoelrnanydifuw +kbqwtrvzgsmhpoelynaxydifug +kbqwtcvzgsmhcoelmnaxydkfuj +kbqwtcvzgsmhpotlqoaxydifuj +kaqatcvzgsmhpoelrnaxyiifuj +kbqttcvwgsmhpoelrnaxydifgj +kpqwtcvzgsmhpwelynaxydifuj +kbqwucvzgsmhpyelrnaxyxifuj +kbqwucvzgsmhprelrnaxyfifuj +kbqwthvzgsmhphelrnaxylifuj +kbqwtcvzosmhdoelrnaxwdifuj +kbqwtxvsgsphpoelrnaxydifuj +koqwtcvfghmhpoelrnaxydifuj +kbtwicvzpsmhpoelrnaxydifuj +kbawtcvzgsmhmoelrnaxyiifuj +kbqwtcvzgslhpbelrnaxydifuk +kbqttcvzgsmypoelrnaxydifua +kbqwtcvrgqmhpnelrnaxydifuj +kbqwtcvzghmhpoekpnaxydifuj +kbqwtcvzgsmupoelrnaxidifui +kbqwtcvzgsmhpbelrnaxrdifux diff --git a/2018/day2/part1.exs b/2018/day2/part1.exs new file mode 100644 index 0000000..096eb70 --- /dev/null +++ b/2018/day2/part1.exs @@ -0,0 +1,33 @@ +defmodule Part1 do + def increment_freq(char, freq_map) do + Map.update(freq_map, char, 1, &(&1 + 1)) + end + + def to_freq_map(str) do + str + |> String.to_charlist() + |> Enum.reduce(%{}, &increment_freq/2) + end + + def contains_frequency?(freq_map, freq) do + Map.values(freq_map) |> Enum.member?(freq) + end + + def count_twos_and_threes(freq_map, {twos, threes}) do + twos = if contains_frequency?(freq_map, 2), do: twos + 1, else: twos + threes = if contains_frequency?(freq_map, 3), do: threes + 1, else: threes + {twos, threes} + end + + def run do + {twos, threes} = + File.stream!("input") + |> Stream.map(&String.trim/1) + |> Stream.map(&to_freq_map/1) + |> Enum.reduce({0, 0}, &count_twos_and_threes/2) + + IO.puts("#{twos} * #{threes} = #{twos * threes}") + end +end + +Part1.run() diff --git a/2018/day2/part2.exs b/2018/day2/part2.exs new file mode 100644 index 0000000..0517cb4 --- /dev/null +++ b/2018/day2/part2.exs @@ -0,0 +1,30 @@ +defmodule Part2 do + def count_diffs(str1, str2) do + Stream.zip(String.to_charlist(str1), String.to_charlist(str2)) + |> Enum.count(fn {a, b} -> a !== b end) + end + + def common_chars(str1, str2) do + Stream.zip(String.to_charlist(str1), String.to_charlist(str2)) + |> Stream.filter(fn {a, b} -> a === b end) + |> Enum.map(fn {a, _b} -> a end) + end + + def run do + boxes = File.stream!("input") |> Enum.map(&String.trim/1) + + diffs = + for box <- boxes, other_box <- boxes -- [box] do + {box, count_diffs(box, other_box)} + end + + [str1, str2] = + diffs + |> Enum.filter(fn {_box, diff} -> diff === 1 end) + |> Enum.map(fn {box, 1} -> box end) + + IO.puts(common_chars(str1, str2)) + end +end + +Part2.run() diff --git a/2018/day3/day3.exs b/2018/day3/day3.exs new file mode 100644 index 0000000..3fdda4b --- /dev/null +++ b/2018/day3/day3.exs @@ -0,0 +1,57 @@ +defmodule Coord do + defstruct [:x, :y] +end + +defmodule Claim do + defstruct id: nil, pos: %Coord{x: 0, y: 0}, len: %Coord{x: 0, y: 0} + @input_pattern ~r/#(\d+) @ (\d+),(\d+): (\d+)x(\d+)/ + + def new_from_str(str) do + [id, pos_x, pos_y, len_x, len_y] = + Regex.run(@input_pattern, str, capture: :all_but_first) + |> Enum.map(&String.to_integer/1) + + %Claim{id: id, pos: %Coord{x: pos_x, y: pos_y}, len: %Coord{x: len_x, y: len_y}} + end + + def all_coords(claim) do + x_coords = claim.pos.x..(claim.pos.x + claim.len.x - 1) + y_coords = claim.pos.y..(claim.pos.y + claim.len.y - 1) + for x <- x_coords, y <- y_coords, do: %Coord{x: x, y: y} + end + + def unshared?(claim, unshared_inches) do + Enum.all?(all_coords(claim), &MapSet.member?(unshared_inches, &1)) + end +end + +defmodule Day3 do + def count_claim_inches(claim, count) do + Enum.reduce(Claim.all_coords(claim), count, fn coord, count -> + Map.update(count, coord, 1, &(&1 + 1)) + end) + end + + def part1 do + File.stream!("input") + |> Stream.map(&Claim.new_from_str/1) + |> Enum.reduce(%{}, &count_claim_inches/2) + |> Stream.filter(fn {_coord, count} -> count >= 2 end) + |> Enum.count() + end + + def part2 do + all_claims = File.stream!("input") |> Enum.map(&Claim.new_from_str/1) + + unshared_inches = + all_claims + |> Enum.reduce(%{}, &count_claim_inches/2) + |> Enum.filter(fn {_coord, count} -> count == 1 end) + |> MapSet.new(fn {coord, _count} -> coord end) + + Enum.find(all_claims, &Claim.unshared?(&1, unshared_inches)) + end +end + +IO.puts("Part1 (number of square inches claimed multiple times): #{Day3.part1()}") +IO.puts("Part2 (id of only claim not overlapping with another): #{Day3.part2().id}") diff --git a/2018/day3/input b/2018/day3/input new file mode 100644 index 0000000..dcc8720 --- /dev/null +++ b/2018/day3/input @@ -0,0 +1,1317 @@ +#1 @ 861,330: 20x10 +#2 @ 491,428: 28x23 +#3 @ 64,746: 20x27 +#4 @ 406,769: 25x28 +#5 @ 853,621: 17x26 +#6 @ 311,802: 27x28 +#7 @ 947,977: 14x13 +#8 @ 786,5: 18x23 +#9 @ 420,429: 14x24 +#10 @ 138,206: 29x28 +#11 @ 474,698: 19x29 +#12 @ 525,141: 16x29 +#13 @ 18,738: 11x29 +#14 @ 166,402: 26x12 +#15 @ 177,580: 18x14 +#16 @ 105,564: 17x21 +#17 @ 336,772: 12x21 +#18 @ 229,923: 29x22 +#19 @ 519,5: 26x14 +#20 @ 245,608: 15x25 +#21 @ 140,235: 11x20 +#22 @ 571,382: 18x29 +#23 @ 646,5: 24x29 +#24 @ 159,677: 21x10 +#25 @ 917,962: 20x29 +#26 @ 692,896: 29x10 +#27 @ 744,92: 12x21 +#28 @ 969,390: 17x21 +#29 @ 232,786: 27x28 +#30 @ 415,568: 11x23 +#31 @ 364,525: 14x21 +#32 @ 936,560: 12x21 +#33 @ 306,700: 25x15 +#34 @ 902,356: 26x11 +#35 @ 395,598: 24x17 +#36 @ 691,977: 18x16 +#37 @ 489,458: 21x27 +#38 @ 10,58: 17x10 +#39 @ 466,850: 14x27 +#40 @ 640,152: 23x19 +#41 @ 510,769: 17x21 +#42 @ 695,332: 11x27 +#43 @ 230,319: 12x15 +#44 @ 356,435: 20x29 +#45 @ 965,643: 14x21 +#46 @ 221,909: 11x11 +#47 @ 178,947: 11x27 +#48 @ 9,508: 19x16 +#49 @ 763,28: 28x15 +#50 @ 154,159: 20x24 +#51 @ 797,515: 11x19 +#52 @ 670,393: 19x25 +#53 @ 401,838: 17x16 +#54 @ 518,153: 11x22 +#55 @ 378,38: 18x27 +#56 @ 759,548: 26x26 +#57 @ 535,388: 16x20 +#58 @ 331,502: 27x24 +#59 @ 632,627: 21x16 +#60 @ 469,351: 11x10 +#61 @ 311,115: 21x12 +#62 @ 373,80: 13x23 +#63 @ 392,223: 24x17 +#64 @ 937,408: 10x24 +#65 @ 835,123: 12x11 +#66 @ 539,420: 26x27 +#67 @ 250,486: 17x25 +#68 @ 130,25: 13x15 +#69 @ 959,802: 19x20 +#70 @ 184,871: 22x23 +#71 @ 585,970: 12x15 +#72 @ 800,251: 25x27 +#73 @ 952,981: 18x12 +#74 @ 274,96: 23x25 +#75 @ 808,666: 11x11 +#76 @ 727,795: 24x18 +#77 @ 617,624: 16x27 +#78 @ 588,398: 26x17 +#79 @ 379,180: 21x20 +#80 @ 875,58: 12x14 +#81 @ 886,166: 20x10 +#82 @ 164,670: 17x11 +#83 @ 248,510: 20x18 +#84 @ 518,548: 29x28 +#85 @ 895,666: 16x22 +#86 @ 80,651: 17x16 +#87 @ 483,565: 23x26 +#88 @ 223,141: 4x13 +#89 @ 696,704: 13x11 +#90 @ 237,965: 10x12 +#91 @ 196,45: 14x17 +#92 @ 520,245: 19x10 +#93 @ 802,441: 15x12 +#94 @ 919,354: 16x22 +#95 @ 722,836: 16x15 +#96 @ 493,863: 9x7 +#97 @ 398,666: 11x27 +#98 @ 608,708: 28x27 +#99 @ 130,39: 17x17 +#100 @ 487,128: 22x19 +#101 @ 277,315: 3x15 +#102 @ 883,612: 29x19 +#103 @ 646,750: 20x29 +#104 @ 512,465: 11x12 +#105 @ 333,818: 22x26 +#106 @ 22,355: 21x15 +#107 @ 180,95: 12x10 +#108 @ 795,278: 27x18 +#109 @ 533,139: 23x18 +#110 @ 507,445: 17x18 +#111 @ 763,147: 19x15 +#112 @ 687,749: 17x13 +#113 @ 597,691: 12x19 +#114 @ 509,44: 11x27 +#115 @ 706,38: 10x20 +#116 @ 112,91: 28x14 +#117 @ 825,416: 14x26 +#118 @ 850,330: 27x13 +#119 @ 576,5: 26x20 +#120 @ 778,75: 29x18 +#121 @ 847,127: 26x29 +#122 @ 265,695: 17x26 +#123 @ 828,676: 21x20 +#124 @ 933,268: 22x28 +#125 @ 74,746: 29x17 +#126 @ 511,66: 29x28 +#127 @ 960,150: 25x13 +#128 @ 891,810: 10x28 +#129 @ 887,899: 13x15 +#130 @ 648,413: 14x20 +#131 @ 113,882: 20x16 +#132 @ 532,171: 10x13 +#133 @ 91,427: 29x12 +#134 @ 86,333: 27x15 +#135 @ 558,725: 29x14 +#136 @ 574,504: 19x15 +#137 @ 219,566: 10x11 +#138 @ 432,333: 9x7 +#139 @ 952,591: 6x15 +#140 @ 894,535: 22x15 +#141 @ 885,345: 21x29 +#142 @ 422,416: 20x24 +#143 @ 620,642: 22x26 +#144 @ 115,459: 14x28 +#145 @ 371,866: 11x14 +#146 @ 677,594: 25x17 +#147 @ 607,638: 26x20 +#148 @ 232,87: 21x16 +#149 @ 738,668: 12x19 +#150 @ 582,782: 28x11 +#151 @ 17,600: 11x24 +#152 @ 519,126: 27x23 +#153 @ 430,331: 16x13 +#154 @ 197,656: 13x21 +#155 @ 480,315: 13x20 +#156 @ 750,80: 12x28 +#157 @ 590,924: 24x29 +#158 @ 699,984: 28x11 +#159 @ 385,488: 20x25 +#160 @ 774,289: 6x19 +#161 @ 197,913: 21x14 +#162 @ 650,91: 20x22 +#163 @ 675,25: 25x25 +#164 @ 159,507: 18x10 +#165 @ 872,60: 20x25 +#166 @ 897,566: 23x25 +#167 @ 73,242: 15x14 +#168 @ 57,785: 12x13 +#169 @ 99,902: 24x22 +#170 @ 840,959: 25x13 +#171 @ 267,965: 28x14 +#172 @ 464,367: 20x11 +#173 @ 945,71: 21x18 +#174 @ 792,918: 28x29 +#175 @ 658,940: 24x13 +#176 @ 284,415: 19x11 +#177 @ 107,221: 23x14 +#178 @ 266,595: 28x16 +#179 @ 531,599: 25x28 +#180 @ 938,97: 20x15 +#181 @ 246,371: 16x16 +#182 @ 922,772: 21x12 +#183 @ 260,911: 18x10 +#184 @ 964,629: 24x18 +#185 @ 773,879: 13x16 +#186 @ 569,803: 17x28 +#187 @ 836,615: 24x19 +#188 @ 970,623: 24x15 +#189 @ 828,216: 19x17 +#190 @ 267,178: 22x18 +#191 @ 302,121: 14x15 +#192 @ 156,165: 12x11 +#193 @ 352,515: 27x28 +#194 @ 151,510: 12x13 +#195 @ 645,335: 25x19 +#196 @ 818,872: 10x12 +#197 @ 460,879: 3x8 +#198 @ 222,391: 14x20 +#199 @ 127,139: 27x13 +#200 @ 676,920: 22x22 +#201 @ 467,479: 12x27 +#202 @ 62,608: 25x26 +#203 @ 843,80: 15x17 +#204 @ 258,600: 26x13 +#205 @ 2,345: 8x4 +#206 @ 181,885: 23x11 +#207 @ 765,656: 11x14 +#208 @ 528,919: 28x15 +#209 @ 311,774: 27x20 +#210 @ 343,683: 27x18 +#211 @ 395,898: 13x23 +#212 @ 322,555: 12x12 +#213 @ 764,661: 16x11 +#214 @ 274,363: 24x16 +#215 @ 845,977: 7x16 +#216 @ 656,641: 13x28 +#217 @ 805,228: 26x11 +#218 @ 51,113: 24x14 +#219 @ 777,658: 28x21 +#220 @ 185,915: 14x15 +#221 @ 296,794: 24x17 +#222 @ 507,468: 17x21 +#223 @ 708,337: 23x11 +#224 @ 522,154: 13x27 +#225 @ 382,762: 22x29 +#226 @ 635,49: 21x22 +#227 @ 646,265: 18x23 +#228 @ 369,562: 28x22 +#229 @ 420,570: 26x19 +#230 @ 487,861: 24x12 +#231 @ 535,29: 29x14 +#232 @ 89,816: 20x27 +#233 @ 835,51: 19x24 +#234 @ 395,473: 11x15 +#235 @ 620,137: 21x27 +#236 @ 314,37: 29x20 +#237 @ 61,426: 27x23 +#238 @ 178,356: 21x26 +#239 @ 95,722: 16x10 +#240 @ 744,879: 11x24 +#241 @ 662,878: 25x13 +#242 @ 359,156: 21x29 +#243 @ 632,620: 29x10 +#244 @ 746,676: 11x20 +#245 @ 474,284: 19x13 +#246 @ 778,506: 27x13 +#247 @ 718,337: 10x17 +#248 @ 52,360: 11x20 +#249 @ 243,492: 12x22 +#250 @ 958,139: 19x23 +#251 @ 810,105: 29x23 +#252 @ 727,897: 11x22 +#253 @ 56,33: 26x19 +#254 @ 198,945: 15x23 +#255 @ 929,319: 22x20 +#256 @ 393,362: 14x22 +#257 @ 273,27: 12x23 +#258 @ 668,857: 24x27 +#259 @ 956,681: 14x13 +#260 @ 685,317: 22x21 +#261 @ 562,410: 21x17 +#262 @ 605,630: 14x23 +#263 @ 946,393: 26x17 +#264 @ 98,225: 14x26 +#265 @ 0,3: 23x20 +#266 @ 162,949: 27x20 +#267 @ 829,548: 18x13 +#268 @ 842,64: 18x17 +#269 @ 80,47: 15x16 +#270 @ 116,613: 22x24 +#271 @ 9,492: 26x26 +#272 @ 29,129: 21x25 +#273 @ 86,246: 15x26 +#274 @ 360,164: 23x15 +#275 @ 528,530: 18x17 +#276 @ 796,668: 19x22 +#277 @ 827,178: 25x29 +#278 @ 873,714: 27x12 +#279 @ 543,276: 18x16 +#280 @ 641,619: 24x10 +#281 @ 658,773: 11x21 +#282 @ 477,442: 13x27 +#283 @ 864,791: 15x20 +#284 @ 508,436: 27x14 +#285 @ 908,348: 19x19 +#286 @ 893,813: 5x20 +#287 @ 801,558: 19x23 +#288 @ 170,324: 12x15 +#289 @ 151,355: 14x8 +#290 @ 247,771: 12x25 +#291 @ 660,862: 11x24 +#292 @ 192,704: 13x28 +#293 @ 370,734: 11x18 +#294 @ 687,877: 21x10 +#295 @ 74,263: 23x22 +#296 @ 609,524: 26x24 +#297 @ 127,723: 20x12 +#298 @ 468,124: 26x14 +#299 @ 153,281: 17x10 +#300 @ 831,261: 11x27 +#301 @ 64,282: 25x27 +#302 @ 873,364: 11x26 +#303 @ 707,305: 15x22 +#304 @ 746,626: 22x20 +#305 @ 718,590: 22x12 +#306 @ 593,745: 17x13 +#307 @ 416,297: 15x27 +#308 @ 82,609: 18x17 +#309 @ 468,885: 12x21 +#310 @ 31,341: 24x24 +#311 @ 585,541: 29x25 +#312 @ 882,713: 13x14 +#313 @ 499,420: 19x27 +#314 @ 108,125: 11x26 +#315 @ 248,709: 3x9 +#316 @ 117,122: 22x28 +#317 @ 965,800: 24x21 +#318 @ 757,567: 17x28 +#319 @ 193,9: 17x12 +#320 @ 89,240: 12x19 +#321 @ 29,726: 13x21 +#322 @ 169,826: 11x17 +#323 @ 475,499: 28x21 +#324 @ 187,323: 12x12 +#325 @ 319,694: 20x22 +#326 @ 91,6: 17x16 +#327 @ 79,174: 28x21 +#328 @ 872,139: 24x21 +#329 @ 74,330: 27x11 +#330 @ 813,965: 29x29 +#331 @ 588,442: 20x10 +#332 @ 901,674: 23x16 +#333 @ 14,248: 29x10 +#334 @ 512,251: 10x13 +#335 @ 409,589: 12x29 +#336 @ 799,537: 18x22 +#337 @ 230,537: 16x12 +#338 @ 491,275: 25x18 +#339 @ 829,183: 19x11 +#340 @ 233,327: 12x27 +#341 @ 844,803: 21x15 +#342 @ 558,115: 19x13 +#343 @ 521,826: 15x29 +#344 @ 152,21: 18x29 +#345 @ 159,37: 14x15 +#346 @ 390,266: 11x12 +#347 @ 297,724: 23x19 +#348 @ 592,318: 11x17 +#349 @ 186,923: 14x13 +#350 @ 471,798: 10x25 +#351 @ 30,192: 25x19 +#352 @ 532,830: 10x27 +#353 @ 71,964: 14x27 +#354 @ 551,7: 28x27 +#355 @ 117,135: 11x23 +#356 @ 240,367: 12x21 +#357 @ 599,700: 8x10 +#358 @ 182,222: 17x24 +#359 @ 449,357: 24x24 +#360 @ 92,521: 26x21 +#361 @ 845,214: 26x22 +#362 @ 188,647: 13x29 +#363 @ 440,24: 12x28 +#364 @ 855,957: 23x27 +#365 @ 229,897: 28x25 +#366 @ 700,971: 20x16 +#367 @ 798,651: 14x12 +#368 @ 889,379: 13x24 +#369 @ 498,787: 13x12 +#370 @ 584,810: 16x15 +#371 @ 8,498: 14x19 +#372 @ 802,467: 21x18 +#373 @ 418,399: 12x20 +#374 @ 300,78: 22x15 +#375 @ 396,917: 15x28 +#376 @ 159,149: 16x25 +#377 @ 37,368: 19x19 +#378 @ 301,599: 12x18 +#379 @ 83,260: 28x14 +#380 @ 563,884: 14x22 +#381 @ 777,189: 21x18 +#382 @ 400,392: 18x15 +#383 @ 168,959: 19x17 +#384 @ 184,952: 11x23 +#385 @ 796,628: 24x27 +#386 @ 493,31: 25x11 +#387 @ 136,129: 27x27 +#388 @ 714,693: 6x21 +#389 @ 557,414: 28x11 +#390 @ 733,601: 28x18 +#391 @ 344,536: 22x25 +#392 @ 782,831: 19x15 +#393 @ 86,260: 18x20 +#394 @ 435,617: 14x15 +#395 @ 78,951: 20x28 +#396 @ 207,138: 26x20 +#397 @ 172,38: 17x17 +#398 @ 158,886: 15x21 +#399 @ 929,563: 26x12 +#400 @ 350,562: 19x27 +#401 @ 187,19: 22x12 +#402 @ 23,320: 28x15 +#403 @ 309,54: 11x27 +#404 @ 880,35: 25x19 +#405 @ 849,58: 29x28 +#406 @ 912,679: 6x5 +#407 @ 785,795: 22x27 +#408 @ 386,681: 29x28 +#409 @ 912,579: 21x29 +#410 @ 749,772: 28x13 +#411 @ 362,175: 21x11 +#412 @ 265,916: 16x16 +#413 @ 863,834: 18x26 +#414 @ 946,64: 18x12 +#415 @ 252,552: 27x28 +#416 @ 952,981: 21x12 +#417 @ 506,11: 16x13 +#418 @ 794,363: 27x11 +#419 @ 259,886: 19x20 +#420 @ 205,879: 23x14 +#421 @ 101,907: 12x22 +#422 @ 366,736: 24x18 +#423 @ 692,50: 25x29 +#424 @ 919,465: 23x10 +#425 @ 73,235: 10x18 +#426 @ 589,664: 27x13 +#427 @ 255,376: 13x12 +#428 @ 804,129: 16x12 +#429 @ 450,340: 25x12 +#430 @ 754,161: 16x20 +#431 @ 368,708: 12x12 +#432 @ 504,365: 27x26 +#433 @ 673,737: 26x10 +#434 @ 462,358: 14x29 +#435 @ 901,569: 7x9 +#436 @ 932,103: 15x21 +#437 @ 262,844: 11x19 +#438 @ 367,400: 25x22 +#439 @ 249,247: 17x28 +#440 @ 451,67: 3x20 +#441 @ 757,152: 14x21 +#442 @ 852,799: 12x10 +#443 @ 554,93: 10x18 +#444 @ 82,420: 13x13 +#445 @ 401,843: 18x27 +#446 @ 454,184: 24x19 +#447 @ 681,253: 16x10 +#448 @ 942,247: 22x17 +#449 @ 774,784: 28x14 +#450 @ 273,94: 26x19 +#451 @ 230,782: 19x20 +#452 @ 517,396: 18x15 +#453 @ 471,485: 17x21 +#454 @ 383,926: 23x11 +#455 @ 481,687: 10x29 +#456 @ 39,171: 18x11 +#457 @ 285,489: 28x10 +#458 @ 0,341: 14x15 +#459 @ 268,206: 14x26 +#460 @ 459,9: 28x29 +#461 @ 244,695: 11x28 +#462 @ 851,227: 20x13 +#463 @ 241,132: 15x12 +#464 @ 287,65: 26x25 +#465 @ 328,700: 16x22 +#466 @ 428,380: 23x27 +#467 @ 695,17: 20x13 +#468 @ 193,187: 21x22 +#469 @ 98,495: 24x16 +#470 @ 720,816: 14x25 +#471 @ 193,400: 28x29 +#472 @ 977,136: 21x27 +#473 @ 645,858: 16x23 +#474 @ 785,416: 17x20 +#475 @ 240,374: 29x25 +#476 @ 9,711: 27x19 +#477 @ 823,273: 28x28 +#478 @ 153,538: 12x3 +#479 @ 286,354: 20x17 +#480 @ 795,657: 21x29 +#481 @ 483,17: 25x10 +#482 @ 87,881: 13x15 +#483 @ 881,897: 14x10 +#484 @ 404,92: 29x24 +#485 @ 946,630: 22x17 +#486 @ 167,257: 20x17 +#487 @ 58,483: 24x16 +#488 @ 632,39: 29x23 +#489 @ 762,248: 19x21 +#490 @ 599,443: 23x14 +#491 @ 455,18: 26x14 +#492 @ 458,817: 27x19 +#493 @ 868,685: 11x3 +#494 @ 190,969: 10x29 +#495 @ 764,460: 24x22 +#496 @ 894,70: 17x16 +#497 @ 541,880: 29x16 +#498 @ 307,837: 13x26 +#499 @ 158,943: 13x29 +#500 @ 447,974: 11x11 +#501 @ 845,881: 23x28 +#502 @ 840,76: 11x25 +#503 @ 785,11: 25x16 +#504 @ 933,625: 18x24 +#505 @ 919,941: 22x12 +#506 @ 812,442: 14x18 +#507 @ 945,834: 21x27 +#508 @ 711,738: 10x20 +#509 @ 269,893: 17x25 +#510 @ 796,408: 19x24 +#511 @ 83,146: 26x21 +#512 @ 611,782: 14x18 +#513 @ 222,168: 23x12 +#514 @ 190,211: 13x14 +#515 @ 455,890: 14x17 +#516 @ 344,350: 15x27 +#517 @ 322,975: 16x12 +#518 @ 96,665: 15x14 +#519 @ 746,936: 29x14 +#520 @ 636,756: 25x28 +#521 @ 769,73: 12x28 +#522 @ 385,591: 24x17 +#523 @ 642,348: 19x19 +#524 @ 696,451: 16x26 +#525 @ 171,319: 27x29 +#526 @ 912,849: 26x21 +#527 @ 25,50: 25x25 +#528 @ 954,927: 19x18 +#529 @ 856,151: 19x25 +#530 @ 168,364: 14x17 +#531 @ 760,588: 12x25 +#532 @ 217,169: 17x28 +#533 @ 241,80: 15x17 +#534 @ 179,388: 18x21 +#535 @ 922,732: 28x27 +#536 @ 637,368: 22x28 +#537 @ 812,563: 13x13 +#538 @ 291,311: 29x19 +#539 @ 260,671: 14x25 +#540 @ 764,141: 19x16 +#541 @ 847,223: 16x8 +#542 @ 862,283: 26x29 +#543 @ 962,624: 10x14 +#544 @ 450,7: 21x18 +#545 @ 469,762: 22x26 +#546 @ 786,611: 26x15 +#547 @ 282,85: 20x17 +#548 @ 952,902: 19x29 +#549 @ 68,556: 19x23 +#550 @ 650,82: 22x20 +#551 @ 870,296: 10x26 +#552 @ 490,24: 26x23 +#553 @ 684,253: 24x18 +#554 @ 606,397: 15x26 +#555 @ 8,54: 28x23 +#556 @ 675,336: 21x14 +#557 @ 378,571: 13x26 +#558 @ 64,39: 20x15 +#559 @ 60,838: 22x17 +#560 @ 401,114: 24x27 +#561 @ 526,33: 23x21 +#562 @ 668,534: 11x26 +#563 @ 370,862: 26x24 +#564 @ 39,188: 28x10 +#565 @ 370,60: 14x13 +#566 @ 448,544: 13x20 +#567 @ 320,919: 19x13 +#568 @ 212,913: 29x22 +#569 @ 951,972: 14x15 +#570 @ 146,628: 12x21 +#571 @ 696,792: 29x15 +#572 @ 509,508: 18x23 +#573 @ 535,320: 21x11 +#574 @ 448,202: 15x23 +#575 @ 483,905: 23x13 +#576 @ 30,799: 18x21 +#577 @ 499,1: 13x23 +#578 @ 654,626: 19x27 +#579 @ 293,975: 22x15 +#580 @ 400,463: 10x10 +#581 @ 55,633: 23x25 +#582 @ 770,200: 11x14 +#583 @ 96,481: 23x21 +#584 @ 651,685: 21x11 +#585 @ 508,394: 24x13 +#586 @ 83,273: 16x11 +#587 @ 94,541: 27x20 +#588 @ 700,181: 19x12 +#589 @ 980,22: 16x24 +#590 @ 884,473: 20x25 +#591 @ 346,613: 25x11 +#592 @ 81,604: 24x13 +#593 @ 677,342: 26x28 +#594 @ 750,786: 16x14 +#595 @ 333,972: 10x14 +#596 @ 976,27: 16x20 +#597 @ 842,974: 16x25 +#598 @ 178,328: 22x21 +#599 @ 401,979: 14x18 +#600 @ 656,788: 27x14 +#601 @ 692,320: 21x23 +#602 @ 741,634: 22x25 +#603 @ 341,711: 25x28 +#604 @ 420,373: 28x14 +#605 @ 250,827: 22x18 +#606 @ 588,513: 29x14 +#607 @ 902,94: 11x14 +#608 @ 418,828: 27x19 +#609 @ 1,471: 19x23 +#610 @ 460,743: 15x10 +#611 @ 213,864: 27x18 +#612 @ 127,237: 14x21 +#613 @ 61,700: 22x12 +#614 @ 864,308: 20x11 +#615 @ 213,264: 14x17 +#616 @ 264,49: 17x29 +#617 @ 391,764: 16x12 +#618 @ 733,822: 14x24 +#619 @ 265,907: 13x15 +#620 @ 612,947: 15x21 +#621 @ 916,208: 27x24 +#622 @ 350,798: 13x14 +#623 @ 175,168: 21x29 +#624 @ 556,886: 11x15 +#625 @ 305,827: 25x19 +#626 @ 699,793: 25x24 +#627 @ 983,202: 17x28 +#628 @ 902,83: 15x18 +#629 @ 209,921: 29x11 +#630 @ 154,611: 26x17 +#631 @ 762,975: 11x13 +#632 @ 476,354: 13x19 +#633 @ 298,401: 26x28 +#634 @ 471,896: 13x11 +#635 @ 853,382: 15x22 +#636 @ 826,690: 26x21 +#637 @ 463,313: 18x23 +#638 @ 590,550: 22x23 +#639 @ 309,904: 18x11 +#640 @ 912,593: 22x25 +#641 @ 781,185: 12x15 +#642 @ 103,396: 16x11 +#643 @ 849,128: 17x11 +#644 @ 82,237: 25x15 +#645 @ 240,2: 21x11 +#646 @ 621,541: 10x21 +#647 @ 918,363: 10x29 +#648 @ 248,138: 15x17 +#649 @ 77,944: 23x26 +#650 @ 544,116: 17x17 +#651 @ 442,806: 16x27 +#652 @ 618,353: 25x14 +#653 @ 138,658: 22x22 +#654 @ 71,832: 18x13 +#655 @ 947,541: 23x21 +#656 @ 114,494: 21x12 +#657 @ 664,331: 12x10 +#658 @ 970,42: 16x27 +#659 @ 475,229: 21x22 +#660 @ 388,399: 14x20 +#661 @ 264,76: 22x13 +#662 @ 228,801: 28x28 +#663 @ 728,673: 28x10 +#664 @ 810,523: 24x28 +#665 @ 168,171: 17x20 +#666 @ 803,365: 5x5 +#667 @ 618,818: 25x22 +#668 @ 771,882: 19x26 +#669 @ 123,608: 17x25 +#670 @ 170,811: 21x15 +#671 @ 460,484: 28x24 +#672 @ 201,260: 23x11 +#673 @ 575,420: 29x16 +#674 @ 859,869: 11x27 +#675 @ 318,293: 12x14 +#676 @ 512,424: 25x18 +#677 @ 911,844: 19x16 +#678 @ 162,394: 25x29 +#679 @ 194,307: 21x21 +#680 @ 922,954: 22x16 +#681 @ 704,797: 18x28 +#682 @ 246,33: 29x10 +#683 @ 421,256: 10x12 +#684 @ 535,280: 27x17 +#685 @ 147,353: 24x15 +#686 @ 796,292: 25x10 +#687 @ 550,653: 11x19 +#688 @ 784,253: 29x22 +#689 @ 368,446: 15x28 +#690 @ 822,285: 18x25 +#691 @ 263,58: 13x14 +#692 @ 746,662: 23x26 +#693 @ 589,693: 19x23 +#694 @ 341,297: 16x12 +#695 @ 60,665: 24x26 +#696 @ 232,1: 12x24 +#697 @ 603,710: 10x14 +#698 @ 345,133: 29x28 +#699 @ 939,930: 11x18 +#700 @ 349,663: 13x16 +#701 @ 457,140: 15x17 +#702 @ 130,729: 15x26 +#703 @ 756,241: 23x19 +#704 @ 830,405: 20x19 +#705 @ 759,954: 14x28 +#706 @ 257,97: 24x11 +#707 @ 826,886: 16x21 +#708 @ 149,233: 21x25 +#709 @ 776,231: 20x22 +#710 @ 890,199: 22x28 +#711 @ 344,218: 22x26 +#712 @ 510,539: 22x27 +#713 @ 785,543: 23x28 +#714 @ 408,471: 20x10 +#715 @ 189,695: 22x19 +#716 @ 768,935: 18x23 +#717 @ 676,349: 11x19 +#718 @ 912,768: 21x11 +#719 @ 395,76: 25x27 +#720 @ 346,694: 22x12 +#721 @ 170,1: 25x11 +#722 @ 545,348: 28x13 +#723 @ 164,819: 25x29 +#724 @ 223,907: 14x24 +#725 @ 601,422: 18x11 +#726 @ 191,375: 29x19 +#727 @ 844,936: 16x26 +#728 @ 65,536: 10x29 +#729 @ 91,17: 23x22 +#730 @ 48,330: 17x22 +#731 @ 379,817: 29x21 +#732 @ 385,963: 25x26 +#733 @ 665,685: 29x28 +#734 @ 92,481: 19x21 +#735 @ 550,658: 21x26 +#736 @ 951,85: 17x20 +#737 @ 387,738: 14x11 +#738 @ 801,898: 26x17 +#739 @ 949,589: 15x24 +#740 @ 2,561: 23x20 +#741 @ 314,672: 10x29 +#742 @ 894,197: 28x26 +#743 @ 244,627: 10x20 +#744 @ 74,70: 13x25 +#745 @ 516,746: 14x20 +#746 @ 825,309: 13x14 +#747 @ 146,323: 27x26 +#748 @ 752,249: 29x11 +#749 @ 529,131: 22x15 +#750 @ 468,524: 14x23 +#751 @ 0,580: 12x11 +#752 @ 94,427: 14x22 +#753 @ 41,245: 21x10 +#754 @ 427,332: 27x21 +#755 @ 796,519: 17x29 +#756 @ 600,725: 23x12 +#757 @ 577,393: 21x10 +#758 @ 579,334: 17x14 +#759 @ 874,953: 15x25 +#760 @ 269,918: 6x7 +#761 @ 765,286: 26x26 +#762 @ 21,65: 12x17 +#763 @ 560,99: 20x25 +#764 @ 947,388: 21x21 +#765 @ 237,449: 11x11 +#766 @ 538,719: 17x16 +#767 @ 425,949: 16x24 +#768 @ 839,862: 11x15 +#769 @ 89,947: 28x28 +#770 @ 460,582: 25x16 +#771 @ 618,882: 17x12 +#772 @ 200,470: 23x13 +#773 @ 36,593: 22x17 +#774 @ 209,277: 10x10 +#775 @ 615,57: 11x15 +#776 @ 910,838: 10x18 +#777 @ 864,275: 14x17 +#778 @ 742,614: 12x21 +#779 @ 805,721: 10x22 +#780 @ 843,162: 21x17 +#781 @ 167,280: 20x14 +#782 @ 487,963: 27x14 +#783 @ 572,379: 29x28 +#784 @ 625,806: 6x5 +#785 @ 405,117: 5x12 +#786 @ 424,624: 19x26 +#787 @ 332,519: 13x22 +#788 @ 800,413: 13x24 +#789 @ 597,381: 28x24 +#790 @ 881,860: 16x24 +#791 @ 866,308: 11x25 +#792 @ 973,640: 21x18 +#793 @ 480,493: 26x26 +#794 @ 158,966: 12x10 +#795 @ 526,439: 15x11 +#796 @ 660,885: 13x10 +#797 @ 97,478: 28x23 +#798 @ 415,91: 17x15 +#799 @ 495,746: 27x10 +#800 @ 947,623: 13x11 +#801 @ 229,417: 11x29 +#802 @ 211,607: 29x15 +#803 @ 789,233: 27x18 +#804 @ 180,26: 14x26 +#805 @ 462,487: 23x16 +#806 @ 118,657: 29x10 +#807 @ 98,713: 24x14 +#808 @ 126,883: 23x15 +#809 @ 724,894: 29x22 +#810 @ 465,216: 27x28 +#811 @ 792,199: 26x14 +#812 @ 881,189: 12x19 +#813 @ 885,721: 23x21 +#814 @ 186,569: 26x12 +#815 @ 74,473: 11x19 +#816 @ 619,887: 26x11 +#817 @ 691,369: 22x10 +#818 @ 929,461: 14x28 +#819 @ 864,664: 22x28 +#820 @ 577,405: 29x21 +#821 @ 678,361: 22x17 +#822 @ 406,465: 27x11 +#823 @ 601,555: 25x17 +#824 @ 74,552: 25x13 +#825 @ 31,780: 10x27 +#826 @ 706,974: 28x11 +#827 @ 873,806: 27x14 +#828 @ 767,270: 26x26 +#829 @ 617,801: 20x22 +#830 @ 850,5: 11x23 +#831 @ 770,28: 22x13 +#832 @ 963,596: 17x20 +#833 @ 47,697: 24x11 +#834 @ 331,662: 23x18 +#835 @ 859,25: 22x23 +#836 @ 160,674: 10x14 +#837 @ 788,612: 29x11 +#838 @ 875,164: 26x25 +#839 @ 832,75: 29x22 +#840 @ 663,0: 10x21 +#841 @ 723,342: 23x11 +#842 @ 832,357: 11x23 +#843 @ 624,436: 12x24 +#844 @ 278,687: 18x23 +#845 @ 681,382: 19x14 +#846 @ 902,952: 25x20 +#847 @ 787,838: 26x24 +#848 @ 825,699: 25x17 +#849 @ 919,285: 18x17 +#850 @ 486,705: 19x24 +#851 @ 222,444: 18x24 +#852 @ 168,615: 14x15 +#853 @ 179,944: 15x26 +#854 @ 87,300: 21x22 +#855 @ 815,974: 25x17 +#856 @ 61,563: 10x15 +#857 @ 538,374: 18x18 +#858 @ 796,663: 23x14 +#859 @ 354,346: 26x23 +#860 @ 604,791: 23x19 +#861 @ 460,730: 25x21 +#862 @ 851,963: 28x12 +#863 @ 91,501: 24x17 +#864 @ 895,272: 3x5 +#865 @ 853,362: 14x29 +#866 @ 227,799: 20x11 +#867 @ 315,306: 23x15 +#868 @ 388,383: 29x21 +#869 @ 84,810: 14x23 +#870 @ 839,879: 23x22 +#871 @ 262,876: 18x25 +#872 @ 302,858: 23x14 +#873 @ 309,542: 25x25 +#874 @ 207,384: 20x29 +#875 @ 534,699: 19x14 +#876 @ 4,470: 21x10 +#877 @ 508,823: 25x19 +#878 @ 616,852: 20x15 +#879 @ 20,14: 23x23 +#880 @ 263,894: 20x21 +#881 @ 554,486: 27x19 +#882 @ 949,426: 15x22 +#883 @ 373,737: 29x18 +#884 @ 299,906: 25x26 +#885 @ 827,173: 28x18 +#886 @ 160,889: 8x14 +#887 @ 425,181: 24x15 +#888 @ 343,600: 14x29 +#889 @ 462,875: 22x10 +#890 @ 792,711: 28x28 +#891 @ 823,844: 10x15 +#892 @ 481,706: 27x29 +#893 @ 971,681: 24x29 +#894 @ 246,577: 18x18 +#895 @ 971,976: 27x17 +#896 @ 412,54: 18x25 +#897 @ 563,797: 10x11 +#898 @ 607,645: 18x11 +#899 @ 481,537: 16x14 +#900 @ 912,353: 14x21 +#901 @ 625,860: 27x14 +#902 @ 768,151: 12x17 +#903 @ 124,132: 16x20 +#904 @ 860,377: 27x10 +#905 @ 659,553: 18x25 +#906 @ 222,965: 26x27 +#907 @ 822,194: 14x22 +#908 @ 11,757: 13x29 +#909 @ 272,780: 26x22 +#910 @ 769,252: 29x15 +#911 @ 549,33: 13x17 +#912 @ 247,82: 28x12 +#913 @ 711,354: 12x13 +#914 @ 357,75: 21x16 +#915 @ 148,554: 21x20 +#916 @ 824,848: 15x17 +#917 @ 531,611: 26x19 +#918 @ 123,461: 29x17 +#919 @ 42,18: 18x24 +#920 @ 414,344: 26x29 +#921 @ 572,419: 24x16 +#922 @ 184,198: 17x14 +#923 @ 484,290: 12x13 +#924 @ 442,184: 14x17 +#925 @ 400,462: 17x24 +#926 @ 820,200: 29x21 +#927 @ 745,873: 13x16 +#928 @ 443,29: 29x28 +#929 @ 876,595: 22x10 +#930 @ 775,848: 29x10 +#931 @ 231,410: 18x14 +#932 @ 586,756: 24x22 +#933 @ 532,548: 24x14 +#934 @ 866,851: 12x11 +#935 @ 566,775: 21x14 +#936 @ 759,651: 10x22 +#937 @ 921,717: 12x26 +#938 @ 577,400: 24x13 +#939 @ 172,379: 12x26 +#940 @ 554,961: 25x23 +#941 @ 219,890: 12x28 +#942 @ 78,556: 7x4 +#943 @ 241,239: 20x10 +#944 @ 203,609: 13x14 +#945 @ 613,661: 27x22 +#946 @ 552,871: 26x14 +#947 @ 587,954: 16x21 +#948 @ 758,895: 15x22 +#949 @ 309,910: 16x20 +#950 @ 523,351: 19x25 +#951 @ 910,541: 22x29 +#952 @ 929,965: 26x15 +#953 @ 394,259: 24x13 +#954 @ 857,955: 23x23 +#955 @ 761,470: 15x24 +#956 @ 551,329: 23x13 +#957 @ 520,707: 28x20 +#958 @ 402,345: 16x24 +#959 @ 507,837: 11x15 +#960 @ 462,816: 16x29 +#961 @ 88,388: 19x25 +#962 @ 816,588: 24x26 +#963 @ 262,862: 27x29 +#964 @ 621,802: 15x17 +#965 @ 335,546: 20x15 +#966 @ 847,17: 28x28 +#967 @ 312,275: 26x20 +#968 @ 562,133: 11x18 +#969 @ 60,106: 25x21 +#970 @ 554,676: 16x11 +#971 @ 776,808: 22x27 +#972 @ 771,602: 12x14 +#973 @ 519,689: 23x19 +#974 @ 740,212: 13x11 +#975 @ 261,212: 13x14 +#976 @ 770,135: 18x24 +#977 @ 731,593: 4x4 +#978 @ 382,229: 15x29 +#979 @ 395,839: 21x14 +#980 @ 549,717: 20x14 +#981 @ 376,702: 29x10 +#982 @ 331,822: 12x18 +#983 @ 683,153: 24x29 +#984 @ 552,668: 29x13 +#985 @ 943,92: 10x11 +#986 @ 895,601: 21x11 +#987 @ 332,636: 15x24 +#988 @ 655,432: 23x20 +#989 @ 61,885: 29x13 +#990 @ 160,674: 10x29 +#991 @ 435,359: 17x15 +#992 @ 882,576: 20x24 +#993 @ 864,288: 12x11 +#994 @ 287,294: 21x16 +#995 @ 831,380: 24x11 +#996 @ 809,316: 22x29 +#997 @ 183,179: 17x12 +#998 @ 922,108: 11x27 +#999 @ 782,426: 16x24 +#1000 @ 333,200: 19x24 +#1001 @ 717,338: 13x22 +#1002 @ 421,89: 17x17 +#1003 @ 880,672: 19x10 +#1004 @ 891,37: 29x28 +#1005 @ 830,352: 26x11 +#1006 @ 436,65: 25x26 +#1007 @ 280,772: 27x26 +#1008 @ 579,395: 18x25 +#1009 @ 670,158: 19x29 +#1010 @ 222,564: 26x29 +#1011 @ 447,503: 28x22 +#1012 @ 622,853: 12x10 +#1013 @ 473,777: 12x25 +#1014 @ 674,335: 22x16 +#1015 @ 888,93: 18x20 +#1016 @ 205,309: 12x20 +#1017 @ 809,902: 23x19 +#1018 @ 50,776: 11x28 +#1019 @ 297,406: 11x27 +#1020 @ 750,578: 16x24 +#1021 @ 887,869: 22x28 +#1022 @ 472,673: 28x28 +#1023 @ 966,446: 12x25 +#1024 @ 792,890: 11x17 +#1025 @ 912,357: 14x24 +#1026 @ 576,966: 16x15 +#1027 @ 949,252: 19x12 +#1028 @ 969,589: 26x25 +#1029 @ 182,39: 18x25 +#1030 @ 967,699: 26x19 +#1031 @ 579,821: 29x19 +#1032 @ 763,937: 17x10 +#1033 @ 35,110: 10x26 +#1034 @ 842,80: 10x13 +#1035 @ 932,609: 29x11 +#1036 @ 800,665: 20x16 +#1037 @ 332,635: 28x18 +#1038 @ 635,818: 27x18 +#1039 @ 271,822: 12x23 +#1040 @ 906,342: 26x25 +#1041 @ 831,224: 22x10 +#1042 @ 619,718: 15x27 +#1043 @ 725,325: 26x13 +#1044 @ 684,336: 23x16 +#1045 @ 804,877: 19x19 +#1046 @ 80,263: 28x13 +#1047 @ 501,280: 21x29 +#1048 @ 624,243: 12x12 +#1049 @ 453,322: 28x23 +#1050 @ 257,523: 29x24 +#1051 @ 211,376: 26x19 +#1052 @ 590,821: 14x17 +#1053 @ 454,551: 23x12 +#1054 @ 580,174: 20x15 +#1055 @ 872,367: 11x14 +#1056 @ 44,557: 25x20 +#1057 @ 303,586: 12x29 +#1058 @ 493,547: 11x11 +#1059 @ 466,586: 10x24 +#1060 @ 219,872: 14x3 +#1061 @ 932,858: 26x27 +#1062 @ 63,51: 27x25 +#1063 @ 942,293: 25x28 +#1064 @ 101,585: 29x11 +#1065 @ 873,280: 18x28 +#1066 @ 717,208: 26x17 +#1067 @ 915,446: 10x3 +#1068 @ 941,969: 11x10 +#1069 @ 217,793: 26x13 +#1070 @ 176,29: 22x10 +#1071 @ 542,436: 25x18 +#1072 @ 619,820: 16x25 +#1073 @ 143,362: 14x14 +#1074 @ 541,123: 11x13 +#1075 @ 413,752: 23x27 +#1076 @ 293,310: 13x18 +#1077 @ 860,324: 28x13 +#1078 @ 423,737: 15x16 +#1079 @ 176,807: 25x22 +#1080 @ 279,309: 18x22 +#1081 @ 101,316: 10x28 +#1082 @ 399,743: 12x29 +#1083 @ 825,961: 27x25 +#1084 @ 533,156: 28x12 +#1085 @ 909,344: 12x20 +#1086 @ 612,720: 21x27 +#1087 @ 384,316: 15x14 +#1088 @ 872,566: 18x23 +#1089 @ 473,407: 23x25 +#1090 @ 464,747: 13x10 +#1091 @ 353,794: 28x13 +#1092 @ 338,293: 25x21 +#1093 @ 148,465: 23x11 +#1094 @ 137,548: 14x16 +#1095 @ 276,486: 17x28 +#1096 @ 413,103: 14x10 +#1097 @ 822,502: 19x26 +#1098 @ 766,863: 23x26 +#1099 @ 911,601: 22x13 +#1100 @ 685,835: 29x13 +#1101 @ 974,407: 18x26 +#1102 @ 912,735: 29x18 +#1103 @ 262,136: 24x13 +#1104 @ 319,422: 20x15 +#1105 @ 147,345: 27x12 +#1106 @ 213,411: 10x16 +#1107 @ 698,387: 20x18 +#1108 @ 832,356: 24x10 +#1109 @ 416,375: 21x25 +#1110 @ 714,746: 22x25 +#1111 @ 787,262: 28x16 +#1112 @ 820,86: 18x29 +#1113 @ 217,401: 10x14 +#1114 @ 254,154: 12x19 +#1115 @ 343,713: 15x11 +#1116 @ 493,154: 26x17 +#1117 @ 255,145: 28x13 +#1118 @ 592,707: 13x13 +#1119 @ 96,323: 29x18 +#1120 @ 815,488: 25x26 +#1121 @ 552,132: 26x20 +#1122 @ 482,784: 24x11 +#1123 @ 805,473: 27x26 +#1124 @ 787,214: 25x22 +#1125 @ 963,486: 28x10 +#1126 @ 84,573: 22x17 +#1127 @ 829,694: 17x23 +#1128 @ 636,241: 27x27 +#1129 @ 879,703: 17x16 +#1130 @ 937,444: 17x10 +#1131 @ 584,698: 28x17 +#1132 @ 363,929: 28x21 +#1133 @ 160,264: 29x10 +#1134 @ 55,574: 10x20 +#1135 @ 848,874: 22x27 +#1136 @ 758,500: 19x20 +#1137 @ 703,881: 29x22 +#1138 @ 165,179: 26x20 +#1139 @ 550,316: 10x21 +#1140 @ 694,730: 18x12 +#1141 @ 781,188: 14x21 +#1142 @ 965,631: 27x21 +#1143 @ 387,345: 17x5 +#1144 @ 898,369: 11x29 +#1145 @ 971,140: 12x26 +#1146 @ 678,136: 14x26 +#1147 @ 342,703: 4x4 +#1148 @ 869,283: 22x24 +#1149 @ 297,840: 22x15 +#1150 @ 75,738: 14x23 +#1151 @ 565,144: 22x17 +#1152 @ 487,392: 27x19 +#1153 @ 673,799: 27x26 +#1154 @ 140,481: 14x12 +#1155 @ 987,28: 11x17 +#1156 @ 693,384: 14x25 +#1157 @ 879,260: 19x29 +#1158 @ 766,482: 15x21 +#1159 @ 945,390: 19x21 +#1160 @ 245,566: 15x20 +#1161 @ 943,588: 20x27 +#1162 @ 415,961: 25x15 +#1163 @ 180,887: 12x10 +#1164 @ 552,276: 21x25 +#1165 @ 888,366: 11x21 +#1166 @ 712,691: 12x26 +#1167 @ 133,561: 22x18 +#1168 @ 889,79: 24x15 +#1169 @ 548,324: 16x24 +#1170 @ 604,802: 20x26 +#1171 @ 483,705: 19x10 +#1172 @ 370,487: 23x14 +#1173 @ 418,314: 22x11 +#1174 @ 184,194: 10x25 +#1175 @ 318,694: 10x14 +#1176 @ 883,477: 12x29 +#1177 @ 694,753: 18x12 +#1178 @ 868,573: 13x21 +#1179 @ 322,704: 28x29 +#1180 @ 828,946: 19x11 +#1181 @ 471,588: 20x15 +#1182 @ 605,809: 27x23 +#1183 @ 887,47: 14x24 +#1184 @ 135,625: 26x10 +#1185 @ 965,823: 12x17 +#1186 @ 528,268: 17x20 +#1187 @ 891,266: 27x15 +#1188 @ 751,944: 22x20 +#1189 @ 162,965: 24x27 +#1190 @ 427,500: 23x15 +#1191 @ 827,117: 19x19 +#1192 @ 968,468: 29x23 +#1193 @ 469,953: 25x15 +#1194 @ 151,532: 18x18 +#1195 @ 166,908: 25x18 +#1196 @ 604,626: 19x10 +#1197 @ 261,588: 16x17 +#1198 @ 103,475: 27x29 +#1199 @ 166,38: 19x24 +#1200 @ 505,253: 24x14 +#1201 @ 802,569: 15x22 +#1202 @ 332,701: 18x27 +#1203 @ 387,471: 29x21 +#1204 @ 494,65: 25x20 +#1205 @ 241,528: 11x17 +#1206 @ 485,316: 27x12 +#1207 @ 911,443: 25x10 +#1208 @ 394,729: 27x28 +#1209 @ 911,614: 24x26 +#1210 @ 62,753: 16x19 +#1211 @ 36,166: 11x16 +#1212 @ 804,769: 23x21 +#1213 @ 785,109: 27x26 +#1214 @ 423,796: 18x14 +#1215 @ 544,105: 21x14 +#1216 @ 450,822: 13x26 +#1217 @ 221,258: 13x11 +#1218 @ 986,480: 12x14 +#1219 @ 792,772: 29x21 +#1220 @ 775,0: 14x14 +#1221 @ 470,526: 3x18 +#1222 @ 127,600: 25x21 +#1223 @ 370,309: 19x12 +#1224 @ 283,677: 19x27 +#1225 @ 186,99: 18x15 +#1226 @ 2,502: 27x11 +#1227 @ 418,244: 11x27 +#1228 @ 282,431: 18x18 +#1229 @ 797,829: 22x23 +#1230 @ 874,961: 11x16 +#1231 @ 436,951: 16x28 +#1232 @ 688,702: 19x22 +#1233 @ 162,406: 23x18 +#1234 @ 454,875: 19x16 +#1235 @ 143,620: 24x21 +#1236 @ 19,612: 3x8 +#1237 @ 285,724: 17x14 +#1238 @ 394,789: 11x29 +#1239 @ 152,471: 26x24 +#1240 @ 145,345: 23x20 +#1241 @ 940,740: 20x16 +#1242 @ 126,644: 28x27 +#1243 @ 870,389: 17x28 +#1244 @ 209,929: 11x21 +#1245 @ 145,549: 25x16 +#1246 @ 656,125: 28x28 +#1247 @ 73,233: 17x18 +#1248 @ 695,306: 23x21 +#1249 @ 606,784: 20x19 +#1250 @ 323,402: 19x24 +#1251 @ 333,268: 26x14 +#1252 @ 674,573: 24x24 +#1253 @ 680,461: 21x12 +#1254 @ 111,104: 20x27 +#1255 @ 572,168: 11x19 +#1256 @ 820,295: 13x23 +#1257 @ 630,649: 12x15 +#1258 @ 617,39: 12x26 +#1259 @ 112,115: 22x22 +#1260 @ 349,123: 28x29 +#1261 @ 709,905: 16x25 +#1262 @ 264,173: 10x19 +#1263 @ 265,161: 16x18 +#1264 @ 341,820: 11x13 +#1265 @ 791,516: 28x25 +#1266 @ 180,964: 28x20 +#1267 @ 885,99: 20x20 +#1268 @ 950,683: 17x15 +#1269 @ 623,444: 28x13 +#1270 @ 140,347: 17x19 +#1271 @ 819,286: 11x25 +#1272 @ 873,39: 24x26 +#1273 @ 627,246: 4x4 +#1274 @ 822,30: 18x22 +#1275 @ 944,541: 14x10 +#1276 @ 428,750: 10x12 +#1277 @ 772,197: 13x26 +#1278 @ 946,92: 12x16 +#1279 @ 716,814: 20x13 +#1280 @ 613,132: 23x14 +#1281 @ 157,674: 25x17 +#1282 @ 516,242: 27x24 +#1283 @ 390,559: 19x17 +#1284 @ 456,724: 11x14 +#1285 @ 165,357: 26x23 +#1286 @ 526,47: 29x26 +#1287 @ 518,912: 19x10 +#1288 @ 966,207: 28x25 +#1289 @ 846,220: 15x17 +#1290 @ 99,667: 6x8 +#1291 @ 195,51: 27x24 +#1292 @ 872,954: 22x25 +#1293 @ 436,23: 23x22 +#1294 @ 79,315: 10x20 +#1295 @ 505,500: 17x16 +#1296 @ 434,715: 14x25 +#1297 @ 175,402: 8x8 +#1298 @ 563,354: 12x10 +#1299 @ 184,458: 25x15 +#1300 @ 454,347: 18x27 +#1301 @ 888,82: 19x22 +#1302 @ 967,661: 21x18 +#1303 @ 188,899: 19x11 +#1304 @ 136,343: 13x14 +#1305 @ 806,336: 14x20 +#1306 @ 362,578: 16x21 +#1307 @ 342,827: 23x13 +#1308 @ 111,552: 26x15 +#1309 @ 464,781: 20x21 +#1310 @ 700,823: 22x25 +#1311 @ 768,26: 25x13 +#1312 @ 410,853: 19x23 +#1313 @ 273,313: 24x21 +#1314 @ 91,183: 14x17 +#1315 @ 646,354: 17x21 +#1316 @ 494,57: 20x22 +#1317 @ 382,340: 28x29 diff --git a/2018/day4/day4.exs b/2018/day4/day4.exs new file mode 100644 index 0000000..0595372 --- /dev/null +++ b/2018/day4/day4.exs @@ -0,0 +1,97 @@ +defmodule Day4 do + @log_pattern ~r/\[(\d\d\d\d-\d\d-\d\d \d\d:\d\d)\] (.+)/ + @guard_pattern ~r/Guard #(\d+) begins shift/ + + def parse_log_line(str) do + [date_str, entry] = Regex.run(@log_pattern, str, capture: :all_but_first) + {:ok, date} = NaiveDateTime.from_iso8601(date_str <> ":00") + {date, parse_entry(entry)} + end + + def parse_entry("wakes up"), do: :wake + def parse_entry("falls asleep"), do: :sleep + + def parse_entry(str) do + [id] = Regex.run(@guard_pattern, str, capture: :all_but_first) + {:arrive, String.to_integer(id)} + end + + # [ + # {~N[1518-02-18 00:08:00], :sleep, 131}, + # {~N[1518-02-18 00:29:00], :wake, 131}, + # ... + # ] + def parse_log() do + File.stream!("input") + |> Stream.map(&String.trim/1) + |> Stream.map(&parse_log_line/1) + |> Enum.sort(fn {d1, _}, {d2, _} -> NaiveDateTime.compare(d1, d2) === :lt end) + |> Enum.map_reduce(nil, fn + {date, {:arrive, id}}, _id -> {{date, :arrive, id}, id} + {date, entry}, id -> {{date, entry, id}, id} + end) + |> elem(0) + |> Enum.reject(fn {_date, event, _id} -> event === :arrive end) + end + + def sleepy do + parse_log() + |> Enum.chunk_every(2) + |> Enum.map(fn [{sleep, _, _}, {wake, _, id}] -> + {id, div(NaiveDateTime.diff(wake, sleep), 60)} + end) + |> Enum.group_by(fn {id, _mins} -> id end, fn {_id, mins} -> mins end) + |> Enum.map(fn {id, mins} -> {id, Enum.sum(mins)} end) + |> Enum.max_by(fn {_id, mins} -> mins end) + |> elem(0) + end + + def most_min_slept(guard_id) do + parse_log() + |> Enum.reject(fn {_date, _event, id} -> id !== guard_id end) + |> Enum.chunk_every(2) + |> Enum.map(fn [{sleep, _, _}, {wake, _, _}] -> sleep.minute..(wake.minute - 1) end) + |> Enum.reduce(%{}, fn range, freq_map -> + Enum.reduce(range, freq_map, fn minute, freq_map -> + Map.update(freq_map, minute, 1, &(&1 + 1)) + end) + end) + |> Enum.max_by(fn {_minute, freq} -> freq end) + |> elem(0) + end + + def part1 do + sleepy = sleepy() + most_min_slept = most_min_slept(sleepy) + IO.puts("Guard most often asleep: #{sleepy}") + IO.puts("Most mintutes that guard slept: #{most_min_slept}") + IO.puts("Part 1 answer: #{sleepy * most_min_slept}") + end + + def most_sleepy_guard_in(guard_freq_map) do + Enum.max_by(guard_freq_map, fn {_id, freq} -> freq end) + end + + def part2 do + {minute, {id, _freq}} = + parse_log() + |> Enum.chunk_every(2) + |> Enum.map(fn [{sleep, _, _}, {wake, _, id}] -> {id, sleep.minute..(wake.minute - 1)} end) + |> Enum.reduce(%{}, fn {id, range}, minute_map -> + Enum.reduce(range, minute_map, fn minute, minute_map -> + Map.update(minute_map, minute, %{id => 1}, fn guard_map -> + Map.update(guard_map, id, 1, &(&1 + 1)) + end) + end) + end) + |> Enum.map(fn {minute, freq_map} -> {minute, most_sleepy_guard_in(freq_map)} end) + |> Enum.max_by(fn {_minute, {_id, freq}} -> freq end) + + IO.puts("The guard that was most freequently alseep on the same minute: #{id}") + IO.puts("The minute that guard was most frequently asleep on: #{minute}") + IO.puts("Part 2 answer: #{id * minute}") + end +end + +Day4.part1() +Day4.part2() diff --git a/2018/day4/input b/2018/day4/input new file mode 100644 index 0000000..4c4b0ea --- /dev/null +++ b/2018/day4/input @@ -0,0 +1,1106 @@ +[1518-08-06 00:13] falls asleep +[1518-06-10 00:37] wakes up +[1518-07-08 00:20] wakes up +[1518-05-13 00:24] falls asleep +[1518-11-07 00:32] falls asleep +[1518-11-21 00:01] Guard #641 begins shift +[1518-05-29 00:31] falls asleep +[1518-09-28 23:59] Guard #3023 begins shift +[1518-02-20 00:40] wakes up +[1518-08-17 00:38] falls asleep +[1518-09-16 00:28] wakes up +[1518-03-13 00:55] wakes up +[1518-10-07 00:02] Guard #2969 begins shift +[1518-04-01 00:28] falls asleep +[1518-05-28 00:02] falls asleep +[1518-10-03 00:28] wakes up +[1518-08-21 00:00] Guard #1613 begins shift +[1518-08-31 00:00] Guard #1973 begins shift +[1518-05-06 00:07] falls asleep +[1518-09-23 00:02] Guard #2437 begins shift +[1518-07-06 00:32] wakes up +[1518-06-12 00:02] Guard #619 begins shift +[1518-07-24 00:29] falls asleep +[1518-08-06 00:59] wakes up +[1518-03-08 00:24] falls asleep +[1518-09-26 00:15] falls asleep +[1518-02-26 00:52] falls asleep +[1518-06-23 00:03] Guard #641 begins shift +[1518-02-18 00:04] Guard #131 begins shift +[1518-04-01 00:24] wakes up +[1518-10-27 00:46] wakes up +[1518-04-26 00:50] wakes up +[1518-03-23 00:55] wakes up +[1518-06-16 00:30] falls asleep +[1518-08-20 00:48] wakes up +[1518-05-18 00:01] falls asleep +[1518-04-19 00:57] wakes up +[1518-06-01 00:04] Guard #641 begins shift +[1518-07-11 00:37] wakes up +[1518-05-04 00:15] falls asleep +[1518-07-04 00:02] Guard #619 begins shift +[1518-10-09 00:32] falls asleep +[1518-08-02 00:48] falls asleep +[1518-04-23 00:23] falls asleep +[1518-07-09 00:04] falls asleep +[1518-04-29 00:29] falls asleep +[1518-10-19 00:57] wakes up +[1518-08-19 00:20] falls asleep +[1518-11-14 00:32] falls asleep +[1518-09-04 00:52] falls asleep +[1518-08-28 00:03] Guard #619 begins shift +[1518-06-05 00:24] falls asleep +[1518-02-16 00:01] Guard #3253 begins shift +[1518-03-10 00:46] wakes up +[1518-10-20 23:58] Guard #2437 begins shift +[1518-07-31 00:42] wakes up +[1518-06-25 23:58] Guard #3023 begins shift +[1518-08-22 00:47] wakes up +[1518-08-05 23:59] Guard #2437 begins shift +[1518-09-02 23:57] Guard #2969 begins shift +[1518-11-16 00:42] wakes up +[1518-08-03 00:14] falls asleep +[1518-02-27 00:04] falls asleep +[1518-06-29 00:38] wakes up +[1518-06-06 00:12] falls asleep +[1518-04-10 00:38] falls asleep +[1518-04-25 00:02] falls asleep +[1518-08-02 00:03] Guard #103 begins shift +[1518-11-05 00:58] wakes up +[1518-08-05 00:04] Guard #1493 begins shift +[1518-06-09 23:49] Guard #1373 begins shift +[1518-04-07 00:13] falls asleep +[1518-04-01 00:00] Guard #1613 begins shift +[1518-05-05 23:57] Guard #131 begins shift +[1518-02-27 00:38] wakes up +[1518-03-24 00:50] wakes up +[1518-05-29 00:55] wakes up +[1518-04-15 00:48] wakes up +[1518-04-13 00:43] wakes up +[1518-06-17 00:19] falls asleep +[1518-10-08 00:52] wakes up +[1518-06-13 00:04] falls asleep +[1518-10-26 00:57] wakes up +[1518-02-19 00:02] Guard #2797 begins shift +[1518-02-26 00:37] wakes up +[1518-06-01 00:55] wakes up +[1518-05-09 00:29] falls asleep +[1518-09-09 00:42] wakes up +[1518-11-03 00:49] falls asleep +[1518-08-14 00:26] falls asleep +[1518-04-04 00:58] wakes up +[1518-03-17 00:00] Guard #1487 begins shift +[1518-09-12 23:56] Guard #1613 begins shift +[1518-08-01 00:18] wakes up +[1518-08-21 00:35] falls asleep +[1518-11-18 00:03] falls asleep +[1518-06-04 00:48] falls asleep +[1518-07-18 00:51] wakes up +[1518-03-29 00:00] Guard #2089 begins shift +[1518-06-07 00:33] wakes up +[1518-10-31 23:51] Guard #3023 begins shift +[1518-07-26 00:20] falls asleep +[1518-04-03 00:10] falls asleep +[1518-04-28 00:59] wakes up +[1518-05-23 00:52] wakes up +[1518-08-01 00:45] wakes up +[1518-09-27 00:40] falls asleep +[1518-02-12 23:57] Guard #103 begins shift +[1518-10-21 00:32] falls asleep +[1518-07-02 00:56] wakes up +[1518-05-17 00:38] wakes up +[1518-11-17 00:59] wakes up +[1518-07-31 00:19] falls asleep +[1518-07-23 23:58] Guard #2089 begins shift +[1518-09-04 23:48] Guard #2389 begins shift +[1518-10-13 00:13] wakes up +[1518-02-19 00:51] wakes up +[1518-04-23 00:56] wakes up +[1518-05-10 00:00] Guard #443 begins shift +[1518-05-09 00:02] Guard #2437 begins shift +[1518-03-19 00:02] falls asleep +[1518-05-19 00:55] wakes up +[1518-05-20 00:03] falls asleep +[1518-10-24 23:56] Guard #2389 begins shift +[1518-09-03 00:14] falls asleep +[1518-09-25 00:05] falls asleep +[1518-09-28 00:01] falls asleep +[1518-07-06 00:23] falls asleep +[1518-04-08 23:57] Guard #1033 begins shift +[1518-08-11 00:45] falls asleep +[1518-06-26 00:37] wakes up +[1518-05-12 23:57] Guard #131 begins shift +[1518-02-14 00:49] falls asleep +[1518-06-08 00:07] falls asleep +[1518-10-28 00:01] Guard #1493 begins shift +[1518-10-20 00:58] wakes up +[1518-04-14 00:42] falls asleep +[1518-09-05 23:56] Guard #1613 begins shift +[1518-04-25 23:59] Guard #2797 begins shift +[1518-07-07 00:18] falls asleep +[1518-06-20 00:36] falls asleep +[1518-04-12 00:13] wakes up +[1518-05-18 23:59] Guard #1033 begins shift +[1518-05-02 00:17] falls asleep +[1518-09-26 00:02] Guard #3391 begins shift +[1518-08-23 00:58] wakes up +[1518-10-12 23:50] Guard #3023 begins shift +[1518-09-24 00:33] wakes up +[1518-09-13 00:59] wakes up +[1518-04-20 00:00] Guard #2389 begins shift +[1518-11-05 00:05] falls asleep +[1518-02-16 00:29] falls asleep +[1518-03-29 00:14] falls asleep +[1518-07-12 00:34] wakes up +[1518-09-20 00:04] Guard #1487 begins shift +[1518-07-29 00:03] Guard #2447 begins shift +[1518-03-21 00:31] falls asleep +[1518-04-06 00:46] falls asleep +[1518-04-10 23:59] Guard #2683 begins shift +[1518-03-30 23:59] Guard #131 begins shift +[1518-09-28 00:51] wakes up +[1518-05-21 00:51] wakes up +[1518-06-12 00:53] falls asleep +[1518-10-30 00:48] falls asleep +[1518-05-17 00:54] falls asleep +[1518-04-30 00:51] falls asleep +[1518-07-26 00:40] wakes up +[1518-10-15 00:03] Guard #1033 begins shift +[1518-06-17 00:50] wakes up +[1518-10-24 00:57] wakes up +[1518-03-03 00:58] wakes up +[1518-06-03 00:03] Guard #641 begins shift +[1518-05-03 00:24] falls asleep +[1518-08-03 00:51] falls asleep +[1518-09-12 00:01] Guard #443 begins shift +[1518-10-29 00:23] wakes up +[1518-08-26 00:50] wakes up +[1518-09-18 00:41] wakes up +[1518-03-15 00:45] wakes up +[1518-09-24 23:53] Guard #1493 begins shift +[1518-03-16 00:42] wakes up +[1518-09-24 00:44] falls asleep +[1518-06-29 23:59] Guard #2389 begins shift +[1518-08-08 00:24] wakes up +[1518-05-26 00:49] wakes up +[1518-07-20 00:58] wakes up +[1518-05-10 00:51] wakes up +[1518-03-30 00:55] falls asleep +[1518-08-23 00:24] falls asleep +[1518-07-16 00:00] Guard #2437 begins shift +[1518-03-29 00:41] wakes up +[1518-03-12 00:59] wakes up +[1518-11-10 00:48] wakes up +[1518-10-14 00:49] falls asleep +[1518-04-15 23:59] Guard #1373 begins shift +[1518-06-25 00:04] falls asleep +[1518-05-25 00:01] Guard #1373 begins shift +[1518-10-19 23:56] Guard #443 begins shift +[1518-10-04 00:34] falls asleep +[1518-08-28 00:29] wakes up +[1518-02-12 00:05] wakes up +[1518-08-03 23:50] Guard #1487 begins shift +[1518-09-15 00:44] wakes up +[1518-09-11 00:00] Guard #443 begins shift +[1518-06-28 00:28] wakes up +[1518-03-01 23:58] Guard #1033 begins shift +[1518-09-01 00:12] falls asleep +[1518-03-08 00:50] wakes up +[1518-08-16 00:36] falls asleep +[1518-09-27 00:09] falls asleep +[1518-05-25 00:57] wakes up +[1518-07-27 23:56] Guard #131 begins shift +[1518-03-12 00:20] falls asleep +[1518-08-10 00:21] falls asleep +[1518-06-08 00:56] wakes up +[1518-11-20 00:40] wakes up +[1518-11-16 00:57] wakes up +[1518-06-07 00:58] wakes up +[1518-02-26 00:18] falls asleep +[1518-09-11 00:45] falls asleep +[1518-05-29 00:01] Guard #2969 begins shift +[1518-06-15 00:27] wakes up +[1518-02-23 00:23] falls asleep +[1518-09-01 00:02] Guard #3253 begins shift +[1518-11-10 00:54] falls asleep +[1518-06-24 23:51] Guard #2447 begins shift +[1518-10-13 00:05] falls asleep +[1518-02-12 00:22] falls asleep +[1518-10-08 00:47] falls asleep +[1518-11-04 00:16] falls asleep +[1518-02-22 00:04] Guard #641 begins shift +[1518-10-19 00:45] falls asleep +[1518-07-21 00:29] wakes up +[1518-09-29 00:12] falls asleep +[1518-03-26 00:52] falls asleep +[1518-04-12 00:03] falls asleep +[1518-10-11 00:55] falls asleep +[1518-04-19 00:13] falls asleep +[1518-04-07 00:03] Guard #3391 begins shift +[1518-04-26 00:14] falls asleep +[1518-03-13 00:12] falls asleep +[1518-10-18 00:58] wakes up +[1518-09-16 00:11] falls asleep +[1518-07-22 00:43] falls asleep +[1518-07-21 00:00] falls asleep +[1518-06-27 00:59] wakes up +[1518-07-14 23:58] Guard #443 begins shift +[1518-09-20 00:49] wakes up +[1518-09-19 00:04] Guard #3253 begins shift +[1518-03-31 00:43] wakes up +[1518-06-27 00:19] falls asleep +[1518-07-14 00:43] falls asleep +[1518-03-18 00:34] wakes up +[1518-03-27 00:38] falls asleep +[1518-05-16 00:23] falls asleep +[1518-03-02 23:59] Guard #131 begins shift +[1518-05-01 00:52] wakes up +[1518-06-15 00:11] falls asleep +[1518-05-23 00:25] falls asleep +[1518-05-03 23:59] Guard #2389 begins shift +[1518-03-03 00:40] wakes up +[1518-11-05 00:56] falls asleep +[1518-10-06 00:39] falls asleep +[1518-03-03 23:48] Guard #2969 begins shift +[1518-10-20 00:50] falls asleep +[1518-08-02 00:52] wakes up +[1518-04-14 00:54] falls asleep +[1518-03-21 00:21] wakes up +[1518-08-27 00:59] wakes up +[1518-10-03 00:36] falls asleep +[1518-11-05 00:13] wakes up +[1518-11-20 00:12] falls asleep +[1518-06-23 00:07] falls asleep +[1518-05-26 00:28] falls asleep +[1518-03-11 00:56] wakes up +[1518-07-28 00:37] wakes up +[1518-09-22 00:52] falls asleep +[1518-03-25 00:30] wakes up +[1518-06-22 00:15] falls asleep +[1518-11-08 00:44] wakes up +[1518-09-06 00:31] falls asleep +[1518-04-06 00:56] wakes up +[1518-11-16 00:03] falls asleep +[1518-07-06 00:01] Guard #2417 begins shift +[1518-10-12 00:53] falls asleep +[1518-09-17 00:01] falls asleep +[1518-05-20 00:13] wakes up +[1518-06-24 00:04] Guard #2447 begins shift +[1518-08-18 00:02] Guard #1913 begins shift +[1518-08-12 00:00] Guard #3391 begins shift +[1518-03-27 00:56] wakes up +[1518-10-05 00:00] Guard #2447 begins shift +[1518-11-08 00:31] falls asleep +[1518-07-22 00:39] wakes up +[1518-06-09 00:43] falls asleep +[1518-03-12 00:38] falls asleep +[1518-06-24 00:38] wakes up +[1518-03-07 00:20] falls asleep +[1518-07-13 00:56] wakes up +[1518-03-20 00:35] wakes up +[1518-04-13 00:26] falls asleep +[1518-09-27 00:53] wakes up +[1518-09-23 00:51] wakes up +[1518-10-15 00:49] wakes up +[1518-07-04 00:36] falls asleep +[1518-09-26 00:23] falls asleep +[1518-03-21 00:59] wakes up +[1518-10-28 23:51] Guard #103 begins shift +[1518-06-22 00:00] Guard #443 begins shift +[1518-06-13 00:49] wakes up +[1518-06-20 00:47] falls asleep +[1518-05-14 00:31] wakes up +[1518-11-09 00:59] wakes up +[1518-05-02 00:46] wakes up +[1518-08-16 00:50] wakes up +[1518-06-20 00:57] falls asleep +[1518-07-14 00:01] Guard #619 begins shift +[1518-11-02 00:26] wakes up +[1518-09-19 00:20] falls asleep +[1518-10-27 00:58] wakes up +[1518-06-02 00:34] wakes up +[1518-03-05 00:00] Guard #2969 begins shift +[1518-05-16 00:33] wakes up +[1518-08-14 00:51] wakes up +[1518-09-08 00:25] falls asleep +[1518-02-23 00:17] falls asleep +[1518-02-18 00:29] wakes up +[1518-06-12 00:15] falls asleep +[1518-08-11 00:42] wakes up +[1518-06-02 00:38] falls asleep +[1518-04-28 23:56] Guard #619 begins shift +[1518-08-27 00:36] wakes up +[1518-11-18 00:53] wakes up +[1518-10-13 00:27] wakes up +[1518-09-05 00:05] falls asleep +[1518-11-15 23:47] Guard #2417 begins shift +[1518-08-27 00:35] falls asleep +[1518-11-06 00:46] falls asleep +[1518-02-22 00:42] wakes up +[1518-10-16 00:02] falls asleep +[1518-03-18 00:51] falls asleep +[1518-05-02 23:57] Guard #1487 begins shift +[1518-08-17 00:19] wakes up +[1518-03-11 00:55] falls asleep +[1518-07-20 00:11] falls asleep +[1518-04-27 00:45] falls asleep +[1518-03-10 00:41] falls asleep +[1518-05-17 23:49] Guard #2969 begins shift +[1518-10-07 23:58] Guard #2389 begins shift +[1518-08-12 23:56] Guard #2389 begins shift +[1518-02-15 00:00] falls asleep +[1518-03-28 00:56] falls asleep +[1518-10-09 23:53] Guard #2797 begins shift +[1518-02-17 00:32] wakes up +[1518-02-15 00:05] wakes up +[1518-05-12 00:21] falls asleep +[1518-06-04 00:54] wakes up +[1518-08-11 00:02] falls asleep +[1518-08-29 00:05] falls asleep +[1518-07-10 00:59] wakes up +[1518-06-21 00:30] wakes up +[1518-07-25 00:02] Guard #2447 begins shift +[1518-04-22 00:45] wakes up +[1518-02-16 23:59] Guard #641 begins shift +[1518-06-27 00:47] wakes up +[1518-06-02 00:29] falls asleep +[1518-02-14 00:44] wakes up +[1518-11-10 00:39] falls asleep +[1518-10-24 00:38] falls asleep +[1518-05-28 00:54] wakes up +[1518-08-08 23:49] Guard #1493 begins shift +[1518-05-02 00:00] Guard #2417 begins shift +[1518-08-24 00:04] falls asleep +[1518-06-21 00:41] falls asleep +[1518-08-19 23:59] Guard #2797 begins shift +[1518-05-02 00:50] falls asleep +[1518-08-04 00:01] falls asleep +[1518-09-11 00:34] falls asleep +[1518-10-15 23:49] Guard #641 begins shift +[1518-07-25 00:14] falls asleep +[1518-04-20 00:28] falls asleep +[1518-02-25 00:41] wakes up +[1518-08-10 00:55] falls asleep +[1518-08-15 00:40] wakes up +[1518-09-21 00:56] wakes up +[1518-08-26 00:27] falls asleep +[1518-07-30 00:59] wakes up +[1518-07-18 00:04] Guard #2389 begins shift +[1518-08-07 00:57] falls asleep +[1518-06-25 00:17] wakes up +[1518-03-23 00:44] wakes up +[1518-06-09 00:36] falls asleep +[1518-10-09 00:40] wakes up +[1518-04-14 00:50] wakes up +[1518-11-14 00:35] wakes up +[1518-05-17 00:30] falls asleep +[1518-03-26 00:43] falls asleep +[1518-10-22 00:53] wakes up +[1518-02-15 00:36] wakes up +[1518-08-21 00:46] wakes up +[1518-07-08 00:03] Guard #2797 begins shift +[1518-10-20 00:46] wakes up +[1518-03-17 00:53] wakes up +[1518-03-27 00:05] falls asleep +[1518-05-04 00:46] wakes up +[1518-03-15 00:30] falls asleep +[1518-10-29 00:00] falls asleep +[1518-05-04 23:59] Guard #1613 begins shift +[1518-04-02 00:07] falls asleep +[1518-06-06 23:59] Guard #2417 begins shift +[1518-04-02 00:51] wakes up +[1518-10-14 00:04] Guard #2389 begins shift +[1518-06-19 00:48] falls asleep +[1518-08-27 00:41] falls asleep +[1518-04-16 00:40] wakes up +[1518-08-11 00:47] wakes up +[1518-03-10 00:13] falls asleep +[1518-10-22 00:04] Guard #1033 begins shift +[1518-05-29 00:42] wakes up +[1518-03-05 00:26] falls asleep +[1518-05-07 00:44] wakes up +[1518-10-25 00:42] falls asleep +[1518-08-13 00:48] falls asleep +[1518-05-18 00:29] falls asleep +[1518-06-01 23:59] Guard #641 begins shift +[1518-08-22 00:00] Guard #641 begins shift +[1518-10-10 00:04] falls asleep +[1518-07-23 00:04] Guard #3253 begins shift +[1518-04-24 23:52] Guard #2797 begins shift +[1518-07-23 00:57] wakes up +[1518-08-07 00:54] wakes up +[1518-03-09 23:56] Guard #1613 begins shift +[1518-09-16 00:00] Guard #1493 begins shift +[1518-06-16 00:07] falls asleep +[1518-03-29 00:24] falls asleep +[1518-05-25 00:48] falls asleep +[1518-09-20 00:13] falls asleep +[1518-08-16 00:14] wakes up +[1518-10-29 00:31] falls asleep +[1518-06-05 00:03] Guard #3253 begins shift +[1518-06-30 00:25] falls asleep +[1518-06-19 00:56] wakes up +[1518-11-21 00:57] wakes up +[1518-09-04 00:35] wakes up +[1518-10-23 23:59] Guard #1487 begins shift +[1518-09-11 00:53] wakes up +[1518-08-01 00:29] falls asleep +[1518-04-04 00:13] falls asleep +[1518-05-24 00:50] wakes up +[1518-04-26 00:42] falls asleep +[1518-03-26 00:29] falls asleep +[1518-02-14 00:56] wakes up +[1518-04-13 00:33] wakes up +[1518-09-23 00:34] falls asleep +[1518-04-03 00:00] Guard #2389 begins shift +[1518-10-09 00:24] wakes up +[1518-03-24 00:00] Guard #2417 begins shift +[1518-11-14 23:57] Guard #1973 begins shift +[1518-11-22 00:55] wakes up +[1518-02-16 00:57] wakes up +[1518-10-01 00:52] wakes up +[1518-11-13 00:13] falls asleep +[1518-06-19 00:03] Guard #1487 begins shift +[1518-10-30 00:10] falls asleep +[1518-03-15 00:51] falls asleep +[1518-08-07 00:42] wakes up +[1518-09-11 00:42] wakes up +[1518-02-11 00:14] falls asleep +[1518-09-30 00:55] wakes up +[1518-06-20 00:59] wakes up +[1518-06-04 00:45] wakes up +[1518-07-24 00:57] wakes up +[1518-06-13 00:20] wakes up +[1518-02-25 23:57] Guard #131 begins shift +[1518-11-14 00:02] Guard #1373 begins shift +[1518-07-05 00:01] falls asleep +[1518-10-03 00:11] falls asleep +[1518-07-16 00:21] falls asleep +[1518-06-11 00:52] wakes up +[1518-06-30 23:56] Guard #2417 begins shift +[1518-11-07 00:35] wakes up +[1518-09-18 00:02] Guard #131 begins shift +[1518-06-12 23:47] Guard #131 begins shift +[1518-03-30 00:08] wakes up +[1518-04-19 00:41] falls asleep +[1518-06-20 00:51] wakes up +[1518-05-28 00:44] wakes up +[1518-07-17 00:56] wakes up +[1518-10-11 00:56] wakes up +[1518-04-14 00:39] wakes up +[1518-08-10 23:50] Guard #3391 begins shift +[1518-10-17 00:54] wakes up +[1518-04-07 00:41] wakes up +[1518-05-21 00:56] falls asleep +[1518-08-09 00:42] wakes up +[1518-11-21 00:23] falls asleep +[1518-04-05 00:16] falls asleep +[1518-07-08 00:19] falls asleep +[1518-02-26 00:53] wakes up +[1518-03-15 00:55] wakes up +[1518-04-02 00:32] falls asleep +[1518-09-08 00:45] wakes up +[1518-10-30 00:02] Guard #1487 begins shift +[1518-10-11 00:51] wakes up +[1518-05-02 00:51] wakes up +[1518-04-04 00:03] Guard #3391 begins shift +[1518-02-10 23:56] Guard #1487 begins shift +[1518-06-27 23:58] Guard #2447 begins shift +[1518-10-31 00:16] falls asleep +[1518-09-25 00:40] wakes up +[1518-09-05 00:37] wakes up +[1518-04-10 00:48] wakes up +[1518-10-04 00:37] wakes up +[1518-04-08 00:00] Guard #2089 begins shift +[1518-02-17 00:06] falls asleep +[1518-06-07 00:07] falls asleep +[1518-04-13 00:42] falls asleep +[1518-10-19 00:50] falls asleep +[1518-06-04 00:05] falls asleep +[1518-04-22 00:03] falls asleep +[1518-05-07 00:14] falls asleep +[1518-10-10 00:40] wakes up +[1518-10-03 00:46] wakes up +[1518-11-04 23:48] Guard #3253 begins shift +[1518-02-23 00:36] wakes up +[1518-10-01 00:57] falls asleep +[1518-03-26 23:50] Guard #2447 begins shift +[1518-08-01 00:17] falls asleep +[1518-06-19 00:19] falls asleep +[1518-10-24 00:42] falls asleep +[1518-07-23 00:54] falls asleep +[1518-04-18 23:56] Guard #619 begins shift +[1518-06-15 00:01] Guard #2089 begins shift +[1518-10-09 00:14] falls asleep +[1518-05-15 00:30] wakes up +[1518-07-05 00:56] wakes up +[1518-05-10 00:32] falls asleep +[1518-05-24 00:25] falls asleep +[1518-09-12 00:27] falls asleep +[1518-11-09 00:32] falls asleep +[1518-06-20 00:02] Guard #619 begins shift +[1518-05-21 23:46] Guard #2389 begins shift +[1518-07-26 23:57] Guard #3391 begins shift +[1518-09-16 23:50] Guard #103 begins shift +[1518-08-12 00:40] wakes up +[1518-04-30 00:00] Guard #3253 begins shift +[1518-02-27 00:59] wakes up +[1518-10-12 00:15] falls asleep +[1518-07-09 00:46] falls asleep +[1518-10-23 00:57] wakes up +[1518-08-17 00:17] falls asleep +[1518-08-16 23:58] Guard #2447 begins shift +[1518-10-22 23:57] Guard #103 begins shift +[1518-02-12 00:04] falls asleep +[1518-06-23 00:37] wakes up +[1518-09-03 00:54] wakes up +[1518-11-17 23:54] Guard #2089 begins shift +[1518-04-27 00:50] wakes up +[1518-09-20 23:52] Guard #103 begins shift +[1518-04-23 00:41] wakes up +[1518-03-20 00:17] falls asleep +[1518-11-12 00:57] wakes up +[1518-07-29 00:47] wakes up +[1518-05-28 00:57] falls asleep +[1518-04-23 23:56] Guard #443 begins shift +[1518-10-15 00:19] falls asleep +[1518-07-14 00:22] wakes up +[1518-05-04 00:58] wakes up +[1518-03-01 00:36] falls asleep +[1518-05-22 00:45] falls asleep +[1518-06-09 00:37] wakes up +[1518-05-22 00:04] falls asleep +[1518-04-07 00:55] wakes up +[1518-06-10 00:40] falls asleep +[1518-03-22 23:56] Guard #1613 begins shift +[1518-05-18 00:10] wakes up +[1518-07-07 00:07] falls asleep +[1518-11-11 00:20] wakes up +[1518-03-30 00:59] wakes up +[1518-02-18 00:08] falls asleep +[1518-03-09 00:02] Guard #443 begins shift +[1518-03-18 00:56] wakes up +[1518-03-30 00:14] falls asleep +[1518-03-06 23:56] Guard #2797 begins shift +[1518-06-28 00:55] wakes up +[1518-08-03 00:04] Guard #443 begins shift +[1518-06-19 00:40] wakes up +[1518-03-14 00:04] Guard #1487 begins shift +[1518-02-21 00:50] wakes up +[1518-08-08 00:03] Guard #1487 begins shift +[1518-10-12 00:55] wakes up +[1518-07-11 00:35] falls asleep +[1518-07-30 00:00] Guard #1373 begins shift +[1518-03-03 00:52] falls asleep +[1518-07-29 00:32] falls asleep +[1518-07-12 00:38] falls asleep +[1518-04-25 00:24] wakes up +[1518-08-02 00:37] wakes up +[1518-10-16 00:56] wakes up +[1518-05-14 00:17] falls asleep +[1518-08-16 00:01] falls asleep +[1518-11-06 00:58] wakes up +[1518-09-15 00:01] Guard #3023 begins shift +[1518-02-11 23:53] Guard #1493 begins shift +[1518-06-02 00:55] wakes up +[1518-06-20 00:22] falls asleep +[1518-06-27 00:57] falls asleep +[1518-02-26 00:26] wakes up +[1518-06-01 00:23] falls asleep +[1518-05-15 00:12] falls asleep +[1518-02-23 00:20] wakes up +[1518-04-06 00:03] Guard #1487 begins shift +[1518-05-11 00:42] wakes up +[1518-04-18 00:01] Guard #2417 begins shift +[1518-06-09 00:02] Guard #641 begins shift +[1518-02-11 00:40] wakes up +[1518-07-12 00:16] falls asleep +[1518-03-09 00:40] falls asleep +[1518-07-01 23:56] Guard #2969 begins shift +[1518-06-26 00:49] falls asleep +[1518-08-19 00:00] Guard #2437 begins shift +[1518-07-27 00:24] wakes up +[1518-09-22 00:02] Guard #2089 begins shift +[1518-09-14 00:21] falls asleep +[1518-09-24 00:24] falls asleep +[1518-06-18 00:45] falls asleep +[1518-09-02 00:22] falls asleep +[1518-05-20 00:24] falls asleep +[1518-04-28 00:03] Guard #1493 begins shift +[1518-09-07 00:26] falls asleep +[1518-04-17 00:28] falls asleep +[1518-07-10 00:00] Guard #619 begins shift +[1518-07-28 00:19] falls asleep +[1518-05-06 23:59] Guard #2089 begins shift +[1518-10-06 00:00] Guard #619 begins shift +[1518-09-19 00:49] wakes up +[1518-09-05 00:48] falls asleep +[1518-10-03 23:57] Guard #641 begins shift +[1518-04-24 00:59] wakes up +[1518-11-17 00:31] falls asleep +[1518-10-02 00:36] wakes up +[1518-09-02 00:37] wakes up +[1518-06-20 00:44] wakes up +[1518-07-25 23:50] Guard #2447 begins shift +[1518-06-08 00:25] wakes up +[1518-04-19 00:26] wakes up +[1518-03-29 23:48] Guard #443 begins shift +[1518-03-11 23:59] Guard #2089 begins shift +[1518-11-01 00:01] falls asleep +[1518-04-24 00:31] falls asleep +[1518-07-07 00:13] wakes up +[1518-07-14 00:52] wakes up +[1518-10-02 00:03] falls asleep +[1518-11-11 00:04] falls asleep +[1518-04-14 00:11] falls asleep +[1518-07-07 00:38] wakes up +[1518-04-14 00:28] falls asleep +[1518-02-26 00:33] falls asleep +[1518-04-05 00:34] wakes up +[1518-02-20 00:15] wakes up +[1518-04-02 00:00] Guard #131 begins shift +[1518-05-23 23:56] Guard #2447 begins shift +[1518-05-25 00:50] wakes up +[1518-10-01 00:04] Guard #1373 begins shift +[1518-03-14 00:41] falls asleep +[1518-07-03 00:46] wakes up +[1518-04-10 00:01] Guard #1487 begins shift +[1518-09-08 00:01] Guard #2797 begins shift +[1518-09-27 23:53] Guard #2447 begins shift +[1518-05-06 00:21] wakes up +[1518-05-24 00:21] wakes up +[1518-07-15 00:48] wakes up +[1518-06-27 00:02] Guard #619 begins shift +[1518-03-18 00:01] falls asleep +[1518-11-10 23:51] Guard #1373 begins shift +[1518-09-14 00:48] wakes up +[1518-05-09 00:58] wakes up +[1518-06-20 00:33] wakes up +[1518-08-19 00:46] wakes up +[1518-02-20 23:49] Guard #2437 begins shift +[1518-05-26 23:56] Guard #1487 begins shift +[1518-08-22 00:13] falls asleep +[1518-06-25 00:55] wakes up +[1518-11-14 00:53] wakes up +[1518-07-12 00:57] wakes up +[1518-09-30 00:34] falls asleep +[1518-08-09 00:00] falls asleep +[1518-04-13 23:57] Guard #619 begins shift +[1518-08-15 23:50] Guard #3391 begins shift +[1518-06-26 00:33] falls asleep +[1518-08-07 00:00] Guard #1613 begins shift +[1518-04-08 00:49] wakes up +[1518-06-07 23:56] Guard #2417 begins shift +[1518-05-12 00:59] wakes up +[1518-03-14 00:30] falls asleep +[1518-02-27 00:48] falls asleep +[1518-09-03 23:53] Guard #2417 begins shift +[1518-04-20 00:53] wakes up +[1518-09-29 00:46] wakes up +[1518-09-10 00:30] falls asleep +[1518-09-01 23:57] Guard #103 begins shift +[1518-10-09 00:00] Guard #1487 begins shift +[1518-08-29 00:57] wakes up +[1518-04-16 00:17] falls asleep +[1518-03-12 00:22] wakes up +[1518-06-10 00:01] falls asleep +[1518-05-21 00:02] Guard #2417 begins shift +[1518-03-30 00:21] wakes up +[1518-05-17 00:00] Guard #1373 begins shift +[1518-08-28 23:50] Guard #1613 begins shift +[1518-06-17 00:01] Guard #2417 begins shift +[1518-04-04 23:58] Guard #641 begins shift +[1518-09-04 00:53] wakes up +[1518-10-11 00:35] wakes up +[1518-10-30 23:57] Guard #103 begins shift +[1518-06-03 00:38] wakes up +[1518-11-03 23:59] Guard #2417 begins shift +[1518-03-21 23:58] Guard #2797 begins shift +[1518-08-10 00:48] wakes up +[1518-03-03 00:36] falls asleep +[1518-10-18 00:09] falls asleep +[1518-05-14 23:56] Guard #641 begins shift +[1518-03-06 00:43] wakes up +[1518-02-25 00:00] Guard #2389 begins shift +[1518-02-21 00:03] falls asleep +[1518-08-03 00:42] wakes up +[1518-11-05 00:42] falls asleep +[1518-08-28 00:21] falls asleep +[1518-11-02 00:00] Guard #131 begins shift +[1518-11-12 00:50] falls asleep +[1518-02-28 00:57] wakes up +[1518-07-16 00:51] wakes up +[1518-02-26 23:54] Guard #619 begins shift +[1518-05-31 00:15] falls asleep +[1518-02-24 00:05] falls asleep +[1518-09-30 00:52] falls asleep +[1518-08-30 00:34] falls asleep +[1518-03-18 23:47] Guard #641 begins shift +[1518-05-27 00:32] falls asleep +[1518-07-27 00:10] falls asleep +[1518-06-17 00:43] falls asleep +[1518-08-29 00:41] falls asleep +[1518-07-22 00:34] falls asleep +[1518-07-16 00:46] falls asleep +[1518-06-28 23:59] Guard #1613 begins shift +[1518-10-12 00:49] wakes up +[1518-04-07 00:45] falls asleep +[1518-04-12 00:58] wakes up +[1518-04-09 00:56] wakes up +[1518-07-03 00:20] falls asleep +[1518-04-12 00:18] falls asleep +[1518-07-11 23:58] Guard #1493 begins shift +[1518-11-13 00:59] wakes up +[1518-02-24 00:42] wakes up +[1518-02-13 00:52] falls asleep +[1518-07-21 00:41] falls asleep +[1518-08-23 00:02] Guard #619 begins shift +[1518-04-15 00:04] Guard #641 begins shift +[1518-09-16 00:54] wakes up +[1518-07-20 23:48] Guard #2089 begins shift +[1518-05-31 00:51] falls asleep +[1518-07-04 00:51] wakes up +[1518-03-12 00:47] falls asleep +[1518-06-12 00:55] wakes up +[1518-05-05 00:40] falls asleep +[1518-09-08 00:35] wakes up +[1518-05-04 00:50] falls asleep +[1518-06-21 00:13] falls asleep +[1518-11-06 00:03] Guard #2389 begins shift +[1518-09-07 00:00] Guard #1033 begins shift +[1518-06-25 00:46] falls asleep +[1518-05-11 00:00] Guard #2437 begins shift +[1518-05-01 00:36] falls asleep +[1518-03-04 00:38] wakes up +[1518-10-27 00:55] falls asleep +[1518-04-14 00:16] wakes up +[1518-02-14 00:36] falls asleep +[1518-07-09 00:51] wakes up +[1518-10-01 00:15] falls asleep +[1518-03-16 00:23] falls asleep +[1518-05-30 00:59] wakes up +[1518-03-25 00:56] wakes up +[1518-05-12 00:49] falls asleep +[1518-05-22 00:58] wakes up +[1518-04-01 00:09] falls asleep +[1518-08-07 00:58] wakes up +[1518-09-13 00:49] falls asleep +[1518-05-13 23:59] Guard #131 begins shift +[1518-09-16 00:46] falls asleep +[1518-11-11 00:58] wakes up +[1518-06-13 00:23] falls asleep +[1518-03-25 00:03] Guard #1487 begins shift +[1518-08-13 00:53] wakes up +[1518-09-07 00:53] wakes up +[1518-07-10 00:32] falls asleep +[1518-03-25 23:57] Guard #3023 begins shift +[1518-10-25 00:57] wakes up +[1518-08-26 00:00] Guard #2089 begins shift +[1518-03-06 00:38] wakes up +[1518-02-12 00:43] wakes up +[1518-03-21 00:18] falls asleep +[1518-06-21 00:00] Guard #2437 begins shift +[1518-10-01 23:49] Guard #2797 begins shift +[1518-09-13 23:56] Guard #1033 begins shift +[1518-07-14 00:07] falls asleep +[1518-09-26 00:56] wakes up +[1518-05-17 00:55] wakes up +[1518-09-12 00:41] wakes up +[1518-03-15 00:15] wakes up +[1518-03-01 00:04] Guard #3253 begins shift +[1518-03-28 00:57] wakes up +[1518-04-02 00:16] wakes up +[1518-07-20 00:00] Guard #131 begins shift +[1518-04-09 00:42] falls asleep +[1518-09-18 00:06] falls asleep +[1518-04-11 23:54] Guard #2089 begins shift +[1518-04-20 23:56] Guard #3253 begins shift +[1518-06-16 00:00] Guard #131 begins shift +[1518-05-21 00:18] falls asleep +[1518-09-01 00:51] wakes up +[1518-05-12 00:34] wakes up +[1518-06-24 00:09] falls asleep +[1518-02-27 23:59] Guard #1613 begins shift +[1518-02-25 00:11] falls asleep +[1518-03-14 00:45] wakes up +[1518-09-21 00:00] falls asleep +[1518-05-20 00:37] wakes up +[1518-05-27 23:47] Guard #1373 begins shift +[1518-04-17 00:46] wakes up +[1518-10-11 00:02] Guard #1033 begins shift +[1518-11-09 23:56] Guard #1487 begins shift +[1518-03-27 00:16] wakes up +[1518-03-07 00:53] wakes up +[1518-04-01 00:45] wakes up +[1518-09-24 00:02] Guard #1033 begins shift +[1518-08-17 00:47] wakes up +[1518-03-14 00:37] wakes up +[1518-05-30 00:13] falls asleep +[1518-02-19 23:50] Guard #3391 begins shift +[1518-08-17 00:58] wakes up +[1518-05-22 00:28] wakes up +[1518-05-29 00:54] falls asleep +[1518-03-13 00:03] Guard #131 begins shift +[1518-07-26 00:06] wakes up +[1518-11-10 00:56] wakes up +[1518-06-17 00:24] wakes up +[1518-09-27 00:37] wakes up +[1518-05-05 00:57] wakes up +[1518-05-29 23:56] Guard #2089 begins shift +[1518-04-15 00:31] falls asleep +[1518-09-04 00:01] falls asleep +[1518-03-30 00:25] falls asleep +[1518-06-14 00:55] wakes up +[1518-07-31 00:01] Guard #1493 begins shift +[1518-06-10 00:57] wakes up +[1518-02-13 00:58] wakes up +[1518-04-21 00:36] falls asleep +[1518-02-23 00:02] Guard #1493 begins shift +[1518-10-19 00:46] wakes up +[1518-04-18 00:53] wakes up +[1518-03-15 23:58] Guard #1493 begins shift +[1518-02-20 00:01] falls asleep +[1518-04-21 23:51] Guard #3391 begins shift +[1518-03-08 00:00] Guard #1487 begins shift +[1518-08-02 00:21] falls asleep +[1518-08-09 23:58] Guard #1613 begins shift +[1518-03-11 00:01] Guard #3253 begins shift +[1518-03-06 00:42] falls asleep +[1518-02-13 00:47] wakes up +[1518-07-08 23:53] Guard #103 begins shift +[1518-09-27 00:01] Guard #1493 begins shift +[1518-11-02 23:56] Guard #2447 begins shift +[1518-06-14 00:02] Guard #3023 begins shift +[1518-03-05 00:29] wakes up +[1518-07-08 00:29] falls asleep +[1518-03-02 00:31] falls asleep +[1518-07-27 00:38] falls asleep +[1518-05-21 00:59] wakes up +[1518-05-11 00:10] falls asleep +[1518-03-26 00:45] wakes up +[1518-07-18 23:59] Guard #1973 begins shift +[1518-04-26 23:57] Guard #2389 begins shift +[1518-11-04 00:54] wakes up +[1518-03-14 23:57] Guard #1033 begins shift +[1518-07-17 00:19] falls asleep +[1518-10-05 00:55] wakes up +[1518-03-22 00:58] wakes up +[1518-09-30 00:00] Guard #2417 begins shift +[1518-07-02 00:53] falls asleep +[1518-10-01 00:59] wakes up +[1518-05-01 00:04] Guard #3253 begins shift +[1518-07-22 00:47] wakes up +[1518-06-18 00:04] Guard #619 begins shift +[1518-10-19 00:01] Guard #1487 begins shift +[1518-11-23 00:36] wakes up +[1518-06-06 00:56] wakes up +[1518-11-20 00:04] Guard #2389 begins shift +[1518-06-28 00:35] falls asleep +[1518-10-18 00:02] Guard #2447 begins shift +[1518-10-26 00:28] falls asleep +[1518-02-28 00:50] falls asleep +[1518-11-07 23:56] Guard #1373 begins shift +[1518-05-15 23:59] Guard #443 begins shift +[1518-08-03 00:57] wakes up +[1518-07-04 00:55] falls asleep +[1518-07-27 00:41] wakes up +[1518-03-12 00:43] wakes up +[1518-03-26 00:55] wakes up +[1518-02-14 00:01] Guard #2389 begins shift +[1518-10-23 00:25] falls asleep +[1518-07-16 00:38] wakes up +[1518-08-06 00:36] wakes up +[1518-06-03 00:30] falls asleep +[1518-07-25 00:56] wakes up +[1518-03-19 00:42] wakes up +[1518-05-26 00:02] Guard #641 begins shift +[1518-10-28 00:42] wakes up +[1518-07-18 00:46] falls asleep +[1518-02-20 00:25] falls asleep +[1518-07-01 00:58] wakes up +[1518-04-14 00:57] wakes up +[1518-10-20 00:20] falls asleep +[1518-05-08 00:00] Guard #2683 begins shift +[1518-07-15 00:31] falls asleep +[1518-09-06 00:42] wakes up +[1518-06-11 00:37] falls asleep +[1518-09-08 00:38] falls asleep +[1518-08-08 00:37] falls asleep +[1518-03-29 00:18] wakes up +[1518-03-31 00:15] falls asleep +[1518-06-03 23:51] Guard #2417 begins shift +[1518-07-12 23:48] Guard #443 begins shift +[1518-06-26 00:58] wakes up +[1518-10-17 00:35] falls asleep +[1518-07-21 00:46] wakes up +[1518-08-14 23:58] Guard #1373 begins shift +[1518-05-31 00:54] wakes up +[1518-10-11 00:43] falls asleep +[1518-07-13 00:03] falls asleep +[1518-05-13 00:37] wakes up +[1518-04-28 00:12] falls asleep +[1518-02-22 00:23] falls asleep +[1518-08-24 23:49] Guard #1487 begins shift +[1518-04-13 00:01] Guard #1493 begins shift +[1518-06-05 23:56] Guard #2437 begins shift +[1518-08-25 00:04] falls asleep +[1518-04-18 00:24] falls asleep +[1518-11-05 00:48] wakes up +[1518-10-22 00:26] falls asleep +[1518-10-31 00:41] wakes up +[1518-10-30 00:41] wakes up +[1518-06-05 00:56] wakes up +[1518-11-17 00:01] Guard #2437 begins shift +[1518-11-13 00:02] Guard #2389 begins shift +[1518-11-11 00:37] falls asleep +[1518-05-03 00:59] wakes up +[1518-07-09 00:11] wakes up +[1518-10-21 00:36] wakes up +[1518-02-14 23:52] Guard #3391 begins shift +[1518-10-13 00:21] falls asleep +[1518-04-23 00:04] Guard #3253 begins shift +[1518-10-29 00:53] wakes up +[1518-03-27 23:59] Guard #3253 begins shift +[1518-09-15 00:31] falls asleep +[1518-03-02 00:44] wakes up +[1518-10-07 00:52] wakes up +[1518-06-16 00:50] wakes up +[1518-03-20 23:57] Guard #1033 begins shift +[1518-06-28 00:18] falls asleep +[1518-09-10 00:03] Guard #1613 begins shift +[1518-08-01 00:04] Guard #3391 begins shift +[1518-04-03 00:48] wakes up +[1518-06-21 00:42] wakes up +[1518-08-07 00:11] falls asleep +[1518-03-25 00:21] falls asleep +[1518-08-17 00:56] falls asleep +[1518-08-14 00:04] Guard #1373 begins shift +[1518-10-05 00:09] falls asleep +[1518-06-09 00:50] wakes up +[1518-04-16 23:56] Guard #3391 begins shift +[1518-10-16 23:59] Guard #2437 begins shift +[1518-08-10 00:59] wakes up +[1518-03-22 00:23] falls asleep +[1518-11-03 00:54] wakes up +[1518-08-27 00:01] Guard #1373 begins shift +[1518-05-28 00:53] falls asleep +[1518-08-15 00:30] falls asleep +[1518-08-25 00:52] wakes up +[1518-11-07 00:00] Guard #1493 begins shift +[1518-07-03 00:00] Guard #443 begins shift +[1518-11-14 00:38] falls asleep +[1518-05-31 00:00] Guard #2437 begins shift +[1518-08-04 00:24] wakes up +[1518-09-22 00:55] wakes up +[1518-04-17 00:21] wakes up +[1518-05-27 00:58] wakes up +[1518-11-22 00:05] falls asleep +[1518-05-24 00:08] falls asleep +[1518-11-19 00:00] Guard #1613 begins shift +[1518-05-18 00:57] falls asleep +[1518-03-17 23:50] Guard #1373 begins shift +[1518-03-01 00:41] falls asleep +[1518-08-30 00:00] Guard #103 begins shift +[1518-07-25 00:27] wakes up +[1518-05-18 00:58] wakes up +[1518-04-30 00:59] wakes up +[1518-10-24 00:39] wakes up +[1518-03-26 00:35] wakes up +[1518-02-23 23:53] Guard #2447 begins shift +[1518-11-12 00:00] Guard #1033 begins shift +[1518-07-21 23:58] Guard #1493 begins shift +[1518-11-23 00:04] Guard #2969 begins shift +[1518-06-18 00:54] wakes up +[1518-08-08 00:18] falls asleep +[1518-04-08 00:39] falls asleep +[1518-08-06 00:42] falls asleep +[1518-02-15 00:20] falls asleep +[1518-10-07 00:28] falls asleep +[1518-08-24 00:25] wakes up +[1518-04-26 00:24] wakes up +[1518-06-22 00:44] wakes up +[1518-03-30 00:41] wakes up +[1518-04-04 00:42] falls asleep +[1518-07-08 00:56] wakes up +[1518-10-28 00:17] falls asleep +[1518-10-30 00:53] wakes up +[1518-08-08 00:57] wakes up +[1518-11-09 00:00] Guard #2389 begins shift +[1518-08-29 00:09] wakes up +[1518-03-06 00:00] Guard #1613 begins shift +[1518-03-01 00:37] wakes up +[1518-05-22 23:57] Guard #131 begins shift +[1518-03-06 00:11] falls asleep +[1518-08-30 00:49] wakes up +[1518-04-17 00:17] falls asleep +[1518-06-30 00:50] wakes up +[1518-09-24 00:51] wakes up +[1518-10-12 00:02] Guard #619 begins shift +[1518-06-10 23:58] Guard #619 begins shift +[1518-05-11 23:56] Guard #2389 begins shift +[1518-08-07 00:52] falls asleep +[1518-07-16 23:58] Guard #1493 begins shift +[1518-07-01 00:17] falls asleep +[1518-04-23 00:46] falls asleep +[1518-08-12 00:33] falls asleep +[1518-10-26 00:04] Guard #131 begins shift +[1518-11-23 00:30] falls asleep +[1518-10-02 23:59] Guard #2969 begins shift +[1518-09-30 00:49] wakes up +[1518-03-24 00:30] falls asleep +[1518-03-10 00:29] wakes up +[1518-02-19 00:09] falls asleep +[1518-09-05 00:58] wakes up +[1518-03-17 00:08] falls asleep +[1518-11-19 00:59] wakes up +[1518-06-08 00:36] falls asleep +[1518-03-30 00:02] falls asleep +[1518-03-01 00:51] wakes up +[1518-05-18 00:52] wakes up +[1518-09-08 23:53] Guard #131 begins shift +[1518-07-25 00:32] falls asleep +[1518-11-02 00:13] falls asleep +[1518-11-21 23:46] Guard #2969 begins shift +[1518-07-30 00:26] falls asleep +[1518-10-14 00:54] wakes up +[1518-08-20 00:18] falls asleep +[1518-11-16 00:56] falls asleep +[1518-04-21 00:53] wakes up +[1518-03-09 00:57] wakes up +[1518-09-17 00:42] wakes up +[1518-05-25 00:54] falls asleep +[1518-05-19 00:28] falls asleep +[1518-06-29 00:13] falls asleep +[1518-11-19 00:07] falls asleep +[1518-04-29 00:55] wakes up +[1518-07-11 00:03] Guard #103 begins shift +[1518-11-01 00:47] wakes up +[1518-07-04 23:53] Guard #2797 begins shift +[1518-02-13 00:25] falls asleep +[1518-10-06 00:41] wakes up +[1518-04-04 00:39] wakes up +[1518-06-16 00:18] wakes up +[1518-06-12 00:35] wakes up +[1518-05-31 00:44] wakes up +[1518-08-05 00:14] falls asleep +[1518-09-09 00:00] falls asleep +[1518-03-23 00:35] falls asleep +[1518-07-04 00:56] wakes up +[1518-05-19 23:50] Guard #2447 begins shift +[1518-08-23 23:48] Guard #131 begins shift +[1518-10-11 00:33] falls asleep +[1518-03-25 00:44] falls asleep +[1518-10-27 00:08] falls asleep +[1518-03-15 00:12] falls asleep +[1518-06-14 00:36] falls asleep +[1518-09-26 00:18] wakes up +[1518-08-05 00:54] wakes up +[1518-05-28 00:59] wakes up +[1518-07-26 00:01] falls asleep +[1518-09-10 00:53] wakes up +[1518-03-04 00:01] falls asleep +[1518-03-20 00:00] Guard #641 begins shift +[1518-10-27 00:00] Guard #443 begins shift +[1518-03-23 00:52] falls asleep +[1518-07-06 23:57] Guard #3391 begins shift +[1518-06-07 00:44] falls asleep diff --git a/2018/day5/day5.exs b/2018/day5/day5.exs new file mode 100644 index 0000000..7d0dbf5 --- /dev/null +++ b/2018/day5/day5.exs @@ -0,0 +1,41 @@ +defmodule Day5 do + def upcase?(char), do: char in ?A..?Z + def same_letter?(c1, c2), do: String.upcase(<>) === String.upcase(<>) + def case_differs?(c1, c2), do: upcase?(c1) !== upcase?(c2) + def react?(c1, c2), do: same_letter?(c1, c2) && case_differs?(c1, c2) + + # note: reverses the list - for part 1 doesn't seem to matter + def react(chars) do + Enum.reduce(chars, [], fn + curr, [] -> [curr] + curr, [prev | old] -> if react?(curr, prev), do: old, else: [curr, prev | old] + end) + end + + def part1 do + File.read!("input") + |> String.trim() + |> String.to_charlist() + |> react() + |> length() + end + + def part2 do + polymer = + File.read!("input") + |> String.trim() + |> String.to_charlist() + + lengths = + for lower <- ?a..?z, upper = lower - 32 do + Enum.reject(polymer, &(&1 in [lower, upper])) + |> react() + |> length() + end + + Enum.min(lengths) + end +end + +IO.puts(Day5.part1()) +IO.puts(Day5.part2()) diff --git a/2018/day5/input b/2018/day5/input new file mode 100644 index 0000000..a617281 --- /dev/null +++ b/2018/day5/input @@ -0,0 +1 @@ +abBAvaDCpPbBlLcsSnNEecZrxXLlRlLUuzCdAmOoSsuUQQqTtRMmrBbqLlqZzQQqhHtbTtBlLTfFOvUuVXxoMaAJQHBbhJjqMDUuoOdVnNvKkmYBbyCcVvjlHhhHLrKBbkRBbBbuUoOBpPRbcCBrQqRRrrGgYWwoOwWqUuQybVvsDlLdcCiIShQqHVWwUnNSsTtMmUuAasXXxxlyYLShSsHHhWIiFEaAlLTBbmMwWteOoHhiIPpfQqRrFPoObBpsIlLiSIiyYoOfmMZzqNnPpDdQwEeOoNWkKtAaTwnEfFrRlXxuUZzIiEvVHThHtVvhOoeoOzZtTNnLSsCoOhHWbBfFwJjwWhHZOozKkcCqQjJchHaAVYyeEtDXxdTQqvVqTtQDdVvQEEeeMmqCfFcvNgGnebBURrXcjJCyYxUvVuaAnNEbBeEeDlgZzGGgGgbBLdurXxRjJwWJjjLlTEetcAfFFdDfpiIPKkaRpPrUoOLloOXxuHyYyYdDhvKkOoVWwigFfGVQqlLAamMQqYyZrRkKzGLmMljnNJLliIgqEeWwsSQNnvEJjUjbBJBbpPRmMuUriIOoaAOounEeNXLlvVTtAiGgQqmMIGgavVkYypPYGgyAhHAsSaaKxCcqQlLzVvZGbBdDWwgAaCcnBmMfKkFVGQqgVKkvUyYwWZzQqaAhHrRuZzbBjJIfGqQGggGgOGyMaAYAayjNnJmSnxXNZVvywWvuUVYsSyYhHHhHuUUuhvmMVzDdeEbQFfqbXxnQqNBMBNleEchHCLnbzZmirRrRwjJkKWIockUuKHJjhqQqVvQQqHhmiIMCkKkKkDdKOBuUJjUukKnNwTCczZfsiISuheEHBbUFzPpFfZzEeciIcCcCCkKFfqDduUnNxXQbBTBbPHhptexXSsLmKkIiMQqlErRZBbeELwWnBbNUuwkKnNWVbBlLWwvVDXKkxJvVjXxdNnaAvoOBbaARuvAayIiYOoVKkuUYUuwQqYTuKkUkKNnbQqBtypkKPaAuUNpPnGgPpDdkKWcDdzZmMChHgcCGCBbOomMcKOoksnNSyzTtZQsSuUqHhYQqdoOAalkJcCoOjKBbyaAYvhHVLIIZzCqQcOozZHhiiVKpPbBwWNnkvDirRpPLYycClzeEZiIILaAIJjJjiqpPHhQlipPWwaAAaIvVGgNvXxVaAnKkNVvnZzvVnIiNsSGYyghHOojByMmYbbBpWAgGawBbzPCcpBbZmMJUcCuDdrRVvVvwWJbWwBjjaAPkSsKwWnNiWuUqBbvNnVgGeLlWwJjEGgkKvVqQIidDNnTtOoAaQIYyBfFbIiSsipPgbiImOoUuMunXxGVvgZztMZzmeiIEbBDdtjJoOIAaiowbBWpPOiIFfSslLjJunwWqIitTQSsnZzNPptTNUfOoFTrREAaeeESXxTtBOznYyNZYyoCHlLhcsJjvGgVoOsSLstTgGoBbOSNkKnlSSsNUunOoPpjJqrRXxTtQyAaGgYqQrRvVltjJYyvVTLGJewWEnNjuDdUkhHKdDvVwWiIyYfnJVvKkjNrRWwhXxHqgoOszZyYbBSiIGrRbBgfFGgGbBzZnOoNtTRtTLcClMmruUZzoOUuQZRrzFBAHhaNWwWAOoaMdDqkeoOOoEfFMDdhWxXMmwHVvDdOoyYRrEKkEXxlDdLeiIIidvCcVDeEoOeowWHDdYysSvVSuUspPpPhJNnCOodDpPcUyMmmMYSsaAfFwWaAdDKsSkuYyUdDuFQqfhLEefFDFfbcCBLFkKfXxldkKQqkoOXxEeKiIEAMghHtTGHhmPbCcBpCcIidwEeWWwFfPpxXYyGXxCGgcBbnNAaAagmikKIMqQIiDEeLlZzSpwWPgNkKKkLrRklLyeuUEYBbKlSsQqToOtjJBIibppPPMmYyiILxXwqQWIlLxCcJjEWHhweXhqwWLlQqQaAqQjJzMmZWZBYyyYbBstTJjHUuUVvuhSdjJFQqYysSfrRbBeEKkDTtPptpPDFfdTYSsytTPohHOpgGbYyfFlLUYyQMmGgEeqXMmxuzAaAiIxXtTDdpjrRuUJPpPCcMmslRhHrxZzHINnzZtTiQPIipqBKyYkuUbmMzWwZeeEESsSshsSkKGgKkuUZzQqTOtToGgneEWwnWAawNGgNtKjIKkLgxXGlgFCcffFGAVTrHCBbBbqQcnTtNuUlLuUaCcMmPpQqtTAYWwtTlEqQcCUtTuepVOovdDOoPLyhlfFzZRmMraAyYKkNpEePUuqQnQqDRrzZkKhmMrZzRxXHkKkxXVvKCNnRDdrBbZqgGQyYzcWZzEejJHNnhwvgFaAfBegGEbGcUJjuCAayYyWwrRYwWjJPplLBHSshbiDdOolLBJjJLlBhHjJbeELXxZEezlJoOKkGgwmMWbBGTWwhHtUhHeEuZyYzSsbBgPpZeEWwbBSoOdZzDTzZpPtKkLljJsqQbBlLWoOMmLlwWVvwDPpuUdxNnxXaANnbBmMyYXcCPpSNnWQqwhSsLPplHxYyXAadDGgIANnaibRjJryVkOonNQpPUuqICcCcioONnOoKJpPvVvxPpCcEeUuXxXbuhhHHUuzXxZUBVZMmfCciIFjJjMcCyYmoOJziIYyjnNIEeiDdGdPpDLZzcCJjlgSsyOqpPSsQkKgGcCWwqyYQYMbdzZXxMmDBkKwWEeqQqNnjmMmMZFfZzfFnNzyJjYwWmMjJhHJSsZzezZpPaPvVpeuUElwWkfFKXxBbvtZzTzZVBbLEbBCcegGjJHhAbyYBOoTtnNXBCcXxAUuafPjJoOaMmeDdEGgzSJjscRrCayYYykecvYyVCEgGmbBMoOKAaAaZzPBbDdNyJjFfYnpHyFfZzYiIOoFfloIzZvVJjePSspERrgNnGlLigGiILNFofFOTtpUzZuPfMmzZjJqQpPtTtTInQCcqxXuUsSmHhMBVvbXWwxrpPRbBqQnMmNukKHhmCLlcMOoUQqqOVvGgoHhQNwWUUuOETtEeTPptDuqccCFfCQQqdmMDdDSsolVvLzZxXrRBXcCxJjqkKZcCzKkQgGPplLwbOonCjJhHWwcNcRrIiCMmeaAEoUuBbOwWMlLbUuewJjWfFeEyYhHEyYJjkKnFAafNMJjmFfBTxUuXoOCcUuSsyiIAaUuKkuUYxFkKBbfBbjaAJwWXUuyXxYybRrXxyYIvVfFEecCMIizZXxXxgMtTRrmjTtwWJrRgbBDduiIUQBbqRrnepPeEEYywWRrWwIBYybvVxXLnNlQsDddDSqAaDcCdFfeaALleHhEhHWwhFfunlLPpNUPSqQspNZFflLAmMgGjJaLloxlLXnIiNCcsSLjYbIiByJlOUCTtEeBPpwWbbBBxUuXuUqejJfFEpxnNAYxXBbJeEmMjQDdqpPQfFquezZEPpvVUusSKJjknNUmMyeEIRrVviaBcCQKkOoBbBbdDqQHfFLmnNMlYyaAGpuUPLlrHhRPpgrRKeJjyYRrkQWwBbqQEuSsSsrROoHMmyYqcgidDIrRGIQqiCMmmMpPwsEeQqUupPgGXxSWhHWuUsSisSIzJoOPmhHKkMTtQGgDdqTzZQDhHWwdfWwFLDdDdHSsqQOQPpGgqofFTtZVDwWQqAHhafepPENnUFfOoulTtLYObOEePpkKoZzBHUXqtTkKQilLfFkKCcIrRHkBbRyYJjvaRrvVyYAVcCYyzZiIrmcEQCCccqvVXxeXvVrzZRiQqKkouBIifFbUOMwWdDtTJjYPpWwNnyXxmTpZzvYtIiTwWTtyqbxXBQqQArZzQEeqRamThHXgJtTUFfFfuOouUsApPcaAZLlKkzWweKkEjvVJCziIRrZpPuTtnNGiIzZgbBTPpLlcCgGNJjkKHhKknkKGgiFaaAQvVIGgXxKkvVoOxmVvVjJBbvFfEZivVIzDSKKkVvdqMXDuUdxmRiiKkIIrhHCcojYyiIJYmMALlAaRAarHhjJRsSryKkYIvLletTTmMipPItELUuGgwyYYysSWAahqQHleXMmAxuSsIiUXVyYUEQlLAacCqBuUbqQuUuUFfQZzTReErYytWNnwlLQWwqHhoOlLRpPrZeEMWwmgGMmRrvVsUuAaVvSSsVvNnJkqQKjvdSsDVQqPWsuUSpPLpPlatTjJOGtTgoAILQqJjdDNngWwdDFfstTSGyYASXqQgGXxxiIYysSfstTSlLUuFZzwTtalLACcWRrDCcLOoPdDZkKTsSDTmzZMxXoODdSstiIEevVtqQPURrupoOvVDdyYZZzkKnWwIgGiYhOowlLDdFsSFNnfuUKkvVGKBbZzkgDdGfFcqvVQkKXygPpGZayYATtHhqQQWwNnXBbtTxqyWsSwBbYWApPthokKOBbYyHIiCcUuTRrCTwWwDdWBbtAeEoynNYqQOaZSZzagGAstTbBlLErRCcePoOJoOjlLplLnNoONnkKxaAXqxXQTtKksfFSUTghHQqFfBNntTEeqoOYLlysuULlPyqQYpvVuqQUSbvBbVnUuSDdrRsEwWeGzZRrgbBorMmQqRSxXSTCFfAymxXMpqBbvBbobDdcCBOojmKkmTtMaVvuUAWwwWMhHvsSFfdcCDiIZzucCKhFfoTtaBbhHAOgEeXrRxTtGTVFfvGgtKUdDukzSsZrrugGUSVvsYOoyRrMmQqFsoOIiPpmyYpwWulUtUufctfFCckKTaAPNnxfFXfFKuUSskMmvyBboOTrRtEeKkmbMhgGHzZmoOJapyYjJxhHCZzpPTVvgGxMAaKknNaoOAZzmMKHhhHkzgGZyYpPWwMUuJjrRvVQquEnAMmaqqQJjOoutTUkKqQrbBWwRinNoOcCIUfFuVviORroaBbAIERreoqQeqQEYJjNnyEeOzZGgxXBtjfjJFJTbFayeEBbYUuFvVcCVkKvGFTthguWdMmpyLlcCYyYNnbTtBYyHlVvszxXZnwWwWNFfiHttfFTlLaACepPIiECKknNPpueEpPMmTcrRCtkKmMuJjxccCaAtTihLifLlFwNnWkaViIcUuQqCvWwdDIvVirRuULlVcCpXqQfFnNxjJxXPDdjhHTtJjJVvvPWwpeynNZRsSCcwWrraAhHKkIiwWRNnaDEeJjdARXxdDnaCcfFXXuUxFuWJjeEnNwzZgGURtTGgMQVQqVvvEeXjJRrxqSWKkweRrEFffFIrAaEzxXvVvuCcHCpUcCtTuuUUwWqFfleELQMctTHhLlgXMAxXSsDyPlxXLCEeerRoZzOEcUuDdpZzUuDsSdAagtTkKSiIxXsgVLlvTeErRtGVvYyVAavzZtJjTGYMCcBbmRrAhHaeqQEJjcCKkJjTtAVIiSsvBuAqQaReErnNkZzAaOorRDdYSGgsyYfLKkXxDdkKlGgyYFaAkJjiIKNjgwWGJRrpPneEhsSBlLbIiITtijJHNnowWAaOQqAaBGgErRMmebUuBnhRrKkWwHsSZzwHhgGekyeEmMOzZowwWSsWToOwBbWmlLPoIfFKQqkdDbBuUBbOoDzZrRvVBbLJbBZGggcChHoTtUuVvOunNYyKkGgdDmMxxiIAzZMmTyYBbAaOoGgfrRFbBgsStTBdDkKWwAaYTtuUDdHdQMmURMXeIiIHhiLPtLQqlBGglaAKkmMLymBbMYbjbtTBCwGgWCctxpPBbXsgOoGSNnBbtTqEpRrPIiGglLeOobxXuUBERwWFfrRGmIimbBmdcCQoOqDMpPBbBKkbxXpPmMUuPpMLQqlkJNFfLlnJsSjcCpMmKCcKkkQqAakVvVTtFAafvpPQQqmbZzBpFfbBEecCIUuwvVXsSuUnNAaiIukKUNAaXxWwSsHhyRrQPSsvVGglLbBHcCheUIilpzZPkKIiLpQXxqUulCmKkDvVARgGBbrkKRrmqhwrMmpuUgzZLRryYiIlvVBVvbTtGUuzjJSXpPxUuIXximHhAaJdaAcCikKIXxBbPpTGgtDOoJfBoJjZVeEnNIiqQlUTtuLClLRbChHchQqcCjtKkTubBUHhoOoORrWwHFfdDAahJHqEeIiGGBbMmdmMgGDUueSeEsEawbIiQqEOcGgCkoOgGKoDdGQqhVvHeEEuUehIqQSsQqRrFaAfrRANFHhYyuUuUDOoPxXbBQwWqyBbYtTpOUfFLGglFfQqDAaAaHQqNnsPpSzZhtTDdQkKzFfZLlJMmUXxcCSjJSsDUMmroOpPZzoOOoHhNnOwUueFfEvIntZzTftTFrRHHVvIihhmDdWwSsBsSVUKkRrtTqQEtTaYyTtAjOGsSaAIhHjZzbBlaLQUufFqjpPCcJdDiIcClALwWmMDdiImvVYSLlTuxXUFfqQmLlSsiIKkLXxZkKgGspPIiSBbzDdiIDbBBbmToOtMuUcXpPomMzZOMmSNnqQMmfFsSsxaGgnNfFAnNXUuirRnCYyOowkKWcCcNjJPEepjJGwGgRrxgtTEMmXfFHhxexHhNnXBLtTAEeacWTFBbqQKkfTTtjJtTtOovVNgGLfFlyyYYXxeEvVRBbndDLHhLlJfFNSNnsJMmLljmMumeENMaAIizcCSsZwWmrVvyYgGoOlVvFZzfhHLROMrCUucCcnNvVYyWwuUfFhHGgOeEoBDdFfUDDdhHrRFfduFfanOCcoopsSTtGOonNgaAMWSmlLzZMwWswokKOISzZsCcrRizZhpPWIbSsBBWZzwWpXeECcQXTtxzZCcqkKkbBANBbnEPgGcqQCxXpFjJEefrRUyYuADdayYlLXxNegGEnfFeKknoLlONgRrFeEfGPZzOoyYaZzRrAjJpTtSdYymRrNneERrXJjNnxfvVzOoZkKMetTEmgpPRrhfcuUgbmMDiYyIyNpQwWiISsOXYyxWRiIxOxXJsYDnDdyYfFNgGnNEepvxXgGniIGOoeEgEVvuUeATtPpPpxiIrRXEwxXrRNnBbWgGBbRAaryRYaAWTRlLrNnwcCdfUuFvVQLmTNXqBbJUuZJjndDNcIiBbCdzZlLsSbLlBaAYyaoOnQqjrqQiXmMxNXxNnEefFnKkIdDuFkKVvDdfUaAnAjJaNJjRxXXGpPKkgFfqQRrxFAaQqNmMvVnMmUufcCWwEwWAhiIHZzaEeSsFzZDeEdfaAOAaoeMmzZFlMmbyYFSsWpeqQRrVviIMmYdDyEEeIFqPpQfFftTihHheEseEqtTgGaAXCeEzZcxQaAcCosSOodDyRrAaZznNLlqQYqAaQfFAafZzLlhHVvyHGglLhmkKyYMmXLJzZjyONnWtTMDpPdzZBbTtQGgzZCcBTRrzZtbqlWjJwBbUHPphGPpgpPpLQqlgJjaAsSGnNpMNnmyFqQUufFRmMiSsdNnqeSdDBblCIiVDPpfFfOonfYyEeFzPOYnNyuNGgJMcXxCeEKkRKkAeeEznNZESoXgycPwkKEeWTIitoRrrRDPpyYddnJLOofFllLAfFvVatTanNfFnzZNdDLuUPpxMmJjEMmOolLSrsSRsbwMSyiqcCEfFMmzZnaAeEFDEcdCqQBqQkBmLltTPgGyYDOHbmMBhNnHdDhCBzxgGYSypPKdiIdDiiIIiqQCcqBACcalLXxXaAzZqVyYvqQmsBbHtThHgGhzZFfSOtTHDhvVpPIMmZbzZBaAHkKhXxJXxtpPTLljVgGBWwgiIGBSvVnhMmHNDGgzSsZdhZIizmUuMmIsSfgcCCLlpIQqiCcfFXeEZrbBRMnNFfKyYkbBmbBuUjlLdDJHhDTttTEsSCcirRIwWRouUOGgpPaArIinpPNkVvKCcwgsSTEetGmlLcCtmMTfFMbxXBnNJJjAakKjWfvVssSSEeJjytTDdPpdwyYQqQhHdDXJjxJMmGwWPpgNnQqjqLZzYydDlxXMKxXSaAdDfEeFtkBbBuUlezZEUxXPoOpuwsStTbhSsUuGgppIzZnNiIUujJaAxXwWdDSsHwTlLoTtzZFfKSskoOTVSsSsLBMmVvDeEsSRrXSrRxXHhsqUuUqtvamMqQuUCyYhHVvKkwWZzFfGgCRGgrNQqnPpmYyPpRzZrDxhHHhFfXJjwWHhvCxXbOoWwBFGxXKOSsXxiILwyYmMWxAaXCeEgGfFsaADdeEgzZcOwMmWmMxXqQWwqmMQyCcpquaAoKkOnNUQPpEJjeAXbPpKkiIxXpPDcCSsdkdDChHZYyoOzWwWwcKNzVvZwWnBxnNsSfRBbrmMUwbBWuKcxXAaTZztCkiIedTtgGvVCmIELKkTtlnNwWeLjJCclQrEeSsBisoOSKhHkIYyYWwwWTtyXEWGgIiTDiIdwzZAaWhBbyYzzZgeEvVGgGpiIrRPoHJjdDhqQeEOZHaASdDsbRruUBuAWwaWLlwYKkyyhTdkKDfaAYyqQFPGuUBbZzZxXzLlcCOMmoXADADdrRvVszIiZSemkOGYEeqQdDpFfLWwlpPzdDNbBBlsATtDduUTtOoifFITglLqQGtlAaKkLXQMWNnrUuuUxXRvVzuUfASkKsElLeSvVsgGTnYLlQiHnhXxluULdgxXGiIRrWwlxblLSpZzkDdKGgPpOoPjICKbBNnqQyYrRWweEIiRrsShYFfzZwOVMmvgGoWFfaZzAWwykGjJgKgGlLHqueEUaAMmEtTmfFfWZzjJwwsSWPHjJhhPprRJjZBbluUhyYLBxhoOALQqlhHQTtUJjUdDtkKTQquiWwIuxXWAZzqQarRaAwzZuiNnaiDdacgGgRrPpcFfbBJjjJrUFfHCchoQqOVvuRNnbwWletTqQEaAjXuiSseEIvsSdDfFsFjJXxIMmibMmBBcPpyiIiILlKCxXfCcdDIcQqSNFiIMQcCqWPEmMVJjkSsKvKkFrRWwaAGgyYyYuUWhHwLlZzinNpFfuEeUjJaAWwVviIRvVqQlLdlLMmjqQQqJIfmMgKsCkCcZmMzKknKkNpPdDZzRrKkDeEJPSSaZzbBFfAaJjFfnNvjgpPGJprhUkVvsSAJjaQpPpPdPpZGgWwzUugzZGEewCcNnTtTtFdLlPqQpyoOCcjJjzZJYcjTtJCvVDBbgGhwnNTrRGgtvVxXUmEegaAFqQSsfwIUpOompmCcMPrIiBtTShpPtmMYfZzjlLAahpmMPiMxTSuZHhlLPnoOaLlANpHtTFHlLhfvVQLlgeoOTtrReEEGqsSQHyRqGgNnGKhHhHkPprReEljJJjWDdwGgZzBHxMQqzZIihrRHJjuUCrzZAaRVIifVvuUcsSCoEeFMsSEoOnNekRVypPYZnNbXxXxuMXxmWrRwjJEeRrXIkuRhHHhBbrUKjTtJFfQqmaAwsSBNnbJjnNFdDfFpHuSsUJjtsCKkIuiIHbthHThqQqQYyKkZTtkKtcynNYUzqQkKZWwxUbBuQqcKkCoMtTwJjDdCjWoOlLwWrwWqgGQZfYySsWTaAOOoIiHhobmQqMEtdDtTiIuUZzTuBbqJhHjhuUcYyCHqeEQGgQqRrrRUuOqQonZLlLZkKzSswWtOoWUrkOozZoyYORrfTtIrRkOouAIxXkKxWbBVEKDdmMYLlyqQkOtTtTjpcCSXeEIjJsHhUzdmMDZDdyYslLSOdrRMtTmDwWNGgOoKkFOofLlNgqRrQFfuQqUGQFfLAaCclqqQMmGgOoDdCcYxolStTseNnEdDhHVGnNPpgvNpPnLLvVlYBbOolLygQqDvVHhIicjJCwnwOosLnNlFefFdaADWoOPvVpZzRrzZrYyRsSdCDAaDducCoOUJjKkAwWaJFfeDdErQumNPCpUfFpPuROorzKNnkZPaAXxKqeFFfflLEbBVZjJFJjfPHhhdDuyYsqzyhXSAahHmAFfLOoWwlQqCcQZoVYyvOhHzEequmMXGRoaipbiIQrvVRqrRdvRTTtHhCmMUudDKfFMmpPpqRhRpPWbBwKocCjFfJtTDvlLVchHNnEnIiIiGKkkuPpUzZKeEPaAptlVvOoLoOFflqQLdHlLOosSWFvMmkKGIhmMHiggGuLnNVkKmJvFfVjhHMMmSWwkRhweEygHhAzYyeEZHhsSQqaOgwWGgGtTiIJxcsLlSpQNnKkYymaANnPpMqYndDNiIyPCIiPpzZXyRrxlOozZuUXyuUYcwvyYXgKgGkGuUnDiIctTCcAaCsSpPsjJSLAvVKkUUAaukiIKuidDFMPCNnzjEpPesSJHhZjJEgFWyfjjJiIJbLlWnpPNCffFFiIcIEeQqzZooOOilysSYDXOoxgluJMmjOMDdmuOJjaXxjuUeEAaGgJdDvsKkSXgFKVvkfkKWwYyLfpvVdUuBbDPHhRuMZzmUdkKGgDyMmYktTKrFGgAgGaIiNlLNnnrAkKQNXsStTynNYwWYxXDRaAwoSsxlLXjnNJzZkKDersDQqKkdOvUuQtMmXxJjRBIibuXxTnJiIqQjjJweMsiPYRrywWdfFcCgGQqxeZZulLUFwWtvVaAcYQrRZzlaALQqhHkKsSlLMmMkjkKJeEtzPzuNnRcCdCkSjapfFPzZYyAtOKkmMoVveEOoTAansYxXbgGiRztrRDdrRTwlJjLPsSZzpKkMPCkKccEesSCmkKnNaDjaAJdPpxXPHHhGOdxXliIdDLpjJPpuUPfniqKxXkTIitsSZzQFdsSgGZzEiAapnNtlLlLQcCgMmGtAaIaqQAzZawCGgcPpWHhAFfiTtidDgCcGOolYyvePpUNEeMmngGfFhzAaFfGqQgOwERrWwRrMmYyOCcDsYyIuuUuUUYyQqHcPCcfFIGhkKqBMaHjJBbWDwWdoOdsSDlLNmsdLTVvtivVSsOusSJjUFBAadbbAaNfFeLlEgjzdRLvVwXxKwWkzZvsnNwWSZzvvViIDbBbBipPxXCceqQJKSKksCUtTrqfFEeZzEetTVvLcCllGEeMpPnFkKfPAagtTQTDdfmiIQyvVSaGgTUuNIcVvCiITtDdpPQDdMcmMcCCEvVtxXOoUuLlQqTpPoPpOpBRrnNkwPpxLTiTtIiPpItdDgNnGwCcStCwWcOKRsXxrEeRSXxBXPsSMkKvVpzLGDbBGXxgdhzsEerRPRWsoOSNwWEhHeMfdDFmGfFhHCfFOFfoOuSsgOkKhZiIzWweEzFuUfcuUCAMmakWRraDdAwcCFDdfnNxNeUuJjmMsSeQFfqvVvsSKkXxyMmMmtTPoOKVvYcCPpwfjJFFfmwWkzpPaADuAKkOoYrRymavXuAaUzuUZxIbBuUoOhRIirHgrcTWojryYDXyYTgGtPpAoSsoQCcgpPsbBSbBppTFfLlCAOQqoLlPpfFrRaEeAsSlLcdCaADuUTEeTtVvtqQtwWuiIoODdGmiIhuDJjnlLNmMTpiIRjJBQqTtbGQqGgBDKkfyAKkIBbXnNxwFfIiMmwfwAyYbESseFfBoBlLbOLEeCiRhHUKkHyYhCceEGxXggGNnucCKkRrhHnhCCEeIiAaUuIirRchdlLOHjJHhHhGNWwxaPppPKkaEeFfvmMVbKMlLgGNaqfQERvVrLROorlwgzZIInXIlbPpqQBOEkKeWwAZtTpPRrzZhoruUPLnNlgGLFIiAaBJOojxmzwWSsBSsJOZbEeyYBGgPVhiIHrlLYEeyXnfAzyYnNrxjJXfIiKifFIAaRrkRroOzZFGIAqQlLaKdDkjJoOiaiItpPUaAuTifFIsSUNbctwqQHhWLyYIIiuUIiildJjYyeBbOoXlLucfFyPpkKkpEjaAJdLoOBcBbSAkKaMlwXxWRkKtTNnGgkvVWuUwKGzMmGgZQqlLQQqMmEeKkYKkEVmWwNnszziIZMoiIKwdOOooALlgTkcYopPAZzPEeUZoOvYfFyrqQDdxXdDQzZgGCJjlrRLZGgdCcEDdrrRQqqQqpPSsLlBfMmFKkSsICbBcpPkeVvEOoQqWwbBXHcChxzZBbDFfCKkcHhLIilNJCEWhHweUhnNVQgMmGvVMmRQoBjHlLhUuPFzZfYybWHkAageBbyYdKkHEoOehDGgLfOHoORrMryYIithsaZzdkKHMmBbZzFfoqQOFskAaFNnfKceXxyYEmOwJjURriIBWwbovsqpPbBRrQJjEehHvGgvwQqWVEJmhovVsPvNwWnNnLNnRrZLlWRYjYyJRrynmjsSdXFDfFuUjJwWfQYTtJfFjQqyLuFdXxDQGgzZwCcRrcuUGnNHwlLWcDGqQdDmhHMFHbeEBkKZzyTtrPpSxXKksRosSqMMmmCHovpZziIKktyYTPVaAHqlaAqQNnSRrsJJFfiIaAuUjCcJRugGRxWwVVRTAgZxvMmVtQqxXQlcCLNFyyYTtqQIitTCBbKkQIioZuUeEoQAaqGgsSSNnRrsVkKSKEedUuqxADdyzYCKkkmMKLloueDdhtTRroOmVvvcHhklLhHuLFfXsjJgGFfShHRjJhrRHcCrNngfqQLlmJjCcnNrgXXxRHBUMfFmSbBsuIogZPNEleoOELTsFfivVgynNRrYGRfkGgGtTgKpJJjjPzeEZFFbBUNnufpycCMmYhjAoOawWJoQqTNntHLXHhxlNnEehUyCcwWkcJYDdaAntTeEjTtJNQqWgFVvfTcCItTYyGgKnNgImTtzwWZrRZzSrpPRNkGgwWKBbmLlMxoOJnvEeyYoOCclLGgMmNHhWwGEoOGgzZHhxXsSIjSstTcWwBysgGSJooBbOAGJtlLCnvppUulHFklLEeXKkvVPuhHUdRrOHuonHfZbByYOoEeCccCLrJjRlzQIimxPpXUuNpPLldDkkKiIgwWGKnzlLGZzHhhGTcAaCtfFgHHEBbebBrRhWwVtTqyACcdDOsSybBYocxXkKCQqtTTtMmIakKerRtyYTEQqjJNFOoORVvxXvVwWoAjJaODddAaDYYKPpiIeoOyYOWwoEkTCmYoQwWlBbxWwZfFfFQqxXoOxaAZuIirRDdeaATtEgGEeNnRxilyYYsrIsGgtoOTqBWwbOPpoQyUpPuBbvVYwWTpPtSHhxXxXOljMAvzXFfEZtHhzZqSsQcbNgHhGnKVHNKQqkpPtCNOjJojJJwjtTcCSfFaAsrNcCPPpDdpFfwBbpkcdDCHhXHBVvbMmnNxkfFxGgXImOrMoOiwkKZlAfoOCkpPHhbuUBKQHiIhEsYmMYyqHZzSyYmNnFDdeECcYzZXxyEeMmqvzhHFfodDXxrRBgGEDhTvLmMlVGYygtLeUuZPpNnVgGvhHgJXfBLCcwRrrRMtTLlLFfliIMmCczrReEZXXEvVZzOoetTUuMmZzuOdDoVvbBPpxIlviVvgxXyUufFmMKkJtQRzZTRIiQwoOLwiIWxUOmeEMSsrRokQWwqVEIDFZiIzyYMmkKcOoCdDfSslJjgGPqQpwWEeVMmvFGgnNUumqQLOoPpDdAtTBbmuUjJLyYnNIiDOLlhHNjJywRrWYGgngfFpuWwRyYcYyKPpBUBbdDAaQqUuumMhDdpPHggqQKkQqKkkKSQNuUDgvViIjXfFbIiaAfvucmMCxpPXfvEexXDdXvVbcnUuulLyYvVVvNnAaUgSxXsSTkKtTDHNnfFbYyvxyOMvZzVCSsKkLGgKXlLSsYTGgqQUHhutrRruqXxjJPSVTtyrRQkKqYnkKPpNvXXeEEeSseyYvVEWTtwBbEevVtTekKEAaQqwqQdDvzOWzkKZRKAUxeMWbSsBmwPpjxXJXxXxKksSvbQsWwWbetfFMKkIEeABsBFfPOoyhSsHYPpyqQYeWwEdDBHOQqoIPpiGgCjJLlmVpPvMVvyYLzZxuMedDMmgGTlLFfTrROVzOoctTkKCGbuUEexvitfFZzTuUVQqHKuoKkvmzUuAwWvVaWgGKbBzGgxDdXOoZzvtlhdDVplDcXxSNneLVwWvnkfGEegGviIVvzZwWYxIbqQXIiLYyIncCmMQhpPHAwYrRIinTtvVNqUhHhcKkrbBDdfCsmSbKkBcdDCscJjjiIIYycCUuqQXzZxGJCctTjyYehkojJOvAaVHhAfFaEekSsLPplvVTkKaAIQNlLmMqDtfZzuOopiNOWiOmMuUoIDtTdyfSsNnvEoOGgIOoiiZPpGzZgEqLvagGdDbBvVAzZJjwWyYaaAXfFFfxFfuUuEpPTgGLlRLliEeIrVvIiaDhXxHdJjAoHtTbBgGEHCxXfFlLyYcYyuUthHkGpPuvVmMiIUkYnMkKEoOgGeNnBNNcWKkwqQIrARfFpDdiIMmpFfPmMMXtmMvpeEPVCAUdDNnLlwkrRKJStTFfsafdUuXxTtNnbjJhHvVgGZCjUuDUuaAdvzZVjaPlthZwWzZaAzZLjUuuNXDNndXEeQuUqApPGhHpDdQqEoOGVvgLlePpYyiIaCcApJDdjgAaYyPpdOmrOQtTXxIimfFUIiaRrAihHIGMTRxXrtIiTtmfFWwTnNteZMmZsSzNnuUrcCRMmXMXxQwWNnZzDdLlpxyYXyNnAaTtJjJOXxortkkrRTvVadcCDAWwrRMeEuUrRtKkcqQCkoOiIiItTDHhEWwEeRravVNuvVvVXxyYUWzZjxLnqQEAaQJEZzUuNneLnHKAoTkXxLlgGKtasSoOgGAbBBpTIiOtDEeIbBiRRBiIbRJHhHhqCzZoeEnNOoOeEeSsEkSllKkLqQRrRXtTWiIwxlLrLEicnZzNOpPoCVBbFAahGhfFkdkPxXpPWWysfIFfTtsSjJPyfmMfYyFPfeGUVOwWDkdbXxzZBJxXKkjHgGhEeHwWDnNvzZYSbBtTfVVvrDdRKUukTmMlpPLZMmqQoOztIilnGTtrRgWnNYoBbGUJjhHugOAoAVvgGaACPqQpQGjyTttJFfjJjVqQdDvoHhOMmrLCeJjBQJfFCcIdQKuUZzkHhrEwpPLwNnWxlShHbAaAtixDVvxOonNXxnNUuIiPpIstTSiiIWwMaTFftAJjunNwWUJdiYSshbXxBwWySsYrhwXpPxgUdDILCcpJjPQkKqSRrcCsSsTQqtCzoOBHYyvVADgGdQdhHBbDEAaeFfBbGalLZEjJcaAmMPxSeYzxaKjJkAXqMJlLJjZlEjOKkxXCcohHtEbBeTWjJoOaWwziIUFyYHhdDYxXmMwWOZRrSszVmFXrjfvoOJjkEtTyzZYwjvVEuUbBoRrehIiLBbvVzZziIZoNUurRUfFyatSnNSsTUXwHFbrRJFfZzQkKEeqsSKRrrgGRRcCrbTtBkWvqoSasqcLlpPCsYylLhqgGHHSshhQHhGgXalLKkJsSzZLlxjLrRnNDXxqkTtKxSsfzMmZsSFPUaiBbpPNFfhsJyVvZsSMTtaAcCwlLbFfBbBWXuiuoHOgiIMmSsGoSnNnNdDsOoYczfFZCZPpYFeEihHfBVCczZDdOovbTDdtdGTtgmCSVvscdWJXPpEofzsSZFsSrwymMQqbGgwjJjJLiIwWMKkmfXsSxgGpbLgasTtSLRrlLlXnNEfaAKkzZyIiwWvuObBoOoToDdZzGNnIigGpPgGlLgKkEsfRtKjenNdlLxQKkifFWKvkvhHVUAXGgKkCDdIikhHKCtnuTtfXxFdNWCaBsHhdRZyeAadakKnNaGVPhHJMBgGfoaETIiiGgjmqQjUVvxXVpPlnmMNnMmwpKkFfPzzsFfbHMmhHFTjJFhHshHJwWTZzNsSngXCglLRYyrNyvGDdUQhjJVwWuHypPUXxmMgbBXxRrGZzwCEecwcYRrXxlrRPhMeEmXxHdDtYaAwJBmVDdMmiYGSsEBeEbjjApdDesSyYEokiIKJRQOmbBPcugPDSsdpGUmhzYGeEaAgOoyOeSIhDaAcrkKkoOsSHeEhLWzZwlPOmaCpPcFdDfLljiIPGgpJMxLlnYNndDCcRcXxlfgGYabOgFUuWXfFfFFgGiyAymMLlYOHIiNnsymLGNkYyKnsGgqPBhmMYyHUuqTtaSsNnegWrRcCwfPuWASlsSqtTULVsLyYlUTtGnmMZzMAgGKkCcuzleELYtTmOjAlleELwWLTPjWsjhHyYFwWGgppwWkstTrRRCcKkrcCSmMKhdyyYfFMmfdAaQZpvZzjRryNnrfFOvVvYQqyVnmHOaFAafPaAuUpAZzkiIKkIiykWPpUJEjJgFfgGWwGsGjGgIisjJeEeLDdQqfFlkQnNEyYKCcCLIozZOtXXgGxcmGzXRptCGSvVIizZdDDdyMwWcCepPxuCcZcCFNSDKDxLdDlXdsSvVsSoOpjmsQnNqrIidDzZyvhwtTFxhHsDdTtGMmXSsoyJaAjcPZqIiKNvVjIcrUiaBbwIdDVtTvXxLlMmiWHhAObBoHhNjDdAJjAajmMsjJCcSIiJHjbBWMmeEIiTtlLsSwJjyVCcbFLRrnNiDdbButdDvVYyRPwWJjpBKcNnCAahPgDjJdkKGRuhPfFYypDdHeyYEUpKHhfFqQbzZZVvBtFHdoJjAIinNEPprkaAKAWwamMReZGgVvvuUVHhzZBbpLlByJgONsWwnOoCwTGlsSDdFfSsMcuUCbBwWkzZwiuiIsSsSOZzpPMmJfHQGtNnTCwyYzUkcCxgIimoOgGPZlcxirQDjgmMsSGuUbBeEumajRrJFMRWcgGlOlLnnrgPAeSsEZCnEzMBAdmEeiGhzKBbeoOweEZOeUuYPmioOIHYsXQqAaKiIsCxXcCcdNxXjsStygiMaEebBAmeEFfkKIMjzUujJtTMmYaILqQaAlaSkGdDgkMmKdDKVUfEIcCcCbRIirtCcGgyYJjrRfriyYLgGlIJjdDRxtybBbZzCoIuJEzZwlLGgEoqBoMmTUmDdMuoODfFMmIiEesUuPWwpSdoOfNnTZNnefFEztqbBVrXxqVziozZOFlLfwWIFfdVOovDyDxNYuPprfmMSIhHrRJzZjmMTtNnrTbBvVtzkIDCpPUuJIijhHJRrgGsUBmMFptTrRZuCcnNJfqiLiICzZcEelccCADVvnNdkJTNnqPLlveEloOWwqQSsLUuVbBYfqQqebtTGggrRfKkFkKeIiEAaGRYyHwJjxWwWwyobrRrWxXPpwRSsgGzRxkKQqNeIiEeEzAptKkCcVvwKNnkWjJHOoFfwWmZZzbbBjvVgihkzZuUaAKRglLGoAcbwauUUuAqJwRrWjQvKtTIHhqIgGNDCtThJZzjHCcpXqDxXDdnoUREwlLWhzZDdfFZzNpPKgGMQqlPjfVvLlFFNndBCIicbHwWhZzxXVliILRrLhHCOooOCMfXLlQqxIGpPABwjJoTlLkfFMmPOosSOwnpOoPwhOotYyfFljQXxDdjfFJdyHhCAjqYXxrHkKhsnyaiIQGgJkcCOoeaAmMEpPOTqQtXiCuUclDAkBVvzZbuwWOZKkovzZTXbBikpPRsGrRWTtdDxmgGllLqrLJjKrRRrxXxLWgDmREuHhUZzGzELwWwTPpkUWwmMurRPEsSBDdLSItHLpnNbBPaAcCIiLMXUtVkKvPzUuaAUuEkfFqBbhaAHQVyAamMyYNnQdBagGTVmkFfKKkEtTlEerRiBbuUhTLlNPTrpNKQqRrJPpjWNnpPwkwWBbEYZrRstTSzBbOovuayYAsRBjSoOFkDdmHHhhtxoKkOXxrRfFXgDdspPyYgGUsjJSWgqjYKaAViIeVIFlLjJAzZqQgroOLlHXcCDeESxXQqdwHhqEeQcLlWwyfFHhlMmUuLHhlsZzbYjJycfHhFCXxfJNLzZOPwnQDVwUYyBzRrZbhHYleVvGRrkusdDdDlLmMyfSEorbBRXxuUzQxXVpyYJMJjnmMNdDNnfFVTtxdDdZPddDZWwbYyRrDdVvBzlLLlfViTtGgJObBgGvJcLcDdkkwIcCdDwWifvVFQYkKkBgGBbTpJjWwTtlLpPmNnZwWzSTBbTtQrRIbYyQOHusSUNnpMmaAkKPlLKeEkIiWwFrvVRfkKGlLjJMOHFDbQqBCcdIiIXxifhobGFIisSfXiIxTBWwwyFfYWbGgDUuhlLHdMmmMjLKEwagGwWSgPpUuEeeEyYIiyYvYyBSWCcwXxxAaXJjUbQeHhEPpCKkeEWqQiCcaGgrRiqQIAIwikeRMuXFfxUXeHhdCjJcyKqQkYyhHxXUqQumDsSQqdjdGgDGEUuoOjQVvuUpNLhoOrRpagRrjpPIiqaAAASsaaOoLlGggGmdoxoKgCxXAnvYgxNnzyWDdwYXTDMcCxXmdtFfVNcCmAIrRkxXKXdDqxXRKNnOoghLlqQfVbBzHEMwWMaAhDoOdQutTUBbRGaAadDQqzhlLYaAyuUpJXxWgqzLVJGMmYyQwWyDdBbYzrFfRbBKSsIHpPhslIiLRZzjJuYPNkGgWXTtHIiyZkDdWwkUwWjLlJkXIZxrsiIFsnKktFfTtTNjJjQqeFfqQdlYqQyzeFfadoOsUuPRrqQrbsSFFfflLsvBJnhHRpCQdfFDhBIibKMmkapftbBGgzZTlrfEZrzZGULEeBbOPpoilLIlwWWhpywWPtBzgGZnNYyUNtDdYyYYyGgJQqrigVvGQHhGgtEemIXxigXuvVUjUSsAaZHhzfFdgGTtBtTrKkXCKYHuUAacHaAHJuUueoUPeEUufFpCcuUEeuOEUVvueZrvjhHJQqVGJVLSPlLFfamAVeEIigyYHUcaAyjJiIVxXJXsSGgpPHwYqmVWwPZjJtiIiIfUmMIBNmMmPpckUpPuEoOnNwmnoOFUuSOxuDbiIBdUZXcCQqQPkzZdPDdHnnrRkvCcdcPwWljRphHvVbBIeENAqsGjxXqeqQRPpTtkYCcAakKoxgQqhAaHpLMmRyRrVUDoRjJKkzcYkUdDZzMmuUwsHhiIiIJjlznLlyEDbBnLPpXLrgJjOKryvKILlbeOwnNBldUpbTZzDoOoTQcCOtToOhIPpidDHhmMnzZZzHhDDtTdDLTmJjcbOoRtlOUWwPtTlLyYMmXDFfJGkPpoaQbaEejsRWwMmYInNiTtyKkanMTUJKbQaOoPpcZxIbBbBiXRDdzkdDBbKvLPpgGaqFVtTGiMmqQfnvtTvGaUuzQRwtTAvmnNSMmcCDuFqOopPQfaARIpEhZzZzrRDUuJjdHBHGiINshIiXxHrxnEfFKDXwzsSpYjJrHvVfFqATkSzZsVvKtlLidDuPpUIUuEcTtsSxXORpnFhMPsuiESKiIfblSslLweZzEwWbfFBbYdDTkInxXIiWBbXsxfnNNnfFFcCdDeVSsAyYHzGgsQCcHLpJxXpbmrNcCZzlCVAkOeEdDGYebpPZzQHhqeoqQjJOwgPpYHhqiLlaAIQCsKDduvsSsUzDdMvuAWzDdlLyJjwCHAjoOZIulLCcyMbIiEBEGhHaAaPKkDHyDrRdhHjJbdDLlWwBfaAfRrFqMmWwgGxXhHsdeEDwWJzZjFfwmctRrUuTrjggGYhGYyHkKWElDCmOQPgiKnvtTQSSLlfmlNvVuNQqwRbJoOJjJsSKRrBbFlPSiyqHuUPYypJjhtcWwCPpaQzZYfzZswnMwuvVlXyYpbBQfCSFNXxPFfHzeEZVRrWwvhcKZzkkeIFfoXQqipbBdIvfDdFVgRrMmviIjKkZzJMmEtUuIhhNnHMmHhJgGkucCPodEpyYrLqQBbTtJYgSUIYEeyEMppTiICZBbIsSVntgFalUzZuckmLxuopdDBDEaHreEkjJTtKnSsOSsNnohHJkKXxoAjJaxXWbRdDGLuUeTVGgYqqQlLYyQMHvjJGwpNnLlmPYypTyYSsWwBXxEJIsNpPnlfQkKCDdDbBvLHvVeeEMmzZitnMmVvrrfFRnaAiVJtYyUnrxiIXwhxXHajJBCMxXIiWwZQqXoZCInWoPpYLljtbFfiIzYySNnhYZMtJeUjDTtdqxUiImjldIilLDLJgCINTLFhwlZZzzfxwwCjJaHhFnqhnMcBbCdesSXSsxHhEDrRmAKHhkPQJdFfDRxkNoquuLoOeEgKYyOLvkvVZaIRDdyixPpSsXvVXTvVXIfFFUVvQqclEFfxOUOMmovVudkzZApLlPuUyweEmMHCzZBbcoHhomzoOZkKJjMSsMubBMmTwCUXDdwoboagGUuDElPpxXhHbrRJjJfQpWbzMmZyYBGhIZtTOoEgSiIsBGLlFfLDdJAEeQqhDdxmiOsFOeEsSuUxwWnNXdDWeEdUlGBFgXAtDrPzgMmGeLlEetrRZzmMSsTqMmzdFtbAqKNGjOCqQYyuXxQAcsFQqglLoCCcfFfLlyYPHWwWhksNnuXxUEyYPpPMFDHAmMahSwImHWPpKkBHhbuomlLURnNfEHoRwgGgWwSsWwHhGAKwWjJkyvyYVQZgYyLXVvEVLLAixYaACRrkXthnciBefFHhNnNnwXvoHZYyiejJVKWwrNnKoYNOzPRryCcDdCeEXiVvgGIkEexXlLQyYKwIcCThHvLsSlwzZatTGtTGgNdoStTmvVWUwZUGvkKuUVgCcKkaAMXmiIwWbBLBDnNgmLllJjaFXsSNnxIYytotVVocPzraXQqCLSDNwibBpiUurZMmRxjJFfpPZHhMmEaHfYIrRUnNbBucCiMBbNlAaJRWwrjtWIiIqQCvVvVfFvzZVQKdDPuUHVfiWwXxIBhjJzhKkaOdIpgCKkcSsXQHUTNnuUtRndWMwzZVxXOwboOQWyYbDRbGkGBbwYyWqLlJRrqQjDZbBTtvswuaAkGIxBbsTwvVWNnLwXjxUyHpPhNtTnfCJpsPiRGrIiRZjNnJvVOLlCcOSlLsVvCJjxhHVvoOZJIDnwWNQVQqbSUSsVfBhHrQAaJHCchPgJjGEVrrIVvwWdCcSWfgGJjVfFdJlmMLXxyYcFlLEJjJVvJHgLnuNmUFZztDhsSrSsGUuXbBjXrRxpKCckNhmgSwsSXxStTJJqqQQjBwiIWVveEfFZRmMruUYyLlaZzEeUYyjOnNhnNHEqkYPpLTtOolbBbBEfFBbZvVvVXwEemmCiNzoOZzZBcSsSjJYIlLhvbBSHaTcnULkbBXxbWVvCyEfGVvVhnrXotTOmVvNIravVxdjJAaYRrskYvVotVvdDHPpiENDdBmnNpiOgGontWwYgGZzygqyYuUQGRjJQSZwsOoIiIYaJoOlLSsjAkaAKfWAawmYyMtTXAJDdBSHYyXlRrzrRulRHtgSHqbESsVvyYVvCcnNlYyOjRPeqQEsauUxCcwmrUlvOGfFTtMiQqIRHzZvuUVzvJjluUfFLrRkoXufFmKkMUYEeyPIiMhHycCyRrYAcXxFfCFfOvVoCpPccXxCBxPZuUQqzRQqrXkUdoAaOtTiIlCsWNFJmqyIAJuUkQBgdDGdDpNnHhPdgGCcFwgbteERrXxgGQqZqOhiCKklbrRBRZzwYyUudDvVWbdDcCfuNTFfMcCmMsiIrinLEOolLkESsehEeRbYvfrfVvURrZzAAyMmcOyYDMiIgGQbBFfsnVjJvAurRFLeNijDJAappcLcClwWOsVMrIMGKkGgczZHATvPpVtahcWKdCtwBhbZbPweXxEWdDFHLvfFBbFPFmUuRvVMmxlLJjDXZeEzZzoOqizYZzyZwnNiIYKkyOzNWwhHKkBsJjoOLlsdDLkrpPegZYacyCcRrxXYXBdIitJnNmPpSqUVlVzOaqQHhdQqDRoORJEejfFrQoOAaQcyYCRupPCKvVkXUaqQjFcqQXVgGGgeEKUukoEbsSPpzZLpALluUHWwWwnHMVdDXlaMmopCcoFFjgsjYyzXXNfwEeDtTQqIiRrSslGgVvFtWXLlqiIxXJjPfFpGELluUgGJtzZAaVvPiKMmetTqsyHhYYZulLwKIiLlwBJjoLpzhHqQWqKVvocCORrYEYwWSiIqeEkKhcwfPhTtEjJLllTUutTgjkiGQUubnFfrGgKepJlJjfLFzzxInuUSqaIiAQaAIcxSsXVsSEtYOCcoeDjwXxMtBnOhTnNpPqKkscCVcbSYyMiMIAkZSWwMJUlLGeHhlyClLjpPJsrXYEeyzPHYBIivQBHTZzhZzLKkJjaxaXAvgkByPpYmMbnNozZSspCtnSyCqQkKzZiGxXCiIbpqrdbBDRJjEJRuaalTtLFfAsSdDtoTtnNOrZzZjaljNoOnmHMmKfFkubQlqpFKkAnNmqvFWldpoeEOPSnNrYChHVvJJhLqJzjJWZlLZvVSuUzZOYnNVvyhHBbwehaAvVmQnoJjVZrRzaAMmGusgIHhXrgxedDElfFFfekKAzZBVvbEiIekvVUuRDWFxXfjJwSfFsCzNlLswAaDjenNgMmGrRfyVxlbBDdbfeEFuGUugoWJIiUuPuEayYCcJjNAqoFdDfXZzJuJjUjoOMlLPJjtTpyYwcfYJbBAeuBbUEWsweEWzCxxXkKfvVlvVLLihHiIutbBuanCXtuIowlaiIMmmWkeBZIhHiRZeRhHrJxhFfLTtEeTYytdHvAaubzZeEZzBASZHDNjJvZzdVvIiOcCHhohUirnNRcCFhOJhOlLlLVvcHhNnDduJdiIbBXwrRWwBQAaAjJwWpbZrODdgrRrRrRXjLliWjGgJsooYSiDdMmQIiyYpLxVMrRysQyLlZaaAhHANCBHSsLlYyYAaphHPbBNwWSUgWjHhgEeLtytOoIyYNDdkspFfeEknvNnAUEeEQqaMmULlqFJnNagGAohpzrOHhxXSHhsNUVfPJQNneTYyxgkJjNSOhfSsfTtwVvWBLlJQbxXPpzFtUfisSWgirXgWwYyGbvVPpPVvpPdrrbnNEwnfiYyNuUwVvKSfAaEeDxXofFIJmMjJjkWcRnjqbHlLvVhLfFOobqpbBDdOmMfNjOKkPrRpxjsGrUYGgejngFtFfSybTdrXCpsqbAaKBbJkCSsXhMomMOmwWHgGGtTtgGdSphMmfGcGNguUwWGaOVvFfFZLCQxcqTXkKDdxAwWmMzhlSFMllLLUcDrSgEAJjaVlEeThzZHtfPAyYYTffFjofzZMmZzTtkBbVubnBYdQJadYzSQxgeEzNEgMzHiAhVuBbVvUNnDdnsxXCuUwxcgRrKiqQmmCcWWwwdbNnBIrRNnHDvVdTjJmzxCAaMFcxXCNfyKhHoXEvyYVUueOoFfXzZkFfHwddOoORLAWwalORrYoiwkTwZZzzWJjZHhbBCcMlBLhHyowshHSEetAatxJjESWvfuEQSsJjJORGuzZTIithluUGtoRqQrOTDVuJWwiQhWNnwWiaAIjGralLARrRgGQqPqQyIifciGSsgGgteRMmrENXxGttRrGPpEeMhHwWgnNMmGNnJzZiSsEfFZVvJBukFsxTnFJjeEWFAmpIVDdvDXhtTJjnmIiSyTtHhRrYtyJxzZIzYaahHuUZXuUzXyohFrBbQqkbVbBJXzvVZeudLehHEKMmKBbYUClaxQeEqseOoJqoOQmziIfnywgZzjJjJPTFlLlLJcrkvVKABnJjxXanrrllLLNnVvOovahbBeRixXRLYlEqTyYIkWJSVvKJlLktBnaaGdrlICcRHerlLXxYVyyfFYYxGuUZVIhHYPtTXxBAabJVGHKZzgiJTtgdHhvXUNHcxbIsEeoaeSrHrNsdvCuUUusCcSAaPpcCGnMmWwkKEfFNnYyCuEVECCJvVjxXqwWzhwWMmqLjJlkMbmGgzZcLzZzZlCGqBqQQZhSsgGyZzYHkKptTTFQcCJPwWEeAahstjJkHhgoOWcZwWzgkqPpQrYFWwzqzYzZXhdktTxXiIKDWqFIXcFfmMCxiFpkMoOgGSsBMSaXmVwWxVKDBxcPYTupZSsDIjJopJNnbBDdjrRpXWKHGgLSKxTiIymcaACmMtvSmVPpIGiuDBbdScCVjQgHuOMIiewWRiIaAopINJQqajMDMFnwFAaxZCrRQQqrjJclkRrsTbmIhiCXxRrXKkxxBllIiSAaQKfBZzbzjJWJjGOAaPppEhHGYauQPukgNbBEQEeqeVPAaGgkTtvVveIityWhHpOGLFfoBbumJUujBVSgEeGrQJjIiHAauULOOooAIVNkKuKkQCzoOJuFcAfwygGDNrpPihVULNYfpEiIMvWNnwFmgmMdJjazZWPvSslYWpGDdYZmMYGgUEdCcylLYrSujoOTAQCUBnNbaAhUEeuLlCcCKGChgzZJpMxwhHAzFNnnNyYecCPrneOrlFOAafrRRscnNhEpjJPXSeEkanZzfUuKEBRrKXxKyYRaypPKFfgtjqmMQsXxWFTtfSsPRrxEXVvxevhHVRXxNnFEeitTYIiyvVIWsJQOoqGdUtTYxXIOoTySNnsNnTfXkWfFwpPJjNCYLlyajOFlLjjQqRrJrRZkcFfTdjpFfLfGxHxDhQNnJpPHLbkUOOoFfdEayYSMmMRrDasWtNnIGvRrUuVBjJDdayOodAWwMIWNRaYyAdPvRrneRrMyYdtFmMCcFSJYyCghQoOqlbLGgyWMAkeQqEbBVnNFARUuByNutTUMmCtTGgvVArqQqMOchkyFtaFfiOtIHpELWPpKCCOwWDyWhHdCNJjQoUaJjyXZrfFIqQiZrRKOnzgGhBbOiOQyYwWsgGuYqQAaqQfFGgrWUAPpauzVPlLtWogpFqpXbkvOgZYygsSqQyYJIVAkLWwKWJOrmLUFfYpPFTTlLZzJJgoORVPyoMllUuknNzZBtuKkGnzbZmvVIitEeZzXxIsSNAapPraEeNHHwKkBiCookfURDdrpUuPsSgSdQspzZPioOsPYHyYJSnuEmMzZtSLwyYSsZzCcZzjmGgmlXNnSzbPQScEeWwWqfTtNbBZJyqgQCcFYDKkIKqQkocmjkdhoEIQSSqDdvpgbnWwNARrEeEeaIiJSlLPsCMDCcnNkKkRvPjpzZzAyQqiJGVmoOaQqulLUFFfgGCcfoOVvvgGsSVGmHbByNOUZusitRrOqQXBFUtHhdVvWQqwVVJhUTaCCpAapPXYyHxeEBXxDybGcelhEgGxXmMVLlyjJuhJoOuUiAFSDQunTtsSpIWOowPptTWnqlRWAtBOobushnyTTLBcCbOjJYTteTtVQpPlfxXYGgklSCSbBsczFxxJIijyUdDzanwSFfQqWWbvIopsSPrfFJnNYseEStGkKgcgDXxpXxdsfLlFSDPXMDdmxdGChgGHtTTwWyjROiIiHhVBwAaIiHNUunhwsWNAZudDYhHXXfZsLIinRrNlLKyFLoOqvAaEMmDdzZyAZzaoIYyilXLAalxtTttYNHSUBbTawrLQNnSsPpTtNSBbswiPNURrqdsfaIjHUYCcveHWwLECNngBYdlLMqnNQmbvFgGfVXhxPccAtuHjXxvzZrRvDTufbxoTISUzuoxXnYhMzZDdgvVsSFfQqAMvgSsuUjIhHYaZPJpVruUKbrRBdmCkKzZccSpsYyjBGPTtMmwWPpbBVQXxssqyYiiIeQqOHDKJMCOiaAxXlLdzSsZyfCcqGQYjznAaFQwceECCsqpBHhZlLsxLMMJhWwEeHWwWlsTFflLeaAUNuUsjhypSISqDsGuFlLZQqzKOOcIbaAWhHhhktTKnsSARCcaAzZniTaAMzBZNgUTbFfRJjrKUuLLmQqimMWwIOLlYpvruUGjjttfyulMRojwklfFKGgQqavijGzGoVKSsBbBxPQfEePtTGOwFfTpvTtZwVvRcCyUSqoIoBbHAaZNgniINGogGtpPTfFkzkKwWRzxYvaAaAVAuOiIqQqncDtTwYdLlrRwWocckwlePhiTorRIgGVvATfFfYKHtnNTCsSoVveGgeEEmQRatTcNgGnlLxXyYnYJjhHbQqzZrafrRvKamXxGgeEwYlBZKkzLPpHGcSWwsjsfflLTDoOmENVpDrHhnwiOomuUaDYYyAMmbBbgiTwSAdmsOrdoODRIioAerZzRDDBOobdwWoGguKBWwlhGgjCcpPqHBbdXhCOocLlXwWgFlPoOJDtjJCKzjlmMLJfFJfoJAmqQMVvcnKxFtYtBbiyuDgjSwfNnrXpUuhQqHqnNQaAaAdDwvVSJTGGfBbFgEeHhkysSDdYXxIiXxYFfArAauVvUksShMmJjHkbekxXFFfNIiLOolleELnOPpoNAAKSssxeHCSrbBFofraAgGRLcCRoENbBRpPpEfZasCcSWXicCXxImPjzZGHNXxXxzZncnNgkcLlaAHOoucqaKknNMmeEAaKktyYoOJUsRDeuyzygPwyLRrVKkpwVvTtzZADGMfEmMevzZFfVWVvZzwUEeuSsXxVmePaAUuFynvVluvHIRndYWFaCwWGoOmMgfUjlMmLeEZcqUnKkrRviaXxlhqRsvbMSEesUOlgKkoPYycIiCweEYTEVKNnIivVpvnVvGHhKUpqdpkKYyPDUAygwWePbBogMmwZFkqMmsLLbXCccIVvHiMBtSKLCoONnRxXqrRczXfsSbBWNfmdmJAjniPOozZOTtrEmdpPDoUhGqaAJvsUIgzzUuZZiTtvMjJsVaATVDdVvvMYAatXzHEehZkslIMmihuUkiIwxPPOidtTYyzPUtyRrpCXbdkvuUXZzvMxAsmbmCaAcKPfIJbBgGjioOfOoQiPpvAaVAaIwHJjxyZQgGZfyRKGtTCTtwoOGwSuUsYyWKasShHLlATSMmhHeaAEHpjqftPxXWwzNGgnqbQgMBmKQUuHZGgQmJjMcYycevbBjLlEeNlLnJeUceMBbaAGgMoOmmNgxOoXAacXxVDzZSndDRhXxbMmoOBoORJjsEAOSiBXChnuxVDGjIGkhvVgvjAabBpyivrrRRzgYyXjJpPkKvyREqQhlLriLRDgKkAANbTdDKjkMmsSWwstTjwKittTtMtTRrmTQKkeNnLylrIqQrEUuHLUulAVRHhRNANbaLjJlRCRrjftVvDKkdpGWJjYNFQqZMjEHhSXALcuykklDUExjvuUCctODXxdhTtcCHoTBKRfHOYvVWwxZxzOoAAyHhCcZiXjYTKksqyYNnwWFsSwBbWwWfQOoMwWNHNnbBxdiPkKMalLfwfNtXSfKUbjvVzeIjGgBZzbxXAacCmCqaAEgPpGeeEQcmMRrgvGgrRVTyYoOTgdDneEaATeEICFYIipgJwqQHvVqIjUvdjJgEeLHmMrPpRUpPCJjcglLrojqeUFVwsSseZyYzXTuUkKTIisUuSWOYlbLmzueEUtKBUuTOoUutbKkWIOoOyorUjJDduoXxDDWhpPKxHWwhxSsOkYFnAzZafmcXZMtPOSsophiDMMYyIvVVzZCcvkgGGCcgGCXWcvVSNPpvzZXxHaIhZmGenZGXqsZyDAjqDybNBUUutTvPpOoKFOqQJyYFtyRrOovXJjSsxVxRryYHhbZzBXaprRkKFLvoJjOeGDdASuUsashHSsTtRdCumfcCsLHZIpPiKkatDUudQoOTaAtCXqclzfSsoYyAngZzCMmgvVFHPsDKCmMckEeTrRgxwWzhHZcrRKjBbZzksSAFfaBnNQSPcxRDtTtBYsPpTfLlGNCKkcJEyuRNngSJkKXPpomMJnFFfogGeEPQlLBlPpkKHhBQJNrCwKiOBbUuWwdFqQskWnIFNWemMBRRDpBzZtTxkKRdDIGwaAIFuTfZoOBqjGgbbBFFHosnKGkKXtEqKLgGkKlxXCckjSJjsMmeEpFvunvVVFfvoRZPdDBbHGZzgOjsSfQhHuuUAkKMmetTuRraVIiNKPKkSKniIiTYTlGnNJwGusnNnyGgLlPpeEhOoSsmMbKkKkEecnCOoQqcKQqmMkzuUYqqQSYrRmvXlPQdDqniINqIsyOOSAawjJIFfVvJRrTtxGWwDdhHoRzBuUPAaaqbIiWxFfDRrjUsSepCcPECoHjzZcCoEeHfIuwWHhHVvDxXVjJndhaVvAKdDkzaAsasSUVsShuUDSQqsmMRrlHXjRrEzrzbEKwMAezZEjJaALCrRcUuWOiUyKkYTxcJjgbBGNAPpUTUIlFcChHXOoPpcnsSNZSwfdDXxFaUujyFCCJAajcWmfFxcCxhHXPpCcOYyQaaAntTaAAeEXxYDdyDdDdeUcCbqQBpjCcwOUkKBQDdqLXvYFQqEJdWSHhcCnZcdrqQKldDLzZnNaELqQMmPpXtTGWwRKCckxiGSUgxndDNXvJjONqxXMvVHQqEWtTYyoPRrpXxYLlyszHhzwWOoeEwZEeiIjxXQlHjjcVvyRsgGRDdAapvVPrXxTtGgYyDLwfVQSsMafPQrRLqBUhMIiFkKfJLWwLlpPAJzRNnTGgSsJKkjswWSFEefqQeEAUjJrjeCwWcQPhHnNBcgIcYOoLlsxXNhHTcPBbOnNfFZzKGVaxAXAaAlHthbzZqVbyhpZLlxRJHTthjSFfaAsSfFEejPpJDdcyYYLmMfFEgujmszKFfaimImsBLlvVCoOvSQLUulfFtHxXoNbTmWJdEEeHhyTevhHjfFJCiBbsNiXwWZZpPflzZNLlnVTtvFLjPEkRNBqgIDdKDdJGtLeXxJjHpxXFWCHQLlsmbBbkKBMyeyCcQiIqkQYywZPlObWkuoppPPOUWUJKkjDdzyxXyYKkSQECckIYypTtTjXocCOxCcehHgQxwTfDdLlJjkVvKzZeElLFfLRrdWFCcnxxZOoXxJSCcTMmtGJffkKBbOPJjCcXxOALwWxIivmhNWwhTHhtiIdDkKaPloOWwBeXBfFbxOVvvxCfQqJjJAbBuxRrcPpjsSJDbBwqQCcWdUrqqFGgfrqQAoZvOiIoLpPmMPpvuCcQvVsPpMGaAgJjuUjTDbxpPwrRIiWCAyzqQGKkERNnKlSUAauSbwWBoDdwKkWObBbnZZzyYoUHhuWIxXQxNndXrUuMfpfPpLlVlhfKxXkpOoBzBHbWTclRsSrLDPEGgepkpWwPwiIYyMmCCgmiRmvwWSKkeEoLlCNnPhHPjdJInElfUamMNSqJjmZzdoCZzJjYaaZzuFRFVyBrUuHyYdDKezZlkKNPpMmXxIRSoOvVmtnJjUFdDBrWwLsScIHoQzuUTBrpPRGWfDbqWwKBbjiqQFfIQqaiYmMQMjfnwBbSMAamcLHdyYDhgGDuKxIiUSsuwWpXpPbaYmmMUgGuEejnNlLJpEVveYuUyiIGgxOKtTVZdJjDhAaCcrmgoVLuRMWSsvVXAVvSpeErJoiAaAaILKRrkeCClLfFoOmLlMccBNnQhsGThrLUZLMmxxXhsbJjjpPaxFyiSWvVzsDkKdqrTPpNIPMbMmneIhTOyKuUSyOoSsFAafDXARWwcFfCinMxyYIiqKkQRNHvgIiFeYcwBtTKlmMtTEeuNCtAhsfFVSsHiysCbnIyYcMMWxQqTtJjgGzeEeZzyNnKvVQeoBmMbJuHhACzZRrcApcKkCPHhaukKUzbjsWBbsGYyMHnfFPvVJxgRHZzdTffFuZUuzMnlLUNlGhjjZzAaDdTtefCrRjDvtTFwsgGDiLlRuUaARvepjqRbFvusSsbmMBBvqdMmiGgjzFfXcoozlLgrIpSsSCcPjcPmMXxpFSsYuoOBwWbXJxWwWlNnlLtSXigdDKkKSssSUWZzSxXVMmgGzdIiQwWgKgBNnIirdwWBwqkKBWovlLUuDdWmwHhDSMmAasNruhqxLlGyYEePiDcCoAHPpZHbfFiIRrKmMZzkFJjvhpuRryYUkqKkcisSwqQTLnmyVvFuUhAebBzjJXrRtdyuRyYrUTtYGgzZDmvVMTrzRlLIQqzoOZPIWjJshHSndsSrRsFPloOLpfDdlPpdDcNnxlLARZpCRrOEPlLpNnedCchHkQQqqKSsDvcZuUzCvDdTOTifALMaAGdblMxZzmurRwuUuUWzGgWuwMsOPpJjDoYSsycCOslLSnZiOoIuUzgAWVtNniQqWkBlLbqGgKdDgbBJjpPGnNxjJcYpZogGnyOkRkvEIzLlhOoOVxrRWonNOLlEbICNHTxKzZQqcyXIallRFfrvexlMmGzqYaWIEeitTwAaHhWrOheFpPWwruMOUaAwhMicCWskvVKympPaAMTtYCcdeDYCrnNRcRrydEfmpaAFfPhHpeSKEoOtTehfFHHHgSsGhDdwhpFIuUicOGfSCaqUcoJgnkQaBTfTtDZQsStTbJjBEVvMmZEepRJjdTaxOoGfbSsgLyYuDxXwofSqAaQhHoIMXDeEdHsSWwajlgbberREBrRLlOoGeziuUHgbHhBwPyYkKYygGqFjBEecCLedfFrRgGAOBOWxulLcWtUmMlLmoDddEeDpmMPOXSsxOxXOWwTthSsWYaKDoUuXegGeEaxDdXpBbPZzALuUCufixtxqUuVvQtZzTRrItTYytTJQqjYrWwiVSsvAzKVlZzoPpkUuGlUUyYQOZDdznKDsSdtnNnNTXShHsMmrjqGgCcdDpRrRrYyaEedDNHQNfAcWJjWNnXFLWBbHflKktaHhVjJzZPMmpvAnqQiqQbBcWwGMcCuXQJuEjTmbBzyIiHsZXxBOotUfFuTCcfFBbOoTJDdyOwNVTtviczOxzIibBQHhNnqmAamueEUMcbJdDjpPAWxXRNuRkKrTjvItTZzaAAaNdDUuUufFIiiIRNTIEhlWwVdcqFGgLiICSscSiTtjebdDNEentvZDdOozVMPWGggdDWwVeEhmJjyvVTtvSstElgWwnAdDcCaNrBwOjAaQqHhNRhAedbstTxXSPsSOBJfFGFfgjbUXbBlMKnNVvCcFfCGgmrRMLAfGTWwNvBblLizctPPmeqhHLlHhQiuuUsGyjlRPeewWEDOsSpUKjQqyYhYyXxPpHFfHiwWTwWesSVGiHhRrDPIxOiEKCeEpIivVJWoOwjnfYyTbBtGgRriIcCsHBDdbhcFQqqPXxxLjTtJlLwWUWmXuUxNbBWSFyqUumMAsmLlMSqQTKkNZznApBbPaNnQYIDdspLEefkoOgGjojJOoxXOlLjnNBrWnUagGAnLMFssqxXuUVNcCrRkIGNnqQpqoMcdTtLewhgaAHjdDJgGyGJRCMWyYQJjqIioOhHSQFleEuUOoLjJRrYhdpAgehHbeBNnmJjYHhAaUnNizrRpPJahcWYZwOoWwasCcSUVmmMmMZBbuSVUkSYycTZztyqQGWZzEBEygFfoKqQaSsvcLZIiznRCcMBVvPjPlbBhNnvbBVhHqSSssrRSZhavmqQqKIiKkrRxXhHkQMEbBdzHhZQqWUuwfPpFDXDdSxMmwNiKBbpPtuUyBzZbRrBhHJjWiILBFFfkQqOosejJIeEUSpmHfBbNProCeiIaQpPhRyPZbBWxsTtSRrdkeNXRSnrGgRghbpdzZDPOoeEyYePirUdsMagGAVvVaWrqZAUEFfeuTgGtgoOVVNFIgTtZzANnavFffQAgaApPyZEezYsSkXxKaAGEelaAVneENZrQqzaACALQqeElzvVARrUpPuaZlJjLqvVPpcCBiIkpPjutmNAPprSJEeAtTBjJqMmAOzXxZKgwWAajBbdxpCcCcWGgwFfuoLTrzZBgGCMtsScrqQRClsEeSddNjJbBHoNnrRqtOdtBPuaADuULbYyWoJjETtBiWwkWwVYNnHWwhRBbkoJjpPXiInNdDxGRlxRrFflJjNcCdGgeYgGyYCcNJjZLSWLltTuKylLCZzZWwdDrPpOduvYrlPHhGgGXOyKrJjEQJgTtcCSQeEaAfFpPaniPrGgJLLlpeECDVKkKNNPphpDKpqxzXQqosfNMOoWnvVNezZKCMnXtTxbiRMmruqQBbCcGgFTzYypvMQHYyhBbyWKkoOhVvsSxdDjwWvYCuhGvakKMAsSlLpzZslvjAVvuUVWwvKkagwWRTtMmpPzEEeOomMUkKjhlLhXNnxqaAQChykjJcxRLlbDuJxGMTqIRjyYyTpPdDnubzZBbTpYgGeEPJjHwuuUgRIiPpzeSsFRMmLFPAHWuULlwqcPpPnNZzUursSyYPpNjbVlLSBRphHSDAEZcCfFjJLDEjJpPJRrSfCcaASvVRXzixKNnuIQqOwWDdpPohHiKKzTtYhxwKnpyULlEerSikpPZVvHhqRrgjvfFiIlZQGWwsSwjPlLEeHZAgruAaUqiIHeESsmRrNnmeWwhgGxXZWcCwzZHhUuvFLpPlHGkiIIiYyrQtTTthHZzxiaMnLlvxjJiGsSgvVTtIZGgXGyVNKkkKacGoOkOXOjJDBbMOmMmMoZzQJGAPHrRlgGnuUgGPhHqJegdDdDJlmMLuUdDMoOYpKkPDExAamyYrEReErWwxXtTKIcqBLluiIJjsbVpPwWBbNnJjAaZzJjGnoONEesAWeklJtCcgBmgZzpPsuUvVgLlyYGSwWwWLlwWhoqBiHhqtsMPtHtThvVbOoKOoymMqJOojjzZJWyOoYIiTtEeKKvVClCAajVcUuCbBojIiIOovFDpRrzDXPpvhHUuKuUodDGGXxggUuOFfkmjNKknPvqZxyYdDbcYyCaEeABSsXORresFkMmKTtjJoOYvVQqSUgGVmMvKUuRrgELyxXulLWvddDqNEeWyeEYpolnyYZdDzjFYkKyNnBSEeLYQqNHhBqQZzrRbnCWDsdGgTtxhoORGafivyYpPEvkydDJFfQGwIiuzZqQUuGgSGTVvMKSscCfshYyHJnNbrGgScCUVGgyeyYnPaARtpntHlLILzXxyYBbDdZenNkeEKFfYygGMvdDtAbDVvSsqXTtxXaAjWwJJLljlLxYhHvUuKeNnRcvVCWwrZtTpTuxmNnluUlhTislJjbepKtKUupPkWlewWZsSgrROoyYerxXLdDkKlMJjdGgGwKklXcluULCklRzdDZQUuLbBMXRgGdDrwgSrkKKxJjXMmIxkKdDtVOzoUqQKeEdDadHhLIxFfosQqSKjfFqnNAYNSsSRgGywWQJacYDqJLVvBbjJTHWCNncNWEeopGgKEetOHeEhoOWbwWagiFmkLlKPpccDdqSsQlvCmzZMcDaeEqQAfJpxXLmTtkIinHexXruONdQSsxPBbRrIicdGwWgaARoHhOaArBSsbsSHhPpnMmiQvvjTtJVVikMmDdRrfFVbBWBAaiIyfjJFNnYCaOgGrHSsIGJnNEkKeBzgGMhMmTbZzBnNPtTCcbBzZoUuOaZAanTtXxXrZBOYoIMmiOqAatTMmtTQXJNnjoOWwWcChrWwbBBGgEQqQFdkKLlDypLlQtYyjKEeaCIQFjnNUzPUHhuGgfbuSjSsjJBDdbCcEemMcdiKriIRZRisFRUpPyRtTrnRroOXrRPpdwWFfYHhZvQRAaQqvQTzZBbtFferRJjEFOoUmMxQqdDXutObFfKkQOeWeEgGgGOolYyMmpPiILWDdgGaAyYoOwejUElLYeEyethHTmMYyiOLJjlcBYKrRkiITXFBbxXTBkKGJjgiedDwWFuuUVvvVvmMEesAiAyZZeEzzZJIimGYTJhHcCnDSkxAanNSyUuhrRMpyECcbBjJozWtTEOoAakZHgPpIMFfDaJjQVvVvqhHiIpPPpbmZAaeeENhuwWUVvjJHYyRzZrczKkapVvGRNNEeuUoLeEvVCwEeKkrmfAyYMCcUgPpGJsfFSdrRqRQqIXCLzpOolLsSMkKpPXcJjCKuCcZPpKOokgoOGWcwWgqUCcuhFjplLPJjoUEeIWKmLgeLlEDddDYytWPpwfFFwWfALlMmaSsWcNRryYSnyYoGXxqQjYblLPbBzGZzglLEeaYyODhfTtTCcbsSzBkPpxXPDdmMLlvVaAkKrYypHAakzZbaArSsTUJjIBZeZfFzmxXMEPmMGbBgpzblfIoOfFiBvrRYJhiOFfoIaTxQjJqXtDdJZzmMnQqIuUPpuQqRCiBbJviIuUVEeKknkQzpFfCYOwWxBbVvggGSjJXfmMWHVYPpZzUuRKkSMJPrRAPpaFfnNLlkdGgsnftTzUXEmCcYdDDdZzsgSspPcqQTPQqrhHxZgMCxxXbBTilVOovcdDkSJjseqKEYkKySUuJgSNnejuIgGiPpnNHhgGDdwKYKFfocbVvOoBCjdDJhMNXIixoRlLYUuJnNVkKxXPRrnNIYyizZzZzqDCcOvNnVovVFYDyYkKlLHDdwXxXxWPPfJjJSwJptMNnmaRrJoMyZUamNguSvlukKQLsawUpFGEYyAQdDcCLiIwWlbpQSglMYnaANmMShqQHhoaYeEIfxwfGoRrBAyhHzZFLXwLWwlWxCryUuGgNlLXicCIzeEZlLmyYAtTPpMgGoTtpKRCdHPpiXxsEoTtZHMTlLtRHhrunNUCVvvuUVpdDtTvVMjJJjoqmMrjOXIixPVvQqPpTXxtaJHhmMPpJrRewWaASMmAxXaJjsgKkdDyICZzcVveEGgvdSsDkuLlUKMbjWyMmTpwWFfjJLuXyVvGgYgdDGdDxUrRXxyCWtTWuYzfFZEezZhMmIiSsUvHqUuugVYZznGcxGtjuUSftPpfhByYSZuUZxXWNLvuJWwZzMJIkKPNnDdpJjDdHuUlLhAgGpPoOaFfhHteFfAOyxXBbLlYFbYqQgGWwymlfPpexXcCEFLWwLljpvghHAADEYZzzrDSbZIizIiAcbTtBoWVvVvwOwnGgrRbBvVDEcCeUZzNTaAccxVvauKcCnNcCxXVkweiIEIrRqXDrREeEJBDdbkTrFSAaeRrKkgGOwWtUulLegGEnNUVSPeEpaAsYFebBEexAWwGweELbBlrRhHrRoKBbuUkOWRqQbiQqIBdDrSslBPFlpPWBNnYWRvVSsOdZzDRrexoOLljVvwDbBVfFvMDTtFJjIfymMqQzyAahOkKUPpwWIUxpPiIGgmEezLlcCYxXjsSSHncCIAFfbBupBbCcXQdlJaeETtAPpKkXjGgAxGgHtTGVvPpgPsSEehHJjpMmSSKksCcAaQSAsOUVvudDLlQfFVwjBMmfhWxEAaFfBIibekKLlplLmMPutsTcCAaAYPpBbunOiIwWlHEUuOUufFmMeJDdWeKVFdDJRxfZzMXxvoDdBCcYybWwxXHuuUUhdDhjJHyfuZTtAwJeFfLOooOztTjksSKUvuUVuAavVmQgGZyDdQqDdKkPpxXMmEsXpCezAgOovCkKcFPpWwlSeEsLcCfVqahbZJjcldDiubBGWHrXxRyYEeRHRryzZIbBEeDjDdmXXxkKdXVbBvIrRTakKBsZzLiYyIXlPpeEWeRKLllcCLkqDNniGgjqbEcltTRTYJgquUcxmxXMXaOaywfFNHhVNwWuFfUnYyGgvLlLAABOobmMpIiPrRxXafmMFsSFfBbocCOavFsyVdkKhIeVvEoOzaAZJjicCCAMmaYHhEeylLtTrRcDKdDdOmkKMouUXujJkKUxIqQiovGUugugEFpXxIibBEVQZzKkqTtveFYQqpjJiFSYJjwwEeyYDdpNnKDKHgHAaAaJjfQYyqyYvIeeuuJgGjUUEnNJjyMmYRjJPpkKrsKpPQqvjJVeEPpcQtTjPpfFrrrSsdfFTxnNXoebjJBEGgAatPbOaksSfFhNtTQqlcCNnmMjYyzZuUyYqeNYoOylLlFfXJEeUuzZwsStTHQAaqhSHhQqHhsIIiiwWnAeddDyYKmMTmMXxDdiImtKKXxTRjaAYTtPRrEeqmxedDEzEgAauMqoRMoDGPmMWmMwUbBuPCcgaxEeVvxnBbUJlzHTLplcCLAajJAJJLlzZcKkzCcBgGDFPOopsSKqAaQkAjWKkuaOoOomMGgZzeTtEZNnFfVRqQrvziIhHxPpXcTxqQGgmqQpPpPPraRihHgGdDCnnbmyYNGzZpPSskKggGyKEegKTgKkVvvVUuLlGhehHtTCchOteUNnAVHhlQerRzIdDQqeVgGFBbYgGwonRGgENnerIPKwWkDdUFTdQiEqQehHnNInqYyVvWwaAitvdDVKIiKHUuEXxgeEMmiJLlCTtSWBbVvwRrkNnKsMSAgGDzZoOTtCaoOAcdacFRpvVPCHuQMQqmyWeEaIivVSRrsqNiXxlEexXOoMmxBiXyBYyRrbVgPfFpBbFKhHNlEscCcCLlCHhwWdLRrHhysSYeEPvYyHLTtTPpjZMmzJIiAaVPPppZkaAwZMuUVOIiBgGqQbIZziUkhvIHhVGgwAaWXOUwWuZzoGgThHtXxZzuhHUrRNnBZvNnotUutEcqQsSCVvNnmUkKXxXpPiIJjYWbBDKkdTtwylWwcCQqXxQgGLlZzKkAaqcBbAahbVvQnNqpkKcCiIHhbSeNnEbiIaiWwmTdDuUNnEBRrwSqGjJnNgBnNAaVPpEeXDdxvVWMHhTNYLlyVvqQnVvtVbBvafFAwmEXurRZjJzakrWwHcChFxXfhHwoZVjJLEelWjJxxkKVbBvsjhHJpYyZzQURyxkdDgGpPlcmoYXVBhNiIEAaNnwWEeewVvWndtMmsGgGNLlRrCBxVFbLlTtBhHRrUVFCcBxJSXxIiQqsUukKtTGgGgGKkwWVvdnqwWswWGGUubkCrqQUgHhGPGodPpoOHTBbMmtnNhlNnrRdHhZzDiIGgMalEeMftWwTBbePpEBPpkKbLlLFfAadkXxKMmpPievtTNnKsSuEeXMVvmkKlWqrtrqzZQqTjpqQPPpYGTttTGgIVLiAaXnNtsSmMCIiKkPppPcgGTlLUxxdDvVpPaAWZzYywCcmWIilIibFUuxjGzEiIlHdIMmiebOZVQYTtKRrkyTBbrRtfpPRrMswWhQdDySyYfFeiIqcwWFaLCcNcCnpPEAaCcezkKCcWImRoMIiiKXhXxxKNnPWnRJWjnzdDaAZcjJTiIqQnOohTtvkUuBiIcCwWQqIZziJjCTzefFXxxJjZVamfqQFYyMmhHJLwWoXxlLiRSyLIXrUzKkpPGgXFfzoOXLqOyMcpPpaPpAPJKvVkjbCcCcQTtGgLlqBtKiSsfFIHhKkkynNySsOoQqQqFffSsFoOroFffnNPpKkWwnArtTRlLinNaYQqQvqxXKXxkQucCWTttTBbwUWwfFgJjZblLBMRriOoIqFhjxXJaqQANlLbdWwDBOUlLtoOThoOnNsSoDpqQxpPKnaBbANTtfyYnNhLPRrdDPhHVNVvVvcThXxHjgmMaAaauUAYyOtTnNjoOYbQqkKlLCJixYNnyXoOeFfgngGwcZzCWVQqNgGPwWyYpjqQXnwWvFfVJrRjNneEMmsMgGiCcMeEmGkVviMTtmtGwyrRJjjCKYuRrOSiIsHDdPcCHhkKrITtrRSQqteVvsSnpznNtTXxGOibDdhVvrxGREeMFXxGtTPpRdEeDfFHhlLYyrxlkKUxHdDhhHZzXKsSCVMYyHotTOEIigGUOJFdDfjuUcyhHZYyYamxXMXlLdQqDQDcCiIksvjJOwWIiIizKgGZXxYyzkOaZzAqcXgGxbBYDJjdfnPpPpjJqQqTXRqQTtrzkKlLGatrvvIihHsSXxXEerUrsZzSqQjjLAZwWzqKkwWQaPEepQInNWwiRKQqVvkJzZjjJrnNhOhjJDdcQQqOYOZzoKkqQhfcsSCGgirRqQoOIdDYivVpnNPIygdmMfFaACUuhLlgCoOptTPWyYqzzZNCcntTMiYyIjJjJmZfUrRcClSsiIqQqFdfxDJMNAahHrwzlwsSdDWJXxrRNnxXlLjVpSiIAaOnFfNHEeMKkjeVKkxXSVOugGWKKkksHhSNnovViIMCSfBbhlLyYDBoOWwbAeEeEeEcChHIuUicCBXxbSHTzZTtIbBiKNnkwWRmhvVnNoFlEMnNpPTtmGKjJzZhwBZzCcpUucCIiJbOqYDdyrQqcCqvCcHuVpPvOocmMlOoLjsSVvnHpPhdKzZibtNJiIjBKbnTHhQyOyYoYReDzcqRrRRrrRoOVzBbupeUuoOEaOyCQqgGlLKtGajqQJlxXLDWiIkkKKkOmMmZEeSMvuUoOeyqgLlnBbwRrGgWGsSQqgzZgGNrLEHhWwVvemsiIPpCbQqKgoOGVvPpulUuLgGUkllLDeLlBbgSweEKMmkIiZSKkAasgHhGIaAiWoPpOOowzWskKdDEvVePpGOoeEPNncCmKkMKwWNniIXxoIiOYZBbzClTtCcLUxEkKmoOMwWXBbxDfEeFdDFfTCpPKkRrBnOosSuxXAKLlkRrgoeEFfOeEtTRzZZaFKkNxRrRvEFbBfQqIiekKNnpLlzwvVDdjJWojbUTtuZMcCWesSEwXSsbGgDpPcCkxXKdfldaADpROHUuyaAYzkKDdaoLYyizZYygGdnNDfFxbBNiiqQgGGWzZBbeqPxXpFQAnmkBxXrRXxoOyYcCAiIIHhiAgFfGCXxSsMqQmgXyYxGcXiIiITtnZzgKbBBbkFfXxhIioDuUHvbBVbBpPlLADdNEenGgaXxdtTDkKcHIiNSsrIcduUwtTWDmMlyqQYazZWFWWiaxXEyYwWeLlYFqQVxXyWwYvfKkFEedHwWOohbHhgMFmMmMfmrPtdPpHhmMUHCHhcYycCMHhqQgiIUbBUuTOOoodcDCactPmMPGqOZzOoOvVTSFfstcCaxdkKHhRJEeOwtgGGLgGlgmMbBCRGrRGuUGggcyYCibiIKkrRmHhMxXBsSyYqnNQVAMdDaUlbBSsLMmdVvfFEeDdYPpyZAaKBbMUPpuWykyYpYPtTpJjVCcQqEEvVnXOorRxXxQqXFfKZHTtoGgGUocfFDdUDddDuQqNnUugbBuoOUnwWwGhHDdWwgdeEDryeTtEYpPpFfIaqQUuCcZwWzAiMmSOoKkEelLZHwWglYqQyZvVvYyfFVQqmMPdHhlLDWiIwmpxiIbyYrPpkFfowWTsWlXlLWKbbBCcPzZJdDjemqTthHinZzvVtFfAcEeCsYqKkMFtqxXRrGecCEpNmgwuUWNYeDdOoEJjyzlLZeEnIiLVvVJjvRzZrZrRzQrMmRgGyYRDRkKrdQZgzZGzqHhrRUdDuuckjEIzZJjdVvoOViIkKWwVWsSQqlhHrcCDZVvzZJGdDncaACBBDRrbjUuJfNnrRocgGCIlNnDSBbtTMrRnidDCcIwhcCmbBMAmbXxdDrRQHcCgzZuUiSfFspLlrRPpCkiAaVvMmIKCKkFiIfVvchZzTtirHhoORKMkHhKmaAkSBbdvVonNWwmMeWuUoiIxrRfFXZHGgBbbBjvVJuZzEdDVDYydLkKeEBbxuUXxXXhHxICckKTqTdDUuVvPIRrerRHtThtTpPyYDWeEYTtyHhwdDfUuIbBMmNFlLDLloghHrRhpAPdDpHlLhHhGgMpDdLUuRrIilLaAlmMmKkWZzZrGgIBySNJdsSDsKimMIlaALSdDyYLlkKIishHVvgGKkpPcDrUDdZpZTtQNnqTKVvmiInNLlMCFfcmDdqyMuUyYlQqcLlCBbLmjJCTfbBzHFfpPnNCchzVvEetTNrRwWXBbbUuBxnmMEZzXoODpYMmRrcCVvyISmSsEWiIhJjCctJjXxTHNtUzxXIHhxXiZrTmMzZqVoSREdOrRoOlLdDLleEWroOXxsStNnTdQKaAkqETbsSBtfFfQqFeyxnhHTTyYttqZzafFReBbzZEdDwWlGgGxFfVgGdDAocCUumXxMUqQoUSsLQNnPpqGDddLwBUuDdQqFYsSHhwfGfFdDwWejJcCcpnqQNmfsSFJjfiPpIOozZXxXxLlQqIPpXxPpJjeVvENnaldJCcjDdNxcCbBVWfFIEeEehHYNnPpyaATtiCTJjtkKHXxhuUKkxoOoyYuUxXOAAayYaMmLXlLYnNjEegGJbdDBjkKYytIiTLlcMmCjJcCoGmOcCnNonnumMUNNFfMLlYMmnnNNpPaAaAWHqtTDdUuQSsrZzhEeVvHaAKkKBbYyJwWjsvlbBUImMNnWwpmMPiVvVfwhjJDTgpPOoiINuUdDeCxXeEnbBYyRrNdhHqQTtoOOkrHrTtQXxPIikCcrRWwctsSrwWVDZzBfFPGfFgZzIAUuOrkKCcWcKkCwqfFQgxUPLpvVPGglpGTtgaHhMsPpaAxHOohHOotzZTYZQSZzUpPHyYpzvQkeuUEmOoMcpSMmCgGcsrRfXxBhHbFJjcAaCnxoOXuUGgMUzZqcNnCkKRjllLLdHEevVvxXVhtTHPphBbqQYOoycjJDiIwYyjJdWpPwDLFeEfqVvQOolEjJqQkKfHhSWNWcCdGvViIsSljJjDdJINncHhCiVtpPtTTvoOHhTtkKkkKAavVKLnNIiVvwWOXsSyCcnnFfouXUuxBbHpLlWwPhVvSixsuUiIsSkhHKJvVjCclrRcCLsbBSPJoKTtiIkegGvuUwuULaAlXiaZzUySsYKiFKRTtmMuAawTlqQYyRrwWzcCnNNQUfFewIiEeWCcBKktwFRrvVtmMTzXxRXxNnoOoOwlPptTLnNNnJcCnNgGZYyzNncYyWwWmDdKkJjOXpPUupPuUVvbBuDdUuuHhUCTRVvNnrzPpZzgWFfwiIGHLaAlBhqQYyyYULlRricSThPfbBYLlvVyhHATtatlLTYycCWDkaAKdMdDyYoOBbNnixQscCPpSsSSsqSYyAaRWwJjrlLsvVUTtBzYgeEGhHyvrkKkKtTEeHhmMKmfRVvrOGJwWjgZzjJjqQJjzZpPJfFFvTthHiDdWwIviIVcdDhHBbmxXGgVvXUuCVvtTYycKkpPXxFfLlhtTbByMmvVYbQqcCPpLNRrYyEengOoQrRtTrRrNnMmXUuOVvoczZCxaAYbBhFqQwWQqfQqqhoOzXxATtkKdXxLjJmcCMKhHklDaUgYyFfCcAagBbAWwTtAaqQaTtGvVWOowGscNnCtXKuUkTrRtcCiIvVCcGgJjmIxXHOouqQUJEeyYFyTVvdDOGgooOcCHsbRMPpxXLlcMmJjRxXryYCliILPuUuAAagGafFofFOlLuUiMmWPpSsMmwWnLlNGLLlgUuGlMNoOnuWvVzZHLlGLOolgfAaWoOdDUuFfNnQqTtbBAYyaHhDYyqKFfgGuEaAeBbBbHhHRWKkiIwPAaVAWwsspjnNoOXxdZEezrjJCclLRKcEeeElLNnNnVvSkGvVFzZcCJjiQqDraomqHhQMxMmCcXOSssSAPIdFfnNAaDzZfuUepwmQDdDdqDdWwcCfTtnsAaCifFFckuUGgvVkKBbiIDOodFfFfxXfFTtNnvVGEVbBvJjexXTtHhqQUusSSsgYEeIiLlCbfSRrKkHhFfVUQqxJxXBbLBhEePTtpHJjCGyYCYyAIAJjIUUVvZzuCcbBqpzWwZsSQUuYkKEvVeyqHhUAaDduhSsHPaHvhHVeEiIXBbeVvPpEJjHhvxXVGFfVKkvUugKkbXxmMgNnGjJIgOoGiuUlHDdLLlzmDdMSsvVXyYLlxmMVPpvHuUvVLWwzZlpoOoOFZzMCNnXtTxcezZwWQZzpPVvkBWwbIicijJJlUuHeEhtMmTLscWwCnNBlLXLjJsbNnBSnaANHhGgDHaAiINUfyiIYFuhTNntIqUuyYyKiIkNFcCLlfyYMOomtaFHpPhZwLlMmfFmqZuUTtzBbxbBaXxSEeSsDdLbWwUatTiIkKfFAuAoOaZUuzDdnNwWPYypnZPyfAaFJUAauYyjqQEeCcgscCSoKcCRVvsSrMEadClLnNcaOoFfIiOoaiIDsSdkKAgTtGxgMmGgpAaAKkatXGghHeExHYUpPeEUuAanPpNNMmntwexFfSIijCcJsKkmMrRzZbsSRqQLlqQdzZDqDdsSieEgGMtqQQqTSsccCDfFFfEFbgmMGzZBamSsMGgPYRrWwDrRdvVtTHhiIsSoCJjGScDdlweAaEWTHhIiFCcVveEGqQgftIDdMmioJPAapeEjkgXsGgSlLksSKEexfcCcCkKqQxXcfFTtVdKFfJjrZzRjJVvJjmMjJkMccNnAXxVvgGvVTqQtBbgGPpVTQWtTwuQvVxdbbBBbsSRrtTKPpkljJMmvIiDWGgcCwdtOJjtOKkOWiIwooiuUIkKHhCcNnbiIBWhisSWwzZvVlLMdDmoOQqbBPPbBHoOtTPWwkKjJzZpBhHwIiWWLbpPEeKTdDMmYmnNMysntTNkmWvVDYgGWwPpVcCvFetTapPOonNmMAJjdYyzxPeUubBEmMcsSkKkKTtpPGRrqQFeEdLlmMeEDiMuUHcCfFTtrnNRwWTrRteEsbbwWvLlAZzaziHSsdrRVvhorRwWtEnNeLfFoOlZzTKnNkaAMVvxXvVDdQoOKkxXxJeEjXFfxbQIvwWlLjJVHhDDBbdMUumkqQkaAKYsNnypPQqYyXZbiIQqiIiIclLEeoTtdGgpMbKxXuUbcDCRrePyYpHVOovhdfNLllLeaBgGTtlLbsSAHCcyYhNnQdPpiIDSsIYoOsmVvWByYeeEXlvVlLAwVEevWEejNDpPOxtTQqXYypcCCYeyHhiIYEyYGxnlKkLsSXxmMNOsarzZLPpTtltTCcbBmxXfFdDVoOvjnttTIiTAaqQUoJMxuUXeEJQjJeEqjmcOoyYAamMCjpYRrzkKfFZhHjJyhHZbxXIiBqQVvNFjAaqQYyJizZIdnNvcLsJWwdDjEaAQDHiIhaAILldsSDrCHhAacCcQqfaAYNXxnmiIMPRxXeEGuUgrPeFfHhEuULuUqQlvVIUdDuoOidDoJjOSsujbxXBJdDLmwolLIiYXxwWlFfQdDqeESspPxlNpwWPnLTtzZEBbeMoxXOmwWJjMBbFfYBWwSsbFOSyYHPwvVYyfUuBLffHhFUOOooDdxXceAwWamMcCrRRMmrEtTtTChHbrRBMmpPAxazZuUAdDXdDYWwyaYyVvaAuJNtfFfxXQqEeYyFTADzKQqOdDonNaAAawRlLrWWCcwkjQVvxgGAaCiIAEeaAacuUoBbMmzZOzZRtTrVvEeZzZzEenJjtMliIJjOoqfFoOQlaAIixXLeElLqpOoPXxtVvTDWtdtTDhKkoOHcfFEdZzcCDeEAaKkzZeCBhHQqbwuUkKyrYqQeauUKkZzEeGVvgEJjeNWwvxXVTteEVPgGUudAafFbBzYyZgGySjoKkJjXBbsSjJKkKgGkkKrwXsSSsxkKzZNnaAoqUulLJYyjcCdDPJwBbWIibBAaUuoOKGgkjFfnYWwdyYsSEeLltTkKvVBjJDdqQGCFYyfyYvVbBbBFHeEGoONqQzZxXeEEenFMDeEOoQtTqsOgGoixXHjJhjJIaKaAVvXxTQkHhvJjVKOoZzqtxPDdwbHhNnRrfFuUiRrGgrRWwDdCccCwHmPUuGgSsOWgGbBwNAbRWwWwMmmhHUulJmMjLonnVvNTtMUnjCclLZzJjlNxXNnMmrqpyYPQnyktTwWnNVvOoKxXYFfkJjjJfFKtoeEcCOwClbGXWMmlLgnNrRIIIhMmHiixCwWOHhozZOkKjJHhozZdzbBZmMNnlSmMitTIsGnNgYySsMmMtXxXvrRVxsVvyNXxeJjBbEnMJjOodYyUuDBbeEMPpuUmJtPrRpCcbBRrTiPnNwHhWpxXlrSsRcCLnNgeEoJeYuUKkOoyOoYyqJjQIiuvjJnNbIiMdDIeELlOpyYZzgGUuCcqQvwWNnuUKkVPoNniNuUfHhRrRlLfMmrRFrFEeicyYCiIlLQqPeEpVKkrRSsefFMmEIiWoaeVoOhHvMmEeuXxUdDETtARulLdsudAaDRRrTxFfECceXtrNnsSmMksSZzKoOZeEzfFjqduoMBbeECcAamtTdnNfnaiuUeEHrRrIKkiRnNtlLTiGgIAagXxzoOZMmeDdBWrRTtALlAauTtUgSsWxXwtstTSTgZTtzZerDdREYyXxzQiIjJJjwWBiIRTtpPcCwWrHXvFfVBbOFfoUuksefFEaASYiIyKxVvsShbBTtOnNEoOZzlLeoxXCcCcrQqcYyKkvzOhHYyhHCcHhNnMmdDFfbdDjJhHFjlLvVjMwIiwlLWWaiIAZiIzszZJjbdDAanNBBbZVvPyYRWHsSLlQRryYsSMacCmFPpfMdJjJjMLlgNnwWGRrMmqQuLdgGDuxXUpPOolMmUcLPppPPRrurRZzPpEecCnNUuEtTpGgqYnUuxfFWsSZzDdiPmMYbByGrRuUgdDMUuXGgXfFiIxxqKQpPccCHhCqMmgJjGgGhHPVvMmOojmMKMoOpPgrMJMZzmVvSoOsjmBbVaAtMmTwWveQdDNnTcLlJzZTplHhFfZzFaAfLlEeEyYvVxAabWwfFiUQquICcYMmsSyBdDeERrGgYymdfFsSDyYMJjmWsEyYeSwrbVZzvltTLYyBEAyYaeOouyGwWwSsWvVgztTMmPppPZsSDiIgwWGdYLlqDhyhHpFfPbEWwemMmMGfaAXxFDdjJMmSoOseyYEYyYYypZzrRZzIiPmMiIyNnCczZtTtpPaEtTeXXuRrUUGtTzsSjkKhrOoRHXxHhUCculPpzZCcWBbFfJNNTtLlnWweENdQqLlDGgnqQtTJlGgLTtMmPpjSscCLlJjVvnzZjSswLPptfrRFbBTldipPYZzyfqQRxXriIFaAOMmpeEMtsSaXxAXxwWbBYyMmJjIVviYKEWNnNjjJJCcSsbywzZWEelLvVcSsVvAaSkKhHOosQOoXxqiiIICKUaaAjJAaAbWwIiarRCcvVqQVvdDIKkiIYyiihfFbBHgGIxfFXRrpPpaAPXxotTOaAsAaSxXdamKkxMmyYAaGTOotVvCmowWklFfLKhHZnNzOQiITcCtrsSRbBeDdECcqEUuegGuPeEchfFrRlLjGgJWwUbBgGVeEZeDdXxRUuiAaxRrzZXiItLlTaAXxsmMmkdDKigGiIICHhcrAaiIfxlLHhAhHWwQqrkRaAOYyqQoNNxXndDJjhZzHcCMmTtrMmdDdDRrzYExXAIkKiDnkKNdKNNnOonIVvHhlEezZHIHGgdLlwWDJUujiIhVlLvzZCGOogUuHJjIihXUkKuUOoUuoOPpUceECFfccTcCeDaAdEeuUEhIYSsySwWLUuhfFAaoOTtsxXNnsSSAaWwPDkKTtwUQMmjJdDMmqfFvVIiGuULAaEXiIxXxevQaAqVlHfaAgbBgTtGfFfAamMWpPhYyHjJGgqQihHIwRKDdkxXbLlBWwrFoOfmMkyYKBbAfVvBUubwWGXxgbmMBvVmMEevVtTuUQGgxpyYPyYVvTtXkKNnJjcCGbBgNeULlpPmuUmVvdDsSXtDdqQcOoXnNPhjJTtHkxUuXKQNwWnqQqfFAjZvVzBMqQYVpCdDFaMmEeAUsSxmMzZXuTbxXaABuFfMmhHTTtOwnNWotfeEFaNnAoJjYyOaALvVnlLNUbBVvSsjJvVRrqRrQXxeECcPMNnShHWwtTLlCcaAfRRuUfFDdWwPpNwWYynrRHuvVUdDkKkTtKRrfFkUNnoOVJOXTtgGmMxVQPbvVBjJASsaSsoHKkhOQiIqbBVtTiIvgGrRYDaAHhaAdtBbKIikrRzZTOKkouUEePpacgWuUwGtYyTLlEetsEesVvaAONRrPAapBwlLWIrYyRiQbmMkKXDdxGtuxXDiISsdDdzyYRrAnNaclLaVvQqFfNTtRrAaQHrRuUTthqEwWeBbngGwdDfFUudDzFfYMaAmTPpfFtqQxBbwWBbCaASsvhHJjyYVrRiIgfiIYysScCWsSAaHyNqIiQnNBNnnNxXbzVvVvTMJjmXxSswWmPpMdPEeplLnNLlkKTttnUuzZNUDdtLlTbBPpgGuqgGpPQzplhHwWpTtPuQqUdJjsSsUuaYZzylFfuUifZzFbCcvVBKxXkhHwLlTUutTmMzZFGgftpzqBbMmesSuvabBGgGmMgAhHcCHhIiFfVvCcjJGgqQaRrxsSFftuUTeELlNneEvVEVihHayOuUvVuUGgkoOzZKdUuDQqfFFfzJjkKZQbBLlzZRsnNnNrzZgGiZzIoJEejPpMCcmXxGgORSrTtZzDkFEefrPpRDdzaAZQXxqeUuEsLlMmdjJeDTMRdDkJjyYKrXxmtdMwWnDWwLldkOaAoKqyVvGgYpPwWoOQtTNXpVvPigGaSsSOosTtAdmZiIzMSsDVvBBbblLSsuaAvVsSmMrRUMmqPphHAxNZznXNnvVbzZBnyYsSNzRrZDdMdDWwvVmxXodDOhHZLlzhHfIUufFwWXxbBTttEfoHhdDOQiTtIqgyYGFCcEeOoaAeUAPpaaAFyYBCiZzIEeYycbzCcZfaJjPmMpoOGxXtWwTtTWwgCcVBbgGvSjnNiTtyYvCQqcVzZLlNnIdgGDpcSsCfFPGdDUuxtMNnVJqQjPaACctIQTtTtCAacqxBdDuUnNCJJjjccCbyUuYBPeEpuUrRZAacmMCwZzZzWzfGgFYyrSsRbjnTtNJNWwluULnsSCUfFgGXxtbBTuFfVvqHhaAQiIMYwWyKRRrrhxLluewWEhhHbBodnNrRAkKaDEesSKkUuyFWwfuUFZzdvSQqQqsiIxDyYdMmXIiFfRrHhiIVvIgYycCRrhHDdGifFZpOoLlXxPzzhlxXfKsBZzbeErRSkTqQjJtFIiqbBsSMWwmlLQqtpFUueEFffjsSgGgGWwXxQyiIYqTtZqAaQwCdIiDYNnyfvVFcfNgGnUuHhJRrjhHFAawWEeQhDuUqQdDdaADdMmHgGcCiIuRVvQqlLrtTdDvVUcwEvVvVeWGgYTtYyyUxXusxXSQqChjJUSsLloWwOeojPbBpPwWpXuUjJFfPoOmMpyYAaxdDJONnNnxuZzUeEXpPqbdDqQGgJjBKEqQkhhHvVviIdDVgGqnNYyhMmGgHWweEsSbmMWwZzoOaAXHhcClLDdvVawZzWKkQqAnNPQBbZzhHkKVvhHOgGoDdhsSHoOLluUbtTcyYFfBbuiIfFzsSXWdDFflLwuUBPpPpxXbxnoOgGVBPpbLlinNIvpPEeHBCcrRbESlLWwZzsNCQUuqcnJjJjjJiaANhtLlfFTbBuUDMmdRmMKkrjfFJlLhsSRrbBHHvrzZXxRVGpmOoYvVyMJJjhHBbjdDWOxXowPrWwpPxXzZRYynSRrsNGmqQirRBcCkdDZKkzkvVKucCUKYtqddDDtcFrRfCqTFftnNQTnNhHQKkmMbnNBmrRNnYExXeBipPIElLnyYNebDgGrRdEuUeoOZzyeDdtTICciMYymkKaFfrRzZYoYysmMCcSPpOyljJSsLAyYjJEBWzZzZvVmGgMYybxmMtTXfFfFCcsSOSQqnNPbBpPpBbDpPqQdsGCcgXxTtGglMrRVvmLgGHhTtUdfFiIeouCcZsSGBbgzTROGgocCrAsShHSsavVIiteEmMEGglLeNnKkiEXxnNgGenCcVvlIiihHoOaIiAVvPpIOhHwCcWNneEVvLhJjrRSsgitkKTIGeEAlFfLVvZTtrRsSjJQqsEeSSTtsQnNaHhAqQqAVgGAaDdvcCBlLbpIiGglpPLVSsEeYlLyvVHiIhvJQrRqjOoFbeEeExEQCcnNzZmMdDmbBkJjHhKyVUEGgeuqQmxIiXolLOZfeEbsSBbBOoZRrdDqKkQzFkBJjbKrRjJKwWkzGgiIMAiISsPpavCcoZzaGgjJhxXHAcCxzZhHVSYysdDdDvaADdcmMCBbBbOoXgGYJvOoVPodDOpoOQIiHhbBqxXAAaiIZzaIijJoOKkFfjVvvYKkacCyYoOAJoOjsSsSArRwUuWuUacCuUzZCcrXxRimBbMIBsSXxWweEsztTLwWljwWjtTPbBOouUpgGIibIVhOQqhHPpRrogGpdJjDPYyQqclLCHdLFflcuUCvVQBbqLIiTAahHtdDwWoOZPpzOYyoOsSoVvwdDWnrRNJmMjmMGgIFfieEIirRRthHviIhIiHlXxLJjGglYyLbBzfFZawWuUuUiJkDdjoOxXJgGJjbBjJGtEeTcCPjJlTtLMmpMmgdDUOQqounCcAaNmEwWeZzzZpPMuUJnNjUHhEedDugGaAgAaGEeXLbBVvkQqswWSKSadpPlKkLHhxXIiHhgGtTiIkWQVvqwKWwDwFfpPbBnNDmxXCcMdjMmuPpOOooUnGwWgNJOoJjHsqQSiIUmCcMulkFfKFfEeyYOHhorPpeElLRLfRrFIkKiiDdlZzEenGXxbNNnnXxBaATtXpPxBbqQrRsVvUugGMmsGgjJSPpmHhgGPSspChDdHciCcbBIFfEpPeDJjZzdFfMOgGrRuUoEZLlaAzmxXMbLlBxXLjJldDkBbdDSsYyBbPpbBKsSGgeWwrOoRWCTtcczZkaAKCTsRrSAgFfGEeeEazZtNnHhqQwFDdLlfcCaEewbBWhHnNxXGgqQiYKkyByYyYsBbSgIiGeEMMmmbjTtJTtIxXNnRrZzlLzZgZzsSGUYZzyeEuiMmoOIiIeXaAYTtyxlvVHFDZzdaAfjkKoOHBbhCccCjLqrRCcQsHhCcSkKfFlvVpSyYsPkKJSqQsIioOcCowWWMmwOXxPpMmMeEmiSsIOmkjyYJcCBbBVvzZbZzKKUhHulLLZztTlmMNnQGgTtkkKKSPpsmtTcPpBLlbCCVaAvcXxlLtTFflLfFWwdDcCGgVvnIiIiNzoOneENZlLPpFfMmgsokKOVnSsNvyYSjJMmzZGfyYXxEefFsCcSrcCgGRsSFwkKxXTtIihQsSzZIiqyYQzhHZqINnNtTnwWRXxreEMmiHnsSbQqMeEIimXxgwWAJjakKlLlZLlKkzLWbBwsSnNYyOVvSsobsKcCdDoVvkKOhxXHkQiIqSsPsSVvZzpIiTNiIIigGvVUzLlAaZhHBsSYxXKkNHhnyYIiyAEeacOoCnNGkhHfFfiIfFJjFKFxXflqqQFwWSsffFCcVvQLTtQiIqwuUEeAaYyMmyYevVEKiIkcCgGLlQquUjuUJpPIHhkdDKIiAqQaklLKWwWHTthwLXxlJnHyYhSZzDdHhuJjUCdDcjSsjJJwTVvtWQpPtTcUuCTMmhHtlLqsNlLULlumMHEeLlraGgAtTycCQdDqDdDdWwYRXxhcCOyYoSskHhxXuUKSsZzJjqQhqQNnQxXpPQtTqUugGqocCOStUuKkzZTbBTtqQwWnNxHOoDdhwWzZCcXOobBwaAWssSSUusHSsRaATtrqBbvDkKZzmMdCNncVQEsSeUuliIUuLBxWVvwXxXMmbyKkkKUuTgGtUpIXhtTHxiPadYyvVDmMOoAxkKXvDdVHhocCOfMJjGgmrRYyFeEwrRWtTpPWYywcCBAaxXbkKKkaAAaOoRyYmMrlLUuDWwfFFfyYeEdBbcaCeEAaiVvIUIiuDdrlIMjJmiZzxXkKiIyYiIwTtAJjabPbBpdOjJVvFfoDBWJjzqiIpbBeErXxREePQqQvViAaTtIJsSjSstTjrRZNnzzZBbwWnNKkwoOWSsJSsAaAbBaPprREedDZNaAeEnYyZzIiZyYoIUugGixXxXhFfIiNSsnHOzuUhaADdHpPvVLlBbtRJjrQqdJjLCZzEeclfBbFXKoOkcCeENnxyYDOohLJNnlLjlEeCcTDdbBnNEzZeLltwWHbRrsnNBbtTSSQqssrRSPpgGNnBdDWVOovsbgSsLlGpPsyXxUuYSvtMmFfZWRlMmLrwUmMuBbzYyjJiiIYyIYyTQqsSvVvVVMmBYRHhGgruaAJjUQUuTtqvVRrgZzJjEeGKkiEeCcEhHRrvVzZeSswLlVvgGWFVvfTtItTnNgviAIixfFXaYyIVYtTyBXxobBKkBbiIBaAbxXObtToiIOHhVqQuUuUHqrRPhHWwpcDYydAaCsSQIihHhvorVvRcuUCOoFfANnxXarhHRnNPpFolOoLnNaAOdKkDpPRrGgimWwchHgaAGCMDGgMEemSsLlVvLldRDdrQqypPNnYtTMvtTVmvJjQqbIizZxeEKkXvVttTTxXzDdZNhHGKMmQqkgTTmMSHhBbsALlatLlfFDdtZzKkFfssSSrRtTcVvCaXxADdfaAeEFefMmFXxAaEHhqQeIjwcTtCFPpSuUsfgGsSLqQlZzAdoOjJtFoOfmoOMFfTyYDzZqQmMexXEJjaLlkKlLWJjAajJaAJCrRhHKkkKHhKkAoOcCaPpIiCCcxXcUDhHdjJkeEPpKiyYmlLMIzqQOoZjJWwklLSsKjBbJKEekbkKNqQnBAoOaNnwWiIAabsSfFBbujJUBaAEeuoOpTXxtPQCHhcqZOTHhtojJzJNnfFFfhsSlqQRrLHKSskoOgGNzZnyiIYuUu diff --git a/2018/day6/day6.exs b/2018/day6/day6.exs new file mode 100644 index 0000000..a2b2c90 --- /dev/null +++ b/2018/day6/day6.exs @@ -0,0 +1,118 @@ +defmodule Area do + defstruct [:min_x, :min_y, :max_x, :max_y] + + def all_coords(area) do + for x <- area.min_x..area.max_x, y <- area.min_y..area.max_y, do: {x, y} + end + + def edge_coords(area) do + top_and_bottom = for x <- area.min_x..area.max_x, y <- [area.min_y, area.max_y], do: {x, y} + sides = for x <- [area.min_x, area.max_x], y <- (area.min_y + 1)..(area.max_y - 1), do: {x, y} + top_and_bottom ++ sides + end +end + +defmodule Day6 do + def parse_danger_pt_list do + File.stream!("input") + |> Stream.map(&String.trim/1) + |> Stream.map(fn line -> String.split(line, ", ") |> Enum.map(&String.to_integer/1) end) + |> Enum.map(fn [x, y] -> {x, y} end) + end + + def bounding_box(coords) do + {max_x, max_y} = + Enum.reduce(coords, {0, 0}, fn {x, y}, {max_x, max_y} -> + {max(x, max_x), max(y, max_y)} + end) + + {min_x, min_y} = + Enum.reduce(coords, {max_x, max_y}, fn {x, y}, {min_x, min_y} -> + {min(x, min_x), min(y, min_y)} + end) + + %Area{min_x: min_x, min_y: min_y, max_x: max_x, max_y: max_y} + end + + def manhattan_distance({x1, y1}, {x2, y2}), do: abs(x2 - x1) + abs(y2 - y1) + + # %{ grid_coordinate => {distance, dangerous_point} } + def proximity_grid_for(danger_pt, field) do + Area.all_coords(field) + |> Enum.map(fn coord -> {coord, {manhattan_distance(coord, danger_pt), [danger_pt]}} end) + |> Map.new() + end + + def proximity_grid(danger_pts, field) do + empty_grid = Enum.map(danger_pts, fn danger_pt -> {danger_pt, {nil, []}} end) |> Map.new() + + Enum.reduce(danger_pts, empty_grid, fn danger_pt, merged_grid -> + Map.merge(proximity_grid_for(danger_pt, field), merged_grid, fn + _grid_coord, {dist, [danger_pt]}, {_dist, []} -> + {dist, [danger_pt]} + + _grid_coord, {dist1, [danger_pt]}, {dist2, _danger_pts} when dist1 < dist2 -> + {dist1, [danger_pt]} + + _grid_coord, {dist1, _danger_pt}, {dist2, danger_pts} when dist2 < dist1 -> + {dist2, danger_pts} + + _grid_coord, {dist1, [danger_pt]}, {dist2, danger_pts} when dist1 === dist2 -> + {dist1, [danger_pt | danger_pts]} + end) + end) + end + + def find_infinite_danger_pts(proximity_grid, field) do + Enum.reduce(Area.edge_coords(field), MapSet.new(), fn coord, infinite_pts -> + with {_dist, [danger_pt]} <- proximity_grid[coord] do + MapSet.put(infinite_pts, danger_pt) + else + _ -> infinite_pts + end + end) + end + + def remove_shared_and_infinite(proximity_grid, infinite_pts) do + proximity_grid + |> Enum.reject(fn {_, {_dist, danger_pts}} -> length(danger_pts) > 1 end) + |> Enum.reject(fn {_, {_dist, [danger_pt]}} -> MapSet.member?(infinite_pts, danger_pt) end) + |> Map.new() + end + + def to_areas(proximity_grid) do + Enum.reduce(proximity_grid, %{}, fn {_coord, {_dist, [danger_pt]}}, areas -> + Map.update(areas, danger_pt, 1, &(&1 + 1)) + end) + end + + def part1 do + danger_pts = parse_danger_pt_list() + field = bounding_box(danger_pts) + proximity_grid = proximity_grid(danger_pts, field) + infinite_pts = find_infinite_danger_pts(proximity_grid, field) + + remove_shared_and_infinite(proximity_grid, infinite_pts) + |> to_areas() + |> Map.values() + |> Enum.max() + end + + def part2 do + danger_pts = parse_danger_pt_list() + + danger_pts + |> bounding_box() + |> Area.all_coords() + |> Enum.map(fn coord -> + Enum.reduce(danger_pts, 0, fn danger_pt, dist -> + dist + manhattan_distance(coord, danger_pt) + end) + end) + |> Enum.filter(&(&1 < 10_000)) + |> length() + end +end + +IO.puts(Day6.part1()) +IO.puts(Day6.part2()) diff --git a/2018/day6/input b/2018/day6/input new file mode 100644 index 0000000..59dbb49 --- /dev/null +++ b/2018/day6/input @@ -0,0 +1,50 @@ +80, 357 +252, 184 +187, 139 +101, 247 +332, 328 +302, 60 +196, 113 +271, 201 +334, 89 +85, 139 +327, 161 +316, 352 +343, 208 +303, 325 +316, 149 +270, 319 +318, 153 +257, 332 +306, 348 +299, 358 +172, 289 +303, 349 +271, 205 +347, 296 +220, 276 +235, 231 +133, 201 +262, 355 +72, 71 +73, 145 +310, 298 +138, 244 +322, 334 +278, 148 +126, 135 +340, 133 +311, 118 +193, 173 +319, 99 +50, 309 +160, 356 +155, 195 +61, 319 +80, 259 +106, 318 +49, 169 +134, 61 +74, 204 +337, 174 +108, 287 diff --git a/2018/day7/day7.exs b/2018/day7/day7.exs new file mode 100644 index 0000000..feb0109 --- /dev/null +++ b/2018/day7/day7.exs @@ -0,0 +1,125 @@ +defmodule Day7 do + def input_to_graph do + input_pattern = ~r/Step (\w) must be finished before step (\w) can begin./ + + File.stream!("input") + |> Enum.map(&Regex.run(input_pattern, &1, capture: :all_but_first)) + |> Enum.reduce(%{}, fn [from, to], routes -> + Map.update(routes, from, [to], fn tos -> [to | tos] end) + end) + end + + def count_predecessors(graph) do + Enum.reduce(graph, %{}, fn {step, _children}, counts -> + counts = Map.put_new(counts, step, 0) + count_predecessors(counts, counts[step], graph[step], graph) + end) + end + + def count_predecessors(counts, _, nil, _), do: counts + + def count_predecessors(counts, level, children, graph) do + child_lvl = level + 1 + + Enum.reduce(children, counts, fn child, counts -> + counts = Map.update(counts, child, child_lvl, fn existing -> max(existing, child_lvl) end) + count_predecessors(counts, counts[child], graph[child], graph) + end) + end + + def resolve_steps(graph, steps) when map_size(graph) === 1 do + [{penultimate, ultimates}] = Map.to_list(graph) + Enum.reverse(steps) ++ [penultimate | Enum.sort(ultimates)] + end + + def resolve_steps(graph, steps) do + before_counts = count_predecessors(graph) + + [next | _] = + Enum.filter(before_counts, fn {_, count} -> count === 0 end) + |> Enum.map(fn {step, _count} -> step end) + |> Enum.sort() + + resolve_steps(Map.delete(graph, next), [next | steps]) + end + + def time_for(step), do: hd(String.to_charlist(step)) - 5 + + def get_work({graph, counts, in_progress}) do + case Enum.filter(counts, fn {_, count} -> count === 0 end) + |> Enum.map(fn {step, _count} -> step end) + |> Enum.sort() do + [] -> + {nil, {graph, counts, in_progress}} + + [step | _] -> + {{step, time_for(step)}, {graph, Map.delete(counts, step), [step | in_progress]}} + end + end + + def get_work_done(completed_step, {graph, _counts, in_progress}) do + graph = Map.delete(graph, completed_step) + counts = count_predecessors(graph) |> Map.drop(in_progress) + get_work({graph, counts, in_progress}) + end + + def all_prerequisites_allocated?(graph, in_progress) do + map_size(Map.drop(graph, in_progress)) === 0 + end + + def tick(workers, graph, counts, in_progress, seconds) do + {workers, {graph, counts, _}} = + Enum.map_reduce(workers, {graph, counts, in_progress}, fn + nil, acc -> get_work(acc) + {step, 0}, acc -> get_work_done(step, acc) + {step, remaining}, acc -> {{step, remaining - 1}, acc} + end) + + {workers, graph, counts, seconds + 1} + end + + def finish_up(workers, counts, seconds) do + remaining_workers = + workers + |> Enum.filter(fn worker -> worker != nil end) + |> Enum.map(fn {_, time} -> time end) + |> Enum.max() + + # This assumes the number of remaining jobs will not be greater than the remaining + # workers. That's probably a bad assumption so if the answer is wrong I'll + # come back and fix this. + if map_size(counts) > length(workers) do + raise("Number of final jobs greater than remaining workers") + end + + remaining_queued = (counts |> Enum.map(fn {step, _} -> time_for(step) end) |> Enum.max()) + 1 + + seconds + remaining_workers + remaining_queued + end + + def work(workers, graph, counts, seconds) do + in_progress = + workers + |> Enum.filter(fn worker -> worker != nil end) + |> Enum.map(fn {step, _} -> step end) + + if all_prerequisites_allocated?(graph, in_progress) do + finish_up(workers, counts, seconds) + else + {workers, graph, counts, seconds} = tick(workers, graph, counts, in_progress, seconds) + work(workers, graph, counts, seconds) + end + end + + def part1, do: input_to_graph() |> resolve_steps([]) |> Enum.join() + + def part2 do + graph = input_to_graph() + counts = count_predecessors(graph) + workers = for _ <- 1..5, do: nil + work(workers, graph, counts, 0) + end +end + +IO.puts(Day7.part1()) +IO.puts(Day7.part2()) diff --git a/2018/day7/input b/2018/day7/input new file mode 100644 index 0000000..7155300 --- /dev/null +++ b/2018/day7/input @@ -0,0 +1,101 @@ +Step J must be finished before step H can begin. +Step N must be finished before step C can begin. +Step G must be finished before step P can begin. +Step M must be finished before step I can begin. +Step H must be finished before step X can begin. +Step B must be finished before step Y can begin. +Step C must be finished before step L can begin. +Step F must be finished before step I can begin. +Step V must be finished before step O can begin. +Step W must be finished before step Q can begin. +Step E must be finished before step L can begin. +Step U must be finished before step S can begin. +Step D must be finished before step K can begin. +Step Y must be finished before step X can begin. +Step T must be finished before step R can begin. +Step I must be finished before step K can begin. +Step A must be finished before step K can begin. +Step L must be finished before step X can begin. +Step Q must be finished before step S can begin. +Step S must be finished before step O can begin. +Step P must be finished before step Z can begin. +Step X must be finished before step R can begin. +Step Z must be finished before step O can begin. +Step O must be finished before step K can begin. +Step R must be finished before step K can begin. +Step J must be finished before step W can begin. +Step F must be finished before step V can begin. +Step A must be finished before step X can begin. +Step Z must be finished before step K can begin. +Step M must be finished before step O can begin. +Step X must be finished before step K can begin. +Step E must be finished before step K can begin. +Step J must be finished before step K can begin. +Step E must be finished before step Y can begin. +Step B must be finished before step Q can begin. +Step X must be finished before step Z can begin. +Step D must be finished before step L can begin. +Step N must be finished before step I can begin. +Step N must be finished before step B can begin. +Step V must be finished before step A can begin. +Step H must be finished before step R can begin. +Step N must be finished before step L can begin. +Step U must be finished before step O can begin. +Step A must be finished before step O can begin. +Step V must be finished before step Z can begin. +Step O must be finished before step R can begin. +Step Q must be finished before step P can begin. +Step F must be finished before step Q can begin. +Step P must be finished before step R can begin. +Step S must be finished before step X can begin. +Step J must be finished before step E can begin. +Step V must be finished before step P can begin. +Step M must be finished before step D can begin. +Step I must be finished before step S can begin. +Step Q must be finished before step O can begin. +Step M must be finished before step H can begin. +Step W must be finished before step X can begin. +Step D must be finished before step O can begin. +Step X must be finished before step O can begin. +Step Y must be finished before step Z can begin. +Step F must be finished before step L can begin. +Step V must be finished before step T can begin. +Step V must be finished before step E can begin. +Step Y must be finished before step A can begin. +Step I must be finished before step R can begin. +Step L must be finished before step O can begin. +Step U must be finished before step X can begin. +Step Q must be finished before step X can begin. +Step P must be finished before step X can begin. +Step G must be finished before step C can begin. +Step A must be finished before step L can begin. +Step M must be finished before step U can begin. +Step L must be finished before step S can begin. +Step S must be finished before step P can begin. +Step S must be finished before step K can begin. +Step F must be finished before step T can begin. +Step Q must be finished before step K can begin. +Step G must be finished before step M can begin. +Step G must be finished before step F can begin. +Step T must be finished before step Q can begin. +Step F must be finished before step Z can begin. +Step I must be finished before step Z can begin. +Step N must be finished before step X can begin. +Step J must be finished before step F can begin. +Step W must be finished before step E can begin. +Step M must be finished before step Z can begin. +Step G must be finished before step X can begin. +Step V must be finished before step U can begin. +Step P must be finished before step O can begin. +Step U must be finished before step R can begin. +Step G must be finished before step Z can begin. +Step F must be finished before step R can begin. +Step L must be finished before step R can begin. +Step F must be finished before step A can begin. +Step I must be finished before step O can begin. +Step D must be finished before step T can begin. +Step U must be finished before step L can begin. +Step B must be finished before step S can begin. +Step S must be finished before step Z can begin. +Step J must be finished before step N can begin. +Step H must be finished before step T can begin. diff --git a/2018/day8/day8.exs b/2018/day8/day8.exs new file mode 100644 index 0000000..e54dc18 --- /dev/null +++ b/2018/day8/day8.exs @@ -0,0 +1,52 @@ +defmodule Day8 do + import Kernel, except: [node: 1] + + def list, do: File.read!("input") |> String.split() |> Enum.map(&String.to_integer/1) + + def node([child_count, data_count | rest]) do + {children, rest} = children(child_count, [], rest) + {data, rest} = Enum.split(rest, data_count) + {{data, children}, rest} + end + + def children(0, acc, list), do: {Enum.reverse(acc), list} + + def children(count, acc, list) do + {child, rest} = node(list) + children(count - 1, [child | acc], rest) + end + + def sum_node({items, children}, sum) do + Enum.sum(items) + Enum.reduce(children, sum, &sum_node/2) + end + + def part1 do + {tree, _} = node(list()) + sum_node(tree, 0) + end + + def select(nodes, indices) do + node_map = + nodes + |> Enum.with_index(1) + |> Map.new(fn {node, index} -> {index, node} end) + + indices + |> Enum.map(&Map.get(node_map, &1)) + |> Enum.reject(&(&1 === nil)) + end + + def value_node({items, []}), do: Enum.sum(items) + + def value_node({items, children}) do + children |> select(items) |> Enum.map(&value_node/1) |> Enum.sum() + end + + def part2 do + {tree, _} = node(list()) + value_node(tree) + end +end + +IO.puts(Day8.part1()) +IO.puts(Day8.part2()) diff --git a/2018/day8/input b/2018/day8/input new file mode 100644 index 0000000..fabfb02 --- /dev/null +++ b/2018/day8/input @@ -0,0 +1 @@ +7 11 6 3 5 5 3 5 1 8 0 8 9 9 2 3 4 3 3 1 1 3 1 2 2 1 1 3 1 9 0 9 4 9 6 4 7 7 4 1 1 1 2 1 1 3 3 3 1 1 1 6 0 8 3 5 3 6 4 1 1 8 1 1 2 3 1 2 1 4 4 1 4 3 5 1 5 0 8 4 1 7 2 4 7 8 7 1 3 2 2 3 1 9 0 7 1 1 4 5 5 4 6 2 1 1 2 3 2 1 1 1 1 9 0 10 9 7 8 1 1 7 8 9 9 1 3 1 2 3 3 3 1 1 2 3 4 1 4 5 3 4 1 7 0 8 4 5 7 2 2 1 8 8 3 3 1 1 2 2 1 1 9 0 11 2 3 9 3 5 3 1 3 4 4 6 3 1 2 3 3 1 3 2 3 1 9 0 7 8 1 1 6 3 5 8 1 1 2 2 3 2 1 3 1 4 1 1 4 3 6 1 8 0 8 6 8 9 5 1 1 9 2 1 1 2 2 1 2 2 1 1 8 0 10 1 3 6 1 4 2 3 4 7 6 3 1 3 3 1 3 1 1 1 7 0 8 7 7 1 6 8 5 3 7 3 3 1 3 2 1 1 1 3 4 2 4 3 3 7 1 6 0 10 6 2 4 1 8 7 7 5 1 2 1 1 1 2 1 2 1 5 0 8 7 7 1 5 4 6 4 1 1 1 1 1 3 1 5 0 7 1 1 8 7 4 8 9 1 1 2 1 3 1 2 5 2 1 1 2 3 3 6 1 5 5 3 3 7 1 7 0 10 2 9 9 7 1 8 6 8 7 5 3 3 2 1 1 3 3 1 8 0 7 8 8 8 1 3 2 7 3 1 2 1 1 2 3 2 1 8 0 9 1 2 1 4 7 7 6 2 1 1 1 2 1 2 1 1 2 2 5 4 5 1 2 1 3 4 1 6 0 6 2 3 4 1 7 7 1 2 1 3 1 3 1 7 0 6 5 1 1 4 1 4 1 2 2 3 3 2 3 1 6 0 8 3 4 1 9 6 3 5 2 2 1 3 2 2 1 3 3 4 1 3 7 1 8 0 7 8 7 3 1 6 4 6 3 1 3 2 1 2 1 2 1 8 0 10 7 1 2 7 9 8 2 8 9 8 1 1 1 2 2 3 1 1 1 6 0 8 4 1 8 3 5 1 8 2 1 1 1 3 1 2 2 4 5 4 3 5 2 3 6 1 5 0 6 6 8 5 1 9 5 3 1 2 2 3 1 6 0 11 7 4 6 5 9 2 9 9 9 6 1 2 3 1 1 2 3 1 8 0 8 8 6 9 5 4 6 1 3 2 1 1 1 3 3 3 2 4 3 1 3 4 2 3 4 1 8 0 8 9 6 6 9 1 2 3 9 2 1 2 2 2 2 2 1 1 9 0 11 5 4 3 1 1 6 6 4 8 5 3 1 2 1 1 2 1 2 2 1 1 5 0 11 8 8 4 6 7 8 7 5 2 9 1 1 1 2 1 2 4 2 3 1 2 5 3 5 3 3 7 1 7 0 11 6 4 3 6 1 9 2 1 3 4 2 1 1 1 3 1 3 3 1 7 0 8 2 2 8 5 1 1 6 3 1 3 1 2 1 3 2 1 7 0 6 1 4 3 8 3 6 3 1 3 1 3 3 2 3 1 1 3 5 4 5 3 4 1 7 0 11 9 1 7 9 7 9 6 1 9 1 8 2 2 3 1 3 3 2 1 5 0 9 1 2 2 1 3 2 5 9 7 1 1 3 1 1 1 5 0 9 3 8 4 6 9 7 5 1 1 1 1 3 1 1 3 2 3 2 3 4 1 9 0 9 1 9 1 8 2 2 4 1 7 2 1 3 1 2 2 2 1 2 1 7 0 7 1 1 5 6 1 8 2 1 1 3 3 3 1 2 1 8 0 10 1 7 1 2 5 4 3 9 6 2 1 3 1 3 3 2 1 3 5 2 5 3 3 5 1 8 0 9 4 1 7 3 2 1 5 5 4 2 1 1 3 3 1 3 3 1 7 0 11 7 9 5 1 1 9 3 8 6 9 4 2 1 1 1 1 1 3 1 6 0 7 1 1 4 5 6 3 3 2 1 3 2 1 1 5 3 3 1 2 3 5 1 8 0 10 8 7 3 6 1 5 9 2 3 4 2 3 1 2 1 3 1 1 1 5 0 9 6 1 5 1 7 1 7 9 5 1 2 1 3 2 1 8 0 6 2 9 4 1 4 5 3 3 3 2 2 3 1 1 3 3 4 1 1 4 3 7 5 5 3 4 1 7 0 7 5 5 6 2 8 1 8 1 2 3 1 1 1 1 1 6 0 11 7 5 4 1 1 3 3 5 3 3 4 1 1 1 3 2 2 1 6 0 6 8 1 8 1 6 5 1 2 2 2 1 1 2 3 5 2 3 6 1 9 0 6 4 1 1 1 9 2 3 2 2 3 1 1 2 2 2 1 6 0 7 4 1 7 1 4 2 5 2 1 2 2 1 3 1 5 0 8 3 5 1 2 1 3 1 7 2 1 1 1 1 2 2 1 2 1 1 3 4 1 5 0 7 5 1 2 7 4 6 6 3 3 1 3 2 1 5 0 7 1 1 2 8 8 6 6 1 2 1 3 1 1 5 0 11 7 2 1 3 8 5 4 9 7 7 8 2 3 2 3 1 3 1 2 1 3 5 1 6 0 10 8 3 1 4 7 8 8 8 9 8 3 1 1 3 3 3 1 6 0 8 3 2 9 5 1 6 1 8 3 3 2 1 2 1 1 5 0 11 6 6 7 7 1 4 1 1 7 1 1 1 2 1 2 3 5 1 1 2 1 3 6 1 8 0 11 2 1 6 6 1 6 2 8 4 9 4 3 1 2 2 2 2 3 1 1 6 0 11 9 7 5 4 6 1 4 6 5 4 6 3 2 3 1 2 1 1 8 0 9 3 7 7 3 1 8 8 8 8 2 3 1 2 3 2 3 3 3 5 1 2 5 2 1 3 5 7 1 5 4 3 5 1 7 0 10 1 6 8 9 7 7 1 9 6 6 3 1 3 2 1 3 3 1 6 0 8 6 9 2 3 4 6 1 2 1 1 3 1 2 3 1 9 0 11 8 6 5 2 6 5 4 7 3 1 3 1 1 1 2 3 2 1 1 1 1 3 3 4 3 3 4 1 7 0 11 8 1 5 7 1 1 3 7 6 7 2 1 3 3 1 2 1 2 1 7 0 8 1 1 1 8 4 5 8 7 2 3 2 1 3 1 3 1 6 0 6 1 6 5 7 6 1 2 1 3 3 2 3 1 1 5 3 3 4 1 5 0 8 2 1 5 1 8 5 8 7 1 1 1 1 3 1 8 0 7 8 4 4 4 1 7 3 2 3 1 2 3 3 2 2 1 5 0 6 5 1 4 6 3 9 1 2 3 3 3 5 4 1 5 3 5 1 7 0 10 7 5 9 2 4 4 9 1 5 1 3 3 1 2 3 2 2 1 6 0 11 1 2 1 5 5 6 1 1 6 3 8 2 1 1 2 2 1 1 9 0 10 5 1 1 7 1 7 4 1 9 8 1 3 1 3 3 1 3 1 2 4 2 4 2 3 3 6 1 9 0 7 1 5 1 6 1 8 7 1 1 3 3 2 1 2 2 1 1 6 0 11 9 1 9 1 6 3 8 7 6 7 1 1 2 2 1 1 1 1 8 0 9 1 7 8 2 8 7 4 1 6 1 3 1 1 3 1 3 3 4 1 2 4 2 2 5 2 3 5 5 4 3 5 1 9 0 8 5 7 9 2 1 7 7 7 2 3 1 1 3 1 3 1 3 1 8 0 11 6 5 1 1 8 8 8 3 9 6 6 1 3 2 1 1 1 1 1 1 5 0 11 5 1 9 5 1 6 9 2 1 9 1 1 2 1 1 2 2 4 1 4 1 3 4 1 6 0 7 8 5 5 4 8 1 1 1 1 2 1 3 1 1 8 0 9 1 7 9 1 2 4 1 5 3 2 1 3 3 3 2 3 1 1 5 0 11 6 9 8 3 2 6 3 8 3 3 1 1 2 3 3 3 5 3 4 4 3 4 1 6 0 9 1 6 5 9 9 8 5 1 5 1 2 1 3 2 1 1 8 0 6 7 2 1 6 5 1 2 2 1 3 1 2 1 2 1 6 0 6 1 8 9 7 8 3 2 1 2 1 1 1 2 1 2 1 3 5 1 7 0 7 6 1 1 8 7 9 2 1 1 1 2 2 3 2 1 8 0 10 8 9 5 2 3 7 3 7 1 9 1 2 2 1 3 1 2 3 1 5 0 6 4 1 9 8 1 9 1 3 3 3 1 3 2 1 2 3 3 4 1 6 0 10 8 7 9 5 1 4 8 1 1 7 2 3 2 2 1 2 1 9 0 6 8 5 1 8 2 1 3 2 2 1 3 2 3 1 1 1 5 0 10 4 3 7 2 4 7 1 5 1 6 3 2 2 1 3 1 1 3 5 1 4 2 1 7 8 2 7 2 5 3 3 5 1 7 0 7 8 3 1 8 1 3 6 2 1 2 3 1 1 3 1 6 0 9 8 1 7 4 1 1 1 3 2 1 3 3 3 3 1 1 9 0 9 2 1 5 3 4 6 1 8 3 3 1 3 1 1 3 2 1 3 2 3 1 1 1 3 7 1 8 0 10 2 4 8 4 1 7 6 8 6 5 3 2 3 3 1 2 3 3 1 5 0 7 6 1 8 8 5 3 3 3 3 3 1 1 1 5 0 10 4 5 3 6 1 2 7 4 6 4 3 1 1 3 2 3 2 3 3 3 3 3 3 5 1 9 0 10 1 8 3 2 7 3 1 1 3 5 3 1 1 2 1 1 1 2 2 1 5 0 11 8 4 1 4 3 5 9 8 2 5 1 1 3 2 1 1 1 5 0 7 4 9 5 4 4 1 9 1 2 2 3 2 2 4 1 2 3 3 4 1 8 0 10 3 4 9 7 1 1 4 4 3 1 1 1 2 2 2 2 1 3 1 6 0 11 7 8 3 1 2 9 4 3 1 7 7 3 3 1 3 2 2 1 9 0 8 1 4 2 3 7 5 8 4 3 2 3 1 1 3 1 3 3 1 4 5 3 3 4 1 6 0 10 1 8 4 5 6 3 9 7 5 4 1 3 3 1 2 1 1 7 0 9 3 7 8 8 6 7 7 1 4 3 2 2 1 2 3 3 1 5 0 11 7 8 1 8 1 1 5 9 6 1 2 1 3 1 3 3 4 5 3 5 4 3 1 5 5 3 7 1 6 0 9 1 4 2 1 8 1 4 6 1 1 3 3 1 1 2 1 8 0 9 5 6 2 9 4 1 6 1 3 3 1 3 1 2 1 3 3 1 6 0 9 5 1 6 9 3 2 9 4 3 1 3 3 2 1 3 3 1 3 3 4 2 1 3 7 1 9 0 7 3 1 3 9 4 6 2 1 3 2 2 3 1 1 1 1 1 9 0 7 1 6 2 3 7 3 2 3 3 3 1 1 3 3 1 1 1 7 0 11 9 8 8 6 7 8 8 1 3 7 8 2 2 2 3 1 1 3 2 5 2 1 5 1 3 3 4 1 8 0 9 8 1 8 3 1 8 7 2 1 3 2 2 3 3 1 1 1 1 8 0 6 3 3 7 7 3 1 3 1 3 1 3 1 2 3 1 5 0 11 2 5 6 1 2 5 7 4 1 8 2 2 3 1 1 3 3 2 1 5 3 5 1 8 0 10 1 8 3 2 2 6 4 6 8 4 3 2 1 3 3 2 2 2 1 5 0 11 3 6 4 8 3 3 7 9 7 1 4 2 2 1 2 2 1 9 0 8 6 9 3 3 3 1 2 5 2 1 2 3 2 1 1 3 1 3 1 3 4 1 3 7 1 9 0 9 3 4 3 5 2 1 8 6 5 2 2 1 1 3 2 1 2 2 1 5 0 8 1 9 2 4 4 3 7 2 1 1 1 1 2 1 5 0 11 5 5 2 9 7 5 6 3 8 1 8 1 3 3 2 3 1 4 3 3 1 1 3 5 2 5 6 2 5 3 3 7 1 8 0 7 2 3 9 3 2 1 5 1 2 1 2 1 2 2 3 1 6 0 6 1 1 4 7 5 6 2 1 2 1 3 1 1 5 0 6 2 2 7 2 2 1 3 2 1 1 3 1 4 1 2 2 1 2 3 5 1 6 0 11 5 1 2 8 5 2 8 4 3 9 1 3 1 1 1 1 1 1 6 0 6 5 1 6 4 8 1 2 3 3 1 3 1 1 6 0 8 7 4 8 4 1 9 7 5 3 3 3 2 1 1 5 5 2 1 3 3 5 1 7 0 8 9 1 7 8 7 3 8 3 2 1 2 3 3 2 1 1 5 0 9 1 1 7 9 2 6 1 7 6 1 1 2 2 2 1 9 0 11 3 9 6 8 8 1 1 1 6 4 1 2 3 2 2 3 2 1 3 3 3 5 1 2 5 3 4 1 9 0 8 7 1 8 8 6 6 9 3 3 2 2 1 3 2 3 3 1 1 6 0 6 2 4 7 9 3 1 1 3 1 3 2 2 1 7 0 6 2 5 7 9 1 7 1 2 1 3 1 1 1 3 3 1 1 3 4 1 7 0 10 7 8 5 6 1 7 9 3 7 1 2 2 3 1 2 3 1 1 9 0 9 4 6 6 1 5 5 7 1 1 1 3 1 2 2 2 2 3 3 1 6 0 8 8 3 1 5 2 1 4 2 1 1 3 3 1 1 1 3 3 1 2 3 5 5 5 3 6 1 6 0 11 7 5 5 6 1 7 1 4 3 5 4 2 3 1 3 3 2 1 6 0 8 3 5 2 9 4 8 1 9 1 2 3 1 1 1 1 8 0 6 7 7 9 1 5 2 1 2 2 2 3 3 1 1 4 1 2 1 3 2 3 6 1 7 0 11 6 4 7 6 8 6 8 6 4 1 4 2 3 3 3 3 1 1 1 7 0 6 1 2 2 1 6 3 2 1 2 3 1 1 1 1 5 0 8 2 1 3 1 1 7 4 5 1 1 1 3 1 3 2 2 3 3 4 3 7 1 8 0 9 9 2 1 1 8 8 9 4 8 2 2 1 2 1 3 3 1 1 6 0 8 9 3 1 9 7 4 1 9 3 3 1 3 2 3 1 8 0 9 5 5 1 7 7 3 7 1 7 2 1 1 1 2 3 3 3 1 3 4 3 3 5 4 3 5 1 8 0 7 5 1 8 3 6 7 5 1 2 1 2 2 2 3 3 1 9 0 8 6 7 9 1 5 4 1 1 3 3 2 1 3 1 1 1 3 1 9 0 6 7 9 1 1 2 2 2 1 3 1 3 2 1 1 1 3 4 2 2 3 3 4 1 5 0 9 2 3 6 7 1 4 8 1 8 2 1 2 1 2 1 9 0 9 1 6 5 5 9 2 1 2 7 1 1 3 1 2 2 3 1 1 1 5 0 9 2 1 1 9 4 1 5 3 5 1 3 1 1 2 3 1 4 2 1 7 6 4 2 5 3 3 5 1 6 0 7 4 9 4 3 1 8 3 2 1 3 3 2 1 1 7 0 9 7 4 9 1 7 1 4 5 2 1 2 1 2 3 1 2 1 5 0 7 1 8 9 3 9 2 1 3 2 3 2 1 2 3 5 3 5 3 6 1 8 0 9 3 2 9 2 1 9 4 5 8 2 3 2 1 2 3 3 3 1 8 0 9 9 9 7 6 1 2 3 9 8 1 1 2 3 3 2 1 1 1 9 0 8 6 3 5 5 7 9 1 9 3 1 3 3 2 3 2 1 1 4 4 3 5 3 3 3 6 1 8 0 6 5 1 3 9 7 1 1 2 3 3 1 3 3 3 1 9 0 9 5 3 2 1 1 7 6 2 9 2 1 1 3 2 1 3 1 3 1 8 0 9 1 9 4 3 4 7 2 2 5 2 1 2 3 2 3 2 2 2 2 5 4 1 5 3 7 1 6 0 8 2 1 3 7 9 2 1 7 2 1 1 1 2 2 1 8 0 10 4 1 1 6 7 7 8 1 9 8 3 3 3 1 2 1 3 1 1 5 0 8 6 1 9 9 3 8 1 3 3 1 1 1 1 5 1 3 3 5 4 1 3 6 1 8 0 9 2 6 9 1 4 6 1 7 7 3 1 1 1 3 1 2 1 1 6 0 9 6 2 9 3 1 7 3 8 4 2 3 1 3 3 1 1 5 0 7 1 7 7 7 1 5 6 1 2 2 1 1 1 3 3 3 3 2 1 2 4 4 5 3 6 1 9 0 9 3 2 8 7 1 8 4 6 3 3 1 1 2 3 1 3 2 1 1 5 0 11 1 5 8 1 1 1 8 2 3 9 3 2 3 2 2 1 1 8 0 10 1 1 2 8 7 1 9 9 9 7 1 1 1 3 1 2 2 2 3 3 3 2 4 2 3 4 1 5 0 10 1 6 5 2 2 6 9 6 9 2 1 2 2 3 2 1 7 0 11 1 4 9 7 5 2 3 4 4 5 1 3 1 1 2 1 1 3 1 9 0 6 4 5 5 9 1 4 1 1 3 1 3 2 2 2 2 5 4 1 2 3 4 1 8 0 8 7 3 6 1 5 5 1 6 2 1 2 1 2 1 1 3 1 5 0 9 9 9 3 9 7 7 9 7 1 1 1 1 1 3 1 8 0 9 5 1 1 8 2 8 1 9 9 3 2 3 1 3 1 1 3 4 1 4 2 3 6 1 8 0 9 3 2 4 2 2 1 1 6 8 2 3 1 1 1 1 3 3 1 8 0 11 3 5 3 1 6 8 9 6 7 3 5 3 1 3 2 1 2 1 2 1 5 0 6 6 3 1 6 6 5 2 2 1 3 2 3 1 5 4 4 1 3 3 5 6 4 5 3 3 4 1 5 0 10 2 6 5 9 7 9 2 1 3 3 3 1 1 1 1 1 6 0 11 8 1 9 8 7 9 6 8 4 7 5 2 2 1 1 3 1 1 9 0 6 1 1 9 2 2 1 3 3 2 1 1 1 2 3 3 4 1 2 4 3 7 1 7 0 7 9 1 1 1 1 3 1 1 2 2 2 3 3 1 1 8 0 10 3 1 1 7 9 8 1 1 2 8 1 1 2 1 1 2 2 3 1 7 0 8 2 6 6 4 1 7 7 1 1 3 3 2 2 1 1 4 1 1 3 1 2 3 3 5 1 6 0 10 1 8 5 9 3 6 1 3 5 6 1 3 3 2 1 2 1 7 0 11 6 8 2 9 4 7 2 3 8 5 1 2 1 3 3 3 3 3 1 5 0 7 5 6 7 1 8 9 1 3 2 2 1 3 5 5 2 2 2 3 5 1 5 0 8 3 5 8 5 1 3 1 8 1 3 2 2 3 1 5 0 10 4 7 1 1 2 3 7 9 8 8 1 1 1 1 2 1 8 0 9 2 7 3 2 7 2 1 9 6 3 1 1 1 1 3 2 2 5 4 4 5 3 3 7 1 5 0 9 4 9 9 4 7 1 6 8 1 3 2 1 2 3 1 9 0 8 3 7 9 3 4 1 8 3 1 3 1 1 2 3 2 2 3 1 8 0 11 4 2 1 8 6 4 5 6 5 7 2 1 2 2 1 1 1 3 2 1 2 3 1 2 3 2 4 5 1 4 7 6 3 5 4 3 7 1 9 0 10 2 5 5 1 2 5 1 1 5 6 2 3 1 1 1 1 3 3 3 1 9 0 10 1 2 3 1 6 1 2 4 4 6 3 1 2 3 1 3 1 2 1 1 8 0 10 2 9 5 1 9 9 4 7 1 7 2 3 1 1 3 1 3 1 2 1 1 4 2 2 3 3 6 1 5 0 10 6 6 4 5 1 6 2 8 7 1 1 2 3 2 1 1 9 0 11 2 4 1 8 9 4 3 4 1 6 8 2 3 3 2 3 1 2 2 2 1 5 0 6 4 1 1 5 8 6 3 2 1 2 2 3 2 1 2 4 3 3 5 1 7 0 10 6 2 3 8 7 1 1 3 8 8 3 1 1 2 1 1 3 1 5 0 11 6 9 7 5 4 8 7 7 1 1 6 2 1 1 3 2 1 9 0 10 5 9 4 8 4 7 7 9 1 3 3 1 2 2 1 1 1 1 3 2 5 3 1 2 3 4 1 5 0 8 4 2 6 6 1 9 7 3 3 1 2 1 1 1 5 0 11 4 4 9 7 1 1 1 3 7 7 9 1 1 3 3 2 1 5 0 10 3 3 1 3 1 1 2 7 6 9 1 1 1 2 2 3 3 3 2 3 6 1 9 0 8 5 9 9 2 3 1 5 3 1 2 3 2 3 3 2 3 2 1 5 0 8 6 2 1 2 1 8 5 4 1 1 1 1 2 1 9 0 7 2 2 1 9 8 6 8 2 1 2 1 2 3 2 1 2 2 1 2 1 4 2 2 3 4 6 4 3 3 6 1 7 0 9 5 4 4 1 3 5 1 1 1 3 1 2 3 1 3 1 1 9 0 6 4 9 1 4 4 1 2 1 2 1 1 3 3 3 2 1 5 0 6 6 9 1 9 1 8 3 3 1 3 2 4 5 3 2 3 2 3 7 1 5 0 7 6 8 6 4 6 1 5 1 3 1 1 2 1 9 0 9 5 1 4 3 1 8 3 6 1 3 1 1 3 1 2 3 2 3 1 6 0 7 1 6 1 4 8 2 3 3 3 2 1 1 3 5 2 1 2 3 4 2 3 5 1 5 0 11 3 3 2 3 5 6 4 3 9 9 1 1 1 2 1 3 1 5 0 8 3 1 1 4 6 9 1 1 1 3 2 1 1 1 6 0 11 8 9 9 4 7 6 4 2 1 7 8 3 1 2 2 3 2 1 1 5 3 5 3 7 1 9 0 7 9 8 1 9 5 1 5 1 3 2 2 1 1 3 1 3 1 6 0 9 3 7 3 6 6 7 1 7 8 1 1 1 1 2 1 1 9 0 6 2 1 7 6 3 9 1 2 3 1 3 3 2 3 3 4 2 5 2 2 2 1 2 2 4 5 3 3 5 1 8 0 9 6 1 1 6 1 3 6 4 3 1 1 3 1 3 2 3 1 1 9 0 10 8 7 6 7 1 9 5 2 1 4 1 2 1 3 3 2 3 2 1 1 9 0 6 4 6 1 8 2 6 2 2 1 1 3 2 2 1 3 1 3 4 3 2 3 4 1 7 0 6 1 2 9 5 2 1 2 3 2 1 1 3 1 1 9 0 10 4 8 7 2 7 1 1 6 6 3 1 1 2 3 1 2 1 1 1 1 8 0 10 6 6 6 9 3 8 3 2 1 9 1 1 2 3 3 2 1 1 3 1 4 3 3 6 1 9 0 6 8 2 2 8 1 2 1 3 2 1 3 2 2 1 1 1 5 0 7 9 1 9 8 9 3 9 3 1 1 3 1 1 9 0 6 9 8 3 1 3 4 1 2 2 1 2 1 2 2 3 5 4 2 1 1 4 3 5 1 8 0 7 6 1 3 4 8 1 1 2 1 2 3 2 1 3 1 1 5 0 9 6 5 5 3 4 1 4 2 2 2 3 1 3 1 1 5 0 10 1 3 8 9 2 1 6 3 2 5 2 1 3 2 3 3 5 1 2 2 3 5 1 6 0 6 3 1 3 2 5 3 2 1 2 2 3 1 1 7 0 10 7 7 3 1 4 1 2 2 4 6 1 3 1 3 1 3 2 1 8 0 6 3 3 7 7 1 4 2 1 1 3 1 1 3 2 4 2 4 3 5 3 6 1 4 4 3 5 1 9 0 9 9 4 9 7 1 5 4 2 9 1 2 1 1 3 2 1 1 1 1 8 0 9 1 8 4 9 8 3 8 5 1 3 1 1 2 3 2 1 3 1 8 0 10 2 6 1 7 8 9 9 7 4 4 2 2 1 1 3 2 2 1 1 5 3 5 1 3 5 1 8 0 7 1 5 8 9 9 8 4 1 2 1 1 2 2 2 3 1 5 0 6 5 5 8 6 5 1 2 1 1 2 2 1 6 0 8 7 9 1 4 3 1 1 9 2 1 3 2 2 3 5 3 5 4 3 3 6 1 9 0 6 7 1 6 3 9 3 3 3 3 1 2 1 2 1 1 1 9 0 7 1 1 8 6 3 2 8 1 1 3 1 3 3 3 3 3 1 7 0 7 1 1 9 9 1 5 1 2 1 3 1 3 1 3 1 4 2 3 5 5 3 4 1 5 0 7 5 1 9 1 1 4 7 1 1 2 3 1 1 5 0 7 9 3 1 7 5 4 7 2 1 1 3 3 1 7 0 8 6 3 7 4 2 7 1 6 1 1 1 1 1 1 1 2 3 1 2 1 4 2 5 4 5 3 5 1 8 0 6 2 7 1 1 7 4 1 1 3 2 1 1 1 1 1 5 0 6 4 3 1 1 4 3 1 2 3 1 1 1 5 0 9 5 9 1 5 5 1 6 4 1 3 2 3 3 1 1 4 5 3 5 3 5 1 6 0 7 4 3 4 8 1 6 1 1 1 3 2 2 3 1 5 0 8 1 3 7 8 5 9 1 5 2 1 1 2 3 1 6 0 6 9 7 1 4 4 7 3 3 1 1 1 2 1 4 2 1 1 3 4 1 8 0 7 6 1 7 1 7 9 5 2 1 3 2 2 1 3 3 1 6 0 8 3 7 2 9 1 2 5 2 1 2 1 1 1 2 1 5 0 7 1 1 4 2 5 2 4 1 2 3 3 3 2 4 3 1 3 5 1 6 0 11 8 8 1 7 2 8 1 9 6 6 9 1 1 1 2 2 2 1 8 0 9 1 3 8 7 8 3 7 6 7 2 1 3 2 1 3 2 3 1 6 0 10 1 1 6 1 8 9 1 3 8 5 3 3 3 3 1 2 5 2 1 2 1 2 1 3 2 6 5 4 3 6 1 8 0 11 8 7 1 4 4 5 6 9 5 7 8 3 3 2 2 3 3 1 1 1 7 0 7 1 9 8 1 8 7 7 2 1 2 1 3 3 2 1 6 0 8 6 5 3 1 8 5 6 2 1 3 3 2 1 2 2 3 2 3 2 5 3 5 1 7 0 9 3 4 9 5 6 1 2 3 7 3 2 1 2 2 1 1 1 7 0 6 3 2 8 6 1 9 3 1 2 3 1 3 3 1 7 0 8 8 9 1 3 1 3 3 3 2 1 2 3 1 2 2 2 5 3 4 5 3 7 1 9 0 7 5 4 9 1 1 3 9 1 3 1 2 2 2 3 3 1 1 8 0 11 3 1 4 6 1 4 2 6 6 3 1 3 3 2 1 1 2 3 3 1 7 0 6 6 6 6 5 8 1 3 3 1 3 2 1 3 5 3 4 1 3 1 1 3 5 1 8 0 9 3 7 2 9 2 6 3 1 2 1 2 2 1 1 3 1 2 1 9 0 8 2 7 6 1 4 5 1 3 1 1 2 2 2 1 2 1 3 1 7 0 10 2 3 7 3 3 8 3 1 1 1 3 1 2 2 3 1 1 4 2 1 1 2 3 4 1 5 0 6 2 4 5 1 5 1 2 2 1 2 2 1 7 0 10 1 3 1 9 1 7 8 4 7 8 2 1 1 3 3 1 1 1 9 0 6 5 1 1 8 4 1 1 3 1 1 2 3 1 1 2 4 3 5 2 1 6 6 2 3 2 6 6 2 5 5 3 5 1 5 0 11 1 2 9 5 6 8 2 2 7 6 2 2 1 3 2 3 1 6 0 9 4 3 8 6 4 1 9 3 3 1 1 1 2 2 3 1 6 0 11 4 8 6 2 9 9 4 1 4 7 8 3 1 3 3 2 2 3 3 3 1 2 3 5 1 8 0 8 8 5 6 1 4 8 2 5 1 2 2 1 3 3 2 1 1 7 0 6 1 2 1 4 3 6 2 3 2 3 1 3 3 1 6 0 11 4 7 1 6 5 1 7 9 9 5 5 1 3 2 3 1 1 3 2 3 3 4 3 5 1 7 0 11 2 5 7 2 2 8 3 7 5 1 7 3 1 3 2 1 1 1 1 5 0 8 8 1 4 9 9 8 2 9 3 1 3 1 1 1 6 0 8 7 4 1 8 7 6 7 7 3 3 3 2 2 1 2 3 3 3 4 3 6 1 5 0 8 5 6 1 5 9 7 8 5 1 3 2 3 1 1 9 0 10 1 8 2 6 7 1 2 3 8 1 3 1 1 2 3 3 1 1 1 1 7 0 8 8 2 2 7 1 3 5 1 2 3 1 2 1 3 2 3 4 5 5 3 1 3 5 1 5 0 9 1 5 8 1 3 7 5 1 9 1 2 2 3 2 1 7 0 7 4 6 1 9 1 3 7 3 3 1 3 3 1 1 1 5 0 6 8 1 1 7 1 7 3 1 1 1 1 2 1 2 2 5 4 5 4 7 6 4 5 3 6 1 5 0 7 1 1 6 8 3 1 4 2 2 1 1 2 1 8 0 9 4 5 2 7 1 1 1 1 6 2 3 3 3 2 1 3 1 1 9 0 10 4 8 1 3 2 5 4 4 1 8 3 2 1 3 2 2 1 2 3 5 1 5 1 5 1 3 5 1 7 0 8 4 9 8 8 1 4 8 6 2 3 2 3 1 3 1 1 9 0 8 5 6 9 5 9 3 3 1 1 1 2 1 2 2 1 1 1 1 7 0 6 8 4 3 1 9 7 3 2 3 2 1 3 3 5 4 4 2 3 3 6 1 8 0 6 6 7 1 2 3 6 1 1 2 2 1 2 1 2 1 5 0 8 4 7 2 5 4 1 9 1 1 3 3 1 2 1 6 0 11 3 4 4 1 8 9 3 4 9 4 4 2 1 3 1 1 3 5 3 2 2 2 3 3 5 1 6 0 9 9 9 7 6 7 8 8 1 1 1 1 1 2 3 2 1 5 0 9 1 5 6 6 6 9 7 9 1 2 2 3 1 1 1 7 0 9 3 3 1 5 2 9 7 3 4 3 3 2 1 1 2 1 2 1 3 5 1 6 1 5 4 3 5 3 3 4 1 7 0 9 1 1 4 5 2 3 9 2 3 3 1 3 2 1 1 1 1 8 0 7 1 1 1 3 2 4 9 2 1 2 1 2 3 2 3 1 9 0 7 5 1 2 5 8 9 9 3 3 1 3 1 2 1 2 1 3 4 5 1 3 4 1 7 0 11 3 2 2 3 5 7 1 4 2 6 9 1 3 1 1 3 1 1 1 5 0 7 6 4 8 2 9 3 1 2 1 3 3 1 1 7 0 11 3 9 6 9 9 5 9 7 1 3 4 2 1 1 1 1 2 1 2 2 5 2 3 6 1 5 0 11 4 9 6 8 8 1 9 1 8 8 3 1 3 2 1 3 1 6 0 8 9 9 5 8 9 1 3 1 3 1 1 1 1 3 1 9 0 6 8 4 2 6 1 3 2 2 2 1 2 1 1 1 1 2 5 4 4 1 3 3 6 1 8 0 6 9 1 5 2 4 9 2 1 2 3 1 1 3 3 1 6 0 10 1 2 5 6 8 9 2 1 3 4 2 1 1 1 2 2 1 7 0 11 4 6 4 6 9 1 8 6 9 5 9 2 3 1 2 1 1 3 3 1 5 1 1 4 3 6 1 8 0 8 3 6 1 7 5 9 5 2 2 3 3 1 2 2 2 1 1 9 0 10 8 5 9 4 1 9 1 8 9 8 1 2 2 2 3 1 1 3 3 1 8 0 6 1 4 8 7 1 1 3 1 1 3 2 3 1 1 1 3 2 1 2 2 2 4 4 5 3 3 6 1 6 0 9 1 2 9 4 6 6 8 5 5 1 2 1 3 1 3 1 8 0 8 8 9 4 1 6 7 3 6 3 2 1 3 1 2 1 1 1 5 0 8 1 6 9 6 1 1 1 1 3 3 3 1 3 1 2 1 3 3 4 3 6 1 5 0 10 7 5 5 6 8 1 4 1 8 9 2 1 1 3 1 1 5 0 6 7 1 3 8 4 8 1 1 1 1 3 1 5 0 10 5 8 4 1 4 2 7 1 6 3 3 1 1 2 3 1 4 3 3 3 1 3 4 1 8 0 10 3 3 8 8 4 1 4 5 5 1 1 2 1 1 2 3 2 1 1 8 0 10 9 6 6 7 6 1 9 8 2 4 1 2 2 2 2 2 3 1 1 8 0 6 1 5 9 2 1 4 3 2 1 2 1 1 2 3 2 2 5 5 3 5 1 5 0 9 2 6 5 7 6 1 7 7 3 1 2 1 1 1 1 7 0 7 6 1 1 3 1 1 4 3 3 1 1 1 2 3 1 7 0 10 7 2 6 9 1 7 1 4 5 4 1 1 1 1 2 3 1 3 3 4 5 4 3 7 1 7 0 9 5 9 2 6 9 2 5 1 5 1 1 1 1 2 2 2 1 9 0 6 8 7 3 9 1 9 1 1 2 3 2 3 3 1 3 1 8 0 11 1 1 9 3 8 9 7 7 7 5 6 2 3 1 2 1 1 1 3 1 3 5 5 2 5 2 2 1 5 4 3 3 4 1 6 0 6 5 1 7 8 9 6 1 2 2 2 3 2 1 5 0 7 2 3 1 6 3 1 1 2 2 1 1 2 1 8 0 11 8 9 8 5 6 5 1 1 8 8 5 2 1 1 2 2 3 3 1 3 4 2 2 3 7 1 5 0 11 6 8 3 3 4 6 8 2 7 1 9 1 3 1 2 1 1 9 0 11 6 5 7 1 1 7 1 4 5 6 7 3 1 1 3 2 2 1 1 1 1 5 0 6 6 2 1 9 6 9 3 2 1 1 2 2 2 3 3 1 2 1 3 6 1 6 0 6 7 2 2 1 5 9 1 2 1 3 3 3 1 7 0 9 6 2 4 3 6 9 4 1 5 3 1 1 1 2 2 3 1 5 0 7 4 4 7 4 1 1 9 2 3 1 3 1 5 1 5 3 2 3 3 7 1 6 0 6 1 2 9 4 4 3 1 2 1 1 1 3 1 5 0 7 1 7 6 1 9 6 6 3 3 2 1 1 1 5 0 10 9 1 5 8 6 4 8 1 1 1 1 2 1 1 3 5 2 2 4 3 1 5 5 6 1 5 4 3 6 1 8 0 6 2 8 2 3 4 1 1 1 1 1 1 2 3 2 1 7 0 11 1 4 5 1 1 7 5 3 6 5 4 1 2 1 2 3 3 3 1 8 0 10 5 6 1 1 6 8 1 9 7 3 1 1 3 1 3 1 2 2 5 2 2 2 3 1 3 4 1 6 0 9 2 8 3 5 4 2 6 5 1 1 1 2 1 3 2 1 9 0 11 7 9 9 8 8 6 6 6 2 1 5 2 3 1 3 2 3 1 2 3 1 7 0 10 7 1 5 1 5 1 7 6 1 9 1 2 2 2 3 2 1 1 4 3 3 3 5 1 5 0 6 2 6 1 8 6 8 2 2 1 3 2 1 7 0 7 1 9 8 5 8 2 7 3 3 2 1 3 2 1 1 5 0 10 5 5 4 1 1 3 8 4 4 8 2 2 1 1 1 4 2 1 1 2 3 6 1 5 0 9 3 9 1 3 7 2 2 8 3 2 1 3 2 1 1 5 0 11 1 5 9 1 4 1 5 1 4 1 8 2 2 3 1 1 1 6 0 7 9 5 8 1 1 5 3 2 2 1 1 3 3 5 3 1 3 5 2 3 7 1 5 0 9 1 9 7 9 8 9 8 6 3 2 2 2 1 1 1 5 0 10 1 6 6 3 4 7 2 3 9 3 2 2 2 2 1 1 8 0 11 4 6 5 5 1 6 2 1 3 8 9 1 1 3 1 3 1 2 2 2 5 3 2 5 2 3 2 6 3 1 4 7 7 2 5 3 3 4 1 7 0 9 9 8 6 1 9 1 1 5 2 2 3 1 2 3 2 1 1 7 0 7 2 5 9 1 3 1 1 1 2 1 1 2 3 2 1 9 0 7 9 5 2 1 7 4 4 2 2 1 3 2 1 1 3 1 2 3 5 4 3 7 1 8 0 10 3 4 1 9 9 1 5 7 9 7 3 2 3 3 1 3 3 2 1 5 0 11 2 7 3 1 3 3 6 9 9 1 8 1 1 1 1 2 1 5 0 8 5 7 1 5 9 2 3 5 3 1 1 2 1 5 3 1 1 1 3 3 3 5 1 7 0 9 7 1 2 4 1 9 4 1 6 3 1 1 2 3 1 1 1 5 0 7 1 4 9 7 2 2 9 1 2 3 1 1 1 6 0 6 3 8 3 1 5 2 1 2 3 2 2 1 2 3 2 5 1 3 5 1 6 0 7 1 2 7 7 5 6 7 3 1 3 1 2 3 1 7 0 11 1 4 1 2 8 5 4 1 5 6 3 1 2 1 1 2 3 1 1 6 0 7 1 3 6 4 7 2 6 1 3 2 1 1 3 1 3 4 1 3 3 5 1 6 0 8 5 1 9 1 1 8 2 3 1 1 3 1 2 1 1 5 0 6 1 9 1 1 5 7 1 3 1 2 2 1 7 0 7 2 6 1 5 1 9 5 2 1 1 2 1 1 2 2 5 2 2 5 1 4 1 4 4 3 4 1 7 0 9 5 1 5 5 2 2 4 7 9 3 1 1 2 3 3 3 1 6 0 7 9 5 1 3 9 9 7 1 2 1 1 3 3 1 9 0 8 1 6 1 1 4 4 1 5 1 1 3 3 3 3 1 2 3 2 5 3 2 3 5 1 6 0 11 8 9 4 1 1 8 6 2 9 7 3 2 2 3 2 1 3 1 7 0 9 1 5 8 5 9 1 4 1 6 1 2 2 3 1 1 2 1 6 0 6 6 9 3 8 1 2 3 2 1 1 2 1 4 5 3 5 5 3 7 1 8 0 6 1 4 2 3 7 4 2 1 2 1 1 2 2 2 1 9 0 7 1 1 1 6 8 1 2 1 1 3 1 1 1 1 1 2 1 5 0 8 5 1 3 5 8 1 7 8 3 1 2 3 2 4 3 1 3 5 5 1 3 5 1 5 0 7 4 8 7 1 5 1 1 3 1 3 2 2 1 7 0 7 8 1 1 4 7 1 8 3 1 3 3 1 3 2 1 6 0 11 7 8 4 2 8 8 6 7 6 1 1 2 1 1 1 1 2 5 3 3 2 1 3 3 3 4 4 5 3 5 1 5 0 10 4 7 3 6 4 1 5 6 4 5 3 1 1 1 1 1 6 0 7 2 7 7 4 4 9 1 2 2 1 1 2 2 1 9 0 8 2 7 1 3 9 9 1 2 3 2 3 1 1 2 1 3 3 4 3 3 3 2 3 4 1 5 0 10 5 1 1 6 3 9 5 5 7 3 1 3 3 2 2 1 6 0 7 2 4 9 2 1 4 7 1 3 1 1 2 2 1 6 0 11 8 2 9 6 7 6 1 1 3 6 5 3 2 1 1 1 3 1 5 2 3 3 6 1 7 0 9 3 7 4 1 8 6 5 3 4 2 2 2 1 1 1 1 1 8 0 8 9 2 4 1 3 8 4 9 1 2 2 1 3 2 1 3 1 6 0 11 4 1 1 6 5 5 7 1 8 3 6 1 1 1 1 3 3 5 2 4 4 5 2 3 5 1 6 0 11 4 7 6 1 2 6 6 2 7 8 3 2 2 1 1 1 1 1 8 0 7 1 4 5 8 2 3 4 2 3 3 2 2 1 2 2 1 6 0 11 4 1 9 6 3 3 1 9 3 6 4 3 1 2 1 1 1 2 3 4 4 3 3 5 2 1 2 4 4 3 7 1 6 0 11 5 5 3 1 6 6 7 3 8 1 8 2 2 3 3 3 1 1 5 0 6 9 1 1 5 4 1 2 3 1 3 2 1 7 0 10 5 1 5 3 2 7 6 7 7 7 2 3 2 2 1 1 2 1 4 1 5 1 3 1 3 7 1 5 0 11 2 5 7 8 4 7 9 1 5 3 9 1 1 2 1 2 1 7 0 11 8 1 1 9 5 1 2 7 5 1 2 3 2 1 1 1 1 1 1 8 0 7 5 9 4 3 7 8 1 1 3 2 3 3 1 3 1 2 3 1 3 4 3 4 3 6 1 6 0 6 6 2 4 6 1 3 2 1 1 3 3 1 1 5 0 9 6 8 7 7 1 7 1 2 5 1 1 2 3 1 1 8 0 7 4 5 6 1 3 6 8 2 2 2 2 1 2 2 1 1 4 3 5 3 5 3 7 1 8 0 9 9 2 1 4 1 9 9 7 5 3 2 2 3 2 1 3 1 1 7 0 10 8 1 1 3 7 5 1 7 9 4 2 1 3 2 2 3 2 1 7 0 11 9 1 4 7 3 2 3 8 8 8 1 2 2 1 1 3 2 1 1 3 2 4 5 4 1 2 5 4 5 4 4 3 6 1 9 0 11 5 3 7 6 3 1 3 8 5 5 4 1 2 3 3 2 1 1 1 3 1 8 0 10 4 5 7 7 8 9 6 1 7 3 1 1 1 3 3 2 1 3 1 6 0 6 1 6 6 6 7 3 3 3 2 1 3 3 3 5 3 5 5 4 3 6 1 5 0 7 3 8 5 7 2 1 1 3 2 1 3 2 1 7 0 10 3 9 5 1 3 9 5 8 6 6 1 1 2 1 2 1 1 1 9 0 7 2 1 3 2 4 8 7 2 2 3 1 3 3 3 2 1 4 3 3 1 2 5 3 7 1 7 0 8 6 7 2 1 4 7 8 4 3 3 2 2 1 1 2 1 9 0 6 9 4 7 1 6 1 3 2 3 1 3 3 2 2 1 1 7 0 6 6 2 1 9 2 9 3 3 1 1 3 2 3 3 1 5 1 3 1 3 3 6 1 7 0 7 7 5 8 3 5 1 2 1 2 1 1 3 1 1 1 9 0 6 5 1 1 8 4 8 1 1 1 1 2 2 3 2 3 1 9 0 11 9 9 5 5 1 4 1 1 6 7 2 3 3 1 2 2 2 1 3 1 2 4 1 1 2 2 3 4 3 1 5 3 3 6 1 9 0 11 6 4 6 9 4 1 5 6 2 6 4 1 1 2 3 1 3 3 2 3 1 7 0 9 6 7 1 6 8 2 5 9 2 2 2 1 3 1 1 3 1 8 0 7 1 3 3 4 5 7 1 2 3 1 1 1 1 1 3 5 3 4 5 3 1 3 7 1 9 0 9 6 5 7 1 3 1 7 1 6 1 2 1 1 1 2 3 1 1 1 5 0 9 4 7 4 3 2 1 6 4 5 1 3 2 1 2 1 5 0 7 2 8 2 8 1 5 2 1 3 1 1 1 3 3 4 3 1 3 4 3 6 1 7 0 7 1 9 8 8 7 5 4 1 2 2 3 1 2 1 1 7 0 6 8 1 3 4 6 1 1 3 3 1 1 2 1 1 5 0 9 4 1 1 7 3 4 1 6 5 1 2 3 2 1 2 1 5 3 4 2 3 4 1 7 0 10 8 2 1 7 8 9 2 1 6 9 2 2 1 1 2 1 2 1 7 0 6 1 6 3 6 8 1 2 2 1 1 2 1 1 1 6 0 10 9 1 1 1 7 4 9 6 2 5 2 3 1 2 1 3 3 2 1 1 3 6 1 7 0 7 1 5 5 3 6 3 9 2 1 2 2 3 1 1 1 7 0 10 4 6 8 3 1 8 9 3 1 4 2 3 2 2 1 1 3 1 8 0 10 9 6 8 5 4 1 2 3 1 4 3 1 1 1 1 3 3 3 1 2 5 2 2 2 7 1 2 4 5 3 7 1 6 0 6 9 9 9 1 3 9 3 3 2 2 2 1 1 6 0 11 9 7 9 9 7 9 1 1 1 1 1 3 1 3 1 2 1 1 7 0 6 3 7 9 5 4 1 2 3 1 3 3 1 1 1 3 3 5 3 5 5 3 5 1 8 0 11 1 2 5 7 1 3 6 6 2 3 8 3 2 1 1 3 2 3 1 1 5 0 11 1 5 3 3 8 2 5 1 6 7 3 3 3 2 1 1 1 8 0 10 1 8 2 9 7 9 1 1 2 7 1 3 3 1 1 1 3 3 2 2 4 1 3 3 4 1 9 0 9 1 9 3 9 1 5 3 8 6 1 1 2 3 2 3 1 3 3 1 9 0 7 7 2 2 2 6 1 6 1 2 1 1 1 2 1 2 1 1 9 0 6 6 1 8 3 4 2 3 1 2 3 2 1 3 2 2 3 1 3 3 3 7 1 5 0 10 3 3 3 3 3 1 6 7 9 4 3 1 3 3 1 1 8 0 6 5 6 1 1 3 1 2 3 2 2 1 1 3 3 1 6 0 8 1 2 7 2 1 9 3 1 1 2 2 3 1 1 3 4 2 3 4 4 4 3 3 3 3 2 9 6 6 3 5 5 3 6 1 9 0 10 8 4 3 1 2 4 3 3 8 3 2 2 2 3 1 2 1 3 3 1 5 0 6 1 7 9 2 9 1 3 1 2 2 1 1 9 0 10 4 1 2 8 2 5 5 2 7 9 1 3 2 2 2 3 1 2 2 4 3 1 3 3 4 3 7 1 9 0 8 2 3 7 7 1 3 9 5 1 2 1 1 2 3 3 1 2 1 5 0 9 7 1 6 1 5 2 2 1 3 3 1 3 2 1 1 9 0 8 1 4 5 9 1 1 3 1 1 1 1 2 3 1 3 2 1 2 4 1 2 4 4 2 3 5 1 9 0 11 8 1 5 5 4 8 1 2 6 1 9 1 3 3 3 3 1 2 3 1 1 9 0 7 9 7 2 4 5 1 4 3 1 2 1 3 2 3 1 1 1 5 0 9 1 2 4 2 5 1 9 7 5 1 2 1 1 2 4 4 5 2 3 3 5 1 6 0 8 2 4 1 1 8 2 6 8 1 2 1 2 1 2 1 7 0 9 8 1 5 8 1 4 5 4 5 1 2 3 3 2 1 2 1 8 0 10 5 9 1 3 1 1 6 9 8 4 3 1 1 3 3 2 1 3 1 2 5 2 2 3 4 1 9 0 11 4 4 2 1 8 1 7 5 8 2 7 1 1 1 2 1 1 3 2 1 1 5 0 11 8 2 9 1 5 2 9 2 8 1 7 3 1 1 1 2 1 9 0 11 9 3 3 3 1 6 2 7 4 8 3 3 1 2 2 1 1 2 2 2 2 2 1 3 2 1 5 2 5 4 3 3 7 1 5 0 6 5 2 1 2 1 7 1 2 2 1 1 1 5 0 8 8 3 5 9 1 1 9 1 3 3 1 1 1 1 9 0 6 1 4 1 9 3 3 2 3 3 1 3 3 3 1 2 3 2 5 2 1 1 4 3 6 1 7 0 9 2 1 4 7 7 5 1 2 1 2 1 1 3 2 3 3 1 8 0 7 1 4 8 8 1 2 3 1 1 3 1 1 1 3 1 1 8 0 9 1 4 6 3 9 9 3 3 7 1 1 3 1 1 3 3 2 1 3 2 4 2 5 3 6 1 8 0 11 6 9 1 3 3 2 1 7 1 8 2 3 3 1 3 2 2 2 1 1 6 0 10 5 4 6 4 6 9 2 2 1 2 3 1 1 2 2 2 1 6 0 9 1 5 2 2 8 2 6 4 1 1 1 1 1 3 1 1 2 5 2 5 1 3 6 1 9 0 8 3 9 9 2 1 6 2 7 2 1 1 1 2 3 1 3 2 1 6 0 10 2 9 9 6 9 5 8 1 6 8 1 1 3 3 1 2 1 7 0 11 4 2 2 8 1 1 3 7 1 8 7 1 1 3 3 3 2 2 1 1 4 4 1 3 6 2 6 4 5 3 6 1 7 0 9 5 6 7 1 5 6 3 2 6 3 1 3 2 1 3 2 1 8 0 10 4 3 4 3 8 2 2 4 1 1 2 2 3 1 2 3 1 1 1 6 0 6 7 4 1 9 3 6 3 3 2 3 1 2 2 4 4 5 2 4 3 6 1 8 0 11 8 8 7 2 3 5 1 7 3 1 3 2 2 2 1 2 3 3 3 1 8 0 7 4 6 9 3 6 1 2 2 1 2 3 2 2 3 1 1 9 0 9 6 8 1 3 1 1 5 5 3 1 1 1 3 3 1 3 3 1 5 3 5 4 4 3 3 5 1 8 0 10 2 6 6 5 1 3 4 6 6 6 1 3 1 2 2 3 3 2 1 5 0 8 2 6 6 5 1 9 4 7 1 1 1 3 3 1 8 0 9 1 5 2 4 3 3 1 5 2 2 3 2 2 1 2 3 1 2 4 5 2 3 3 7 1 9 0 8 8 1 5 4 1 3 5 8 1 3 1 2 2 2 1 3 1 1 9 0 8 6 4 4 3 1 9 1 7 2 1 2 3 1 1 2 2 3 1 5 0 6 4 3 1 7 1 3 2 3 1 2 3 2 5 1 3 4 1 3 5 3 3 4 2 5 5 3 7 1 8 0 9 3 8 3 3 8 7 2 3 1 1 3 1 3 1 1 3 2 1 6 0 7 3 1 3 5 9 4 2 3 3 2 1 2 1 1 6 0 6 3 2 8 1 3 5 2 1 1 3 2 1 3 2 4 5 3 1 5 3 4 1 7 0 6 2 1 3 9 6 8 2 1 3 2 1 3 3 1 9 0 6 9 9 8 6 1 6 1 1 2 1 2 3 1 1 3 1 6 0 9 5 4 1 2 7 2 1 2 1 1 3 1 1 1 3 4 5 1 4 3 5 1 9 0 7 3 4 3 8 1 1 5 2 1 1 1 1 3 2 3 1 1 9 0 7 4 4 1 8 3 1 2 3 3 1 2 1 3 1 1 1 1 7 0 11 5 4 5 4 7 2 8 1 1 2 4 3 3 1 2 3 2 2 3 5 3 5 2 3 4 1 6 0 6 3 1 2 6 9 1 1 2 2 1 2 3 1 5 0 9 8 2 6 7 8 3 1 7 1 2 2 1 3 2 1 5 0 10 3 1 1 8 4 5 1 4 5 2 1 1 1 3 2 3 1 2 5 3 5 1 5 0 11 4 6 1 8 8 1 6 5 3 8 2 1 1 3 1 1 1 5 0 10 1 5 1 1 5 1 1 7 7 9 3 3 1 1 1 1 6 0 7 9 4 6 1 9 8 9 2 3 2 3 1 3 2 1 1 1 4 1 7 6 5 6 5 5 3 7 1 8 0 7 1 9 6 1 4 6 7 1 3 2 3 2 2 3 2 1 7 0 6 9 6 5 6 1 1 1 1 2 3 3 2 1 1 6 0 11 1 7 1 9 8 4 2 4 3 9 9 3 3 3 1 2 3 3 3 2 3 5 1 4 3 4 1 7 0 8 9 1 7 2 5 8 9 5 1 2 2 2 1 2 3 1 9 0 9 6 1 9 4 7 2 5 4 2 3 2 3 1 3 1 2 1 3 1 5 0 10 4 7 7 4 2 1 4 1 9 9 1 3 2 1 2 3 1 3 4 3 5 1 8 0 8 4 1 7 6 2 8 9 3 1 1 1 1 1 1 2 3 1 6 0 8 8 2 9 9 4 1 1 1 1 2 1 1 1 1 1 8 0 6 4 7 1 8 1 8 1 3 2 3 1 2 1 1 3 2 3 4 2 3 4 1 6 0 10 7 1 4 2 3 1 1 8 4 4 1 1 3 2 1 1 1 8 0 10 7 9 4 7 7 1 8 8 1 2 3 1 1 3 3 2 3 1 1 5 0 9 4 1 9 1 6 9 9 2 6 2 3 3 1 1 1 3 1 4 3 5 1 7 0 9 9 3 8 3 8 1 1 1 6 1 1 1 3 1 1 1 1 7 0 11 3 6 5 3 1 4 6 9 9 6 1 2 1 3 2 3 1 1 1 9 0 6 1 3 3 9 6 1 2 2 1 3 1 3 2 2 3 5 2 1 2 3 3 1 1 5 3 5 5 3 4 1 5 0 11 7 1 8 3 8 4 1 4 3 1 1 3 2 1 3 3 1 8 0 10 4 5 4 9 1 6 4 5 1 1 1 2 2 1 1 1 2 3 1 5 0 10 3 1 4 9 3 7 6 7 1 3 3 1 1 1 1 2 2 3 4 3 5 1 6 0 10 1 4 4 4 7 4 8 5 1 9 1 2 1 2 1 1 1 9 0 11 4 3 4 1 5 6 1 1 5 1 7 1 3 2 1 3 2 1 3 3 1 6 0 8 1 3 3 5 6 1 4 3 1 2 1 1 1 3 3 4 4 4 4 3 6 1 9 0 10 1 4 2 5 2 6 8 3 3 8 3 1 2 1 2 1 2 2 2 1 9 0 7 1 1 9 3 3 1 2 2 3 1 2 3 2 3 1 3 1 9 0 8 3 3 5 1 5 7 3 8 1 2 1 1 3 2 2 2 1 4 1 5 4 5 3 3 5 1 5 0 6 9 1 6 5 1 7 1 1 3 2 1 1 9 0 11 1 9 8 5 3 7 2 3 4 6 4 1 2 1 1 2 2 3 3 2 1 7 0 7 1 9 7 6 1 3 6 1 1 1 1 1 3 3 4 3 4 2 2 3 4 1 9 0 10 3 5 2 3 6 7 8 9 1 7 2 1 2 3 3 2 3 1 2 1 8 0 8 4 1 2 4 5 1 2 5 1 1 3 2 1 1 3 2 1 8 0 6 1 3 3 5 1 1 3 1 1 3 3 1 2 2 5 4 2 1 5 5 2 5 6 6 4 2 7 2 4 5 3 7 1 6 0 8 1 1 4 1 1 9 2 8 1 1 2 2 1 3 1 6 0 7 1 7 7 6 8 5 9 2 3 1 2 1 1 1 6 0 8 2 6 5 4 1 4 2 1 1 1 2 1 3 1 4 1 2 2 1 1 1 3 6 1 8 0 9 1 9 5 7 6 4 3 2 1 3 2 1 1 2 2 1 1 1 9 0 6 6 5 3 9 1 1 1 3 1 3 3 1 2 1 3 1 6 0 10 6 8 1 9 5 8 4 4 2 1 2 1 1 1 3 2 3 1 1 3 4 2 3 5 1 8 0 11 5 2 8 1 5 4 8 1 3 1 3 3 2 1 2 2 1 3 3 1 6 0 6 1 2 7 6 1 6 2 2 1 1 1 3 1 9 0 9 4 8 5 3 1 8 6 1 7 1 3 3 2 3 2 1 3 1 3 2 1 4 1 3 5 1 7 0 10 7 5 6 5 4 2 1 9 9 5 1 1 3 1 3 3 1 1 9 0 7 3 5 6 9 1 4 1 1 1 2 1 2 3 2 1 3 1 8 0 6 7 5 1 1 9 9 1 2 2 1 2 2 2 1 2 4 5 1 4 2 5 4 1 3 4 3 3 5 1 7 0 6 1 4 7 8 2 2 1 1 3 2 2 3 3 1 6 0 8 1 6 5 3 6 4 1 8 1 1 3 2 3 1 1 7 0 10 3 1 7 5 6 1 1 2 2 6 3 1 3 1 1 2 2 3 3 5 5 5 3 7 1 7 0 11 2 1 7 5 6 1 1 3 2 3 5 1 2 2 1 2 3 2 1 5 0 10 5 8 5 9 3 6 1 3 5 1 3 1 1 3 2 1 8 0 8 1 9 5 2 4 7 1 5 1 2 1 2 3 1 2 2 4 5 2 5 4 2 2 3 4 1 9 0 11 2 1 1 9 8 1 1 1 9 1 1 2 1 1 3 1 3 1 1 2 1 9 0 8 9 8 2 1 2 6 5 2 3 3 3 1 1 3 2 3 1 1 5 0 10 9 4 9 2 6 1 7 6 9 8 3 1 1 3 1 1 5 2 3 3 4 1 8 0 8 8 7 3 7 1 3 1 7 1 3 3 1 3 1 3 1 1 7 0 11 3 5 9 8 1 3 1 1 8 3 6 2 2 3 1 2 1 1 1 5 0 10 9 2 3 8 3 3 1 4 3 1 2 1 1 2 3 3 5 1 1 3 4 4 4 3 3 4 1 8 0 9 6 1 9 2 2 7 2 5 9 3 3 1 3 1 3 2 2 1 6 0 11 7 1 6 2 5 4 6 3 5 3 3 3 3 3 2 2 1 1 7 0 9 7 3 8 2 1 7 2 7 6 1 2 2 3 2 3 2 3 2 4 3 3 6 1 8 0 11 9 1 8 4 7 9 5 4 6 2 4 1 2 1 2 2 2 2 1 1 5 0 9 6 7 6 9 2 2 1 6 9 3 1 3 2 2 1 9 0 8 3 1 5 5 1 6 4 9 3 1 2 1 1 2 1 2 1 2 2 2 5 2 1 3 5 1 5 0 9 1 2 2 6 6 8 5 1 2 1 2 3 3 1 1 8 0 6 4 8 1 7 1 8 2 1 1 3 2 2 1 2 1 8 0 9 9 8 3 4 2 6 8 1 8 1 3 3 1 2 2 3 1 1 2 1 4 5 3 4 1 6 0 11 1 3 4 1 5 8 5 8 8 1 8 3 1 3 1 2 2 1 7 0 8 3 8 1 8 7 7 6 7 1 1 2 1 1 2 3 1 7 0 10 3 5 6 1 5 9 3 9 8 1 1 1 3 3 2 3 1 1 5 5 2 3 1 1 5 5 3 5 1 5 0 9 7 5 1 4 1 1 7 1 1 1 2 1 3 3 1 9 0 7 1 3 2 5 4 3 7 1 2 2 3 2 1 3 1 3 1 5 0 9 1 1 3 9 8 8 1 5 1 1 1 3 1 2 1 2 4 3 5 3 4 1 5 0 7 3 1 1 5 3 9 6 1 1 1 1 1 1 5 0 7 1 7 4 4 1 8 5 3 1 3 2 2 1 8 0 11 8 1 8 6 7 6 2 1 9 1 1 2 1 3 1 1 1 3 1 4 2 1 2 3 6 1 6 0 8 7 3 8 3 7 7 1 9 2 1 2 1 3 1 1 8 0 8 4 5 4 8 2 1 6 8 3 1 1 2 3 2 1 1 1 6 0 8 7 5 9 1 6 9 3 7 2 3 3 2 1 1 3 3 3 1 2 2 3 7 1 7 0 10 2 3 5 3 4 1 1 5 3 1 1 2 3 3 3 2 1 1 8 0 7 8 1 4 7 3 1 4 3 2 3 1 1 2 1 3 1 7 0 9 6 3 1 9 8 1 2 2 7 3 1 3 2 1 1 2 3 3 4 5 2 2 1 3 6 1 5 0 7 6 9 1 3 3 3 1 2 1 1 3 3 1 5 0 7 4 1 4 3 8 4 3 3 2 1 3 1 1 8 0 9 9 9 1 7 6 7 4 3 7 1 2 2 2 1 1 3 1 3 5 4 4 1 3 5 3 7 6 7 5 5 3 5 1 7 0 8 5 3 1 3 2 6 9 6 1 2 3 3 3 3 1 1 5 0 9 6 7 2 9 1 6 7 6 9 2 2 1 1 3 1 5 0 6 9 4 9 1 4 6 3 2 3 1 1 3 4 4 1 3 3 5 1 5 0 11 1 5 4 1 9 9 4 2 6 8 1 3 1 2 3 1 1 5 0 10 1 2 4 7 2 3 7 8 2 1 1 3 3 1 1 1 5 0 10 3 5 4 1 8 1 3 1 4 7 1 3 1 1 1 2 2 5 5 2 3 7 1 8 0 11 3 7 9 1 5 1 1 4 6 7 6 3 2 2 3 1 1 3 2 1 8 0 9 7 5 3 9 2 7 6 1 2 2 3 2 3 3 3 1 1 1 9 0 10 7 1 1 1 9 1 5 4 8 1 1 1 1 3 2 1 1 1 3 2 2 2 3 2 1 1 3 5 1 6 0 7 8 1 8 1 2 6 2 2 3 1 3 1 1 1 6 0 6 9 8 2 1 3 5 1 3 3 2 3 2 1 5 0 10 4 4 6 1 7 5 8 1 4 5 2 1 1 3 1 5 1 2 3 3 3 4 1 9 0 11 9 8 6 3 1 9 9 2 4 2 1 2 1 2 3 3 3 2 2 1 1 9 0 6 8 4 7 1 2 9 3 3 2 2 1 2 3 3 3 1 7 0 10 5 4 6 7 7 4 2 1 8 1 3 1 3 2 1 3 1 4 2 3 3 2 3 5 5 7 4 4 3 4 1 5 0 8 5 2 6 8 7 2 6 1 3 1 2 1 3 1 8 0 8 6 5 2 4 1 6 9 3 3 2 3 2 3 3 2 1 1 8 0 10 6 5 6 1 3 6 7 8 2 6 3 1 2 1 3 3 2 1 3 3 1 2 3 5 1 5 0 11 7 5 2 7 1 9 1 1 7 2 6 1 2 2 1 2 1 6 0 8 9 7 6 1 7 8 8 8 1 2 1 3 1 3 1 7 0 7 3 6 1 7 5 6 5 1 1 2 1 3 3 3 3 4 1 2 1 3 5 1 9 0 6 1 6 4 1 3 9 1 1 1 2 3 1 2 1 1 1 7 0 6 2 6 1 1 5 5 3 3 1 3 3 2 2 1 8 0 11 2 7 4 8 4 6 4 5 5 5 1 3 3 3 3 1 2 3 3 1 3 5 1 4 3 5 1 5 0 8 9 6 1 5 5 7 9 9 3 1 3 2 1 1 9 0 9 1 1 2 6 1 5 6 2 5 2 1 3 1 2 1 3 2 1 1 8 0 10 7 1 9 3 8 4 3 4 1 5 1 1 1 1 1 1 3 3 4 2 3 1 1 3 3 5 4 4 3 3 7 1 6 0 10 3 1 4 4 3 5 1 1 1 6 3 2 2 1 1 1 1 8 0 6 1 6 8 3 1 7 1 2 3 3 1 1 1 1 1 5 0 9 9 4 7 1 3 6 8 5 8 3 1 2 3 3 3 4 4 1 2 1 3 3 7 1 5 0 8 8 5 6 8 5 1 4 4 1 3 2 1 3 1 9 0 10 9 6 6 2 1 1 1 3 6 3 3 1 3 1 2 1 1 1 1 1 5 0 8 9 5 1 3 2 4 7 9 1 3 1 2 1 5 5 2 4 2 3 1 3 5 1 5 0 6 7 9 5 1 2 4 1 3 1 2 2 1 6 0 11 3 5 8 7 1 1 7 2 8 7 8 1 1 2 2 2 1 1 7 0 7 1 9 9 5 9 4 4 3 2 2 1 2 1 1 2 5 4 1 3 3 4 1 5 0 10 3 2 2 3 1 5 2 5 3 5 3 2 1 2 1 1 7 0 11 1 9 2 2 8 3 3 1 5 6 7 3 1 1 1 2 1 3 1 8 0 6 1 1 3 1 1 4 2 3 3 1 3 2 3 3 3 2 2 4 4 2 3 6 4 4 6 4 5 9 9 6 8 3 1 3 diff --git a/2018/day9/day9.exs b/2018/day9/day9.exs new file mode 100644 index 0000000..98d0a60 --- /dev/null +++ b/2018/day9/day9.exs @@ -0,0 +1,102 @@ +defmodule Marble do + defstruct [:cw, :ccw] +end + +defmodule Game do + defstruct [:current, :next, :circle, :players, :active, :scores, :marbles] + + def start(players, marbles) do + game = %Game{ + current: 0, + next: 1, + circle: %{0 => %Marble{ccw: 0, cw: 0}}, + players: players, + active: 1, + scores: Map.new(1..players, &{&1, 0}), + marbles: marbles + } + + play(game) + end + + def next_turn(%Game{next: next, marbles: marbles} = game) when next > marbles do + game.scores |> Map.values() |> Enum.max() + end + + def next_turn(%Game{players: players, active: active} = game) do + next = active + 1 + next = if next <= players, do: next, else: 1 + play(%Game{game | active: next}) + end + + def insert(circle, val, ccw, cw) do + circle + |> Map.put(val, %Marble{ccw: ccw, cw: cw}) + |> Map.update!(ccw, &%Marble{&1 | cw: val}) + |> Map.update!(cw, &%Marble{&1 | ccw: val}) + end + + def remove(circle, val, ccw, cw) do + circle + |> Map.delete(val) + |> Map.update!(ccw, &%Marble{&1 | cw: cw}) + |> Map.update!(cw, &%Marble{&1 | ccw: ccw}) + end + + def find_remove(cw, circle, 1) do + remove = circle[cw].ccw + ccw = circle[remove].ccw + {remove, ccw, cw} + end + + def find_remove(current, circle, dec) do + find_remove(circle[current].ccw, circle, dec - 1) + end + + def play(%Game{current: current, next: val, circle: circle} = game) when rem(val, 23) == 0 do + # Find and remove the item 7 items over + {remove, ccw, cw} = find_remove(current, circle, 7) + circle = remove(circle, remove, ccw, cw) + + # Update the player's score + scores = Map.update!(game.scores, game.active, &(&1 + val + remove)) + + game = %Game{game | current: cw, next: val + 1, circle: circle, scores: scores} + next_turn(game) + end + + def play(%Game{current: current, next: val, circle: circle} = game) do + one = circle[current].cw + two = circle[one].cw + game = %Game{game | current: val, next: val + 1, circle: insert(circle, val, one, two)} + next_turn(game) + end +end + +defmodule Day9 do + def part1 do + input = File.read!("input") + pattern = ~r/(\d+) players; last marble is worth (\d+) points/ + + [players, marbles] = + Regex.run(pattern, input, capture: :all_but_first) + |> Enum.map(&String.to_integer/1) + + Game.start(players, marbles) + end + + # Probably supposed to make this more efficient, but it still runs in 30 seconds... + def part2 do + input = File.read!("input") + pattern = ~r/(\d+) players; last marble is worth (\d+) points/ + + [players, marbles] = + Regex.run(pattern, input, capture: :all_but_first) + |> Enum.map(&String.to_integer/1) + + Game.start(players, marbles * 100) + end +end + +IO.puts(Day9.part1()) +IO.puts(Day9.part2()) diff --git a/2018/day9/input b/2018/day9/input new file mode 100644 index 0000000..6dfed1b --- /dev/null +++ b/2018/day9/input @@ -0,0 +1 @@ +459 players; last marble is worth 71790 points