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

Day 1

day1.livemd

Day 1

Mix.install([
  {:benchee, "~> 1.3"}
])

Setup

input =
  System.fetch_env!("LB_AOC_DIR")
  |> Path.join("data/day1.txt")
  |> File.read!()
nil
nil

Solve

defmodule Day1 do
  def split_dataset(input) do
    {left, right, _which} =
      input
      |> String.split()
      |> Enum.reduce({[], [], :left}, fn
        item, {left, right, which} ->
          {item, ""} = item |> String.trim() |> Integer.parse()

          case which do
            :left ->
              {[item | left], right, :right}

            :right ->
              {left, [item | right], :left}
          end
      end)

    {left, right}
  end

  def part1(input) do
    {left, right} = split_dataset(input)

    Enum.zip_reduce(Enum.sort(left), Enum.sort(right), 0, fn
      left, right, acc ->
        acc + abs(right - left)
    end)
  end

  def part2(input) do
    {left, right} = split_dataset(input)
    right_freqs = Enum.frequencies(right)

    Enum.reduce(left, 0, fn item, acc ->
      acc + item * Map.get(right_freqs, item, 0)
    end)
  end

  def bench(input) do
    Benchee.run(
      %{
        "part1" => fn -> part1(input) end,
        "part2" => fn -> part2(input) end
      },
      time: 10,
      memory_time: 2
    )
  end
end
{:module, Day1, <<70, 79, 82, 49, 0, 0, 14, ...>>, {:bench, 1}}
Day1.bench(input)
Error trying to determine erlang version enoent, falling back to overall OTP version
Operating System: macOS
CPU Information: Apple M1 Max
Number of Available Cores: 10
Available memory: 32 GB
Elixir 1.17.2
Erlang 27
JIT enabled: true

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 10 s
memory time: 2 s
reduction time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 28 s

Benchmarking part1 ...
Benchmarking part2 ...
Calculating statistics...
Formatting results...

Name            ips        average  deviation         median         99th %
part1        2.09 K      479.05 μs    ±28.38%      457.88 μs      712.56 μs
part2        1.94 K      515.46 μs    ±10.03%      515.79 μs      675.96 μs

Comparison:
part1        2.09 K
part2        1.94 K - 1.08x slower +36.41 μs

Memory usage statistics:

Name          average  deviation         median         99th %
part1       744.04 KB     ±0.00%      744.04 KB      744.04 KB
part2       606.94 KB     ±0.00%      606.94 KB      606.94 KB

Comparison:
part1       744.04 KB
part2       606.94 KB - 0.82x memory usage -137.10366 KB
%Benchee.Suite{
  system: %Benchee.System{
    elixir: "1.17.2",
    erlang: "27",
    jit_enabled?: true,
    num_cores: 10,
    os: :macOS,
    available_memory: "32 GB",
    cpu_speed: "Apple M1 Max"
  },
  configuration: %Benchee.Configuration{
    parallel: 1,
    time: 10000000000.0,
    warmup: 2000000000.0,
    memory_time: 2000000000.0,
    reduction_time: 0.0,
    pre_check: false,
    formatters: [Benchee.Formatters.Console],
    percentiles: ~c"2c",
    print: %{configuration: true, benchmarking: true, fast_warning: true},
    inputs: nil,
    input_names: [],
    save: false,
    load: false,
    unit_scaling: :best,
    assigns: %{},
    before_each: nil,
    after_each: nil,
    before_scenario: nil,
    after_scenario: nil,
    measure_function_call_overhead: false,
    title: nil,
    profile_after: false
  },
  scenarios: [
    %Benchee.Scenario{
      name: "part1",
      job_name: "part1",
      function: #Function<0.24482852/0 in Day1.bench/1>,
      input_name: :__no_input,
      input: :__no_input,
      before_each: nil,
      after_each: nil,
      before_scenario: nil,
      after_scenario: nil,
      tag: nil,
      run_time_data: %Benchee.CollectionData{
        statistics: %Benchee.Statistics{
          average: 479047.29306294647,
          ips: 2087.476569601659,
          std_dev: 135934.3719203083,
          std_dev_ratio: 0.28375981638716125,
          std_dev_ips: 592.3419681026679,
          median: 457875.0,
          percentiles: %{50 => 457875.0, 99 => 712558.6000000001},
          mode: 433625,
          minimum: 396834,
          maximum: 11085338,
          relative_more: nil,
          relative_less: nil,
          absolute_difference: nil,
          sample_size: 20859
        },
        samples: [571416, 499541, 561751, 516875, 617250, 464417, 464292, 595459, 531875, 533417,
         542500, 482792, 465167, 498500, 465292, 463708, 519250, 498458, 463918, 500125, 463916,
         462250, 499125, 462501, 461959, 509250, 476208, 541625, 564501, 483084, 481792, 588542,
         552250, ...]
      },
      memory_usage_data: %Benchee.CollectionData{
        statistics: %Benchee.Statistics{
          average: 761896.0,
          ips: nil,
          std_dev: 0.0,
          std_dev_ratio: 0.0,
          std_dev_ips: nil,
          median: 761896.0,
          percentiles: %{50 => 761896.0, 99 => 761896.0},
          mode: 761896,
          minimum: 761896,
          maximum: 761896,
          relative_more: nil,
          relative_less: nil,
          absolute_difference: nil,
          sample_size: 3117
        },
        samples: [761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896,
         761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896,
         761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896, 761896,
         ...]
      },
      reductions_data: %Benchee.CollectionData{
        statistics: %Benchee.Statistics{
          average: nil,
          ips: nil,
          std_dev: nil,
          std_dev_ratio: nil,
          std_dev_ips: nil,
          median: nil,
          percentiles: nil,
          mode: nil,
          minimum: nil,
          maximum: nil,
          relative_more: nil,
          relative_less: nil,
          absolute_difference: nil,
          sample_size: 0
        },
        samples: []
      }
    },
    %Benchee.Scenario{
      name: "part2",
      job_name: "part2",
      function: #Function<1.24482852/0 in Day1.bench/1>,
      input_name: :__no_input,
      input: :__no_input,
      before_each: nil,
      after_each: nil,
      before_scenario: nil,
      after_scenario: nil,
      tag: nil,
      run_time_data: %Benchee.CollectionData{
        statistics: %Benchee.Statistics{
          average: 515458.31554249173,
          ips: 1940.0210838534142,
          std_dev: 51709.99708720266,
          std_dev_ratio: 0.1003184845951718,
          std_dev_ips: 194.61997521485722,
          median: 515791.0,
          percentiles: %{50 => 515791.0, 99 => 675963.88},
          mode: 529625,
          minimum: 418626,
          maximum: 828459,
          relative_more: 1.07600715630129,
          relative_less: 0.9293618487050216,
          absolute_difference: 36411.02247954527,
          sample_size: 19392
        },
        samples: [579292, 556958, 530375, 536667, 544751, 535208, 534083, 546791, 523708, 534418,
         566750, 521833, 530667, 558460, 521166, 534167, 562667, 526042, 535209, 586583, 524750,
         531166, 559250, 521460, 532959, 562667, 522416, 531667, 564460, 522417, 531583, 580458,
         ...]
      },
      memory_usage_data: %Benchee.CollectionData{
        statistics: %Benchee.Statistics{
          average: 621501.8539642745,
          ips: nil,
          std_dev: 13.550693713250404,
          std_dev_ratio: 2.180314286565158e-5,
          std_dev_ips: nil,
          median: 621504.0,
          percentiles: %{50 => 621504.0, 99 => 621504.0},
          mode: 621504,
          minimum: 621464,
          maximum: 621680,
          relative_more: 0.815730564229599,
          relative_less: 1.225894975437669,
          absolute_difference: -140394.14603572548,
          sample_size: 3191
        },
        samples: [621504, 621464, 621504, 621504, 621504, 621504, 621504, 621504, 621504, 621504,
         621504, 621504, 621504, 621504, 621504, 621504, 621504, 621504, 621464, 621504, 621504,
         621504, 621504, 621504, 621504, 621504, 621504, 621504, 621504, 621504, 621504, ...]
      },
      reductions_data: %Benchee.CollectionData{
        statistics: %Benchee.Statistics{
          average: nil,
          ips: nil,
          std_dev: nil,
          std_dev_ratio: nil,
          std_dev_ips: nil,
          median: nil,
          percentiles: nil,
          mode: nil,
          minimum: nil,
          maximum: nil,
          relative_more: nil,
          relative_less: nil,
          absolute_difference: nil,
          sample_size: 0
        },
        samples: []
      }
    }
  ]
}