トップページに戻る    次の増井さんの書籍の問題へ    前の増井さんの書籍の問題へ

Q36 「0」と「7」の回文数


C#のソース

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        for (int I = 1; I <= 18; I++) {
            long[] NumArr = DeriveNumArr(I);

            //正の倍数のみ
            NumArr = Array.FindAll(NumArr, X => X > 0);

            bool WillContinue = false;
            for (int N = 1; N <= 50; N++) {
                if (Array.Exists(NumArr, X => X % N == 0) == false) {
                    WillContinue = true;
                    break;
                }
                if (WillContinue) continue;
            }
            if (WillContinue) continue;

            int AnswerCnt = 0;
            for (int N = 1; N <= 50; N++) {
                long wkMinNum = NumArr.Where(X => X % N == 0).Min();

                //回文数のみ
                if (IskaibunSuu(wkMinNum) == false) continue;

                //0と7の両方を含むか判定
                //if (Exist0And7(wkMinNum) == false) continue;

                AnswerCnt++;
                Console.WriteLine("解{0}を発見。{1}の倍数の{2}", AnswerCnt, N, wkMinNum);
            }
            break;
        }
    }

    struct JyoutaiDef
    {
        internal int Level;
        internal long CurrNum;
    }

    //最大桁数以下の、数字が0と7のみの数値を列挙
    static long[] DeriveNumArr(int pLimitLevel)
    {
        var WillReturn = new List<long>();

        var stk = new Stack<JyoutaiDef>();
        JyoutaiDef WillPush;
        WillPush.Level = 0;
        WillPush.CurrNum = 0;
        stk.Push(WillPush);

        while (stk.Count > 0) {
            JyoutaiDef Popped = stk.Pop();

            WillReturn.Add(Popped.CurrNum);

            //レベル制限
            if (Popped.Level == pLimitLevel)
                continue;

            Action<long> PushSyori = pNewNum =>
            {
                WillPush.Level = Popped.Level + 1;
                WillPush.CurrNum = pNewNum;
                stk.Push(WillPush);
            };

            PushSyori(Popped.CurrNum * 10 + 0);
            PushSyori(Popped.CurrNum * 10 + 7);
        }
        return WillReturn.ToArray();
    }

    //回文数かを判定
    static bool IskaibunSuu(long pTargetNum)
    {
        var NumList = new List<long>();
        long CopiedNum = pTargetNum;
        do {
            long ModVal = CopiedNum % 10;
            NumList.Add(ModVal);
            CopiedNum /= 10;
        } while (CopiedNum > 0);

        long RevNum = 0;
        foreach (long EachNum in NumList) {
            RevNum *= 10;
            RevNum += EachNum;
        }
        return pTargetNum == RevNum;
    }

    //0と7の両方を含むか判定
    static bool Exist0And7(long pTargetNum)
    {
        var NumList = new List<long>();
        long CopiedNum = pTargetNum;
        do {
            long ModVal = CopiedNum % 10;
            NumList.Add(ModVal);
            CopiedNum /= 10;
        } while (CopiedNum > 0);

        if (NumList.Contains(0) == false) return false;
        return NumList.Contains(7);
    }
}


実行結果

解1を発見。1の倍数の7
解2を発見。3の倍数の777
解3を発見。7の倍数の7
解4を発見。9の倍数の777777777
解5を発見。11の倍数の77
解6を発見。13の倍数の7007
解7を発見。21の倍数の777
解8を発見。33の倍数の777777
解9を発見。37の倍数の777
解10を発見。39の倍数の70707
解11を発見。41の倍数の77777
解12を発見。49の倍数の7007


解説

0と7から構成される数値を先に列挙してます。