Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Day 14

day14.livemd

Day 14

# Note: when making the next template, something like this works well:
#   `cat day04.livemd | sed 's/14/04/' > day04.livemd`
# When inspecting lists of numbers, use "charlists: :as_lists"
#
Mix.install([
  # Join the string so a copy of dayN to dayM doesn't destroy it.
  {:kino, "~> 0.1" <> "4.2"}
])

# Join the string so a copy of dayN to dayM doesn't destroy it.
IEx.Helpers.c("/Users/johnb/dev/2" <> "0" <> "2" <> "4adventOfCode/advent_of_code.ex")
alias AdventOfCode, as: AOC
alias Kino.Input

Installation and Data

input_example = Kino.Input.textarea("Example Data", monospace: true)
input_puzzleInput = Kino.Input.textarea("Puzzle Input", monospace: true)
input_source_select =
  Kino.Input.select("Source", [{:example, "example"}, {:puzzle_input, "puzzle input"}])
data = fn ->
  (Kino.Input.read(input_source_select) == :example &amp;&amp;
     Kino.Input.read(input_example)) ||
    Kino.Input.read(input_puzzleInput)
end

Solution

defmodule Day14 do
  @parser ~r/p=(\d+),(\d+) v=(-?\d+),(-?\d+)/
    
  def parse(text) do
    text
    |> AOC.as_single_lines()
    |> Enum.map(fn line ->
      [_px, _py, _vx, _vy] = Regex.scan(@parser, line) 
        |> List.flatten()
        |> Enum.slice(1..-1//1)
        |> Enum.map(&amp;String.to_integer/1)
    end)
  end

  def solve1(text) do
    seconds = 100
    robots = parse(text)
    [space_x, space_y] = (Enum.count(robots) > 50) &amp;&amp; [101, 103] || [11, 7]

    final_positions = robots
      |> Enum.map(fn [px, py, vx, vy] -> 
        new_x = rem(rem(px + seconds * vx, space_x) + space_x, space_x)
        new_y = rem(rem(py + seconds * vy, space_y) + space_y, space_y)
        
        [new_x, new_y]
      end)
      |> Enum.sort()

    final_positions
    |> Enum.reduce([0,0,0,0], fn [x, y], [q1,q2,q3,q4] ->
      cond do
        x < floor(space_x / 2) &amp;&amp; y < floor(space_y / 2) ->
          [q1+1,q2,q3,q4]
        x >= ceil(space_x / 2) &amp;&amp; y < floor(space_y / 2) ->
          [q1,q2+1,q3,q4]
        x < floor(space_x / 2) &amp;&amp; y >= ceil(space_y / 2) ->
          [q1,q2,q3+1,q4]
        x >= ceil(space_x / 2) &amp;&amp; y >= ceil(space_y / 2) ->
          [q1,q2,q3,q4+1]
        true ->
          [q1,q2,q3,q4]
      end
    end)
    |> Enum.reduce(1, fn q, acc -> q * acc end)
  end

  def format(robots, space_x, space_y, title) do
    positions = robots
      |> Enum.map(fn [x, y, _, _] -> [x,y] end)

    space = for y <- 0..(space_y - 1) do
        for x <- 0..(space_x - 1) do
          ([x,y] in positions) &amp;&amp; "#" || "."
        end
        |> Enum.join()
      end
      |> Enum.join("\n")
    
    "=== #{title} ===\n" <> space
  end

  def display(file, robots, space_x, space_y, title) do
    IO.puts(file, format(robots, space_x, space_y, title))
    robots
  end

  def step(robots, space_x, space_y) do
    robots
    |> Enum.map(fn [px, py, vx, vy] ->
      [
        rem(rem(px + vx, space_x) + space_x, space_x), 
        rem(rem(py + vy, space_y) + space_y, space_y), 
        vx, vy
      ]
    end)
  end

  def solve2(text) do
    seconds = 6587 # found iteratively from commented-out code below
    robots = parse(text)
    [space_x, space_y] = (Enum.count(robots) > 50) &amp;&amp; [101, 103] || [11, 7]
    tree_position = robots
      |> Enum.map(fn [px, py, vx, vy] -> 
        [rem(rem(px + seconds * vx, space_x) + space_x, space_x),
        rem(rem(py + seconds * vy, space_y) + space_y, space_y),
          vx, vy]
      end)
    
    # {:ok, file} = File.open("6587.text", [:write])
    IO.puts(format(tree_position, space_x, space_y, "6587"))
    # display(file, tree_position, space_x, space_y, "#{seconds}")
    # File.close(file)
    IO.puts("closed file")
    6587

    # Original code used to find 6587
    # robots = parse(text)
    # [space_x, space_y] = (Enum.count(robots) > 50) && [101, 103] || [11, 7]
    # # IO.puts(format(robots, space_x, space_y, "START"))
    # # {:ok, file} = File.open("6587.text", [:write])
    # IO.puts("START")
    # 1..10_000
    # |> Enum.reduce(robots, fn second, acc ->
    #   robots = step(acc, space_x, space_y)
    #   screen = format(robots, space_x, space_y, "#{second}")
    #   if screen =~ "##########" do
    #     IO.puts(screen)
    #   end
    #   # if second in 0..100 do
    #     # display(file, robots, space_x, space_y, "#{second}")
    #   # end
    #   robots
    # end)
    # # File.close(file)
    # IO.puts("closed file")
  end
end

# Example:
# p=0,4 v=3,-3
# p=6,3 v=-1,-3
# p=10,3 v=-1,2
# p=2,0 v=2,-1
# p=0,0 v=1,3
# p=3,0 v=-2,-2
# p=7,6 v=-1,-3
# p=3,0 v=-1,-2
# p=9,3 v=2,3
# p=7,3 v=-1,2
# p=2,4 v=2,-3
# p=9,5 v=-3,-3

data.()
|> Day14.solve1()
|> IO.inspect(label: "\n*** Part 1 solution (example: 12)")
# 211692000

data.()
|> Day14.solve2()
|> IO.inspect(label: "\n*** Part 2 solution (example: none)")
# 6587
# ....................................#................................................................
# ...........................#.........................................................................
# .....................................................................................................
# .................................#......###############################..............................
# ............#...........................#.............................#..............................
# ........................................#.............................#..........#...................
# ........................................#.............................#..............................
# ....................#...................#.............................#..............................
# ........................................#..............#..............#..............................
# ........................................#.............###.............#...................#..........
# ........................................#............#####............#..............................
# ......................................#.#...........#######...........#..............................
# ........................................#..........#########..........#..............................
# ........................................#............#####............#..............................
# .............#..........................#...........#######...........#...........#.........#........
# .....#..#...............................#..........#########..........#.....#........................
# .......#........#.......................#.........###########.........#..............................
# ........................................#........#############........#..............................
# .#...#..................................#..........#########..........#..............................
# ........................................#.........###########.........#.......#......................
# .................#......................#........#############........#..............................
# ......#......................#..........#.......###############.......#..............................
# #.......................................#......#################......#..............................
# ........................................#........#############........#....#.........................
# .....#..................................#.......###############.......#..............................
# ........................................#......#################......#..............................
# ........................................#.....###################.....#..............................
# .................#......................#....#####################....#...................#..........
# ........................................#.............###.............#..............................
# ..............#.........................#.............###.............#..............................
# ........................................#.............###.............#............#.................
# ........................................#.............................#..............................
# ........................................#.............................#..............................
# ........................................#.............................#...#..........................
# ........................................#.............................#............#.................
# ........................................###############################..............................
# ...........................#.........................................................................