トップページに戻る    次のC#のサンプルへ    前のC#のサンプルへ

Cマガ電脳クラブ(第146回) 逆さ電卓数字

問題

デジタル時計や電卓に昔からよく使われている数字 (ここでは電卓数字と呼ぶ) の表記では、
逆さから見ても数字として読めるものがある。
つまり、0、1、2、5、6、8、9は、
逆さから0、1、2、5、9、8、6と読めるのだ。

さて、Fig.1の四角に逆さから読める電卓数字を1字ずつ入れて式を成り立たせ、
さらに全体を180度回転して逆さから見ても数式として成立するようにしたい。

Fig.1にその例を示す。このような式は例も入れて何通り作れるだろうか?
ただし、逆さにした場合も含めて各3桁の数の左端には0はこないこととし、
また、和をとっている2数を入れ替えたものは別の解とはしない。

Fig.1 逆さから見ても成立する式


ソース

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        //3桁の数の変換表を作成
        DeriveConvInfoArr();

        int AnswerCnt = 0;
        int wkUB = ConvInfoArr.GetUpperBound(0);
        foreach (ConvInfoDef ConvInfoA in ConvInfoArr) {
            if (ConvInfoA.BeforeVal > 900) break;
            if (ConvInfoA.AfterVal > 900) continue;
            foreach (ConvInfoDef ConvInfoB in ConvInfoArr) {
                if (ConvInfoA.BeforeVal > ConvInfoB.BeforeVal) continue;

                if (ConvInfoA.BeforeVal + ConvInfoB.BeforeVal > 900) break;
                if (ConvInfoA.AfterVal + ConvInfoB.AfterVal > 900) continue;
                foreach (ConvInfoDef ConvInfoC in ConvInfoArr) {
                    if (ConvInfoC.BeforeVal < 200) continue;
                    if (ConvInfoC.AfterVal > 900) continue;
                    foreach (ConvInfoDef ConvInfoD in ConvInfoArr) {
                        if (ConvInfoD.BeforeVal > 900) break;

                        int Sahen1 = ConvInfoA.BeforeVal + ConvInfoB.BeforeVal;
                        int Uhen1 = ConvInfoC.BeforeVal - ConvInfoD.BeforeVal;
                        if (Sahen1 != Uhen1) continue;

                        int Sahen2 = ConvInfoD.AfterVal - ConvInfoC.AfterVal;
                        int Uhen2 = ConvInfoB.AfterVal + ConvInfoA.AfterVal;
                        if (Sahen2 != Uhen2) continue;

                        Console.WriteLine("解{0}を発見。{1}+{2}={3}-{4}",
                            ++AnswerCnt, ConvInfoA.BeforeVal, ConvInfoB.BeforeVal,
                            ConvInfoC.BeforeVal, ConvInfoD.BeforeVal);
                    }
                }
            }
        }
    }

    struct ConvInfoDef
    {
        internal int BeforeVal;
        internal int AfterVal;
    }
    static ConvInfoDef[] ConvInfoArr;

    //3桁の数の変換表を作成
    static void DeriveConvInfoArr()
    {
        var ConvInfoList = new List<ConvInfoDef>();

        int[] BaseNum = { 0, 1, 2, 5, 6, 8, 9 };
        int wkUB = BaseNum.GetUpperBound(0);

        for (int I = 0; I <= wkUB; I++) {
            //100の位の0は不適
            if (BaseNum[I] == 0) continue;
            for (int J = 0; J <= wkUB; J++) {
                for (int K = 0; K <= wkUB; K++) {
                    //1の位の0は不適
                    if (BaseNum[K] == 0) continue;

                    int wkBeforeVal = BaseNum[K];
                    wkBeforeVal += 10 * BaseNum[J];
                    wkBeforeVal += 100 * BaseNum[I];

                    Func<int, int> wkFunc = pInt =>
                    {
                        if (pInt == 6) return 9;
                        if (pInt == 9) return 6;
                        return pInt;
                    };
                    int wkAfterVal = wkFunc(BaseNum[I]);
                    wkAfterVal += 10 * wkFunc(BaseNum[J]);
                    wkAfterVal += 100 * wkFunc(BaseNum[K]);

                    ConvInfoList.Add(
                        new ConvInfoDef() { BeforeVal = wkBeforeVal, AfterVal = wkAfterVal });
                }
            }
        }
        ConvInfoArr = ConvInfoList.ToArray();
    }
}


実行結果

省略
解190を発見。255+261=812-296
解191を発見。261+282=812-269
解192を発見。261+285=812-266
解193を発見。262+281=812-269
解194を発見。265+281=812-266
解195を発見。282+282=862-298


解説

3桁の数を、180度回転した後の変換表を、事前に作成してから、

A+B = C-D
RevD-RevC = RevB+RevA
となる組み合わせを列挙してます。