diff --git a/lib/day15/day15.ex b/lib/day15/day15.ex new file mode 100644 index 0000000..02d9671 --- /dev/null +++ b/lib/day15/day15.ex @@ -0,0 +1,135 @@ +defmodule Day15 do + def part1(example \\ false) do + find_number_spoken_at(example, 2020) + end + + def part2(example \\ false) do + find_number_spoken_at(example, 30_000_000) + end + + def find_number_spoken_at(example, final_turn) do + inputs = parse_input(example) + + # inputs + # |> Enum.reverse() + # |> step_times(final_turn - length(inputs)) + # |> List.first() + + # numbers = parse_input(example) + + inputs + |> Enum.with_index() + |> Enum.map(fn {e, i} -> {e, i + 1} end) + |> Map.new() + |> do_van_eck(List.last(inputs), length(inputs) + 1, final_turn) + + # |> step_until_turn(final_turn, length(numbers) + 1) + # |> what_was_spoken_on_turn(final_turn) + end + + def parse_input(example) do + case example do + 1 -> "0,3,6" + 2 -> "1,3,2" + 3 -> "2,1,3" + 4 -> "1,2,3" + 5 -> "2,3,1" + 6 -> "3,2,1" + 7 -> "3,1,2" + _ -> "9,12,1,4,17,0,18" + end + |> String.split(",") + |> Enum.map(&String.to_integer/1) + end + + def do_van_eck(_, prev, turn, count) when turn == count + 1 do + prev + end + + def do_van_eck(map, prev, turn, count) do + # IO.inspect(map) + + new_val = + if Map.has_key?(map, prev) do + turn - map[prev] + else + 0 + end + + # IO.inspect(map) + IO.puts("turn: #{turn} \tprev: #{prev} \tnew: #{new_val}") + + do_van_eck(Map.put(map, prev, turn - 1), new_val, turn + 1, count) + end + + def step_van_eck([prev | rest] = sequence) do + next = + case Enum.find_index(rest, &(&1 == prev)) do + nil -> 0 + index_in_rest -> index_in_rest + 1 + end + + [next | sequence] + end + + def step_times(sequence, 0) do + sequence + end + + def step_times(sequence, count) do + step_times(step_van_eck(sequence), count - 1) + end + + # def step(map, turn) do + # # IO.puts("current turn: #{turn}") + + # {prev_spoken, prev_spoken_on_turns} = what_was_spoken_on_turn(map, turn - 1) + + # # IO.puts("prev spoken: #{prev_spoken}") + # # IO.puts("prev spoken on turns: #{inspect(prev_spoken_on_turns)}") + + # number_to_speak = + # case prev_spoken_on_turns do + # [_] -> + # 0 + + # [most_recent, second_most_recent | _] -> + # most_recent - second_most_recent + # # List.last(prev_spoken_on_turns) - Enum.at(prev_spoken_on_turns, -2) + # end + + # # IO.puts("will speak #{number_to_speak}") + + # Map.update(map, number_to_speak, [turn], fn turns -> [turn | turns] end) + # end + + # def step_until_turn(map, final_turn, turn) when final_turn + 1 == turn do + # map + # end + + # def step_until_turn(map, final_turn, turn) do + # # IO.inspect(map) + # step_until_turn(step(map, turn), final_turn, turn + 1) + # end + + # # def step(numbers, turn) do + # # # prev = Map.get(map, cur - 1) + # # {prev, prev_turn} = Enum.find(numbers, &(elem(&1, 1) == turn - 1)) + + # # IO.puts("turn #{turn}") + # # IO.puts("prev #{prev}") + + # # new = + # # case Enum.find(numbers, &(elem(&1, 0) == prev)) |> IO.inspect() do + # # nil -> 0 + # # {_, ^prev_turn} -> 0 + # # {_, last_spoken_turn} -> turn - last_spoken_turn + # # end + + # # # IO.inspect({prev, new}) + # # IO.puts("speak #{new}") + + # # [{new, turn} | Enum.reject(numbers, fn {n, _} -> n == new end)] + # # |> IO.inspect() + # # end +end diff --git a/lib/day15/test.swift b/lib/day15/test.swift new file mode 100644 index 0000000..83a7993 --- /dev/null +++ b/lib/day15/test.swift @@ -0,0 +1,22 @@ +import Foundation + +func vanEckSequence(start: [Int], maxLength: Int) -> [Int] { + let toCompute = maxLength - start.count + var seq = start + Array(repeating: 0, count: toCompute) + // print(seq.count) + + for i in start.count..