派遣で働くエンジニアのスキルアップを応援するサイト

PRODUCED BY RECRUIT

【イベントレポート】パズルを解いてプログラミング的思考力や課題解決力を養おう

株式会社リクルートスタッフィングが運営するITSTAFFINGでは、弊社に派遣登録いただいている皆さまのスキル向上を支援するイベントを、定期的に開催しています。

12月21日のクリスマス前に開催されたイベントはその名も「クリスマスなのに(?)パズルを解いてエンジニア力をアップしよう」。このイベントのために作られたオリジナルのパズルをワーク形式で解いていきます。

パソコンを持参して、ソースコードを書いたり、インターネットで調べ物をしたりしながら、問題を解いていきました。ぜひ記事を読みながら、パズルに挑戦してみてくださいね。

【講 師】増井敏克さん
▲【講 師】増井敏克さん
増井技術士事務所代表。技術士(情報工学部門)。情報処理技術者試験にも多数合格。ITエンジニアのための実務スキル評価サービス「CodeIQ」にて、アルゴリズムや情報セキュリティに関する問題を多数出題。また、ビジネス数学検定1級に合格し、公益財団法人日本数学検定協会認定トレーナーとしても活動。著書に『おうちで学べるセキュリティのきほん』(翔泳社)、『プログラマ脳を鍛える数学パズル』(翔泳社)、『シゴトに役立つデータ分析・統計のトリセツ』(ソシム)、『エンジニアが生き残るためのテクノロジーの授業』(翔泳社)がある。

事前に解いてきてもらっていたサンプル問題を解説

参加者には事前にサンプル問題を配ってあり、解いてきてもらいました。チーム内の自己紹介が終わると、増井さんがその解説から始めます。ちなみに、クイズを解く際には、インターネット検索などはいくら使ってもよいというルールです。

■事前に出題していた問題1(プログラミング問題)

 桁数が同じ2つの素数を掛けてできた数を真ん中で区切ったとき、前半と後半のいずれもが素数で構成されている数を考えます。例えば、31と37という2つの素数をかけたとき、31×37=1147となり、その前半である11と後半の47はともに素数です。なお、できた数は桁数が必ず偶数のもののみ考えるものとし、真ん中で区切れないものは考えないものとします。
 このような数を小さな方から順に探した時、上記の1147は初めて4桁になる数で全体の3番目、初めて6桁になるのは131×773=101263で全体の20番目の数、初めて8桁になるのは10091051で全体の372番目の数です。では全体の3976番目の数を答えてください。

考え方は次の2通りあります。

1. 素数を掛け算して、上位と下位が素数になるものを探す
2. 上位と下位の素数を決め、素因数分解して同じ桁数の素数になるものを探す

増井さんは、2のほうでプログラムを作成しました。その場合、以下のような手順になります。

1. 桁数に応じた素数のリストを生成する
2. 桁数を増やしながら、上位と下位を決め、素因数分解する
3. 素因数分解の結果画素数2つになった時と、素数1つの2乗になった時カウント
4. 3976番目になれば終了

Rubyの場合は次のようなソースコードになります。

f:id:itstaffing:20180215162604j:plain

これを実行すると、答えは20171117という数字になります。

■事前に出題していた問題2(暗号問題)

暗号文と国名の間に以下の対応があるとき、AとBに当てはまる国名を答えてください。
暗号問題

考え方としては、よく出てくる文字に注目します。@がよく出てくることがわかります。@が入る国は、濁音が入っていることに気が付くかもしれません。また、アメリカとアルゼンチンは両方とも「ア」で始まり、暗号文は「3」で始まっています。3のキーボードを見てみると、日本語キーボードを利用している人は「あ」と表記されているはず。そのため、英語モードのままかな入力したものが暗号文だとわかります。ここまで気が付けば、Aは韓国、Bは台湾だと解けるでしょう。

f:id:itstaffing:20180215162607j:plain

■事前に出題していた問題2(パズル問題)

以下の覆面算を解いたとき、60826033という数字に対応する文字列を答えてください。なお、覆面算では、0から9の数字がそれぞれ対応する別の記号に割り当てられ、同じ文字には同じ数字が入ります。
BOOKS+PANEL=TABLET

わかりやすいように縦に並べてひっ算してみましょう。

 BOOKS
+PANEL
――――――
 TABLET

5桁と5桁を足して6桁になっているので、一番左の位が繰り上がっていることがわかります。つまり、「T」は1であると分かります。次に、1の位を見ると、SとLを足してT(=1)になっていますから、ここも繰り上がっています。十の位では、「1+K+E=E」なので、Kは9だと分かります。このようにしてひとつずつ順番に文字に数字を当てていくと、答えは60826033=BASEBALL、ということになります。

最後に、この3つの解答をキーワードとして浮かび上がる「場所」を見つけます。

「20111117」は2011年11月17日のこと。その他「韓国」「台湾」「BASEBALL」に関連するのは、「ENEOSアジアプロ野球チャンピオンシップ2017」でした。行われた場所は「東京ドーム」。とても凝っているクイズです。

いよいよ、参加者が考えるクイズ演習のスタート

参加者はチーム対抗でクイズを解いていきます。問題は6問。本番の問題にも、サンプルの問題のように答えから導き出されるキーワードがあります。それぞれ、解けた人から答えをネット上のフォームに書き込みます。それを随時、増井さんがチェックしていきます。

f:id:itstaffing:20180215162612j:plain

勝敗の決め方は、6問の解答から導き出されるキーワードを最初に正解したチームが優勝。どのチームもキーワードを導き出せなかった場合には、解けた問題の多いチームが優勝。解答数が同じ場合には、早かったチームを優勝とします。

問題は、次のように出題されました。

問1 プログラミング問題
問2 暗号問題
問3 論理パズル問題
問4 プログラミング問題
問5 暗号問題
問6 論理パズル問題

f:id:itstaffing:20180215162619j:plain

各チームで、プログラミングが得意な人、暗号問題をやりたい人、などと担当分けをして解いていきます。話し合いながら解くチームもありました。

45分ほど時間を取りましたが、問題が難しかったのか、解けたのは数名。6チームのうち、4チームが1問を解くことができました。そのうち最も早かったEチームが優勝となりました。

意外と難解だったオリジナルクイズの答え合わせ

f:id:itstaffing:20180215162622j:plain

ここではすべて紹介することはしませんが、1問目のプログラミング問題を解説していきます。

■問1 プログラミング問題

3つの球とそれぞれに外接する立方体があるとき、立方体の体積の和を考える。
球の半径はいずれも素数で、すべて異なっている。

例)素数を小さい方から3つ選ぶと2, 3, 5
半径が2, 3, 5の球に外接する立方体の一辺の長さはそれぞれ4, 6, 10であり、その体積の和は
4^3+6^3+【10】^3=64+216+1000=1280
3つの素数の組み合わせをすべての素数に対して考え、体積の和を小さい方から順に並べる。
4187番目の値は?

考え方は、次の通りになります。

1. 素数を小さい方から順に生成する。
2. それらの組み合わせを考え、体積を計算する。
3. 体積をキーにした配列を作成し、小さいほうから順に調べる。

Rubyで作成したソースコードは次の通り。

require 'prime'
primes = Prime.each(300).to_a
cube = {}
primes.combination(3) do |a, b, c|
 cube[a ** 3 + b ** 3 + c ** 3] = 1
end
sorted = cube.keys.sort
puts sorted[0]*8
puts sorted[4186]*8

Prime.eachのeachメソッドで、素数を生成しています。primes.combinationのcombinationメソッドで、素数a、b、cの重複を許さない組み合わせを生成。次のcubeは、体積の和(の1/8)をキーにした配列になります。キーでソートし、1番目と4187番目に8を掛けて出力しています。

f:id:itstaffing:20180215162626j:plain

簡単なパズル問題と思いきや、プログラミングの知識も含む頭の体操となりました。参加者からは、苦戦したものの楽しかったという声が多数聞こえてきました。うまく解けず「すっきりしない」という人もいたかもしれませんが、論理的に考えたり、工夫してみたりすることは、日常の仕事にも役立つことでしょう。