CodeIQ MAGAZINECodeIQ MAGAZINE

【夏のミステリー】時間制限の密室 解答と解説

2017.07.31 Category:CodeIQ問題解説・リーダーボード Tag:

  • 3
  • このエントリーをはてなブックマークに追加

夏のミステリーということで、ちょっとした仕掛けのある、プログラミング問題でした。

あなたは見事、プログラムを書けましたか? というわけで、出題者の柳井さんによる解答と解説をどうぞ!
by CodeIQ運営事務局

【夏のミステリー】時間制限の密室

本問題は、表題のテーマで、簡単なプログラムを書くものです。

それでは以下、問題とその解答を見ていきましょう。

問題

(なんやかんやあって)命からがら逃げてきた、あなた。

しかし逃げ込んだ部屋にあなたが入った途端、自動でドアはロックされ、
しかも10分後にはガスが噴き出してくるという緊急アナウンスが流れてきた。

脱出するには、プログラムで鍵を作成して、3Dプリンタで出力しなければならない。

鍵の長さは100で、1から100までに区切られている。各数字に対応する場所は、凸部の高さが決まっている。

各部の高さは、最低1で、2の倍数の時は+2、3の倍数の時は+3、5の倍数の時は+5される。

鍵の1から100までの凸部の高さを、1行ずつ「]」の数で出力して鍵を作り、密室から脱出しよう。

制限時間は10分です。

なんやかんやで怪我をしているため、時間につれて画面が見づらくなってしまう。一刻も早く鍵を手に入れてこの密室から脱出しよう!

// 出力例(1~10まで)
]
]]]
]]]]
]]]
]]]]]]
]]]]]]
]
]]]
]]]]
]]]]]]]]

答え

問題自体は、とても簡単なFizzBuzz系のものです。少し変わった所として、実際に問題を解いた方は分かると思いますが、時間と共に解答欄が血糊で埋まっていきます。

血糊が増えていく処理は、JavaScriptのCanvasを使い画像を作成して、入力欄の背景に適用しました。

tinori

というわけで、問題の方を解いていきましょう。以下、解答例を示します。サンドボックスで実行してください。

// https://codeiq.jp/tools/sandbox/
// 参考コード JavaScript (Node.js)
for (var i = 1; i <= 100; i ++) {
    var len = 1;
    if (i % 2 === 0) {len += 2}
    if (i % 3 === 0) {len += 3}
    if (i % 5 === 0) {len += 5}
    for (var j = 0; j < len; j ++) {
        process.stdout.write(']');
    }
    process.stdout.write('\n');
}

FizzBuzz系なので、とても簡単です。

凸部の長さを表す変数「len」の初期値を「1」にして、2の倍数(2の剰余が0)の場合は「+2」、3の倍数(3の剰余が0)の場合は「+3」、5の倍数(5の剰余が0)の場合は「+5」します。

これで、答えを求めることができます。

// 出力した答え
]
]]]
]]]]
]]]
]]]]]]
]]]]]]
]
]]]
]]]]
]]]]]]]]
]
]]]]]]
]
]]]
]]]]]]]]]
]]]
]
]]]]]]
]
]]]]]]]]
]]]]
]]]
]
]]]]]]
]]]]]]
]]]
]]]]
]]]
]
]]]]]]]]]]]
]
]]]
]]]]
]]]
]]]]]]
]]]]]]
]
]]]
]]]]
]]]]]]]]
]
]]]]]]
]
]]]
]]]]]]]]]
]]]
]
]]]]]]
]
]]]]]]]]
]]]]
]]]
]
]]]]]]
]]]]]]
]]]
]]]]
]]]
]
]]]]]]]]]]]
]
]]]
]]]]
]]]
]]]]]]
]]]]]]
]
]]]
]]]]
]]]]]]]]
]
]]]]]]
]
]]]
]]]]]]]]]
]]]
]
]]]]]]
]
]]]]]]]]
]]]]
]]]
]
]]]]]]
]]]]]]
]]]
]]]]
]]]
]
]]]]]]]]]]]
]
]]]
]]]]
]]]
]]]]]]
]]]]]]
]
]]]
]]]]
]]]]]]]]

血糊の部分は、Canvasの2D Contextを、以下の設定にして円を描画しています。

// 背景描画用のCanvas
var $cnvs = $('<canvas>').attr('width', w).attr('height', h)
    .appendTo('body').css({display: 'none'});
var cntx = $cnvs[0].getContext('2d');
cntx.fillStyle = '#a00';
cntx.shadowBlur = 10;
cntx.shadowColor = '#a00';
// 血糊の描画
// w, h は、エディタの横幅と高さ
var x = w * Math.random();
var y = h * Math.random();
var r = 5 + 30 * Math.random();

cntx.beginPath();
cntx.arc(x, y, r, 0, Math.PI * 2, false);

// 複数回描画して、ぼかし部分を濃くする
for (var i = 0; i < 5; i ++) {cntx.fill()}
// 背景を取り出して、エディタの背景に設定
var img = $cnvs[0].toDataURL();

// $edtWrpprは、エディタを囲んでいる要素
$edtWrppr.css({backgroundImage: 'url("' + img + '")'});

CodeIQ運営事務局より

柳井さん、ありがとうございました!
現在、柳井さんの小説出版を記念して、CodeIQでは特別問題を出題中です。
挑戦者全員に小説の試し読み限定版PDFをプレゼントのほか、正解者の中から抽選で3名様には小説の単行本をプレゼントいたします。
ぜひ、挑戦してみてくださいね。

  • 3
  • このエントリーをはてなブックマークに追加

■関連記事

【息抜き】カードを上手く並べよう【言語不問】解答と解説... 【息抜き】カードを上手く並べよう【言語不問】 本問題は、表題のテーマで、簡単なプログラムを書くものです。 それでは以下、問題とその解答を見ていきましょう。 問題 あなたは、11から99までの、89枚のカードを持っています。問題では、横幅と高さの整数が与えられます。この横幅と高さで作られるマス...
【コードミステリ】数字に隠されたメッセージ【言語不問】解答と解説... 【コードミステリ】数字に隠されたメッセージ【言語不問】 本問題は、表題のテーマで、簡単なプログラムを書くものです。 喜屋武ちあきさんによるCodeIQ MAGAZINEでのブックレビューに合わせて、『顔貌売人』(文藝春秋)とのコラボ問題として出題されたものです。 それでは以下、問題とその解...
数学の問題をプログラミングで解こう!「ディバイド・アウト」問題解説... 問題のおさらい 自然数 n と素数 p に対し、n の階乗(n!)を p でこれ以上割り切れなくなるまで繰り返し割り、その商をさらに p で割ったときの余りを F(n, p) と定義します。 例えば F(12, 5)=4 です。 12!(=479001600)は 5 で最大 2 回割ることができ...
【息抜き】ファイル名を作ろう【言語不問】解答と解説... 【息抜き】ファイル名を作ろう【言語不問】 本問題は、表題のテーマで、簡単なプログラムを書くものです。 それでは以下、問題とその解答を見ていきましょう。 問題 ファイルをディレクトリ内に作成する際、同じ名前のファイルがあると、末尾に数字を付けるなどして同じ名前にならないようにします。 こうし...
【夏のミステリー】殺人現場のコード 解答と解説... 【夏のミステリー】殺人現場のコード 本問題は、表題のテーマで、簡単なプログラムを書くものです。 それでは以下、問題とその解答を見ていきましょう。 問題 殺人現場にプログラマが倒れていて、途中までプログラムが書かれている。 「続きを書いて欲しい」 これはダイイングメッセージなのか? どう...
数学の問題をプログラミングで解こう!「キャンディ・アンド・チョコレート」問題解説... 問題のおさらい n 個のキャンディをグループに分けます。 グループの最大のキャンディの個数が k 個となるような分け方の数を F(n, k) と定義します。 例えば、F(8, 3)=5 です。このときの分け方を以下に示します。 なお個々のキャンディを区別せずに扱う点に注意してください。 同...

今週のPickUPレポート

新着記事

週間ランキング

CodeIQとは

CodeIQ(コードアイキュー)とは、自分の実力を知りたいITエンジニア向けの、実務スキル評価サービスです。

CodeIQご利用にあたって
関連サイト
codeiq

リクルートグループサイトへ