これは先生が出した課題で、1A2B というゲームを作るものでした。この授業を受けるまで、1A2B は難しいものだと思っていました。授業が終わってみると、全然難しくありませんでした。私が引きこもりすぎて、1A2B のルールすら知らなかっただけでした….

1A2B は数当てゲームです。答えが 1234 だとして、あなたがその数字を当てようとするとします。

1567 と入力すると、位置も数字も合っている数字が 1 つ(1)あるので、結果は 1A0B です。

1256 と入力すると、位置も数字も合っている数字が 2 つ(1 と 2)あるので、結果は 2A0B です。

次に B の由来を説明します。

4321 と入力すると、4 つの数字すべてが答えに含まれていますが、どれも位置が合っていないので、結果は 0A4B です。

4325 と入力すると、3 つの数字が答えに含まれていますが、どれも位置が合っていないので、結果は 0A3B です。

簡単にいうと、A は位置も数字も合っている数の個数で、B は答えに含まれているけれど位置が違う数の個数です。

ウィキペディアの説明:http://goo.gl/FvfLq

2 人で遊びます。一方が重複のない 4 桁の数字を決め、相手に知られないようにします。もう一方が当て始めます。数字を当てるたびに、数字を決めた側が xA yB の形で結果を返します。A の前の数字は位置も数字も合っている数の個数、B の前の数字は数字は合っているけれど位置が違う数の個数です。

以上のルールから、A を計算する部分と B を計算する部分に分けて考えられます。

解き方の説明:

まず A と B を調べる前に、答えとユーザーが入力した数字を、どちらも配列に分けておく必要があります(1 マスに 1 文字)。

A の計算は簡単で、ほとんどの人が書けるはずです。同じ位置を 1 つずつ比べていき、答えと入力が同じ位置で一致したら A を 1 増やします。次のように書けます。

if(x[i]==y[i]){a++;}

/*

x と y は答えとユーザーの入力を入れる配列です。i は i++ で増えていき、x と y のサイズに達するまで続きます。

*/

以上が A の計算ロジックです。B の計算は少し複雑です。

B は「答えに含まれているが、位置が違う数字」なので、線形探索に似た方法を使います。配列の各マスを調べ、違う位置で同じ数字が見つかったら B を 1 増やし、次の数字の探索に進みます。

以下が完全なコードです。A と B を分けて書きました。私のコードは簡単で、数学的な方法で解いています。読めるように、まずコメントを読んでください。

プロジェクトファイルのダウンロード:Box.net | 4Shared | Dropbox | Google

コード:

/*
    1A2B のプログラム
    アルゴリズムは一般的な文字列比較とは異なります。
    ユーザーの入力を直接整数として保存し、割り算を使って各桁を取り出します。
    例:
    1234/1000%10=4
    1234/100%10=3
    1234/10%10=2
*/

#include 
#include 

using namespace std;

int main(int argc, char *argv[])
{
    int x=1234;     //当てられる数字
    int a=0,b=0;        //A と B を数えるカウンター
    int y;      //ユーザーの入力を保存
    while(x!=y){
        a=0;b=0;
        cout<<"請輸入你要猜的數字:";
        cin>>y;
        cout<