-
-
Save kwando/e77830299ae6b3c1f1944d3fdc7ed455 to your computer and use it in GitHub Desktop.
AoC 2017 Day 15
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule AoC.Generators do | |
defmodule Generator do | |
def next({impl, args}) when is_atom(impl) do | |
{value, gen} = impl.next(args) | |
{value, {impl, gen}} | |
end | |
end | |
defmodule StandardGenerator do | |
@divisor 2147483647 | |
def new(seed, factor) do | |
{__MODULE__, {seed, factor}} | |
end | |
def next({previous_value, factor}) do | |
new_value = rem(previous_value * factor, @divisor) | |
{new_value, {new_value, factor}} | |
end | |
end | |
defmodule PickyGenerator do | |
def new(factor, generator) do | |
{__MODULE__, {factor - 1, {factor, generator}}} | |
end | |
def next({previous_value, {factor, generator}}) do | |
{value, generator} = get_next(factor, generator) | |
{value, {value, {factor, generator}}} | |
end | |
defp get_next(factor, generator) do | |
{value, generator} = Generator.next(generator) | |
get_next(factor, generator, value) | |
end | |
defp get_next(factor, generator, value) when rem(value, factor) == 0 do | |
{value, generator} | |
end | |
defp get_next(factor, generator, _), do: get_next(factor, generator) | |
end | |
defmodule Matcher do | |
use Bitwise | |
def score(value1, value2) when (value1 &&& 65535) == (value2 &&& 65535) do | |
1 | |
end | |
def score(_, _), do: 0 | |
end | |
def compare(genA, genB, opts) do | |
iterations = Keyword.get(opts, :iterations, 40_000_000) | |
initial_state = {genA, genB, 0} | |
|> IO.inspect(label: "initial state") | |
matches = count_matches(initial_state, iterations) | |
|> IO.inspect(label: "match count") | |
end | |
defp count_matches({_, _, matches}, 0), | |
do: matches | |
defp count_matches({genA, genB, matches}, n) do | |
{valueA, genA} = Generator.next(genA) | |
{valueB, genB} = Generator.next(genB) | |
{ | |
genA, | |
genB, | |
matches + Matcher.score(valueA, valueB) | |
} | |
|> count_matches(n - 1) | |
end | |
end | |
alias AoC.Generators.{Generator, PickyGenerator, StandardGenerator} | |
AoC.Generators.compare(StandardGenerator.new(65, 16807), StandardGenerator.new(8921, 48271), iterations: 40_000_000) | |
AoC.Generators.compare( | |
StandardGenerator.new(618, 16807), | |
StandardGenerator.new(814, 48271), | |
[ | |
iterations: 40_000_000 | |
]) | |
AoC.Generators.compare( | |
PickyGenerator.new(4, StandardGenerator.new(618, 16807)), | |
PickyGenerator.new(8, StandardGenerator.new(814, 48271)), | |
[ | |
iterations: 5_000_000 | |
]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment