$\huge{元氣ですかーーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$
$\huge{闘魂とは己に打ち克つこと。}$
$\huge{そして闘いを通じて己の魂を磨いていく}$
$\huge{ことだと思います}$
はじめに
今年もいよいよやってまいりました!
Elixirで、Advent of code 2023の問題を解いてみます。
1日1題ずつ問題が出題されます。
実行時間は問われません。
What is Elixir ?
Elixirという素敵なプログラミング言語があるのですね。
その素敵具合は「Elixir Saves Pinterest $2 Million a Year In Server Costs」によく現れています。開発者も経営者もこの事実に瞠目することでしょう。 $2 Million/年の節約ですってよ!、奥さん。
Day 8: Haunted Wasteland
Day 8: Haunted Wastelandを解いてみます。
問題はリンク先をご参照ください。
Google翻訳を使って問題を理解しました。
英文が(私にとって長く)なかなか意味がわかりませんでした。
Part 1は普通にやったら解けて、Part 2は普通にやったら30分実行しても終わらないプログラムになってしまいひと工夫が必要でした。
あー、そういえばPart 1もはじまりがAAA
ということを理解できていませんでした。先頭行からだとおもいこんでいました。
2つともどうやって解決したかというと他の方の解答(Python)を見て解決しました。
この場をお借りして御礼申し上げます。
ありがとうーーーーッ!!! ございます。
私の答え Part 1
私の答えです。
折りたたんでおきます。
▶を押して開いてください。
私の答え
input = """
RL
AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
EEE = (EEE, EEE)
GGG = (GGG, GGG)
ZZZ = (ZZZ, ZZZ)
"""
defmodule Awesome do
def run(input) do
instructions = parse_instructions(input)
nodes = parse_nodes(input)
solve(instructions, nodes)
end
defp solve(instructions, nodes) do
Stream.cycle(instructions)
|> Enum.reduce_while({"AAA", 0}, fn instruction, {node, acc} ->
new_node = get_in(nodes, [node, instruction])
{halt_or_cont(new_node), {new_node, acc + 1}}
end)
|> elem(1)
end
defp halt_or_cont("ZZZ"), do: :halt
defp halt_or_cont(_), do: :cont
defp parse_instructions(input) do
input
|> String.split("\n\n", trim: true)
|> Enum.at(0)
|> String.to_charlist()
end
defp parse_nodes(input) do
input
|> String.split("\n\n", trim: true)
|> Enum.at(1)
|> String.split("\n", trim: true)
|> Enum.reduce(%{}, fn s, acc ->
key = String.slice(s, 0, 3)
l = String.slice(s, 7, 3)
r = String.slice(s, 12, 3)
Map.merge(acc, %{key => %{?L => l, ?R => r}})
end)
end
end
Awesome.run(input)
私の答え Part 2
私の答えです。
折りたたんでおきます。
▶を押して開いてください。
私の答え
末尾がZ
でおわる文字列のパターンマッチについては以下の記事の知見を活かしています。
闘魂Elixir ── "闘魂"とは<<0xE99798::24, 0xE9ad82::24>>である
input = """
LR
11A = (11B, XXX)
11B = (XXX, 11Z)
11Z = (11B, XXX)
22A = (22B, XXX)
22B = (22C, 22C)
22C = (22Z, 22Z)
22Z = (22B, 22B)
XXX = (XXX, XXX)
"""
defmodule Awesome2 do
def run(input) do
instructions = parse_instructions(input)
nodes = parse_nodes(input)
solve(instructions, nodes)
end
defp solve(instructions, nodes) do
nodes
|> Enum.filter(fn {node, _} -> String.ends_with?(node, "A") end)
|> Enum.map(fn {node, _} ->
Stream.cycle(instructions)
|> Enum.reduce_while({node, 0}, fn instruction, {current_node, acc} ->
new_node = get_in(nodes, [current_node, instruction])
{halt_or_cont(new_node), {new_node, acc + 1}}
end)
|> elem(1)
end)
|> Enum.reduce(1, &lcm/2)
end
defp lcm(a, b), do: div(a * b, Integer.gcd(a, b))
defp halt_or_cont(<<_, _, ?Z>>), do: :halt
defp halt_or_cont(_), do: :cont
defp parse_instructions(input) do
input
|> String.split("\n\n", trim: true)
|> Enum.at(0)
|> String.to_charlist()
end
defp parse_nodes(input) do
input
|> String.split("\n\n", trim: true)
|> Enum.at(1)
|> String.split("\n", trim: true)
|> Enum.reduce(%{}, fn s, acc ->
key = String.slice(s, 0, 3)
l = String.slice(s, 7, 3)
r = String.slice(s, 12, 3)
Map.merge(acc, %{key => %{?L => l, ?R => r}})
end)
end
end
Awesome2.run(input)
解けました
I just completed "Haunted Wasteland" - Day 8 - Advent of Code 2023 https://t.co/vOUUHHmkiO #AdventOfCode
— TORIFUKU Kaiou (@torifukukaiou) December 8, 2023
さいごに
Advent of code 2023のDay 8: Haunted WastelandをElixirで解きました。
Advent of code 2023は己との闘い、まさに闘魂です。
リポジトリにあげておきます。
人類は不老不死の霊薬を意味する素敵なプログラミング言語Elixirを手に入れました。並行処理を他のプログラミング言語よりも比較的容易に書くことができます。それはきっとコンピュータ資源を有効活用できることにつながるでしょう。巡り巡って世界平和に貢献できることでしょう。
さあ、そこのあなたもElixirの世界へようこそ。
手始めにエリクサーチなんていかがでしょうか。私のオススメです。
闘魂とは、 「己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことである」 との猪木さんの言葉をそのまま胸に刻み込んでいます。
知っているだけで終わらせることなく、実行する、断行する、一歩を踏み出すことを自らの行動で示していきたいとおもいます。
アントニオ猪木さんのメッセージから元氣をもらったものとして、それを次代に語り継ぎ、自分自身が「闘魂」を体現するものでありたいとおもいます。
$\huge{元氣ですかーーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$
$\huge{1、2、3 ぁっダァー!}$