LoginSignup
10
4

More than 1 year has passed since last update.

2021/12/04の回です。

前日は、@rute_not_routeさんによる「【初心者向け】AtCoder Beginner Contest の 取り組み方」でした。
AtCoderのアカウント作成から、『ABCの参加方法』や『ABCの対策方法』を丁寧に解説されています。
@rute_not_routeさんは、現在大学3年生なのだそうです。
競プロ人口を増やしたい」という思いを語ってくださいました。
未来は明るいと私は感じました。
本日は齢40を過ぎた私が、「競技プログラミングとElixirと私」を話します。

はじめに

競技プログラミングを楽しんでいますか:bangbang::bangbang::bangbang:
Elixirを楽しんでいますか:bangbang::bangbang::bangbang:

競技プログラミングと一口に申しましてもいろいろと種類があるとおもいます。
この記事では私自身が参加したことがあるAtCoderのことを指しています。

AtCoderは、世界最高峰の競技プログラミングサイトです。

(https://atcoder.jp/?lang=ja)

この記事では2つのことを書きます。

  • Elixirで競技プログラミングを始める人に伝えたいこと
    • AtCoderに参加するために知っておくとよいことをご説明します
  • 競技プログラミングとElixirと私
    • オリジナルの視点から説明をいたします
    • まずはなんでもやってみることで、serendipity的なことが巻き起こるかもしれません

the fact of something interesting or pleasant happening by chance

Elixirで競技プログラミングを始める人に伝えたいこと

AtCoderに参加するために知っておくとよいことをご説明します。
Elixirを始めたばかりの人を対象に書きます。
2021/11/13現在、AtCoderで使用できるElixirのバージョンは1.10.2です。

AtCoderをElixirでやってみる

Zennに書いた記事をご紹介します。
詳しくはリンク先をご参照ください。

デモ(論よりRun)

AtCoderにまだ参加をしたことがない方は、以下の動画(48秒):video_camera:をみて雰囲気を掴んでください。
これから説明していくことを動画にしております。

基礎知識

リンク先は、ある程度のElixirの心得がある人を対象に書いています。
まずは、かいつまんで、AtCoderでの解答までの流れを説明いたします。
まだあまりElixirに自信がない人は、まずは本記事を読んでいただいてから「AtCoderをElixirでやってみる」に進んでいただけるとよいとおもいます。1

おおまかには以下の流れで問題に答えていきます。

  1. 問題文を理解する
  2. 「入力 |> 入力値を問題文の仕様に合うように変換 |> 出力」というプログラムを書く
  3. 提出する

提出の際には、モジュール名はMain、エントリーポイントとでも申しましょうか採点時に最初に呼び出される関数名はmain/0にしておく必要があります。
AtCoderは過去問を解けますので練習ができるのがよいです :tada:

それではさっそく一題解いてみましょう。

ABC086A - Productに対するElixirでの解答例を示します。

問題は

シカのAtCoDeerくんは二つの正整数 a,b を見つけました。 a と b の積が偶数か奇数か判定してください。

です。
いきなりですが、Elixirでの解答例です。
どの問題でもおおよそこういった流れのプログラムを作っていくことになります。

lib/main.ex
defmodule Main do
  def main do
    IO.read(:line)
    |> String.trim()
    |> String.split(" ")
    |> Enum.map(&String.to_integer/1) # ここまでが入力(入力値を扱いやすくするための前処理を含む)
    |> do_solve() # 問題文の仕様に合うように変換
    |> IO.puts() # 出力
  end

  defp do_solve([a, _b]) when rem(a, 2) == 0, do: "Even"

  defp do_solve([_a, b]) when rem(b, 2) == 0, do: "Even"

  defp do_solve([_a, _b]), do: "Odd"
end

この問題は、偶数か奇数かを判定する単純なものです。
問題の難易度に応じて、do_solveが複雑なものとなります。
問題の難易度があがるとdo_solveが長くなる傾向にありますが、上に示した大枠はそれほど変わりません。
こうして眺めてみると、簡単そうにみえてきませんか。

簡単そうにみえるのは、それはそのはず。私が説明できる簡単な問題を選んで説明に使っています。
Elixirで標準入力ってどうやるんだっけ? とかString.trim/1をしておかないと改行がくっついてくるとかそのへんは知っておかないと無駄にハマるかもしれません。私はハマりました... 私の経験を共有することは誰かの役に立つかもしれないとおもって書いています。

ちなみに、「|>: パイプ演算子」を使わない場合はこうなります。

lib/main.ex
defmodule Main do
  def main do
    IO.puts(do_solve(
      Enum.map(String.split(String.trim(IO.read(:line)), " "), 
               &String.to_integer/1)))
  end

  defp do_solve([a, _b]) when rem(a, 2) == 0, do: "Even"

  defp do_solve([_a, b]) when rem(b, 2) == 0, do: "Even"

  defp do_solve([_a, _b]), do: "Odd"
end

AtCoder Beginners Selection

もう少し準備体操をしたい方にオススメです。

このコンテストは、「AtCoderに登録したけど何をしていいか分からない・・・!」という人に向けて作られた、初心者向け問題集です。
問題は、dr.kenさんの、「AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~」から選出しています。
まずはこの問題を順番に解いていきましょう!

まずはここの問題から腕試ししてみましょう。
Elixirでの解答例は以下に書いています。

解答例

AtCoder に登録したら解くべき精選過去問 10 問を私も"Elixir"で解いてみた

Where to go Next

さらにステップアップしたいあなたに贈ります。:gift::gift::gift:

問題解決力を鍛える!アルゴリズムとデータ構造 :book:

@drken さんの:book:で、アルゴリズムとデータ構造を学びましょう。

ライブラリ

AtCoderに対してElixirを使って挑むあなたの強力な味方となってくれるツールをご紹介します。

ex_at_coder

@tamanugi さん作 :tada:
mix taskにて、問題文からテストの自動生成、解答用の雛形ファイルを作ってくれます :rocket:
参考: @tamanugiさんのex_at_coderを使ってみる (Elixir)

g-kenkun/kyopuro

@g_kenkun さん作 :tada:
mix taskにて、問題文からテストの自動生成、解答用の雛形ファイルを作ってくれます :rocket:
さらに提出機能をサポートしています。
参考: @g_kenkunさんのg-kenkun/kyopuroを使ってみる (Elixir)

まとめ

Elixirを使って、AtCoderに挑むとはどういうことなのかを簡単に説明しました。
雰囲気を感じていただけたら幸いです。
準備はできました :tada:

Leap before you look :rocket::rocket::rocket:


競技プログラミングとElixirと私

競技プログラミングとの出会いは2020年10月です。
社内で毎月月末に行われている社内ハッカソンでその存在を知りました。
20年近くソフトウェア開発という世界に身を置きながら、おおよそ1年前にはじめて知りました。
お恥ずかしい限りです。

一時期熱心に取り組んでいた時期はありますが、灰色ランクのままです。
何の自慢にもなりませんし、そもそもこのカレンダーに投稿参加する資格があるのかどうかはなはだ怪しいです。
それでも自分が感じたことは書けるので参加しました。

のちほどまた後述しますが、AtCoderに取り組むことでElixirEnumモジュールへの理解が深まりました。
このことは、これまでの20年間では経験することのなかった、その後に起きるさまざまな出来事と無関係であるとはおもえません。
ものすごく強く結びついているとおもいます。

私は2019年にElixirに出会いました。
2019/01/25に行われた「kokura.ex#1:小倉Elixirコミュニティ発足【セッション/LTと懇親会】(19:30~)」に参加したことがはじまりです。
@zacky1972 先生、@piacerex さんはじめ、参加者のみなさんがElixirを楽しそうに語っていたことが印象に残っています。
当時のことを正直に書きますと、関数型言語Elixirと聞いて、「関数型言語」のところに変な先入観をもっていました。

  • 難しそう
  • 恐れ
  • (もっと言うと)実用とは関係なくて研究用なんでしょ

最初が肝心と申します通り、「kokura.ex#1:小倉Elixirコミュニティ発足【セッション/LTと懇親会】(19:30~)」に参加したことがよかったです。
さきほども申しました通り、参加者がElixirを楽しそうに語っていたことから私にもできるんじゃないかと勘違いをしたのです。
私の第一印象は、Rubyに似ているとおもったことです。
それと当時はコードの断片をチラ見しただけでしたが、美しいと感じました。

その後で、知ったのですがElixirの作者José ValimさんはRailsのご経験がある方ならご存知のあのdevise最初のコミッターですし、Elixirのバージョンがまだ0.9.0だった2013年には、東京で行われたRubyKaigiにて基調講演をされています。
このことはプログラミングElixir 第2版(オーム社):book:の「Appendix E 日本語版に寄せて」にてJosé Valimさんの言葉が載っています。

デモを開始したとき、ElixirのインタラクティブコンソールであるIExを起動しました(この名前はRubyのirbに強くインスパイアされています)。そのIExのセッションで、Elixirがサポートするドキュメンテーションやパターンマッチといった機能について見せました。それから、もう一つIExセッションを開始し、どれくらい簡単に分散ノード上でコードを移送できるかというデモンストレーションを行いました。最初の分散呼び出しを実行すると、部屋全体で「オオオー」という声が広がりました。マジシャンが帽子から兎を取り出したような気分でした。この経験は、何度もElixirのプレゼンテーションをしてきたなかでも、いまだに特に好きな瞬間の一つです。しかし、それは魔法ではありません。 (略) 言語ランタイムの裏にある美しさは、私たちが並行性のために理由する抽象化と同じものであり、それは堅固で分散したシステムを作り上げるために利用できるものです。それはすべてを変えるのです。Elixirをマスターする途上で、開発者は、ソフトウェアの実装と設計のための、多くの可能性があることを学ぶでしょう。

(プログラミングElixir 第2版(オーム社))

このときのRubyKaigiの様子は「Jose Valim,Rubyにおける並行プログラミングのためのいくつかのアイデアを提案。~ RubyKaigi 2013 基調講演 2日目」にて知ることができます。
基調講演のレポートだけにとても貴重な記事です。

このようにRubyのプログラムと似ているなあとおもった私の直感は間違ってはいなかったようです。

Elixirが、Rubyの影響をもしかするともっとも色濃く受け継いでいるのは「A PROGRAMMER'S BEST FRIEND2の部分ではないかとおもいます。
とにかく、Elixirでプログラミングすることは楽しいです。
それほど多くの海外の方と交流したわけではありませんが、これまでやりとりがあった彼らはナイスガイでした。
こういった経験は私にとっては、Elixirと出会ってからのことです。
Elixirは海外との距離が近いです。
というか、少なくとも英語を読むことをしないと最新の情報にはついていけないです。
英語に接する機会が圧倒的に増えます。

話をBEST FRIENDに戻します。
私はいつもWe Are The Alchemists, my friends!とLT(Lightning Talks)などで歌っています :microphone:
QueenのWe Are The Championsをもじっています。
Elixirは日本語に訳すと「不老不死の霊薬」です。
Elixir言語の使い手のことは、Alchemist(錬金術師)と尊称されます。
いまの私にとって、Elixirは、プログラミングすることは楽しいんだよということを思い出させてくれた優しい友人です。
いまのレベルでも以前の私と比べるとできることは格段には増えましたが、世の中にはもっともっともっともっともっと上がいます。
こんなところで満足しているわけにはいきません。
さきほど引用した「プログラミングElixir 第2版(オーム社):book:」のJosé Valimさんの言葉の中で、Elixirの言語を象徴するキーワードである「並行性」「分散」を私は雰囲気でしか理解できていません。
さらに高みを目指すにはこれからの私にとってのElixirくんは、厳しいことも言ってくれる友人に変わっていくのだとおもいます。
そうして突き詰めていくと、チラチラと背中が見えはじめたErlang( -- 私にはプログラムがにみえました3)と仲良くなっていきたいとおもっています。

話を「kokura.ex#1:小倉Elixirコミュニティ発足【セッション/LTと懇親会】(19:30~)」にまた戻します。
私は厚かましいところがあって、ElixirHello, Worldしかできていない状態でいきなりLT(Lightning Talks)をしました。
当時の資料を振り返ってみると、時間が余ってしまうことを懸念したのだとおもいます -- 最後に「私は将棋が趣味です。さあ、みんなで詰将棋を解いてみましょう!:rocket:」というノリのページがありました。
こんなLTでもあたたかく迎え入れてくれたみなさまに感謝します。

だいぶ長くなってしまいましたが、Elixirと以上のような出会いをしました。

実績

その後いろいろあったことは端折りますが、さきほども申した通り、AtCoderに取り組むことでElixirEnumモジュールへの理解が深まったことはその後の実績と強く関係しているとおもいます。
Elixir界での私の足跡です。

すべてElixirをはじめてから体験したことです。
齢40を過ぎてからのことです。
遅咲きの狂い咲きです。
ただ、こんなところで満足しているわけにはいきません :rocket::rocket::rocket:

どうして、私がElixirを覚えたいとおもったかというそもそものところに話を戻すと、憧れ美しさに惹かれたからです。
本当に好きなものに理由は必要でしょうか。
耐障害性、並行、関数型? -- Erlangから受け継いださまざまな利点はそれはそれでどれも魅力ですが、私はFunの部分を強く感じました。
私はプログラミング言語Elixirそのものに魅力を感じたから、AtCoderの活用は最良の教材でした。
これは私の場合です。
あなたがもしなにか作りたいものがあるのなら、寄り道はせずに一直線に作りたいものを作っていけばよいとおもいます。
目的意識が強固であれば、必要な知識はあとから付いてくるものです。
私の場合は特に作りたいものがあるわけでもなく、ただただElixirを書けるようになりたいという憧れだけではじめました。

競技プログラミング

ここからは再び競技プログラミングの話をしてみます。
自分が競技プログラミングを語れる域には決して達していないのにおこがましくも語ってみます。

新しいプログラミング言語を覚えるツールとして、競技プログラミングAtCoderを活用することはアリだとおもいます

Elixirにおいては、Enumモジュールから親しくなるとよいです。
@cooldaemon さんの「私が愛する Elixir/Erlang の楽しさと辛さ」スライドにその理由が詳しく書いてあります。
この目的にだけ絞れば、AtCoderのABC(AtCoder Beginner Contest)のA問題〜C問題が解ければ十分です。
Elixirを楽しんでいけます。
Elixirを使って何かsomethingを作ることができます。

もちろん、問題は全部解けたほうがよいです。

競技プログラミングは若い時分からコツコツ取り組んでいたほうがいいとおもいます。
若いフレッシュなうちからはじめるのと40歳を過ぎてから始めるのでは、一般的には伸びのカーブに大きな違いがでるとおもいます。
それはちょうどプロの将棋の世界で、若い世代が台頭していくさまと同じだとおもいます。
いま圧倒的な強さを誇る若い世代でも次の次くらいの世代に駆逐されてしまうのでしょう。
それが自然の摂理であり、発展ということなのでしょう。

一方でこんな言葉があります。

It’s never too late – never too late to start over, never too late to be happy. (Jane Fonda)

これからのソフトウェアエンジニアには次の2点が求められていくのだとおもいます。
- ハードウェア
- 数学的素養

ハードウェアについてはこれまで一言も話していませんし、これまた語るほどなにかを知っているわけではありませんが、IoTというキーワードに代表されるように、必須の技能になると予感しています。

数学的素養を鍛える手段として、競技プログラミングへの参加/練習などの取り組みはその一つになり得るとおもいます。
道場だとおもいます。

@drken さんの「問題解決力を鍛える!アルゴリズムとデータ構造:book: の最初のほう(「もくじ」の前)を味読してみてください。
「一生モノ」の下地を築きあげましょう。

まとめ

  • 新しいプログラミング言語を覚えるツールとして、競技プログラミングAtCoderを活用することはアリだとおもいます
  • Elixirにおいては、Enumモジュールから親しくなるとよいです
  • Elixir コワくないよ
  • Elixirを始めると自然と英語に接する機会が増えますよ

It’s never too late – never too late to start over, never too late to be happy. (Jane Fonda)


Wrapping up :lgtm::lgtm::lgtm::lgtm::lgtm:

全体のまとめです。

  • AtCoderElixirで楽しみ方を紹介しました
  • 「競技プログラミングとElixirと私」と題して、私のおもいと私に起こったserendipity的なことを述べました
    • 部屋とYシャツと私」という歌がありまして、その題名から強くインスパイアされています
  • Enjoy 競技プログラミング :bangbang::bangbang::bangbang:
  • Enjoy 競技プログラミング with Elixir :bangbang::bangbang::bangbang:
  • Enjoy Elixir :rocket::rocket::rocket:

おまけ -- Elixir

Elixirを始めてみよう! とおもった、あなたに参考情報(クリスマス🎄プレゼント)を贈ります。:gift::gift::gift:
思い立ったが吉日です!!!

オススメの書籍 :books:

Webアプリケーションを楽しむなら

IoTを楽しむなら

AIを楽しむなら

コミュニティ

FCOvBkAUYAE6mL8.jpeg
@piacerex さん作 :pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5:


明日は、@malleroidさんによる「VSCodeでAtCoder用の開発環境を簡単に作る(Python編)」です。
楽しみにしています〜〜〜:tada::tada::tada:


  1. 余計な老婆心、お節介です。 

  2. https://www.ruby-lang.org/ja/ の一番上に、「A PROGRAMMER'S BEST FRIEND」と書いてあります。 

  3. @takasehideki 先生が「父がErlang、母がRuby」とElixirのことをおっしゃっていたことは言い得て妙だとおもいました。 

10
4
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
10
4