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

Advent of Code Day 3

day_03/day_three.livemd

Advent of Code Day 3

Setup

test_data = """
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010
"""

data = File.read!("day_03/input.txt")
"000010000011\n001010000111\n011010000010\n000011111110\n101101000101\n000100010100\n111101111110\n111111000010\n000011010011\n100011100000\n101110110001\n111011111101\n111011011001\n010101000010\n000010001000\n101010011111\n010000111101\n011010111100\n101111010110\n000110110101\n001010000001\n110101100110\n111110010100\n001000001011\n100111101001\n000010010001\n100100101010\n011010110111\n000001100100\n101111000111\n010101101100\n001111010010\n010001011100\n110101011011\n000010101000\n011011101101\n101001000011\n101111000000\n001111101111\n001101110111\n110110110101\n100011001011\n010110110011\n001010001110\n110110100100\n001001111111\n100111011100\n101101001010\n011110000011\n010101111000\n001101000101\n100011001100\n110000110001\n011101010001\n000110001101\n110001101101\n011001000110\n011101010101\n110110011010\n001000011001\n100101100101\n010110001100\n110100011001\n001011000010\n101011110101\n011101001010\n011011000111\n000101000001\n100001010110\n111101000011\n111010111011\n000011101001\n011111110000\n110011100101\n110011100110\n101011001011\n100110110111\n010001111100\n101010011001\n111001111011\n111001000011\n010010111010\n011011011110\n101000010000\n000010011111\n000101110000\n101010000110\n101100000100\n110000110000\n000010100010\n010001111001\n001000001111\n010110000011\n010000111110\n001011001010\n011010100001\n001001000110\n011010001101\n100111011101\n011101010000\n100111010100\n100101001101\n111010101001\n011001011101\n010011000000\n000001100110\n110101011100\n000110101000\n011110001000\n010011000001\n100011011111\n100100001111\n010011101010\n001011000001\n111101011000\n011101000110\n111011001101\n110110010110\n111011000110\n111111010101\n101110100111\n011110010001\n010100011111\n001111000101\n101100010011\n111101000010\n100001110100\n110001110011\n011011110101\n100110111101\n110010011010\n111001000110\n100010111111\n100010101110\n011110111001\n011100101100\n010101111101\n101010111011\n111111110100\n010111100110\n111010101111\n011001110000\n101011100011\n101000000110\n111100011011\n001001010010\n001010110001\n000111101101\n100010000101\n010001101110\n000100100001\n010100011000\n001100011011\n111111110011\n111010010000\n001100101001\n000101001110\n111100111010\n111110010000\n010111001000\n011100001100\n000010011010\n101010101011\n110100011011\n010110101101\n000001000101\n111111010011\n110000000110\n110100111111\n111000000010\n000101010111\n001110110110\n111111111011\n010010100100\n110000010011\n010111110111\n111000010010\n111011100000\n010100000101\n010011011001\n000110101111\n110111101111\n101001001011\n101111110111\n111010101011\n100100010101\n100100011100\n000011010111\n011010101011\n101000111010\n010101011101\n101101000001\n010111110010\n111101011010\n000001010100\n011010101000\n010000110010\n101000011100\n010001010000\n000001001101\n100101110001\n001101010010\n001100111110\n011101010111\n111110011100\n100011000101\n101111100100\n111011001000\n010111000110\n001010111100\n011011110001\n111010011110\n101011100110\n001100010111\n111110110111\n101011010001\n011110100011\n110000001110\n101011101011\n101101000111\n110111111111\n010000011000\n001110001000\n111000000101\n010111101100\n000100000101\n001111100101\n101001111101\n010111110101\n100110010101\n111101101100\n111100010010\n110011111110\n011100010101\n111001001100\n101010110000\n010100010010\n111100110000\n111100001000\n111100110110\n101101110010\n010001101100\n010110010000\n100000100101\n000000001110\n011001100110\n100101000010\n011111100010\n010010100010\n100101011001\n011100100100\n010111110000\n100111000110\n111110011011\n011111000011\n101001100101\n000110101110\n111001111110\n011110011101\n101011111111\n010110101010\n100001100111\n000101001111\n110100011101\n111110100111\n101000111110\n010010011110\n100110100111\n000111010011\n110101110110\n101101000000\n110110111110\n001100111111\n000010101010\n001001001001\n101000110110\n010011111000\n000101110011\n011100001111\n000001101110\n100001010010\n001100000011\n011100101110\n111000111000\n110010110111\n100100000010\n010101100100\n100111001101\n011101100100\n110010001010\n100111000000\n111011001100\n010010010011\n110110100001\n001011110001\n010000100110\n001111100100\n100110001000\n101000010001\n001000001000\n110001001011\n001010010101\n101001111011\n011101110010\n101000100110\n010000101110\n000110010110\n001111010001\n011010100111\n101110011001\n001010001100\n010001011010\n110010100010\n100001111001\n001001010001\n0" <> ...

Part 1

# What is the power consumption of the submarine?
# gamma rate 
# epsilon rate

defmodule Day3Part1 do
  def parse_raw_data(data) when is_binary(data) do
    String.split(data, "\n", trim: true)
  end

  def zero_one_counts(data) when is_list(data) do
    for i <- 0..(String.length(hd(data)) - 1) do
      Enum.reduce(data, {0, 0}, fn element, {zero_count, one_count} ->
        case String.at(element, i) do
          "1" ->
            {zero_count, one_count + 1}

          "0" ->
            {zero_count + 1, one_count}
        end
      end)
    end
  end

  def most_common(zero_one_counts) when is_list(zero_one_counts) do
    Enum.map(zero_one_counts, fn
      {zero_count, one_count} when zero_count > one_count -> "0"
      {zero_count, one_count} when one_count > zero_count -> "1"
    end)
  end

  def least_common(zero_one_counts) when is_list(zero_one_counts) do
    Enum.map(zero_one_counts, fn
      {zero_count, one_count} when zero_count > one_count -> "1"
      {zero_count, one_count} when one_count > zero_count -> "0"
    end)
  end
end

zero_one_counts =
  data
  |> Day3Part1.parse_raw_data()
  |> Day3Part1.zero_one_counts()

gamma_rate =
  zero_one_counts
  |> Day3Part1.most_common()
  |> Enum.join()
  |> Integer.parse(2)
  |> elem(0)

epsilon_rate =
  zero_one_counts
  |> Day3Part1.least_common()
  |> Enum.join()
  |> Integer.parse(2)
  |> elem(0)

gamma_rate * epsilon_rate
3242606

Part 2

#  oxygen generator rating by the CO2 scrubber rating

defmodule Day3Part2 do
  def process_ratings(data, fun) when is_list(data) and is_function(fun, 2) do
    0..(String.length(hd(data)) - 1)
    |> Enum.reduce_while(data, fn index, acc ->
      case fun.(index, acc) do
        [answer] -> {:halt, String.to_integer(answer, 2)}
        ratings -> {:cont, ratings}
      end
    end)
  end

  def keep_oxygen_generator_rating?(index, ratings) do
    {zeros, ones} =
      ratings
      |> Day3Part1.zero_one_counts()
      |> Enum.at(index)

    Enum.filter(ratings, fn rating ->
      case String.at(rating, index) do
        "1" when ones == zeros -> true
        "1" when ones > zeros -> true
        "0" when zeros > ones -> true
        _ -> false
      end
    end)
  end

  def keep_co2_scrubber_rating?(index, ratings) do
    {zeros, ones} =
      ratings
      |> Day3Part1.zero_one_counts()
      |> Enum.at(index)

    Enum.filter(ratings, fn rating ->
      case String.at(rating, index) do
        "0" when zeros < ones -> true
        "1" when ones < zeros -> true
        "0" when ones == zeros -> true
        _ -> false
      end
    end)
  end
end

data = Day3Part1.parse_raw_data(data)

oxygen_generator_rating =
  Day3Part2.process_ratings(
    data,
    &amp;Day3Part2.keep_oxygen_generator_rating?/2
  )

co2_scrubber_rating =
  Day3Part2.process_ratings(
    data,
    &amp;Day3Part2.keep_co2_scrubber_rating?/2
  )

oxygen_generator_rating * co2_scrubber_rating
4856080