循環数

数学の秘密の本棚

数学の秘密の本棚

 ウイルスの如き遅さで読み進めています。

 さっそく今回の話。

142857に、2,3,4,5,6,7を掛けるとどうなるか

という問題…問題?
さっそく計算してみたら、こうなった。

142857 × 2 = 285714
142857 × 3 = 428571
142857 × 4 = 571428
142857 × 5 = 714285
142857 × 6 = 857142
142857 × 7 = 999999

 答えが循環してる。
×2だったら答えは285714。順番をずらすと142857!
4だと571428で、順番をずらすと142857!
んで、勝手にそういう「桁順がずれる数」を循環数と呼ぶことにした。

 というわけで、やりすぎてみた。

142857 × 8 = 1142856  7桁目以上:1 修正値:142857
142857 × 9 = 1285713  7桁目以上:1 修正値:285714
142857 × 10 = 1428570 7桁目以上:1 修正値:428571
142857 × 11 = 1571427 7桁目以上:1 修正値:571428
142857 × 12 = 1714284 7桁目以上:1 修正値:714285
142857 × 13 = 1857141 7桁目以上:1 修正値:857142
142857 × 14 = 1999998 7桁目以上:1 修正値:999999
142857 × 15 = 2142855 7桁目以上:2 修正値:142857
142857 × 16 = 2285712 7桁目以上:2 修正値:285714
142857 × 17 = 2428569 7桁目以上:2 修正値:428571
142857 × 18 = 2571426 7桁目以上:2 修正値:571428
142857 × 19 = 2714283 7桁目以上:2 修正値:714285

 普通に計算すると似てる感じだった。
×8なんて、1142856でギリギリ違う。

 そこで、7桁目を削って1桁目に加えてやれば、綺麗な数が出るかもしれないと予想。
やってみた結果が修正値。
綺麗に元の値からズレた値になってる。

 修正値も×2と×9、×4と×11、×7と×14で同じになっている。
ある×aがあったとき、そのaに7の倍数を足した時の修正値も同じ値になってるのがわかる。


 さらにやりすぎてみた。

 理屈はよくわからんので(そこは賢い人が考えてくれるはず)、総当たりで似たような感じになる循環数を探してみた。
無論、手計算じゃなくてプログラムした。

 やりかた。
・調べる値p (p = 10,11,…,9999999)
pk (k = 2,3,…,9)を掛けて、答えa を得る
ap の循環数になっているかどうか調べる(修正値にしない)

 こんな感じで10から9999999まで総当たりをしてみた結果、
102564*4=410256
109890*9=989010
128205*4=512820
142857*2=285714
142857*3=428571
142857*4=571428
142857*5=714285
142857*6=857142

153846*3=461538
153846*4=615384

179487*4=717948
190476*4=761904
205128*4=820512
230769*3=692307
230769*4=923076

238095*4=952380
285714*2=571428
285714*3=857142

307692*3=923076
428571*2=857142
これだけ。
他はヒットしなかった。

もしかしてだいぶ特殊な数字なんだろうかなぁと思ったり。


 ついでにもう一つやりすぎてみた。
やりかた。
・調べる値p (p = 10,11,…,9999999)
pk (k = 2,3,…,9)を掛けて、答えa を得る
a を修正値にしてp の循環数になっているかどうか調べる

 やってみた結果(答えは修正値。最上位桁があふれていれば削って1桁目に加えてある)
33 × 4 = 33
33 × 7 = 33
66 × 4 = 66
66 × 7 = 66
99 × 2 = 99
99 × 3 = 99
99 × 4 = 99
99 × 5 = 99
99 × 6 = 99
99 × 7 = 99
99 × 8 = 99
99 × 9 = 99
333 × 4 = 333
333 × 7 = 333
666 × 4 = 666
666 × 7 = 666
999 × 2 = 999
999 × 3 = 999
999 × 4 = 999
999 × 5 = 999
999 × 6 = 999
999 × 7 = 999
999 × 8 = 999
999 × 9 = 999
3333 × 4 = 3333
3333 × 7 = 3333
6666 × 4 = 6666
6666 × 7 = 6666
9999 × 2 = 9999
9999 × 3 = 9999
9999 × 4 = 9999
9999 × 5 = 9999
9999 × 6 = 9999
9999 × 7 = 9999
9999 × 8 = 9999
9999 × 9 = 9999
33333 × 4 = 33333
33333 × 7 = 33333
66666 × 4 = 66666
66666 × 7 = 66666
99999 × 2 = 99999
99999 × 3 = 99999
99999 × 4 = 99999
99999 × 5 = 99999
99999 × 6 = 99999
99999 × 7 = 99999
99999 × 8 = 99999
99999 × 9 = 99999
102564 × 4 = 410256
109890 × 9 = 989010
128205 × 4 = 512820
142857 × 2 = 285714
142857 × 3 = 428571
142857 × 4 = 571428
142857 × 5 = 714285
142857 × 6 = 857142
142857 × 8 = 142857
142857 × 9 = 285714
153846 × 3 = 461538
153846 × 4 = 615384
164835 × 9 = 483516
179487 × 4 = 717948
190476 × 4 = 761904
197802 × 9 = 780219
205128 × 4 = 820512
230769 × 3 = 692307
230769 × 4 = 923076
238095 × 4 = 952380
241758 × 9 = 175824
282051 × 4 = 128205
285714 × 2 = 571428
285714 × 3 = 857142
285714 × 4 = 142857
285714 × 5 = 428571
285714 × 6 = 714285
285714 × 8 = 285714
285714 × 9 = 571428
307692 × 3 = 923076
307692 × 4 = 230769
307692 × 9 = 769230
318681 × 9 = 868131
329670 × 9 = 967032
333333 × 4 = 333333
333333 × 7 = 333333
380952 × 4 = 523809
384615 × 3 = 153846
384615 × 4 = 538461
395604 × 9 = 560439
410256 × 4 = 641025
428571 × 2 = 857142
428571 × 3 = 285714
428571 × 4 = 714285
428571 × 5 = 142857
428571 × 6 = 571428
428571 × 8 = 428571
428571 × 9 = 857142
435897 × 4 = 743589
461538 × 3 = 384615
461538 × 4 = 846153
461538 × 9 = 153846
472527 × 9 = 252747
476190 × 4 = 904761
483516 × 9 = 351648
487179 × 4 = 948717
564102 × 4 = 256410
571428 × 2 = 142857
571428 × 3 = 714285
571428 × 4 = 285714
571428 × 5 = 857142
571428 × 6 = 428571
571428 × 8 = 571428
571428 × 9 = 142857
589743 × 4 = 358974
593406 × 9 = 340659
615384 × 3 = 846153
615384 × 4 = 461538
619047 × 4 = 476190
641025 × 4 = 564102
648351 × 9 = 835164
659340 × 9 = 934065
666666 × 4 = 666666
666666 × 7 = 666666
703296 × 9 = 329670
714285 × 2 = 428571
714285 × 3 = 142857
714285 × 4 = 857142
714285 × 5 = 571428
714285 × 6 = 285714
714285 × 8 = 714285
714285 × 9 = 428571
717948 × 4 = 871794
736263 × 9 = 626373
743589 × 4 = 974358
769230 × 3 = 307692
791208 × 9 = 120879
794871 × 4 = 179487
809523 × 4 = 238095
820512 × 4 = 282051
824175 × 9 = 417582
846153 × 3 = 538461
846153 × 4 = 384615
857142 × 2 = 714285
857142 × 3 = 571428
857142 × 4 = 428571
857142 × 5 = 285714
857142 × 6 = 142857
857142 × 8 = 857142
857142 × 9 = 714285
871794 × 4 = 487179
897435 × 4 = 589743
904761 × 4 = 619047
912087 × 9 = 208791
923076 × 3 = 769230
923076 × 4 = 692307
923076 × 9 = 307692
934065 × 9 = 406593
945054 × 9 = 505494
948717 × 4 = 794871
952380 × 4 = 809523
956043 × 9 = 604395
967032 × 9 = 703296
974358 × 4 = 897435
978021 × 9 = 802197
999999 × 2 = 999999
999999 × 3 = 999999
999999 × 4 = 999999
999999 × 5 = 999999
999999 × 6 = 999999
999999 × 7 = 999999
999999 × 8 = 999999
999999 × 9 = 999999
3333333 × 4 = 3333333
3333333 × 7 = 3333333
6666666 × 4 = 6666666
6666666 × 7 = 6666666
9999999 × 2 = 9999999
9999999 × 3 = 9999999
9999999 × 4 = 9999999
9999999 × 5 = 9999999
9999999 × 6 = 9999999
9999999 × 7 = 9999999
9999999 × 8 = 9999999
9999999 × 9 = 9999999

 とりあえず、3…×4、3…×7、6…×4、6…×7、9…×2~9は確実。
あとやっぱり6桁の場合だけが異常。

 使ったソースコードはこんな感じ

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            int value;                  //元値
            int answer;                 //答え
            int[] arrvalue = null;      //元値の値配列
            int[] arranswer = null;     //答えの値配列

            //10から総当たり
            for (int i = 10; i <= 9999999; i++)
            {
                value = i;
                arrvalue = ToBigNum(value);
                int keta = i.ToString().Length; //元値の桁数

                for (int j = 2; j <= 9; j++)
                {
                    answer = i * j;
//                    if (answer.ToString().Length > keta) break;   //修正値の場合はON
                    answer = CheckAnswer(answer, keta);
                    if (answer.ToString().Length < keta) break; //答えの最上位桁が0だったら排除
                    arranswer = ToBigNum(answer);

                    if (CheckNumLoop(arranswer, arrvalue))
                    {
                        Debug.WriteLine(value + " × " + j + " = " + answer);
                    }
                }
            }
        }

        /// <summary>
        /// 数値を桁配列に直す
        /// </summary>
        /// <param name="n">桁配列にする値</param>
        /// <returns>桁配列</returns>
        static public int[] ToBigNum(int n)
        {
            int[] v = new int[n.ToString().Length];
            char[] c = n.ToString().ToCharArray();

            for (int i = 0; i < v.Length; i++)
            {
                v[i] = int.Parse(c[c.Length-i-1].ToString());
            }

            return v;
        }

        /// <summary>
        /// 数値の循環チェック
        /// </summary>
        /// <param name="v">チェックする桁配列</param>
        /// <param name="n">循環数</param>
        /// <returns>順関数:true その他:false</returns>
        static public Boolean CheckNumLoop(int[] answer, int[] value)
        {
            Boolean f = false;

            //最初の一致点を探す
            for (int a = answer.Length-1; a >= 0; a--)
            {
                if (answer[a] == value[value.Length - 1])
                {
                    f = CheckOrder(a, answer, value);
                    break;
                }
            }

            if (f == false) return false;    //一致点が無い
            else return true;
        }

        /// <summary>
        /// 順序チェック
        /// </summary>
        /// <param name="agree">最上位桁の一致点</param>
        /// <param name="answer">答えの値配列</param>
        /// <param name="value">元値の値配列</param>
        /// <returns>循環:true その他:false</returns>
        static public Boolean CheckOrder(int agree, int[] answer, int[] value)
        {
            for (int v = value.Length - 1; v >= 0; v--)
            {
                if (answer[agree] != value[v]) return false;
                if ((--agree) < 0) agree = answer.Length - 1;
            }
            return true;
        }

        /// <summary>
        /// 答えの桁修正
        /// </summary>
        /// <param name="answer">答えの値</param>
        /// <param name="k">指定桁</param>
        /// <returns>桁修正値</returns>
        static public int CheckAnswer(int answer, int k)
        {
            int t = (int)(answer * Math.Pow(0.1, k));
            answer = answer - (int)(t * Math.Pow(10, k)) + t;

            return answer;
        }
    }
}