前記事の結果、100桁では粘度12が見つからなかったので、迷走中である。
とりあえず、何桁でも求められるプログラムを組んでみた。
#include <stdio.h>
#include <stdlib.h>
#define KETA 1000
#define K1 KETA/4
#define K2 K1-1
#define K3 K2-1
void calc(void);
void n9(void);
void n8(void);
void n7(void);
void n6(void);
void n5(void);
void n4(void);
void n3(void);
void n2(void);
int x[K1] = {1}, y, z=2;
int n[10] = {0};
int hb = 0;
void calc()
{
int i, j, k, l, m;
for (i=9, k=KETA-1; i>0; i--)
for (j=0; j<n[i]; j++, k--)
if ( k%4 == 3 && i == 1 ) {
x[k/4] = 1;
break;
} else if ( k%4 == 3 ) {
x[k/4] = i;
} else if ( i > 1 ) {
x[k/4] *= i;
}
for (; k>0; k-=4) x[k/4] = 1;
y = 1;
while ( x[K2] > 9 ) {
y ++;
for (j=K3; j>-1; j--) {
if ( x[j] > 1 ) {
m = 0;
for (k=K2; k>j; k--) {
l = x[j]*x[k]+m;
x[k] = l%10000;
m = l/10000;
}
x[j] = m;
} else if ( x[j] == 1 ) {
x[j] = 0;
} else {
x[K2] = 0;
break;
}
}
k = 1;
for (j=0; j<K1; j++) {
if ( k == 0 ) {
x[j] = (x[j]/1000)*((x[j]/100)%10)*((x[j]/10)%10)*(x[j]%10);
} else if ( k && x[j] > 999 ) {
x[j] = (x[j]/1000)*((x[j]/100)%10)*((x[j]/10)%10)*(x[j]%10);
k = 0;
} else if ( k && x[j] > 99 ) {
x[j] = ((x[j]/100)%10)*((x[j]/10)%10)*(x[j]%10);
k = 0;
} else if ( k && x[j] > 9 ) {
x[j] = ((x[j]/10)%10)*(x[j]%10);
k = 0;
} else if ( k && x[j] > 0 ) {
x[j] = (x[j]%10);
k = 0;
} else if ( k && x[j] == 0 ) {
x[j] = 1;
}
}
}
if ( y > z ) {
z = y;
printf("\r%2d:", z);for (i=2; i<10; i++) for (j=0; j<n[i]; j++) printf("%d", i); printf("\n");
}
}
void n9()
{
n[9] = KETA-n[1]-n[2]-n[3]-n[4]-n[5]-n[6]-n[7]-n[8];
calc();
}
void n8()
{
if ( !n[5] ) {
for (n[8]=KETA-n[1]-n[2]-n[3]-n[4]-n[5]-n[6]-n[7]; n[8]>-1; n[8]--) {
if ( !n[2] && !n[3] && !n[4] && !n[6] ) printf(".8\b\b");
n9();
}
} else {
n[8] = 0;
n9();
}
}
void n7()
{
for (n[7]=KETA-n[1]-n[2]-n[3]-n[4]-n[5]-n[6]; n[7]>-1; n[7]--) {
if ( !n[2] && !n[3] && !n[4] && !n[5] && !n[6] ) printf(".7\b\b");
n8();
}
}
void n6()
{
if ( !n[3] ) {
for (n[6]=min(KETA-n[1]-n[2]-n[3]-n[4]-n[5],1); n[6]>-1; n[6]--) {
if ( !n[2] && !n[3] && !n[4] ) printf(".6\b\b");
n7();
}
} else {
n[6] = 0;
n7();
}
}
void n5()
{
for (n[5]=KETA-n[1]-n[2]-n[3]-n[4]; n[5]>0; n[5]--) {
n[6] = 0;
n7();
}
n[5] = 0;
n6();
}
void n4()
{
printf(".4\b\b");
n[4] = 1;
n[5] = 0;
n6();
n[4] = 0;
n5();
}
void n3()
{
printf(".3\b\b");
n[3] = 1;
n[4] = 0;
n5();
n[3] = 0;
n4();
}
void n2()
{
printf(".2\b\b");
n[2] = 1;
n[3] = 0;
n[4] = 0;
n[5] = 0;
n6();
n[2] = 0;
n3();
}
int main(int argc, char *argv[])
{
int a = -1, b = -1;
if ( argc >= 2 ) a = atoi(argv[1]);
if ( argc == 3 ) b = atoi(argv[2]);
if ( 15 < a && a < b && b < KETA-2 ) {
printf(" 1:10\n");
printf(" 2:25\n");
for (n[1]=KETA-2; n[1]>KETA-16; n[1]--) {
printf("\r%d", KETA-n[1]);
n2();
}
for (n[1]=KETA-a; n[1]>KETA-b-1; n[1]--) {
printf("\r%d", KETA-n[1]);
n2();
}
} else if ( 15 < a && a < KETA-2 ) {
printf(" 1:10\n");
printf(" 2:25\n");
for (n[1]=KETA-2; n[1]>KETA-16; n[1]--) {
printf("\r%d", KETA-n[1]);
n2();
}
for (n[1]=KETA-a; n[1]>-1; n[1]--) {
printf("\r%d", KETA-n[1]);
n2();
}
} else {
printf(" 1:10\n");
printf(" 2:25\n");
for (n[1]=KETA-2; n[1]>-1; n[1]--) {
printf("\r%d", KETA-n[1]);
n2();
}
}
return EXIT_SUCCESS;
}
KETAで4の倍数の桁数を設定し、コンパイルすればよいが、とりあえず、1000にしておく。
前回のプログラムでは、各桁でネストしていたのをやめ、1、2、3、4、5、6、7、8、9が何桁連なるかということで、それぞれをサブルーチンとしてみた。
また、パラメータで桁数を与えることで、途中から開始、途中で終了されられるようにもしてみた。
前回の100桁プログラムで60秒程度掛かっていたものが、今回のプログラムを1000桁設定で100桁まで実行してみたところ、20秒前後とかなりの速度アップはしてはいる。
とはいっても、ある程度の桁数になると速度が低下するので、DOS窓を沢山開いて、各レンジでパラレルで動かしてということも可能ではある。
裏でプログラムで検索しながら、表で粘度12が存在するのかを別角度から検証してみることになるだろう。
つづく