カプレカ数ネタ、まだまだやっております。
さて、当初はカプレカ数を探索するプログラムを書きました。
あのプログラムは、カプレカ数をローラー作戦で探索するようなプログラムだったのですが、今回は全く違うアプローチとなります。
何が違うかっていうと、探すのではなく、作る感じです。
先日、手書きでも作れる方法を示した通り、あれをプログラミングしてみたということでもあります。
自ら作り出すので、桁数に制限がなくなります。
これはヤバいです。
ネットには60桁までしか情報がなかったけど、このプログラムを使えば、100桁でも1000桁でも10000桁でも関係ありません。
但し、60桁までは正しいことは確認しましたが、それ以降漏れなく例外なく正しいのかまでは解りません。
#include <stdlib.h>
int type45(int d)
{
int i;
if ( d%3 != 0 || d < 3 ) return 0;
for (i=1; i<d/3; i++) printf("5"); printf("4");
for (i=0; i<d/3; i++) printf("9");
for (i=1; i<d/3; i++) printf("4"); printf("5\n");
return 1;
}
int type64(int d)
{
int i;
if ( d%2 != 0 || d < 4 ) return 0;
printf("6");
for (i=0; i<(d-4)/2; i++) printf("3");
printf("17");
for (i=0; i<(d-4)/2; i++) printf("6");
printf("4\n");
return 1;
}
int type82(int d)
{
int i, n, e, f, t;
for (e=1; e<=d/9; e++)
for (n=1; n<=(d-2*e)/7; n++) {
if ( d >= 9*n && n == e && (d-9*n)%2 == 0 ) {
t = (d-9*n)/2;
for (i=0; i<n; i++) printf("8");
for (i=0; i<n; i++) printf("6");
for (i=0; i<n; i++) printf("4");
for (i=0; i<t; i++) printf("3");
for (i=0; i<n-1; i++) printf("2"); printf("1");
for (i=0; i<n; i++) printf("9");
for (i=0; i<n; i++) printf("7");
for (i=0; i<t; i++) printf("6");
for (i=0; i<n; i++) printf("5");
for (i=0; i<n; i++) printf("3");
for (i=0; i<n-1; i++) printf("1"); printf("2\n");
}
if ( d == 7*n+2*e && n > e && (n-e)%2 == 0 ) {
f = (n-e)/2;
for (i=0; i<e; i++) printf("8");
for (i=0; i<n-e; i++) printf("7");
for (i=0; i<e; i++) printf("6");
for (i=0; i<f; i++) printf("5");
for (i=0; i<n-f; i++) printf("4");
for (i=0; i<f; i++) printf("3");
for (i=0; i<n-f-1; i++) printf("2"); printf("1");
for (i=0; i<n; i++) printf("9");
for (i=0; i<n-f; i++) printf("7");
for (i=0; i<f; i++) printf("6");
for (i=0; i<n-f; i++) printf("5");
for (i=0; i<f; i++) printf("4");
for (i=0; i<e; i++) printf("3");
for (i=0; i<n-e; i++) printf("2");
for (i=0; i<e-1; i++) printf("1"); printf("2\n");
}
}
return 1;
}
int type91(int d)
{
int i, n, e, s, t;
for (n=0; n<=(d-8)/2; n++)
for (e=0; e<=(d-2*n-6)/(8+d%2); e++)
for (s=1; s<d-2*n-(8+d%2)*e; s++) {
if ( d%2 == e%2 && d-2*n-6*s-9*e-2 >= 0 ) {
t = (d-2*n-6*s-9*e-2)/2;
for (i=0; i<n+1; i++) printf("9");
for (i=0; i<e; i++) printf("8");
for (i=0; i<s; i++) printf("7");
for (i=0; i<e; i++) printf("6");
for (i=0; i<s; i++) printf("5");
for (i=0; i<e; i++) printf("4");
for (i=0; i<t; i++) printf("3");
for (i=0; i<e; i++) printf("2");
for (i=0; i<s-1; i++) printf("1"); printf("0");
for (i=0; i<e; i++) printf("9");
for (i=0; i<s; i++) printf("8");
for (i=0; i<e; i++) printf("7");
for (i=0; i<t; i++) printf("6");
for (i=0; i<e; i++) printf("5");
for (i=0; i<s; i++) printf("4");
for (i=0; i<e; i++) printf("3");
for (i=0; i<s; i++) printf("2");
for (i=0; i<e; i++) printf("1");
for (i=0; i<n; i++) printf("0"); printf("1\n");
}
}
return 1;
}
int main(int argc, char *argv[])
{
int d, s, e;
switch ( argc ) {
case 2:
s = e = atoi(argv[1]);
break;
case 3:
s = atoi(argv[1]);
e = atoi(argv[2]);
break;
default:
s = 3;
e = 100;
break;
}
for (d=s; d<=e; d++) {
type45(d);
type64(d);
type82(d);
type91(d);
}
return EXIT_SUCCESS;
}
もし、カプレカ数を見つけろというプログラミングの課題があったとして、これを提出したらヤバすぎると思います。(自画自賛)
多倍長演算とかそういう類のことをしているわけではありません。
表示される数値がカプレカ数かどうかを、プログラム内部でチェックしていません。
9が何個、8が何個、…という規則に従って愚直に列挙しているに過ぎないのです。
こんなプログラムを書いちゃダメってのの見本みたいだなぁ。
まぁ、多少は考慮するところもあって、小さい順に出力するように、ネストを考えました。
プログラム的には、
パラメータには、桁数を指定できます。
第1引数に桁数を与えると、その桁数のカプレカ数を出力します。
第1引数、第2引数に桁数与えると、何桁から何桁までのカプレカ数を出力します。
パラメータなしでは、3桁から100桁までを出力するようになっていますが、特に100桁までの制限を掛けているわけではありませんので、100桁と言わず、1000桁でも、10000桁でも、お好きなだけ、どうぞ。
カプレカ数を作るプログラムなので、前のプログラムとの差別化もあって、kapmaker.exeにしました。
サンプル
495
6174
549945
631764
63317664
97508421
554999445
864197532
6333176664
9753086421
9975084201
86431976532
555499994445
633331766664
975330866421
997530864201
999750842001
8643319766532
63333317666664
97533308666421
97755108844221
99753308664201
99975308642001
99997508420001
555549999944445
864333197666532
6333333176666664
9753333086666421
9775531088644221
9975333086664201
9977551088442201
9997533086642001
9999753086420001
9999975084200001
86433331976666532
98765420987543211
555554999999444445
633333331766666664
886644219977553312
975333330866666421
977553310886644221
997533330866664201
997755310886442201
999753330866642001
999775510884422001
999975330866420001
999997530864200001
999999750842000001
8643333319766666532
9876543209876543211
9987654209875432101
63333333317666666664
88664432199776553312
97533333308666666421
97755333108866644221
97775551108884442221
99753333308666664201
99775533108866442201
99975333308666642001
99977553108864422001
99997533308666420001
99997755108844220001
99999753308664200001
99999975308642000001
99999997508420000001
こんな感じで、前に作った探索プログラムとは桁違いの速さで出力しますよ。
まぁ、当たり前ですがw
とりあえず、3桁から100桁までの、45/55型、64型、82型、91型の個数を集計してみました。
The Number of Kaprekar's Constant from 3 to 100 digits.
Digits | Type 45/55 495 549945 554999445 ︙ | Type 64 6174 631764 63317664 ︙ | Type 82 864197532 86431976532 8643319766532 ︙ | Type 91 97508421 9753086421 9975084201 ︙ | Total |
3 | 1 | 0 | 0 | 0 | 1 |
4 | 0 | 1 | 0 | 0 | 1 |
5 | 0 | 0 | 0 | 0 | 0 |
6 | 1 | 1 | 0 | 0 | 2 |
7 | 0 | 0 | 0 | 0 | 0 |
8 | 0 | 1 | 0 | 1 | 2 |
9 | 1 | 0 | 1 | 0 | 2 |
10 | 0 | 1 | 0 | 2 | 3 |
11 | 0 | 0 | 1 | 0 | 1 |
12 | 1 | 1 | 0 | 3 | 5 |
13 | 0 | 0 | 1 | 0 | 1 |
14 | 0 | 1 | 0 | 5 | 6 |
15 | 1 | 0 | 1 | 0 | 2 |
16 | 0 | 1 | 0 | 7 | 8 |
17 | 0 | 0 | 1 | 1 | 2 |
18 | 1 | 1 | 1 | 9 | 12 |
19 | 0 | 0 | 1 | 2 | 3 |
20 | 0 | 1 | 1 | 12 | 14 |
21 | 1 | 0 | 1 | 3 | 5 |
22 | 0 | 1 | 1 | 15 | 17 |
23 | 0 | 0 | 2 | 5 | 7 |
24 | 1 | 1 | 1 | 18 | 21 |
25 | 0 | 0 | 1 | 7 | 8 |
26 | 0 | 1 | 1 | 23 | 25 |
27 | 1 | 0 | 2 | 9 | 12 |
28 | 0 | 1 | 1 | 28 | 30 |
29 | 0 | 0 | 2 | 12 | 14 |
30 | 1 | 1 | 1 | 33 | 36 |
31 | 0 | 0 | 2 | 15 | 17 |
32 | 0 | 1 | 2 | 40 | 43 |
33 | 1 | 0 | 2 | 18 | 21 |
34 | 0 | 1 | 1 | 47 | 49 |
35 | 0 | 0 | 2 | 23 | 25 |
36 | 1 | 1 | 2 | 54 | 58 |
37 | 0 | 0 | 3 | 28 | 31 |
38 | 0 | 1 | 2 | 63 | 66 |
39 | 1 | 0 | 2 | 33 | 36 |
40 | 0 | 1 | 2 | 72 | 75 |
41 | 0 | 0 | 3 | 40 | 43 |
42 | 1 | 1 | 2 | 81 | 85 |
43 | 0 | 0 | 2 | 47 | 49 |
44 | 0 | 1 | 2 | 93 | 96 |
45 | 1 | 0 | 3 | 54 | 58 |
46 | 0 | 1 | 3 | 105 | 109 |
47 | 0 | 0 | 3 | 63 | 66 |
48 | 1 | 1 | 2 | 117 | 121 |
49 | 0 | 0 | 3 | 72 | 75 |
50 | 0 | 1 | 3 | 132 | 136 |
51 | 1 | 0 | 4 | 81 | 86 |
52 | 0 | 1 | 2 | 147 | 150 |
53 | 0 | 0 | 3 | 93 | 96 |
54 | 1 | 1 | 3 | 162 | 167 |
55 | 0 | 0 | 4 | 105 | 109 |
56 | 0 | 1 | 3 | 180 | 184 |
57 | 1 | 0 | 3 | 117 | 121 |
58 | 0 | 1 | 3 | 198 | 202 |
59 | 0 | 0 | 4 | 132 | 136 |
60 | 1 | 1 | 4 | 216 | 222 |
61 | 0 | 0 | 3 | 147 | 150 |
62 | 0 | 1 | 3 | 238 | 242 |
63 | 1 | 0 | 4 | 162 | 167 |
64 | 0 | 1 | 4 | 260 | 265 |
65 | 0 | 0 | 5 | 180 | 185 |
66 | 1 | 1 | 3 | 282 | 287 |
67 | 0 | 0 | 4 | 198 | 202 |
68 | 0 | 1 | 4 | 308 | 313 |
69 | 1 | 0 | 5 | 216 | 222 |
70 | 0 | 1 | 3 | 334 | 338 |
71 | 0 | 0 | 4 | 238 | 242 |
72 | 1 | 1 | 4 | 360 | 366 |
73 | 0 | 0 | 5 | 260 | 265 |
74 | 0 | 1 | 5 | 390 | 396 |
75 | 1 | 0 | 4 | 282 | 287 |
76 | 0 | 1 | 4 | 420 | 425 |
77 | 0 | 0 | 5 | 308 | 313 |
78 | 1 | 1 | 5 | 450 | 457 |
79 | 0 | 0 | 5 | 334 | 339 |
80 | 0 | 1 | 4 | 485 | 490 |
81 | 1 | 0 | 5 | 360 | 366 |
82 | 0 | 1 | 5 | 520 | 526 |
83 | 0 | 0 | 6 | 390 | 396 |
84 | 1 | 1 | 4 | 555 | 561 |
85 | 0 | 0 | 5 | 420 | 425 |
86 | 0 | 1 | 5 | 595 | 601 |
87 | 1 | 0 | 6 | 450 | 457 |
88 | 0 | 1 | 5 | 635 | 641 |
89 | 0 | 0 | 5 | 485 | 490 |
90 | 1 | 1 | 5 | 675 | 682 |
91 | 0 | 0 | 6 | 520 | 526 |
92 | 0 | 1 | 6 | 720 | 727 |
93 | 1 | 0 | 6 | 555 | 562 |
94 | 0 | 1 | 5 | 765 | 771 |
95 | 0 | 0 | 6 | 595 | 601 |
96 | 1 | 1 | 6 | 810 | 818 |
97 | 0 | 0 | 6 | 635 | 641 |
98 | 0 | 1 | 5 | 861 | 867 |
99 | 1 | 0 | 6 | 675 | 682 |
100 | 0 | 1 | 6 | 912 | 919 |
Total | 33 | 49 | 292 | 20808 | 21182 |
もし、このプログラムで表示されないカプレカ数、カプレカ数ではないのに表示されるもの、などがございましたら、コメントにてお知らせください。
確認が取れ次第、プログラムを更新します。
ではでは