CodeIQ MAGAZINECodeIQ MAGAZINE

【謎解きプログラム】どう比較する?【ソート】解答と解説

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

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

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

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

【謎解きプログラム】どう比較する?【ソート】

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

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

問題のオープニング

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

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

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

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

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

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

問題1

配列のソートは、プログラムでよく見られる処理です。その際、ソートの比較を関数で指定して、並べ替えを制御する方法が、よく用いられます。

以下、プログラムはJavaScriptで書いていますが、内容自体は汎用的なものです。

下記のような入力と出力が行なわれる際、ソートの比較を行なう関数は、選択肢1~3のうち、どのような内容になるでしょうか?

0, 2, 3, 5, 6, 7, 8, 4, 1, 9    // 入力
9, 8, 7, 6, 5, 4, 3, 2, 1, 0    // 出力
// プログラム
var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力
// 選択肢1
res = b + a;

// 選択肢2
res = b - a;

// 選択肢3
res = b * a; 

以下は、参考用のJavaScriptの数値のソートです。

// 数値のソート
var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {return a - b});   // ソート
console.log(a.join(', '));   // 出力
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

多くのプログラミング言語では、配列のソートを行なう際に、Comparator(コンパレーター)などと呼ばれる、比較を専門に行なう関数を引数に取れるようになっています。そして、この関数の中で、どちらの要素が前で、どちらの要素が後かを判定し、順番を並べ替えます。

参考として挙げているJavaScriptのソートでは、a, bの2つの値を引数に取る関数(compareFunction)が、sort関数の引数として設定されています。

この引数の関数では、0未満の値を戻すと、aをbより前に移動します。0の場合は移動なし。0より大きい場合は、bをaより前に移動します。

上記では、2つの引数a, bを使い、「a – b」の計算結果を戻すことで、昇順で出力されています。「a – b」の計算を行なうことで、0未満の値、0、0より大きい値、が得られるわけです。

問題は、降順で出力されていますので、「a – b」とは逆の順番になっています。

そのため、「b – a」の計算結果を戻せばよいことになります。

というわけで、2番目の選択肢『res = b – a;』が答えになります。

以下、Webブラウザのコンソールで実行可能な、JavaScriptのコードを掲載しておきます。

// サンプルコード
var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = b + a;    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力


var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = b - a;    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力


var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = b * a;    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力
// 出力
9, 1, 4, 8, 7, 6, 5, 3, 2, 0
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
0, 9, 1, 4, 8, 7, 6, 5, 3, 2

問題2

配列のソートは、プログラムでよく見られる処理です。その際、ソートの比較を関数で指定して、並べ替えを制御する方法が、よく用いられます。

以下、プログラムはJavaScriptで書いていますが、内容自体は汎用的なものです。

下記のような入力と出力が行なわれる際、ソートの比較を行なう関数は、選択肢1~3のうち、どのような内容になるでしょうか?

32, 53, 25, 46, 97, 78, 84, 11, 69    // 入力
11, 32, 53, 84, 25, 46, 97, 78, 69    // 出力
// プログラム
var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力
// 選択肢1 (乗算)
res = a*10 - b*10;

// 選択肢2 (除算)
res = a/10 - b/10;

// 選択肢3 (剰余)
res = a%10 - b%10;

以下は、参考用のJavaScriptの数値のソートです。

// 数値のソート
var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {return a - b});   // ソート
console.log(a.join(', '));   // 出力
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

出力結果の規則性を見つけられれば、すぐに解けます。下1桁でソートが行なわれています。

規則性を見つけられなくても、選択肢の計算の結果、どのようなソートが行なわれるかを考えれば、自ずと答えが出ます。

「選択肢1 (乗算)」と「選択肢2 (除算)」は、「(a – b) * 10」「(a – b) / 10」と変形可能です。これは、単なる昇順のソートと同じです。この2つを除外した、「選択肢3 (剰余)」が答えになります。

というわけで、3番目の選択肢『res = a%10 – b%10;』が答えになります。

以下、Webブラウザのコンソールで実行可能な、JavaScriptのコードを掲載しておきます。

// サンプルコード
var a = [32, 53, 25, 46, 97, 78, 84, 11, 69];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = a*10 - b*10;    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力


var a = [32, 53, 25, 46, 97, 78, 84, 11, 69];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = a/10 - b/10;    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力


var a = [32, 53, 25, 46, 97, 78, 84, 11, 69];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = a%10 - b%10;    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力
// 出力
11, 25, 32, 46, 53, 69, 78, 84, 97
11, 25, 32, 46, 53, 69, 78, 84, 97
11, 32, 53, 84, 25, 46, 97, 78, 69

問題3

配列のソートは、プログラムでよく見られる処理です。その際、ソートの比較を関数で指定して、並べ替えを制御する方法が、よく用いられます。

以下、プログラムはJavaScriptで書いていますが、内容自体は汎用的なものです。

下記のような入力と出力が行なわれる際、ソートの比較を行なう関数は、選択肢1~3のうち、どのような内容になるでしょうか?

0, 2, 3, 5, 6, 7, 8, 4, 1, 9    // 入力
1, 3, 5, 7, 9, 0, 2, 4, 6, 8    // 出力
// プログラム
var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    // 選択肢のコードは、ここに入る
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力
// 選択肢1
res = a%2 - b%2;
if (res == 0) {res = a - b};

// 選択肢2
res = b%2 - a%2;
if (res == 0) {res = a - b};

// 選択肢3
res = b%2 - a%2;
if (res == 0) {res = b - a};

以下は、参考用のJavaScriptの数値のソートです。

// 数値のソート
var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {return a - b});   // ソート
console.log(a.join(', '));   // 出力
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

今回は、出力結果の規則性を、すぐには見つけられないかもしれません。

規則性を見つけられない場合は、選択肢の計算の結果がどのようになるのか、確認していけばよいです。

3つの選択肢の処理は、共通点が多いです。最初にa, bの、2の剰余を取って、引き算を行なっています。この部分では、偶数か奇数かという比較を行なっています。

次の行では、resの値が0、つまりどちらも偶数、あるいはどちらも奇数の場合に、a, bを比較して順番を決めています。

「選択肢1」では、最初に偶数を前に、奇数を後ろにして、次に昇順にソートしています。

「選択肢2」では、最初に奇数を前に、偶数を後ろにして、次に昇順にソートしています。

「選択肢3」では、最初に奇数を前に、偶数を後ろにして、次に降順にソートしています。

というわけで、2番目の選択肢『res = b%2 – a%2;』『if (res == 0) {res = a – b};』が答えになります。

以下、Webブラウザのコンソールで実行可能な、JavaScriptのコードを掲載しておきます。

// サンプルコード
var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = a%2 - b%2;
    if (res == 0) {res = a - b};
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力


var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = b%2 - a%2;
    if (res == 0) {res = a - b};
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力


var a = [0, 2, 3, 5, 6, 7, 8, 4, 1, 9];   // 入力
a.sort((a, b) => {   // ソート
    var res;
    res = b%2 - a%2;
    if (res == 0) {res = b - a};
    return res;   // 戻り値
});
console.log(a.join(', '));   // 出力
// 出力
0, 2, 4, 6, 8, 1, 3, 5, 7, 9
1, 3, 5, 7, 9, 0, 2, 4, 6, 8
9, 7, 5, 3, 1, 8, 6, 4, 2, 0

CodeIQ運営事務局より

柳井さん、ありがとうございました!
現在、柳井さんの最新問題が出題中です。
ぜひ挑戦してみてくださいね!

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

■関連記事

数学の問題をプログラミングで解こう!「タンジェント・フラクション」問題解説... 問題のおさらい α と β を、0 < α < β < π/2 を満たす実数とします。 α, β の組のうち、tan(α), tan(β), tan(α+β) がすべて単位分数(分母が自然数、分子が 1 の分数として書き表せる数)となるものを考えましょう。(α, β の単位はラジアンと見なします...
数学の問題をプログラミングで解こう!「ロンリー・ルーク」問題解説... 問題のおさらい 自然数 n, k に対し、縦横 n×n のマス目にチェスのルークの駒を k 個配置することを考えます。 このとき、自身から見て上下方向・左右方向のいずれにも他の駒が存在しないような駒を「はぐれルーク」と呼びます。 例えば以下は、(n, k)=(4, 5) のときの駒の配置例を示...
【謎解きプログラム】どんな数字になる?【整数のキャスト】解答と解説... 【謎解きプログラム】どんな数字になる?【整数のキャスト】 本問題は、表題のテーマで、プログラムにちなんだ謎を解くというものでした。 それでは以下、各問題とその解答を見ていきましょう。 問題のオープニング ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。 「24...
【謎解きプログラム】テキストのバイナリは?【テキスト バイナリ】解答と解説... 【謎解きプログラム】テキストのバイナリは?【テキスト バイナリ】 本問題は、表題のテーマで、プログラムにちなんだ謎を解くというものでした。 それでは以下、各問題とその解答を見ていきましょう。 問題のオープニング ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。 ...
【謎解きプログラム】条件に当てはまる文字列は?【正規表現】解答と解説... 【謎解きプログラム】条件に当てはまる文字列は?【正規表現】 本問題は、表題のテーマで、プログラムにちなんだ謎を解くというものでした。 それでは以下、各問題とその解答を見ていきましょう。 問題のオープニング ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。 「2...
【謎解きプログラム】乱数で発生する数値は?【組み合わせ】解答と解説... 【謎解きプログラム】乱数で発生する数値は?【組み合わせ】 本問題は、表題のテーマで、プログラムにちなんだ謎を解くというものでした。 それでは以下、各問題とその解答を見ていきましょう。 問題のオープニング ある日、出社すると、あなたのPCのログイン画面に、謎の挑戦状が表示されていた。 「24...

今週のPickUPレポート

新着記事

週間ランキング

CodeIQとは

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

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

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