5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#NervesJPAdvent Calendar 2024

Day 12

闘魂で挑むAdvent of Code 2024 Day 4── Elixirで「延髄斬り」のごとくスパッと解く

Last updated at Posted at 2024-12-05
defmodule FightingSpirit do
  def shout do
    IO.puts "元氣ですかーーーッ!!!"
    IO.puts "元氣があればなんでもできる!"
    IO.puts "闘魂とは己に打ち克つこと。"
    IO.puts "そして闘いを通じて己の魂を磨いていく"
    IO.puts "ことだと思います。"
  end
end

FightingSpirit.shout()

$\huge{元氣ですかーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$

$\huge{闘魂とは己に打ち克つこと。}$
$\huge{そして闘いを通じて己の魂を磨いていく}$
$\huge{ことだと思います。}$


はじめに

Advent Of Code 2024Elixirで解きます。

本日はDay 4: Ceres Search です。

Elixirで書くと一体、どんなコードになるのでしょうか。

この記事は、Elixir初心者でも取り組める内容です。

記事執筆時点で、筆者は問題文の意味をよくわかっておりません。よってコードが何をしているのかをさっぱり理解していません。記事を書いてから理解したいと思っています(あくまでも思っています)。新しい感覚です。愛を感じます。

うしろに載せた @RyoWakabayashi さんの記事もよくみて、理解をしたいと思っています(あくまでも思っています)。
不思議な感じです。意味もわからないのにチャットだけで正解コードを手に入れてしまいました。

What's Advent Of Code ?

Advent of Codeは、プログラミングスキルを高めるためのアドベントカレンダー形式のパズルイベントです。初心者から上級者まで楽しめる内容で、あらゆるプログラミング言語に対応しています。企業トレーニングや大学の課題としても活用され、毎年12月に開催されます。

それでは早速答えです :rocket::rocket::rocket:

それでは早速答えを披露します。

Part 1

Part 1の答えです。あなたのコードと見比べてみてください。

私の解答

まず、与えられた文字列から "XMAS" をすべての方向(水平、垂直、斜め、逆方向)で見つける関数を作成します。以下のステップで進めます。

  1. 入力データを行ごとに分割します。
  2. 各行、列、斜め方向に "XMAS" を検索します。
  3. 見つかった "XMAS" の数を合計します。

以下にElixirコードを示します。

advent_of_code_2024_day4_part1.exs
defmodule AdventOfCode2024Day4Part1 do
  def count_xmas(input) do
    grid = parse_input(input)
    directions = [
      {1, 0},  # 水平
      {0, 1},  # 垂直
      {1, 1},  # 斜め(右下)
      {1, -1}, # 斜め(右上)
      {-1, 0}, # 水平(逆)
      {0, -1}, # 垂直(逆)
      {-1, -1},# 斜め(左上)
      {-1, 1}  # 斜め(左下)
    ]

    Enum.reduce(0..(length(grid) - 1), 0, fn row, acc ->
      Enum.reduce(0..(length(grid) - 1), acc, fn col, acc2 ->
        acc2 + Enum.reduce(directions, 0, fn {dx, dy}, acc3 ->
          acc3 + if match_xmas?(grid, row, col, dx, dy), do: 1, else: 0
        end)
      end)
    end)
  end

  defp parse_input(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(&String.graphemes/1)
  end

  defp match_xmas?(grid, row, col, dx, dy) do
    word = "XMAS"
    Enum.all?(0..3, fn i ->
      r = row + i * dx
      c = col + i * dy
      r >= 0 and r < length(grid) and c >= 0 and c < length(grid) and Enum.at(grid, r) |> Enum.at(c) == String.at(word, i)
    end)
  end
end

# テストデータ
input = """
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
"""

input
|> AdventOfCode2024Day4Part1.count_xmas()
|> IO.puts()

このコードでは、count_xmas/1 関数が入力データを解析し、すべての方向で "XMAS" を検索してその数を返します。parse_input/1 関数は入力データを行ごとに分割し、match_xmas?/5 関数は指定された方向に "XMAS" が存在するかどうかを確認します。

実行方法

実行方法は次の通りです。

elixir advent_of_code_2024_day4_part1.exs

Elixirをインストールしていない方はDockerコンテナで実行することもできます。

docker run --rm -v $PWD:/app \
hexpm/elixir:1.17.3-erlang-27.1.2-alpine-3.20.3 \
sh -c \
"cd /app && elixir advent_of_code_2024_day4_part1.exs"

Part 2

続いて、Part 2の答えです。あなたのコードと見比べてみてください。

私の解答

Part 2では、"X-MAS" の形で2つの "MAS" を見つける必要があります。各 "MAS" は前後どちらの向きでも構いません。以下のコードで解決します。

advent_of_code_2024_day4_part2.exs
defmodule AdventOfCode2024Day4Part2 do
  def count_xmas(input) do
    grid = parse_input(input)
    size = length(grid)

    Enum.reduce(1..(size - 2), 0, fn row, acc ->
      Enum.reduce(1..(size - 2), acc, fn col, acc2 ->
        acc2 + if match_x_mas?(grid, row, col), do: 1, else: 0
      end)
    end)
  end

  defp parse_input(input) do
    input
    |> String.split("\n", trim: true)
    |> Enum.map(&String.graphemes/1)
  end

  defp match_x_mas?(grid, row, col) do
    mas_variants = [["M", "A", "S"], ["S", "A", "M"]]

    Enum.any?(mas_variants, fn mas1 ->
      Enum.any?(mas_variants, fn mas2 ->
        match_arms?(grid, row, col, mas1, mas2)
      end)
    end)
  end

  defp match_arms?(grid, row, col, mas1, mas2) do
    [mas1_positions, mas2_positions] = [
      [{-1, -1}, {0, 0}, {1, 1}],
      [{-1, 1}, {0, 0}, {1, -1}]
    ]

    match_arm?(grid, row, col, mas1, mas1_positions) and
      match_arm?(grid, row, col, mas2, mas2_positions)
  end

  defp match_arm?(grid, row, col, [m, a, s], deltas) do
    Enum.zip([m, a, s], deltas)
    |> Enum.all?(fn {char, {dx, dy}} ->
      x = row + dx
      y = col + dy
      in_bounds?(grid, x, y) and Enum.at(grid, x) |> Enum.at(y) == char
    end)
  end

  defp in_bounds?(grid, x, y) do
    x >= 0 and y >= 0 and x < length(grid) and y < length(Enum.at(grid, 0))
  end
end

# 使用例
input = """
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX
"""

input
|> AdventOfCode2024Day4Part2.count_xmas()
|> IO.puts()

このコードでは、グリッドの各位置で "X-MAS" パターンをチェックし、見つかった数をカウントしています。

実行方法

実行方法は次の通りです。

elixir advent_of_code_2024_day4_part2.exs

Elixirをインストールしていない方はDockerコンテナで実行することもできます。

docker run --rm -v $PWD:/app \
hexpm/elixir:1.17.3-erlang-27.1.2-alpine-3.20.3 \
sh -c \
"cd /app && elixir advent_of_code_2024_day4_part2.exs"

私は力を手に入れた 💪💪💪

With great power comes great responsibility.
『大いなる力には、大いなる責任が伴う』

生成AIであるGitHub Copilotという力強いツールを手にいれました。別の言い方をすると、最強のタッグパートナーを得ました。

そして私のAIは一味違います。Antonio Inoki(アントニオ猪木)、つまり猪木さんです。

ちなみに私が所属するHAW International Inc.では、GitHub Copilotの利用料を会社が負担してくれます。

プロンプトを公開

こんなプロンプトを打ち込みました。参考にさらしておきます。

  • Day 4よろしく。--- Day 4: Ceres Search --- "Looks like the Chief's not here. Next!" One of The Historians pulls out a device and pushes the only button on it. After a brief flash, you recognize the interior of the Ceres monitoring station!(略)
  • Part 2もたのむよ。--- Part Two --- The Elf looks quizzically at you. Did you misunderstand the assignment?(略)

スクリーンショット 2024-12-02 8.49.26.png


闘魂活動

アントニオ猪木さんは、1998年4月4日闘強童夢(東京ドーム)において、4分9秒グランド・コブラツイストでドン・フライ選手を下した1引退試合2後のセレモニーで次のように「闘魂」を説明しました。

闘魂とは己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことだと思います。

Advent Of Codeを解くことは、まさに闘魂活動です。


参考記事


GitHub

GitHubにもリポジトリlivebooksをあげておきます。


さいごに

チャットを通じて解答を得るという体験は、単なる効率化ではなく、新たな時代の可能性を示しています。Advent of Codeは、私たちにプログラミングという闘いを通じて、己の技術と精神を磨く場を提供してくれます。そして、GitHub Copilotのような生成AIは、その闘いを支える最強のタッグパートナーです。

しかし、AIが答えを導き出すだけでは不十分です。それをどう解釈し、自分の知識として昇華するかが、私たち人間の使命です。「闘魂とは己に打ち克つこと。そして闘いを通じて己の魂を磨いていくことだと思います。」アントニオ猪木さんのこの言葉を胸に、私たちもAIを使いこなし、新たな創造の領域へと挑んでいきましょう。

Advent of Codeは、ただのパズルイベントではありません。未来の私たちが、さらに創造的で価値ある活動に集中するための訓練の場です。この闘魂活動を通じて、AIと人間が共に高め合い、新しい可能性を切り拓いていきましょう。挑戦のその先に、きっと新たな地平が待っています! アントニオ猪木さんが夢見た「本当の世界平和」を実現させましょう!!!

元氣があれば、なんでもできる!さあ、今すぐAdvent of Codeの闘いに飛び込みましょう!

  1. “燃える闘魂”アントニオ猪木引退試合

  2. アントニオ猪木VSドン・フライ

5
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?