ガジェット通信 GetNews

見たことのないものを見に行こう
ワンダーウーマン

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

DATE:
  • ガジェット通信 GetNewsを≫

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

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

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

問題のオープニング

ある日、出社すると、あなたの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運営事務局より

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

カテゴリー : デジタル・IT タグ :
CodeIQ MAGAZINEの記事一覧をみる ▶
  • 誤字を発見した方はこちらからご連絡ください。
  • ガジェット通信編集部への情報提供はこちらから
  • 記事内の筆者見解は明示のない限りガジェット通信を代表するものではありません。