Day 5
Mix.install(
[
{:benchee, "~> 1.3"}
]
)
Setup
input =
System.fetch_env!("LB_AOC_DIR")
|> Path.join("data/day5.txt")
|> File.read!()
nil
nil
Solve
defmodule Day5 do
defp parse(input) do
[instructions, pages] = String.split(input, "\n\n")
instructions =
for instruction <- String.split(instructions, "\n") do
for i <- String.split(instruction, "|") do
String.to_integer(i)
end
end
|> MapSet.new()
pages =
for page <- String.split(pages, "\n"), page != "" do
for number <- String.split(page, ",") do
String.to_integer(number)
end
end
{instructions, pages}
end
@doc ~S"""
iex> Day5.part1("47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47\n")
143
"""
def part1(input) do
{instructions, pages} = parse(input)
for page <- pages, reduce: 0 do
sum ->
reordered = Enum.sort(page, &MapSet.member?(instructions, [&1, &2]))
if reordered == page do
middle = floor(length(page) / 2)
sum + Enum.at(page, middle)
else
sum
end
end
end
@doc ~S"""
iex> Day5.part2("47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47\n")
123
"""
def part2(input) do
{instructions, pages} = parse(input)
for page <- pages, reduce: 0 do
sum ->
reordered = Enum.sort(page, &MapSet.member?(instructions, [&1, &2]))
if reordered == page do
sum
else
middle = floor(length(reordered) / 2)
sum + Enum.at(reordered, middle)
end
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, Day5, <<70, 79, 82, 49, 0, 0, 18, ...>>, {:bench, 1}}
Day5.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 1.05 K 951.94 μs ±11.95% 928.92 μs 1141.02 μs
part2 1.05 K 955.29 μs ±18.72% 929.38 μs 1134.73 μs
Comparison:
part1 1.05 K
part2 1.05 K - 1.00x slower +3.36 μs
Memory usage statistics:
Name average deviation median 99th %
part1 722.37 KB ±0.00% 722.37 KB 722.41 KB
part2 722.61 KB ±0.00% 722.60 KB 722.65 KB
Comparison:
part1 722.37 KB
part2 722.61 KB - 1.00x memory usage +0.23 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.96581357/0 in Day5.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: 951935.9977145034,
ips: 1050.4907918188756,
std_dev: 113779.55023414688,
std_dev_ratio: 0.11952436981826449,
std_dev_ips: 125.55924989204077,
median: 928923.0,
percentiles: %{50 => 928923.0, 99 => 1141021.6599999995},
mode: 914257,
minimum: 869340,
maximum: 5411247,
relative_more: nil,
relative_less: nil,
absolute_difference: nil,
sample_size: 10501
},
samples: [1056758, 955257, 991423, 938757, 1022799, 955215, 936090, 968090, 937632, 954091,
916382, 915506, 913382, 911590, 978590, 1088508, 1003257, 925799, 972340, 929174, 1007174,
940965, 1184925, 997842, 1134841, 1063758, 1045507, 959965, 1031091, 1074592, 1420844,
964007, 1030092, ...]
},
memory_usage_data: %Benchee.CollectionData{
statistics: %Benchee.Statistics{
average: 739707.9061032864,
ips: nil,
std_dev: 13.127269633597354,
std_dev_ratio: 1.774655850679035e-5,
std_dev_ips: nil,
median: 739704.0,
percentiles: %{50 => 739704.0, 99 => 739752.0},
mode: 739704,
minimum: 739704,
maximum: 739752,
relative_more: nil,
relative_less: nil,
absolute_difference: nil,
sample_size: 1917
},
samples: [739704, 739704, 739704, 739704, 739704, 739704, 739704, 739704, 739704, 739704,
739704, 739752, 739704, 739704, 739752, 739704, 739704, 739704, 739704, 739704, 739752,
739704, 739704, 739704, 739752, 739704, 739704, 739704, 739704, 739704, 739752, 739704,
...]
},
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.96581357/0 in Day5.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: 955294.3271858576,
ips: 1046.7977999469945,
std_dev: 178817.49346367034,
std_dev_ratio: 0.18718575874980617,
std_dev_ips: 195.94564044070597,
median: 929382.0,
percentiles: %{50 => 929382.0, 99 => 1134730.78},
mode: 897048,
minimum: 871006,
maximum: 9666529,
relative_more: 1.0035278941855514,
relative_less: 0.9964845080978894,
absolute_difference: 3358.32947135414,
sample_size: 10465
},
samples: [1070466, 935548, 1003007, 973548, 970465, 971257, 976090, 998175, 942673, 967799,
919132, 912632, 921173, 920966, 985215, 942549, 964632, 947716, 903215, 927214, 911132,
989924, 942090, 954132, 931757, 915174, 911923, 954882, 983716, 945715, 956424, 915965,
...]
},
memory_usage_data: %Benchee.CollectionData{
statistics: %Benchee.Statistics{
average: 739947.9979434448,
ips: nil,
std_dev: 13.266809195171335,
std_dev_ratio: 1.7929380486255923e-5,
std_dev_ips: nil,
median: 739944.0,
percentiles: %{50 => 739944.0, 99 => 739992.0},
mode: 739944,
minimum: 739944,
maximum: 739992,
relative_more: 1.0003245765499833,
relative_less: 0.9996755287657705,
absolute_difference: 240.09184015833307,
sample_size: 1945
},
samples: [739944, 739944, 739944, 739944, 739944, 739944, 739944, 739944, 739944, 739944,
739944, 739992, 739992, 739944, 739944, 739944, 739944, 739992, 739944, 739944, 739992,
739944, 739944, 739944, 739944, 739944, 739944, 739944, 739944, 739944, 739944, ...]
},
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: []
}
}
]
}