闘魂プログラミング（ストロングスタイル）をElixirで楽しむ！

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>

<b><font color="red">$\huge{闘魂とは、己に打ち克つこと。}$</font></b>
<b><font color="red">$\huge{そして、闘いを通じて己の魂を磨いていく}$</font></b>
<b><font color="red">$\huge{ことだと思います}$</font></b>


# はじめに

アントニオ猪木さんは、[1998-04-04引退試合](https://njpwworld.com/p/s_series_00151_1_01)でドン・フライを4分9秒グラウンドコブラツイストで破ったあとの引退セレモニーで次のように述べられています。

「わたしは色紙に、いつの日か闘魂という文字を書くようになりました。それを称して、ある人が『燃える闘魂』と名づけてくれました。**闘魂とは、己に打ち克つこと。そして、闘いを通じて己の魂を磨いていくこと**だと思います」

**闘魂とは、己に打ち克つこと。そして、闘いを通じて己の魂を磨いていくこと** です。
将棋の大山康晴永世名人流に言うと、**克己** です。
王陽明先生流に言うと、 **山中の賊を破るは易く、心中の賊を破るは難し** です。
稲盛和夫師流に言うと、 **[燃える闘魂](https://www.kyocera.co.jp/inamori/management/twelve/twelve08.html)** です。

https://mainichibooks.com/books/business/post-433.html

この記事では、**闘魂プログラミング** をしてみます。
わたしは、[Elixir](https://elixir-lang.org/)で楽しみます。

:::note info
闘魂とは、己に打ち克つこと。そして、闘いを通じて己の魂を磨いていくこと
:::

# **闘魂プログラミング**

関数を呼び出すときに、 `"闘魂"` を指定（注入）しないと動作しないようにします。
`"闘魂"` の指定を必須とします。

[Elixir](https://elixir-lang.org/)での例を示します。

```elixir
iex> Inoki.Enum.map(1..3, & &1 * 2)         
** (UndefinedFunctionError) function Inoki.Enum.map/2 is undefined or private. Did you mean:

      * map/3

    Inoki.Enum.map(1..3, #Function<42.3316493/1 in :erl_eval.expr/6>)
    iex:57: (file)
```

`"闘魂"` を指定（注入）しないので、エラーがでています。
`"闘魂"` を指定（注入）すると正しく動きます :tada::tada::tada: 

```elixir
Inoki.Enum.map(1..3, & &1 * 2, "闘魂")
[2, 4, 6]
```

関数の定義はどうなっているかというと、次のようになっています。

```elixir
defmodule Inoki.Enum do
  def map(enumerable, fun, "闘魂"), do: Enum.map(enumerable, fun)
end
```

[Enum](https://hexdocs.pm/elixir/Enum.html#content)モジュールをラップしているだけです。

第3引数に`"闘魂"`を必ず指定しないといけないわけです。
これを
<b><font color="black">$\huge{ストロングスタイル}$</font></b>
といいます。

:::note alert
ウソデス
:::

# `"闘魂"`を指定（注入）しないと動かない関数をつくる

:::note info
この記事のポイントです。一丁目一番地です。
:::


全部手で書くのは辛いのでちょっと楽をします。
以下の２つを使います。

- [Module.\_\_info\_\_/1](https://hexdocs.pm/elixir/Module.html#c:__info__/1)
- [Code.eval_string/3](https://hexdocs.pm/elixir/Code.html#eval_string/3)

[Module.\_\_info\_\_/1](https://hexdocs.pm/elixir/Module.html#c:__info__/1)を使うと、関数の一覧が得られます。
たとえば[Enum](https://hexdocs.pm/elixir/Enum.html#content)モジュールの場合は以下のような結果が得られます。

```elixir
iex> Enum.__info__(:functions)
[
  all?: 1,
  all?: 2,
  any?: 1,
  any?: 2,
  at: 2,
  at: 3,
  ...
]
```

[Code.eval_string/3](https://hexdocs.pm/elixir/Code.html#eval_string/3)は、文字列を[Elixir](https://elixir-lang.org/)のコードとして解釈、実行してくれます。
たとえば、 `"1 + 2"` を実行してみます。

```elixir
iex> Code.eval_string "1 + 2"
{3, []}
```

ここまで書けばカンのいい方はもうお分かりですよね。

必ず`"闘魂"`を指定する必要がある関数群で構成されたモジュールを文字列で作って、[Code.eval_string/3](https://hexdocs.pm/elixir/Code.html#eval_string/3)を実行すればよいわけです。

無名関数に`binta`という名前をつけてみます。
闘魂注入といえばやはりビンタです。

```elixir
binta = fn mod ->
  short_mod = "#{mod}" |> String.split(".") |> Enum.at(-1)

  args = fn arity, add_args ->
    "#{1..arity//1 |> Enum.map(&"a#{&1}") |> Kernel.++(add_args) |> Enum.join(",")}"
  end

  funs =
    mod.__info__(:functions)
    |> Enum.map(fn {name, arity} ->
      """
      def #{name}(#{args.(arity, ["\"闘魂\""])}), do: #{short_mod}.#{name}(#{args.(arity, [])})
      """
    end)
    |> Enum.join("\n")

  """
  defmodule Inoki.#{short_mod} do
    #{funs}
  end
  """
  |> Code.eval_string()
end
```

使い方は、`binta.(Enum)`です。
`Inoki.Enum`モジュールが手に入ります。

```elixir
iex> Inoki.Enum.map(0..2, & &1 + 1)
** (UndefinedFunctionError) function Inoki.Enum.map/2 is undefined or private. Did you mean:

      * map/3

    Inoki.Enum.map(0..2, #Function<42.3316493/1 in :erl_eval.expr/6>)
    iex:66: (file)

iex> Inoki.Enum.map(0..2, & &1 + 1, "闘魂")
[1, 2, 3]
```

説明が前後しますが以下のような`Inoki.Enum`モジュールの定義を文字列で作っています。

```elixir
defmoudle Inoki.Enum do
  def all?(a1, "闘魂"), do: Enum.all?(a1)
  def all?(a1, a2, "闘魂"), do: Enum.all?(a1, a2)
  ...
  def map(a1, a2, "闘魂"), do: Enum.map(a1, a2)
  ...
end
```

できあがった文字列を[Code.eval_string/3](https://hexdocs.pm/elixir/Code.html#eval_string/3)に渡して実行することで、`Inoki.Enum`モジュールが手に入るわけです。


# **闘魂**プログラミングは何の役に立つのか?

役に立つことはありません。
趣味です。

否、役に立つことがあるかもしれません。

迂遠なようではありますが、有形無形になにかの役に立っているかもしれません。
少なくともわたしはこの記事を書くことを楽しみましたし、この記事がどなたか天才の頭脳を刺激して、すごいものがうみ出されるかもしれません。

楽しみです。ワクワクです。

# 闘魂は連鎖する！

1998-04-04、アントニオ猪木さんがドン・フライを4分9秒グラウンドコブラツイストで破った[引退試合](https://njpwworld.com/p/s_series_00151_1_01)のあとで行われたセレモニーで、古舘伊知郎アナウンサーは次のように言いました。

闘う旅人、アントニオ猪木。
いま相手のいないリングに猪木はたった一人で佇んでいます。
おもえば38年におよぶプロレス人生。旅から旅への連続であり、そして猪木の精神も旅の連続であった。
安住の場所を嫌い、突き進んでは出口を求め、飛び出しては次なる場所に歩を進める。
どん底からの新日旗揚げ、世界王者とのストロングマッチ、大物日本人対決、格闘技世界一決定戦、IWGP、巌流島、人質解放、国会に卍固め、魔性のスリーパー。
決して人生に保険をかけることなく、その刹那、刹那を燃やし尽くせばよいという生き様。
猪木はこのあとの旅はどの方角に舵をとろうというのか。
一人ひとりのいま、ファンの胸には、どんな闘いの情景が映し出されているか。
猪木はすべての人間が内包している闘う魂をリング上で代演する宿命にあった。
我々は猪木が闘いの果てにみせる表情に己自身を投影させてきたのだ。
しかし、この瞬間をもって猪木はリングから姿を消す。
我々はどうやって今後、火を灯していけばいいのか。
物質に恵まれた世紀末、商業主義に踊る世紀末、情報が豊かでとても心が貧しい世の中、一人で闘うことを忘れかけた人々。
もう我々は闘魂に癒やされながら時代の砂漠をさまよってはいられない。
我々は今日をもって猪木から自立しなければいけない。
闘魂のかけらを携え、今度は我々が旅に出る番だ。
**闘魂は連鎖する！**

1943年2月20日、鶴見に生まれし一人の<ruby>漢<rp>(</rp><rt>おのこ</rt><rp>)</rp></ruby>姓名猪木寛至闘魂の火種。
あなたを見続けることができたことを光栄におもいます。
燃える闘魂に感謝。
ありがとう！　アントニオ猪木!

---

猪木さんの活躍がぎゅっと詰まっています。


# 闘魂を連鎖する！

わたしは「闘魂を連鎖させたい」とおもっています。
しかしながらわたしは、色紙を頼まれることはありません。

そこでインターネットの大地に、**闘魂** を掘るように刻み込んでいるのです。
他には、年賀状に **闘魂** を揮毫しています。年賀状はチャンスが年に一回です。
「とうこん（**闘魂**）」と「とうこう(投稿)」は音にすると一字違いです。わたしは、記事を **闘魂** しています。話し言葉では、こっそり「とうこう」を「とうこん」と発しています。
他には自分が主催するコミュニティチャンネルに毎朝、 **闘魂** を発信しています。
**闘魂** を書く機会がないのなら、嘆く前に自分でその機会を作ればいいのです。これこそ **闘魂** です。己との闘いです。

![スクリーンショット 2023-01-28 18.40.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/a11445f2-be92-2651-0054-9e9d9b5c5fb4.png)




**闘魂プログラミング** をすると自然と、 **闘魂** に接する機会が増えます。

「**闘魂とは、己に打ち克つこと。そして、闘いを通じて己の魂を磨いていくこと**」を胸に刻みながら、**闘魂プログラミング**をしています。
こうした投稿（**闘魂**）が増えることが、闘魂が連鎖することにつながるとおもいます。
世界文化の進展に寄与するものとおもいます。

Googleや[OpenAI](https://openai.com/)に、**闘魂**をたくさん学んでもらいましょう。

# AtCoderを解く

問題は[B - Shift only](https://atcoder.jp/contests/abc081/tasks/abc081_b)を解いてみます。
この問題は、「[AtCoder Beginners Selection](https://atcoder.jp/contests/abs)」、「[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)」に取り上げられている問題です。

:::note info
ちなみに、 **闘える** と書いてありますのは単なる偶然ではないとおもいます。競技プログラミングの本筋は、己との闘い、 **闘魂** なのです。ランクが低い私が言うと全く説得力はありませんが、一言申し上げておきます。ランクは誇るものでもなく、ましてや卑下するものでもなく自分の位置を把握するための目安に過ぎないのです。大事なことは、 **己の弱い心に打ち克つ** ことにあるのです。
:::

```
6
382253568 723152896 37802240 379425024 404894720 471526144
```

こういうインプットがある場合に、2行目の数字を2で割っていって奇数がでるまで何回割ることができるのかという問題です。


## ふつうに解く

まずはふつうに解いてみます。

```elixir
defmodule Main do
  def main do
    IO.read(:line)

    IO.read(:line)
    |> String.trim()
    |> String.split(" ")
    |> Enum.map(&String.to_integer/1)
    |> Enum.reduce_while(10_000_000_000, fn a, acc ->
      a
      |> do_solve(0)
      |> calc_new_acc(acc)
      |> calc_result()
    end)
    |> IO.puts()
  end

  defp do_solve(a, acc) when rem(a, 2) == 1, do: acc

  defp do_solve(a, acc), do: do_solve(div(a, 2), acc + 1)

  defp calc_new_acc(cnt, acc) when cnt < acc, do: cnt

  defp calc_new_acc(cnt, acc), do: acc

  defp calc_result(0), do: {:halt, 0}

  defp calc_result(acc), do: {:cont, acc}
end
```

https://atcoder.jp/contests/abc081/submissions/38365766

[AtCoderへの提出結果](https://atcoder.jp/contests/abc081/submissions/38365766)

![スクリーンショット 2023-01-28 14.11.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/30072842-6bec-1303-dc96-2c0cc55c3b7b.png)

だいたい339msで実行して、全件パス:tada:しています！

## **闘魂プログラミング**で解く

**闘魂プログラミング**で解いてみます。
意図した通り、ソースコード中に**闘魂**がたくさんでてきます。

```elixir
defmodule Main do
  def main do
    binta = fn mod ->
      short_mod = "#{mod}" |> String.split(".") |> Enum.at(-1)

      args = fn arity, add_args ->
        "#{1..arity |> Enum.map(&"a#{&1}") |> Kernel.++(add_args) |> Enum.join(",")}"
      end

      funs =
        mod.__info__(:functions)
        |> Enum.map(fn {name, arity} ->
          """
          def #{name}(#{args.(arity, ["\"闘魂\""])}), do: #{short_mod}.#{name}(#{args.(arity, [])})
          """
        end)
        |> Enum.join("\n")

      """
      defmodule Inoki.#{short_mod} do
        #{funs}
      end
      """
      |> Code.eval_string()
    end

    binta.(IO)
    binta.(String)
    binta.(Enum)

    Inoki.IO.read(:line, "闘魂")

    Inoki.IO.read(:line, "闘魂")
    |> Inoki.String.trim("闘魂")
    |> Inoki.String.split(" ", "闘魂")
    |> Inoki.Enum.map(&Inoki.String.to_integer(&1, "闘魂"), "闘魂")
    |> Inoki.Enum.reduce_while(
      10_000_000_000,
      fn a, acc ->
        a
        |> do_solve(0, "闘魂")
        |> calc_new_acc(acc, "闘魂")
        |> calc_result("闘魂")
      end,
      "闘魂"
    )
    |> Inoki.IO.puts("闘魂")
  end

  defp do_solve(a, acc, "闘魂") when rem(a, 2) == 1, do: acc

  defp do_solve(a, acc, "闘魂"), do: do_solve(div(a, 2), acc + 1, "闘魂")

  defp calc_new_acc(cnt, acc, "闘魂") when cnt < acc, do: cnt

  defp calc_new_acc(cnt, acc, "闘魂"), do: acc

  defp calc_result(0, "闘魂"), do: {:halt, 0}

  defp calc_result(acc, "闘魂"), do: {:cont, acc}
end
```

https://atcoder.jp/contests/abc081/submissions/38429742

[AtCoderへの提出結果](https://atcoder.jp/contests/abc081/submissions/38429742)

![スクリーンショット 2023-01-29 0.33.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/882111e6-f9ea-4419-2fbd-57bc066e6c8c.png)



全件パス:tada:しています！
だいたい692msの実行時間がかかっています。
ふつうに解いたときとくらべておおよそ倍の実行時間がかかっています。
余計なことをしているからです。当然の結果です。

コードをよーくみますと、 [Elixir](https://elixir-lang.org/)で作った解答ソースコードは、 **表現の中核として関数** が使われています。

https://qiita.com/hiruberuto/items/26a813ab2b188ca39019

感覚的なところです。ご自身でなにかを書いてみるとわかるとおもいます。


---

# さいごに

**闘魂プログラミング**をわたしは[Elixir](https://elixir-lang.org/)で楽しみました。

**闘魂プログラミング** の定義はありません。
各自の **闘魂** の数だけ **闘魂プログラミング** があるのです。
そういうものです。

:::note warn
**闘魂プログラミング** の定義はありません。
:::

わたしの場合はおおよそ以下の通りです。

- ソースコードの中に**闘魂**ができるだけ多くでてくる
- **闘魂** がないと本当に動かない箇所がある

競技プログラミングという時間に厳しい制約条件がある場面では、わたしの **闘魂プログラミング** は邪魔でしかありませんし、非常に簡単な問題しか解いていませんが、AtCoderにも **闘魂** を刻みこむことができました。単なるコメントなどよりは多少意味があるものとして、 **闘魂** をソースコードの中に登場させました。
世知辛い世の中ではありますが、たまにはこういうふうにのんびりコードと戯れるのもよいのではないでしょうか。

これからもインターネットの大地に、 **闘魂** を掘るように刻み込み続けます！


ぜひみなさんも、お気に入りのプログラミング言語で **闘魂プログラミング** をお楽しみください。

:::note info
ぜひみなさんも、お気に入りのプログラミング言語で **闘魂プログラミング** をお楽しみください。
:::

---

https://qiita.com/torifukukaiou/items/5e96f4e9f12ec3c4b3f4

https://qiita.com/torifukukaiou/items/b6361f98194f3687a13c

https://qiita.com/torifukukaiou/items/4c35ace6db3f02ac3897

https://qiita.com/torifukukaiou/items/17d55cf896c24b13350e

https://qiita.com/torifukukaiou/items/44db8a4997812518730a


---

# おまけ

Thanks to: https://techblog.gmo-ap.jp/2021/06/15/text-visualization-wordcloud/

この記事を可視化してみました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/e68a9cd5-dc81-dd00-ec08-e234605fcd7a.png)



---

https://www.youtube.com/watch?v=AWxwmqzbOaw








<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>