CodeIQ MAGAZINECodeIQ MAGAZINE

【謎解きプログラム】条件に当てはまる文字列は?【正規表現】解答と解説

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

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

言語不問で、プログラムにちなんだ謎を解く「謎解きプログラム」。

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

【謎解きプログラム】条件に当てはまる文字列は?【正規表現】

本問題は、表題のテーマで、プログラムにちなんだ謎を解くというものでした。

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

問題のオープニング

ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。

「24時間以内にが解けない場合は、このPCのデータは消失する。

 は、あなたが真のプログラマーなら解けるものだ」

これは挑戦状ではなく脅迫状だ!

そこには、見たことのない謎が掲載されていた。

あなたは歴戦のプログラマーとして、データを救うために、この謎に挑むことになった。

問題1

あなたは、縦横のヒントに正規表現が書かれた、空欄のマスを提示されました。

下記の選択肢のうち、1~n文字目を、下の表の1~n文字目のマスに入れた場合、縦横の正規表現を満たすものを選んで下さい。

// 問題のパズル
[^q] [^i]
[iq] 1文字目 2文字目
// 選択肢
qq
qi
iq
ii

この問題を2つの方法で解いていきましょう。1つ目は縦軸と横軸に当てはまる文字を、人手で確認して、結果を求める方法です。2つ目は、プログラミングで、条件に一致する選択肢を探す方法です。

まずは、1つ目の方法です。人手で、選択肢から当てはまる文字の候補を確認します。

// 文字の候補を確認
横軸 [iq] は、iかqです。
縦軸1 [^q] は、q以外です。
縦軸2 [^i] は、i以外です。

// 確認した文字を表に
[^q] [^i]
[iq] 横:iかq
縦:q以外
横:iかq
縦:i以外
[^q] [^i]
[iq] i q

というわけで、選択肢の「iq」が条件に当てはまります。

また、プログラミング(JavaScript)で、条件に一致する選択肢を探してみましょう。共通関数は、以降の問題でも使います。

// 共通関数
var checkXW = function(sel, reX, reY) {
    for (var i = 0; i < sel.length; i ++) {
        var txt = sel[i].map(function(x) {return x.join('')}).join('');
        var chck = [];
        console.log(txt);

        // 横方向正規表現確認
        for (var x = 0; x < reX.length; x ++) {
            var t = sel[i][x].join('');
            var c = !!t.match(reX[x]);
            chck.push(c);
            console.log(t, c, reX[x]);
        }

        // 縦方向正規表現確認
        for (var y = 0; y < reY.length; y ++) {
            var t = sel[i].map(function(x) {
                return x[y];
            }).join('');
            var c = !!t.match(reY[y])
            chck.push(c);
            console.log(t, c, reY[y]);
        }

        // 結果出力
        var res1 = chck.map(function(x) {
            return x ? 'o' : '-';
        }).join('');
        var res2 = chck.every(function(x) {
            return x;
        });
        console.log('[result]', txt, res1, res2 ? 'ok!!' : '');
        console.log('');
    }
    console.log('');
};
// 問題1
var sel = [
    [['q', 'q']],  // 選択肢1
    [['q', 'i']],  // 選択肢2
    [['i', 'q']],  // 選択肢3
    [['i', 'i']]   // 選択肢4
];
var reX = [/[iq]/];          // 横方向正規表現
var reY = [/[^q]/, /[^i]/];  // 縦方向正規表現

checkXW(sel, reX, reY);  // 横縦確認
// 出力結果(resultの、oはOK、-はNG)
qq
qq true /[iq]/
q false /[^q]/
q true /[^i]/
[result] qq o-o

qi
qi true /[iq]/
q false /[^q]/
i false /[^i]/
[result] qi o--

iq
iq true /[iq]/
i true /[^q]/
q true /[^i]/
[result] iq ooo ok!!

ii
ii true /[iq]/
i true /[^q]/
i false /[^i]/
[result] ii oo-

「[result] iq ooo ok!!」と出力された、「iq」が条件に当てはまります。

というわけで、3番目の選択肢「iq」が答えになります。

問題2

あなたは、縦横のヒントに正規表現が書かれた、空欄のマスを提示されました。

下記の選択肢のうち、1~n文字目を、下の表の1~n文字目のマスに入れた場合、縦横の正規表現を満たすものを選んで下さい。

// 問題のパズル
[A-C] . [T-d]
[^C-b]{2}[^A-C] 1文字目 2文字目 3文字目
// 選択肢
CAT
CUT
BAT
BAD

この問題を2つの方法で解いていきましょう。1つ目は縦軸と横軸に当てはまる文字を、人手で確認して、結果を求める方法です。2つ目は、プログラミングで、条件に一致する選択肢を探す方法です。

まずは、1つ目の方法です。人手で、選択肢から当てはまる文字の候補を確認します。

// 文字の候補を確認
横軸の [^C-b]{2}[^A-C] は、BAT BAD が当てはまります。
縦軸1 [A-C] は、AからCなので、全て当てはまります。
縦軸2 . は、任意の1文字なので、全て当てはまります。
縦軸3 [T-d] は、大文字のTから小文字のdまでなので、CAT CUT BAT が当てはまります。

// 確認した文字を表に
[A-C] . [T-d]
[^C-b]{2}[^A-C] 横:Bが当てはまる
縦:全て当てはまる
横:Aが当てはまる
縦:全て当てはまる
横:TかDが当てはまる
縦:Tが当てはまる
[A-C] . [T-d]
[^C-b]{2}[^A-C] B A T

というわけで、選択肢の「BAT」が条件に当てはまります。

また、プログラミング(JavaScript)で、条件に一致する選択肢を探してみましょう。

// 問題1
var sel = [
    [['C', 'A', 'T']],  // 選択肢1
    [['C', 'U', 'T']],  // 選択肢2
    [['B', 'A', 'T']],  // 選択肢3
    [['B', 'A', 'D']]   // 選択肢4
];
var reX = [/[^C-b]{2}[^A-C]/];      // 横方向正規表現
var reY = [/[A-C]/, /./, /[T-d]/];  // 縦方向正規表現

checkXW(sel, reX, reY);  // 横縦確認
// 出力結果(resultの、oはOK、-はNG)
CAT
CAT false /[^C-b]{2}[^A-C]/
C true /[A-C]/
A true /./
T true /[T-d]/
[result] CAT -ooo

CUT
CUT false /[^C-b]{2}[^A-C]/
C true /[A-C]/
U true /./
T true /[T-d]/
[result] CUT -ooo

BAT
BAT true /[^C-b]{2}[^A-C]/
B true /[A-C]/
A true /./
T true /[T-d]/
[result] BAT oooo ok!!

BAD
BAD true /[^C-b]{2}[^A-C]/
B true /[A-C]/
A true /./
D false /[T-d]/
[result] BAD ooo-

「[result] BAT oooo ok!!」と出力された、「BAT」が条件に当てはまります。

というわけで、3番目の選択肢「iq」が答えになります。

問題3

あなたは、縦横のヒントに正規表現が書かれた、空欄のマスを提示されました。

下記の選択肢のうち、1~n文字目を、下の表の1~n文字目のマスに入れた場合、縦横の正規表現を満たすものを選んで下さい。

// 問題のパズル
[a-k][a-k] [a-k][a-k]
[cm][oa] 1文字目 2文字目
de|ke 3文字目 4文字目
// 選択肢
code
mode
cake
make

この問題を2つの方法で解いていきましょう。1つ目は縦軸と横軸に当てはまる文字を、人手で確認して、結果を求める方法です。2つ目は、プログラミングで、条件に一致する選択肢を探す方法です。

まずは、1つ目の方法です。人手で、選択肢から当てはまる文字の候補を確認します。

// 文字の候補を確認
横軸1の [cm][oa] は、co ca mo ma の組み合わせなので、全ての選択肢が当てはまります。
横軸2の de|ke は、de あるいは ke なので、全ての選択肢が当てはまります。
縦軸1 [a-k][a-k] は、cd ck が範囲内の、code cake が当てはまります。mode make は、m が範囲外なので該当しません。
縦軸2 [a-k][a-k] は、ae が範囲内の、cake make が当てはまります。code mode は、o が範囲外なので該当しません。

// 確認した文字を表に
[a-k][a-k] [a-k][a-k]
[cm][oa] 横:全て当てはまる
縦:cが当てはまる
横:全て当てはまる
縦:aが当てはまる
de|ke 横:全て当てはまる
縦:全て当てはまる
横:全て当てはまる
縦:全て当てはまる
[a-k][a-k] [a-k][a-k]
[cm][oa] c a
de|ke (all) (all)

というわけで、選択肢の「cake」が条件に当てはまります。

また、プログラミング(JavaScript)で、条件に一致する選択肢を探してみましょう。

// 問題1
var sel = [
    [['c', 'o'], ['d', 'e']],  // 選択肢1
    [['m', 'o'], ['d', 'e']],  // 選択肢2
    [['c', 'a'], ['k', 'e']],  // 選択肢3
    [['m', 'a'], ['d', 'e']]   // 選択肢4
];
var reX = [/[cm][oa]/, /de|ke/];         // 横方向正規表現
var reY = [/[a-k][a-k]/, /[a-k][a-k]/];  // 縦方向正規表現

checkXW(sel, reX, reY);  // 横縦確認
// 出力結果(resultの、oはOK、-はNG)
code
co true /[cm][oa]/
de true /de|ke/
cd true /[a-k][a-k]/
oe false /[a-k][a-k]/
[result] code ooo-

mode
mo true /[cm][oa]/
de true /de|ke/
md false /[a-k][a-k]/
oe false /[a-k][a-k]/
[result] mode oo--

cake
ca true /[cm][oa]/
ke true /de|ke/
ck true /[a-k][a-k]/
ae true /[a-k][a-k]/
[result] cake oooo ok!!

made
ma true /[cm][oa]/
de true /de|ke/
md false /[a-k][a-k]/
ae true /[a-k][a-k]/
[result] made oo-o 

「[result] cake oooo ok!!」と出力された、「cake」が条件に当てはまります。

というわけで、3番目の選択肢「cake」が答えになります。

CodeIQ運営事務局より

柳井さん、ありがとうございました!
柳井さんの次の問題にご期待ください。

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

■関連記事

【謎解きプログラム】この処理は?【コードを読もう】解答と解説... 【謎解きプログラム】この処理は?【コードを読もう】 本問題は、表題のテーマで、プログラムにちなんだ謎を解くというものでした。 それでは以下、各問題とその解答を見ていきましょう。 問題のオープニング ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。 「24時間以...
数学の問題をプログラミングで解こう!「ループ・トラッキング」問題解説... 問題のおさらい 自然数 n に対し、関数 Fn(x) を次のように定義します(floor():床関数)。 例えば n=10, x=1 のとき、F10(1) = floor(4×1×9÷10) = 3 です。 さて、整数 k(0 ≦ k ≦ n)に対して、関数 Fn による変換を繰り返し行い...
【謎解きプログラム】どんな結果になる?【アロー関数】解答と解説... 【謎解きプログラム】どんな結果になる?【アロー関数】 本問題は、表題のテーマで、プログラムにちなんだ謎を解くというものでした。 それでは以下、各問題とその解答を見ていきましょう。 問題のオープニング ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。 「24時間...
数学の問題をプログラミングで解こう!「カウント・スリー」問題解説... 問題のおさらい 自然数を 1 から順に書き並べていきます。 このとき、3 の数字が現れる回数を数えます。 自然数 n に対し、ちょうど n 個目の 3 の数字が現れたときに書いている数を F(n) と定義します。 例えば F(10)=35 です。 下の通り、10 個目の 3 は、35 を書いて...
【息抜き】カードを上手く並べよう【言語不問】解答と解説... 【息抜き】カードを上手く並べよう【言語不問】 本問題は、表題のテーマで、簡単なプログラムを書くものです。 それでは以下、問題とその解答を見ていきましょう。 問題 あなたは、11から99までの、89枚のカードを持っています。問題では、横幅と高さの整数が与えられます。この横幅と高さで作られるマス...
【コードミステリ】数字に隠されたメッセージ【言語不問】解答と解説... 【コードミステリ】数字に隠されたメッセージ【言語不問】 本問題は、表題のテーマで、簡単なプログラムを書くものです。 喜屋武ちあきさんによるCodeIQ MAGAZINEでのブックレビューに合わせて、『顔貌売人』(文藝春秋)とのコラボ問題として出題されたものです。 それでは以下、問題とその解...

今週のPickUPレポート

新着記事

週間ランキング

CodeIQとは

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

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

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