Quantcast
Channel: 円周率近似値の日に生まれて理系じゃないわけないだろ! - knifeのblog
Viewing all articles
Browse latest Browse all 5376

カプレカ数を生成するプログラムを組む

$
0
0

カプレカ数ネタ、まだまだやっております。

さて、当初はカプレカ数を探索するプログラムを書きました。

あのプログラムは、カプレカ数をローラー作戦で探索するようなプログラムだったのですが、今回は全く違うアプローチとなります。

何が違うかっていうと、探すのではなく、作る感じです。

先日、手書きでも作れる方法を示した通り、あれをプログラミングしてみたということでもあります。

自ら作り出すので、桁数に制限がなくなります。
これはヤバいです。

ネットには60桁までしか情報がなかったけど、このプログラムを使えば、100桁でも1000桁でも10000桁でも関係ありません。

但し、60桁までは正しいことは確認しましたが、それ以降漏れなく例外なく正しいのかまでは解りません。
 

#include <stdio.h>
#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にしました。

サンプル

> kapmaker 3 20
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.

DigitsType 45/55
495
549945
554999445
Type 64
6174
631764
63317664
Type 82
864197532
86431976532
8643319766532
Type 91
97508421
9753086421
9975084201
Total
310001
401001
500000
611002
700000
801012
910102
1001023
1100101
1211035
1300101
1401056
1510102
1601078
1700112
18111912
1900123
200111214
2110135
220111517
2300257
241111821
2500178
260112325
27102912
280112830
290021214
301113336
310021517
320124043
331021821
340114749
350022325
361125458
370032831
380126366
391023336
400127275
410034043
421128185
430024749
440129396
451035458
46013105109
470036366
48112117121
490037275
50013132136
511048186
52012147150
530039396
54113162167
55004105109
56013180184
57103117121
58013198202
59004132136
60114216222
61003147150
62013238242
63104162167
64014260265
65005180185
66113282287
67004198202
68014308313
69105216222
70013334338
71004238242
72114360366
73005260265
74015390396
75104282287
76014420425
77005308313
78115450457
79005334339
80014485490
81105360366
82015520526
83006390396
84114555561
85005420425
86015595601
87106450457
88015635641
89005485490
90115675682
91006520526
92016720727
93106555562
94015765771
95006595601
96116810818
97006635641
98015861867
99106675682
100016912919
Total33492922080821182


もし、このプログラムで表示されないカプレカ数、カプレカ数ではないのに表示されるもの、などがございましたら、コメントにてお知らせください。
確認が取れ次第、プログラムを更新します。


ではでは


Viewing all articles
Browse latest Browse all 5376

Trending Articles