$\huge{元氣ですかーーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$
$\huge{闘魂とは己に打ち克つこと。}$
$\huge{そして闘いを通じて己の魂を磨いていく}$
$\huge{ことだと思います}$
はじめに
@torifukukaiou さんの パク リスペクト記事です
Elixir Livebook で Advent of Code 2023 の問題を解いてみます
実装したノートブックはこちら
問題はこちら
セットアップ
Kino AOC をインストールします
Mix.install([
{:kino_aoc, "~> 0.1.5"}
])
Kino AOC の使い方はこちらを参照
入力の取得
Day 4 の入力を取得します
私の答え
私の答えです。
折りたたんでおきます。
▶を押して開いてください。
details
回答用のモジュールです
入力を扱いやすい形にするための parse
と、回答を作るための resolve
関数を持っています
defmodule Resolver do
def parse(input) do
input
|> String.split("\n")
|> Enum.map(fn line ->
[_, card] = String.split(line, ":")
[winning_card, my_card] = String.split(card, "|")
%{
winning_card: parse_card(winning_card),
my_card: parse_card(my_card)
}
end)
end
defp parse_card(card) do
card
|> String.split(" ")
|> Enum.filter(fn value -> value != "" end)
|> Enum.map(fn value -> String.to_integer(value) end)
end
def resolve(games) do
games
|> Enum.map(fn %{winning_card: winning_card, my_card: my_card} ->
winning_card
|> Enum.count(fn winnig_number ->
Enum.member?(my_card, winnig_number)
end)
|> get_point()
end)
|> Enum.sum()
end
defp get_point(0), do: 0
defp get_point(1), do: 1
defp get_point(nuber_of_matches) do
0..(nuber_of_matches - 2)
|> Enum.map(&Integer.pow(2, &1))
|> Enum.sum()
|> Kernel.+(1)
end
end
parse
では、数字をスペース区切りした後、空文字を除いてカードの数字を読み取っています
defp parse_card(card) do
card
|> String.split(" ")
|> Enum.filter(fn value -> value != "" end)
|> Enum.map(fn value -> String.to_integer(value) end)
end
resolve
では Enum.member?
を使うことで、当選番号が自分のカードに含まれているかを検査しています
get_point
関数でマッチした数をポイントに変換します
defp get_point(0), do: 0
defp get_point(1), do: 1
defp get_point(nuber_of_matches) do
0..(nuber_of_matches - 2)
|> Enum.map(&Integer.pow(2, &1))
|> Enum.sum()
|> Kernel.+(1)
end
ポイントはマッチ数が 0 のとき 0、 1 のとき 1 で、それ以上では以下の数式で表されます
$$
p = 1 + \sum_{k=0}^{m-2}2^k
$$
(p: ポイント、 m: マッチ数)
まとめ
ポイントの説明が分かりにくかったので最初戸惑いましたが、理解できれば実装は単純ですね
Part 2 はこちら