$\huge{元氣ですかーーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$
$\huge{闘魂とは己に打ち克つこと。}$
$\huge{そして闘いを通じて己の魂を磨いていく}$
$\huge{ことだと思います}$
はじめに
@torifukukaiou さんの パク リスペクト記事です
Elixir Livebook で Advent of Code 2023 の問題を解いてみます
実装したノートブックはこちら
問題はこちら
Part 1 はこちら
セットアップ
Kino AOC をインストールします
Mix.install([
{:kino_aoc, "~> 0.1.5"}
])
Kino AOC の使い方はこちらを参照
入力の取得
Day 3 の入力を取得します
私の答え
私の答えです。
折りたたんでおきます。
▶を押して開いてください。
details
回答用のモジュールです
入力を扱いやすい形にするための parse
と、回答を作るための resolve
関数を持っています
defmodule Resolver do
def parse(input) do
parsed_input =
input
|> String.split("\n")
|> Enum.with_index()
|> Enum.map(fn {line, row_index} ->
number = Regex.scan(~r/[0-9]+/, line)
number_index = Regex.scan(~r/[0-9]+/, line, return: :index)
symbol = Regex.scan(~r/[^0-9\.]+/, line)
symbol_index = Regex.scan(~r/[^0-9\.]+/, line, return: :index)
numbers =
Enum.zip(number_index, number)
|> Enum.into(%{}, fn {[{col_index, length}], [number]} ->
{{row_index, col_index, length}, String.to_integer(number)}
end)
symbols =
Enum.zip(symbol_index, symbol)
|> Enum.into(%{}, fn {[{col_index, length}], [symbol]} ->
{{row_index, col_index, length}, symbol}
end)
%{
numbers: numbers,
symbols: symbols
}
end)
numbers =
parsed_input
|> Enum.reduce(%{}, fn line, acc ->
Map.merge(acc, line.numbers)
end)
symbols =
parsed_input
|> Enum.reduce(%{}, fn line, acc ->
Map.merge(acc, line.symbols)
end)
{numbers, symbols}
end
def resolve(numbers, symbols) do
symbols
|> Enum.map(fn {{sym_row_index, sym_col_index, _sym_length}, _symbol} ->
adjacents = Enum.filter(numbers, fn {{num_row_index, num_col_index, num_length}, _number} ->
sym_row_index >= num_row_index - 1 and \
sym_row_index <= num_row_index + 1 and \
sym_col_index >= num_col_index - 1 and \
sym_col_index <= num_col_index + num_length
end)
if Enum.count(adjacents) > 1 do
adjacents
|> Enum.map(fn {_, number} -> number end)
|> Enum.product()
else
0
end
end)
|> Enum.sum()
end
end
parse
は Part 1 と同じです
数字と記号について座標と値のマップとして読み込みます
resolve
関数では、記号毎に隣接する数字を取得して、二つ以上あれば積を返し、そうでなければ 0 を返します
全ての記号について合計すると答えです
symbols
|> Enum.map(fn {{sym_row_index, sym_col_index, _sym_length}, _symbol} ->
adjacents = Enum.filter(numbers, fn {{num_row_index, num_col_index, num_length}, _number} ->
sym_row_index >= num_row_index - 1 and \
sym_row_index <= num_row_index + 1 and \
sym_col_index >= num_col_index - 1 and \
sym_col_index <= num_col_index + num_length
end)
if Enum.count(adjacents) > 1 do
adjacents
|> Enum.map(fn {_, number} -> number end)
|> Enum.product()
else
0
end
end)
まとめ
入力をパースできてさえしまえば、その後はほぼ自動的に解けますね