Day 13 Part 1
This commit is contained in:
parent
4e2dd439f3
commit
37d5a57f5f
1 changed files with 133 additions and 0 deletions
133
2020/day13/day13.ex
Normal file
133
2020/day13/day13.ex
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
defmodule Numbers do
|
||||
use GenServer
|
||||
|
||||
def start_link do
|
||||
primes = [2, 3]
|
||||
max_n = 2
|
||||
GenServer.start_link(__MODULE__, {primes, max_n})
|
||||
end
|
||||
|
||||
def is_prime?(pid, n) do
|
||||
GenServer.call(pid, {:is_prime?, n})
|
||||
end
|
||||
|
||||
def primes_up_to(pid, n) do
|
||||
GenServer.call(pid, {:up_to, n})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(primes) do
|
||||
{:ok, primes}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call({:is_prime?, n}, _from, {primes, max_n}) do
|
||||
IO.inspect({:is_prime?, n, {primes, max_n}})
|
||||
{ans, {primes, max_n}} = check_prime(n, {primes, max_n})
|
||||
{:reply, ans, {primes, max_n}}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call({:up_to, n}, _from, {primes, max_n}) do
|
||||
{ans, {primes, max_n}} = gen_primes(n, {primes, max_n})
|
||||
{:reply, ans, {primes, max_n}}
|
||||
end
|
||||
|
||||
defp check_prime(n, {primes, max_n}) do
|
||||
if n / 2 <= max_n do
|
||||
{Enum.member?(primes, n), {primes, max_n}}
|
||||
else
|
||||
possible_factors = primes ++ Enum.to_list((max_n + 1)..div(n, 2))
|
||||
has_factor = Enum.any?(possible_factors, &(rem(n, &1) == 0))
|
||||
{!has_factor, {primes, max_n}}
|
||||
end
|
||||
end
|
||||
|
||||
defp gen_primes(n, {primes, max_n}) do
|
||||
if n <= max_n do
|
||||
{Enum.filter(primes, &(&1 <= n)), {primes, max_n}}
|
||||
else
|
||||
new_primes =
|
||||
Enum.reduce((max_n + 1)..n, primes, fn p, primes ->
|
||||
{is_prime, {primes, _}} = check_prime(p, {primes, p - 1})
|
||||
|
||||
if is_prime do
|
||||
primes ++ [p]
|
||||
else
|
||||
primes
|
||||
end
|
||||
end)
|
||||
|
||||
{new_primes, {new_primes, n}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Day13 do
|
||||
defp read_input do
|
||||
Path.expand('input', Path.dirname(__ENV__.file))
|
||||
|> File.read!()
|
||||
end
|
||||
|
||||
defp test_input do
|
||||
"""
|
||||
939
|
||||
7,13,x,x,59,x,31,19
|
||||
"""
|
||||
end
|
||||
|
||||
defp parse_int(val, default) do
|
||||
try do
|
||||
String.to_integer(val)
|
||||
rescue
|
||||
ArgumentError -> default
|
||||
end
|
||||
end
|
||||
|
||||
defp parse_schedule(text) do
|
||||
[line_1, line_2] = String.split(text, "\n", trim: true)
|
||||
timestamp = String.to_integer(line_1)
|
||||
|
||||
bus_ids =
|
||||
String.split(line_2, ",")
|
||||
|> Enum.map(&parse_int(&1, nil))
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
{timestamp, bus_ids}
|
||||
end
|
||||
|
||||
# defp lcm(a, b, numbers) do
|
||||
# bag_union(factors(a, numbers), factors(b, numbers))
|
||||
# end
|
||||
|
||||
# defp factors(n, numbers) do
|
||||
# Numbers.primes_up_to(numbers, div(n, 2))
|
||||
# |> Enum.reduce(2..n, {n, %{}}, fn )
|
||||
# end
|
||||
|
||||
# defp bag_union(b1, b2) do
|
||||
# Enum.reduce(b1, b2, fn {k, v}, bag ->
|
||||
# Map.put(bag, k, max(v, Map.get(bag, k, 0)))
|
||||
# end)
|
||||
# end
|
||||
|
||||
defp first_multiple_after(timestamp, bus_id) do
|
||||
if rem(timestamp, bus_id) == 0 do
|
||||
timestamp
|
||||
else
|
||||
bus_id * (div(timestamp, bus_id) + 1)
|
||||
end
|
||||
end
|
||||
|
||||
def part1 do
|
||||
{timestamp, bus_ids} = read_input() |> parse_schedule()
|
||||
|
||||
{bus_id, time} =
|
||||
Enum.map(bus_ids, &{&1, first_multiple_after(timestamp, &1)})
|
||||
|> Enum.min_by(fn {_, time} -> time end)
|
||||
|
||||
bus_id * (time - timestamp)
|
||||
end
|
||||
end
|
||||
|
||||
Day13.part1() |> IO.inspect()
|
||||
Loading…
Reference in a new issue