トップページ⇒tech
523コメント255KB

■■C++で大きな数を作るスレ■■

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2009/03/24(火) 20:27:50
C++ で大きな数を返すプログラムを作るスレです。
以下のプロトタイプの関数の戻り値で出来るだけ大きな数を返すものを作りましょう。

int main();

●ルール
最大でも1スレに収まる範囲とし、
1スレで完結したプログラムとしてください。
文字数も書いてください

●言語仕様
言語は C++ 2003 準拠とします
int と float は十分な精度があるとします
メモリは十分にあるとします
実行時間は問わないこととします

機種依存、コンパイラ依存の値が返るプログラムは不可
プリプロセッサ、ライブラリの使用は不可

●文字数カウントルール
動作上不要なコメント、スペース、タブ、改行は文字数に含めない
言語上必要なスペース、タブ、改行はカウントする(改行は1文字とする)
0030デフォルトの名無しさん2009/03/25(水) 21:21:59
>>27 >>29
int で表せる範囲は十分大きいということしか決まっていない。
決まってないにも関わらずmain関数が同じ値を返すようなプログラムに
しなくてはいけないというのがルール。

十分大きいとはどういうことかというと、
>>1 のルールでいくら大きな数を作っていったとしても、
1レスではオーバーフローさせることが出来ないほど大きいということ。

ISO/IEC 14882:2003 では int の最小範囲は決まってるが、
最大範囲は決まっていないので、
int の範囲がいくら広くても
ISO/IEC 14882:2003 に反しない。

charがintと同じサイズでsizeof(int)は1という可能性もあるし、
sizeof(int)はとてつもなく大きな値である可能性もある。
0031デフォルトの名無しさん2009/03/25(水) 21:30:58
>>13 はなぜダメかというと、
int の大きさに依存した値が返るから。
(厳密に言うとISO/IEC 14882:2003のルールでは無限ループの可能性もある)

int や float の大きさに依存しないプログラムであれば、
1レスで作れる最大の数があるはずで、
それよりも int は大きな数を保持できますよ
ということ。
0032デフォルトの名無しさん2009/03/25(水) 21:38:10
>>31
さっぱり分からんのだが、
int main() { return 1e99999999999999999999;}
じゃだめなのか?
0033デフォルトの名無しさん2009/03/25(水) 21:41:31
それじゃ小さすぎる。
0034デフォルトの名無しさん2009/03/25(水) 21:41:56
floatに関して十分な精度というのは、
たとえば内部的には整数÷整数の有理数の形で保持されていて
誤差がまったく無いようなものを想定している。

有限文字の浮動小数点定数と四則演算では
有理数しか作れないので。
0035デフォルトの名無しさん2009/03/25(水) 21:46:38
>>32
42文字使えばもっとずっと大きな数が作れる。
たとえば、

int main(){return 9<<(9<<(9<<(9<<9999)));} // 42文字
0036デフォルトの名無しさん2009/03/25(水) 22:13:25
多くのプログラマは自力で>>9を超えるプログラムは組めまい。
というか>>9のプログラムが何であるか知らずに>>9を超えるプログラムを自力で組んだらほとんど天才だが。
0037デフォルトの名無しさん2009/03/25(水) 22:24:39
>>36
ルール違反だし(m)の括弧とか不要だし、プログラマとしては三流だな。
0038デフォルトの名無しさん2009/03/25(水) 22:28:26
>>37
どの辺がルール違反?
括弧はおれもすごく気になってた。
0039デフォルトの名無しさん2009/03/25(水) 22:34:41
main関数の中にすべて入れる必要はないですよ。

int factorial(int n){ return n ? n*factorial(n-1) : 1; }
int main(){ return factorial(99); }

こんなのもOK。
0040デフォルトの名無しさん2009/03/25(水) 22:37:13
できたぞ。まさか無限とは言わんだろうな。
int main(){char a=1,b=0;for(;a==b+1;a++,b++);return a;}
0041デフォルトの名無しさん2009/03/25(水) 22:38:09
もちろんcharじゃなくてintな。
0042デフォルトの名無しさん2009/03/25(水) 22:41:56
>>39
それ許すならmain()の引数許した方がよっぽどスマート。
0043デフォルトの名無しさん2009/03/25(水) 22:45:58
>>42
最初に呼ばれるmainの引数は何になるの?
不定?
0044デフォルトの名無しさん2009/03/25(水) 22:47:19
>>43
int argc, char argv[]に決まってる。
別に不定でもなんでもいいだろ。
0045デフォルトの名無しさん2009/03/25(水) 22:53:59
>>44
不定の引数なんて意味が無いと思って
int main();
に限定したんだけど、
その引数で大きな数が作れるなら是非作ってみて!
ただし、引数に依存しない数を返してね。
00469=362009/03/25(水) 22:55:50
mainの引数許してどうするんだよ。
結果がmainの引数に依存したら評価しにくいだろ。

括弧は三項演算子書くときの癖だ。
つい、いつものように書いちまった。

0047デフォルトの名無しさん2009/03/25(水) 22:58:19
>>9 を整形してみた。

// 86文字
int a(int m,int n){return m?n?a(m-1,a(m,n-1)):a(m-1,1):n+1;}
int main(){return a(9,9);}

たぶん下の方が大きいよね。

// 80文字
int a(int m,int n){return m?n?a(m-1,a(m,n-1)):m:n*9;}
int main(){return a(99,9);}
0048デフォルトの名無しさん2009/03/25(水) 23:02:40
>>40で終了だろうが。
0049デフォルトの名無しさん2009/03/25(水) 23:08:19
>>40
・charのサイズに依存した値が返る

・オーバーフローした場合の値は ISO/IEC 14882:2003 では未定義であり
 環境によっては無効値を表す値をとる場合がある
 無効値での == の結果も ISO/IEC 14882:2003 では未定義
0050デフォルトの名無しさん2009/03/25(水) 23:16:32
>>40
それ以前に、ほとんどの環境で無限ループだった。
インクリメントでオーバーフローしたときの値と
+1 でオーバーフローした時の値は
普通は同じだよ。
0051デフォルトの名無しさん2009/03/25(水) 23:23:09
オーバーフローねたは>>1の思い描くスレの趣旨とは違うので、そろそろ勘弁してやれ。
0052デフォルトの名無しさん2009/03/25(水) 23:23:30
これまでの記録

int main(){return 9;} // 21文字
int main(){return 99;} // 22文字
int main(){return 999;} // 23文字
int main(){return 1e+9;} // 24文字
int main(){return 1e+99;} // 25文字
int main(){return 9<<(9<<(9<<(9<<9999)));} // 42文字
int main(){int n=99,m=n;while(m--)n<<=n;return n;} // 50文字
int main(){int i=9e+99,f=i;while(f--)i<<=i;return i;} // 53文字

// 80文字
int a(int m,int n){return m?n?a(m-1,a(m,n-1)):m:n*9;}
int main(){return a(99,9);}
0053デフォルトの名無しさん2009/03/25(水) 23:30:32
>>50
無限ループじゃねーよ。+1と++の違いには依存してねーよ。
0054デフォルトの名無しさん2009/03/25(水) 23:33:54
>>52
1e+9なら9e99の方がでかい。
0055デフォルトの名無しさん2009/03/25(水) 23:54:18
>>53
b+1 の型は int になるんだったね。
うっかりしてた。

>>40 は
char の範囲よりも int の範囲が広い場合には、
char の最大値をインクリメントした値が返る。
(多くの場合 -128)

char の範囲と int の範囲が同じ場合には、
無限ループ。
0056デフォルトの名無しさん2009/03/26(木) 00:00:36
>>54
たしかに。

int main(){return 9e99;} // 24文字
int main(){int i=9e99,f=i;while(f--)i<<=i;return i;} // 52文字
0057デフォルトの名無しさん2009/03/26(木) 00:02:22
これもだ

int main(){return 9e9;} // 23文字
0058デフォルトの名無しさん2009/03/26(木) 02:00:38
>>30の
>ISO/IEC 14882:2003 では int の最小範囲は決まってるが、
が結論で、その最小範囲内における最大値が唯一の答えだと思うんだが。
それ以上は環境によってオーバーフローする可能性がある。



0059デフォルトの名無しさん2009/03/26(木) 11:52:16
表向きは数学の演習問題だが、>>1の本心は
C++の規約(ISO/IEC 14882:2003)を理解しているかどうか試したいんだろ。
0060デフォルトの名無しさん2009/03/26(木) 21:01:53
>>58
標準規格で定義してない部分を追加で定義してるんで。
int のサイズが制限されてたら大きな数を作れないでしょ。

自力で巨大な整数を保持出来るクラスを作るにも、
組み込み整数型のサイズ制限があったら、
メモリ確保時のサイズが制限を超えちゃうんで作れないし。

>>59
当方、標準規格に詳しいわけでもないし、
C++のテクニックをたくさん知っているわけでもない。
むしろ教えてもらいたい方ですよ。

単純に、C++という言語を使って限られた文字数で
どのくらい大きな数が定義できるのか知りたいのよ。

たとえば私の能力では50文字で >>2 が精一杯だけど、
C++に詳しい人やいろんな人の頭脳を使えば
もっと大きく出来たり文字数を減らせたりするんじゃないかと。

>>21 のような、浮動小数点定数を用いる発想は私には無かったわけだし。
0061デフォルトの名無しさん2009/03/26(木) 23:14:42
おりゃ!

int a(int z){ return z?z<<a(z-1):9 }
int b(int z){ return z?a(b(z-1)):9 }
int c(int z){ return z?b(c(z-1)):9 }
int d(int z){ return z?c(d(z-1)):9 }
int e(int z){ return z?d(e(z-1)):9 }
int f(int z){ return z?e(f(z-1)):9 }
int g(int z){ return z?f(g(z-1)):9 }
int h(int z){ return z?g(h(z-1)):9 }
int i(int z){ return z?h(i(z-1)):9 }
int j(int z){ return z?i(j(z-1)):9 }
int k(int z){ return z?j(k(z-1)):9 }
int l(int z){ return z?k(l(z-1)):9 }
int m(int z){ return z?l(m(z-1)):9 }
int n(int z){ return z?m(n(z-1)):9 }
int o(int z){ return z?n(o(z-1)):9 }
int p(int z){ return z?o(p(z-1)):9 }
int q(int z){ return z?p(q(z-1)):9 }
int r(int z){ return z?q(r(z-1)):9 }
int s(int z){ return z?r(s(z-1)):9 }
int t(int z){ return z?s(t(z-1)):9 }
int u(int z){ return z?t(u(z-1)):9 }
int v(int z){ return z?u(v(z-1)):9 }
int w(int z){ return z?v(w(z-1)):9 }
int x(int z){ return z?w(x(z-1)):9 }
int y(int z){ return z?x(y(z-1)):9 }
int main(){ return y(9e9999999999); }
0062デフォルトの名無しさん2009/03/26(木) 23:30:34
>>36
あっさり抜かれてるじゃん。
0063デフォルトの名無しさん2009/03/26(木) 23:41:48
>>61
それa〜yを一つの関数にできるな
第一引数が0ならa, 1ならbとして振舞うって具合に
で、そのように書き換えると>>9とほぼ同じコードになる
0064デフォルトの名無しさん2009/03/27(金) 08:07:10
int main() { return INT_MAX; }
終了。
0065デフォルトの名無しさん2009/03/27(金) 10:47:20
>>64 #include <limits.h>が必要だろ
0066デフォルトの名無しさん2009/03/27(金) 18:31:07
int の最大値を返すプログラムはいい加減かんべんしてください。
0067デフォルトの名無しさん2009/03/27(金) 18:41:15
これまでの記録

int main(){return 9;} // 21文字
int main(){return 99;} // 22文字
int main(){return 9e9;} // 23文字
int main(){return 9e99;} // 24文字
int main(){return 9<<(9<<(9<<(9<<9999)));} // 42文字
int main(){int n=99,m=n;while(m--)n<<=n;return n;} // 50文字
int main(){int i=9e99,f=i;while(f--)i<<=i;return i;} // 52文字

// 80文字
int a(int m,int n){return m?n?a(m-1,a(m,n-1)):m:n*9;}
int main(){return a(99,9);}

// 883文字
>>61
0068デフォルトの名無しさん2009/03/27(金) 18:43:33
883文字のやつより80文字のやつの方が大きいか。
0069デフォルトの名無しさん2009/03/27(金) 19:05:02
プログラムの終了値をbashから表示させる方法ある?
0070デフォルトの名無しさん2009/03/27(金) 19:12:22
自己解決。終了コードは$?に代入されますね。
0071デフォルトの名無しさん2009/03/27(金) 19:26:17
良く覚えてないけど、あれって0〜255しか返せないんじゃなかったっけ?
0072デフォルトの名無しさん2009/03/27(金) 19:32:33
>>71
ぽいですね。
int main(int argc, char **argv) {
if (argc < 2) return -1;
int i = atoi(argv[1]);
printf("%d\n", i);
return i;
}
$ ./a.exe 256; echo $?
256
0

$ ./a.exe 255; echo $?
255
255
0073デフォルトの名無しさん2009/03/28(土) 06:19:22
9e99999 の時点で結果は画面内に収まりきらないよ。
浮動小数点の指数表現にしても 9<<(9<<99999) の時点で無理。
0074デフォルトの名無しさん2009/03/29(日) 02:19:30
883文字も使うなら
a(9,9)->a(a(9,9),a(9,9))->a(a(a(9,9),a(9,9)),a(a(9,9),a(9,9)))
と重ねたほうがでかくなるよな。
0075デフォルトの名無しさん2009/03/29(日) 03:33:00
int p(int x,int y){return y?x*p(x,y-1):1;}
int k(int x,int y,int n){return n-1?y?k(x,k(x,y-1,n),n-1):1:p(x,y);}
int g(int z){return k(3,3,z);}
int G(int w){return w-1?g(G(w-1)):g(4);}
int main(){return G(64);}

205文字。
0076デフォルトの名無しさん2009/03/29(日) 08:46:01
結局数学的に停止が証明されてるものをコーディングするしかないんじゃねーの。
C++だからって特別に何かあるわけじゃなし、何がおもしろいんだか。
0077デフォルトの名無しさん2009/03/29(日) 09:33:16
>>75
同じ値で文字を減らせる
int k(int x,int y,int n){return n?y?k(x,k(x,y-1,n),n-1):1:x*y;}
int main(){int n=4,m=64;while(m--)n=k(3,3,n);return n;}
118文字


>>74
こんな感じかな?

// 113文字
int a(int m,int n){return m?n?a(m-1,a(m,n-1)):a(m-1,1):n+1;}
int main(){int n=9,m=99;while(m--)n=a(n,n);return n;}

これで >>75 よりは大きくなったかな?
0078デフォルトの名無しさん2009/03/29(日) 10:19:23
return ~(unsigned)0;
0079デフォルトの名無しさん2009/03/29(日) 10:59:17
>>2
0080デフォルトの名無しさん2009/03/30(月) 09:30:55
インラインアセンブラで多倍長整数型演算を実装するとかそんなんじゃないのね
多ビットのそこそこ速い計算が必要で自分でJAVAのヒッグデシマルみたいなクラス作るのマンドクセとおもったから覗いてみたけど
ネタスレだったか
0081デフォルトの名無しさん2009/03/31(火) 01:12:04
>>80
うん、バイバイ。
0082デフォルトの名無しさん2009/03/31(火) 06:26:40
http://science6.2ch.net/test/read.cgi/math/1194777915/
0083デフォルトの名無しさん2009/03/31(火) 21:29:10
たとえば50文字だと >>2 みたいなループが作れるけど、
48文字で書ける最高の数って何だろう?

あと2重の再帰定義を77文字にすることは出来たんだけど、
76文字の場合の最高は何だろう?
>>2 みたいな普通のループ+シフトかな?

// 77文字
int a(int b,int c){return b*c?a(b-1,a(b,c-1)):c+9;}
int main(){return a(9,9);}


2重再帰定義と >>2 のループを合わせると、
103文字で、大きな数で有名な >>75 を超えることが出来るけど、
100文字以下だと最大はどんな数だろう?

// 103文字
int a(int b,int c){return b*c?a(b-1,a(b,c-1)):c+9;}
int main(){
  int n=99,m=n;
  while(m--)
    n=a(n,n);
  return n;
}
0084デフォルトの名無しさん2009/03/31(火) 23:04:31
神に祈りながら
int main(){
   int n(0)
   while( rand()%2 == 0 ){
      n++;
   }
   return n;
}
0085デフォルトの名無しさん2009/04/01(水) 15:20:27
>>84
おしい つ >>1
0086デフォルトの名無しさん2009/04/01(水) 18:38:18
こっちの方が大きいんじゃね?
まあいずれにしろ >>1

int main(){
int n(0);
while( rand() ){
n++;
}
return n;
}
0087デフォルトの名無しさん2009/04/01(水) 18:39:29
あれ、行頭のスペースが消えた。
>>84 みたいにスペースを付けるのはどうやんの?
0088デフォルトの名無しさん2009/04/01(水) 21:20:18
>>87 &nbsp;じゃない?多分。
int main() {
    return 9;
}
0089デフォルトの名無しさん2009/04/01(水) 21:42:58
テスト

int main(){
    int n(0);
    while( rand() ){
        n++;
    }
    return n;
}
0090デフォルトの名無しさん2009/04/03(金) 00:07:42
100文字以内でのチャンピオンは俺がもらった!
100文字の制限がなくても今までで最大。

// 100文字
int a(int b,int c,int d){
    return b+c&&d?a(c?b:0,c?c-1:d,a(b,c,d-1)):d+9;
}
int main(){return a(1,9,9);}
0091デフォルトの名無しさん2009/04/03(金) 01:47:44
int a=9;int main(){return a--?1<<main():1;}

とりあえずテトレーションを書いて見たかった。
0092デフォルトの名無しさん2009/04/03(金) 08:31:01
>>91
お〜〜〜、目から鱗。
引数無しでも再帰が書けるのか。
0093デフォルトの名無しさん2009/04/03(金) 11:16:47
>>91
その1は9にした方がいいんジャマイカ?
つーか、それぞれいくつになるのかと1文字あたりいくつになるかくらい書いとけ。
0094デフォルトの名無しさん2009/04/03(金) 13:15:58
>>93
>>92のままだと要するに2↑↑9だから簡単な数式であらわせるから、
大きさの見積もり楽だなぁという理由であえて1にしてました。

このスレは出来る限り大きな数を目標にしてるから9のほうがいいんだろうけどねぇ。
0095デフォルトの名無しさん2009/04/03(金) 19:29:35
ちょっと質問だが、 new int[n]は使ってよいの?
もっとも使ったところで役に立つかどうかはまだわからないけど。
0096デフォルトの名無しさん2009/04/03(金) 22:49:26
>>95
もちろんOK.
C言語ではなくC++にした一番の理由が、
言語上でメモリ確保が出来ること。

メモリは十分にあるのでメモリ確保は失敗しない。
mainリターン時に解放していなくてもOK.
ということで。

>>94
このスレ的には
値の綺麗さや実行時間やメモリ使用量やバイナリサイズは一切問わず、
同じ文字数なら1でも大きい数を返す、
同じ大きさを返すなら1文字でも短くする、
のが目的。

ということで、
1を9に変えさせていただきます。
int a=9;int main(){return a--?9<<main():9;} // 43文字

きれいな数値でなくても、>>1 が責任を持って大きさを比較します。

>>93
mainの戻り値は簡単に書けないくらいの大きさになるので、
いくつになるか書くのは難しいかと。
0097デフォルトの名無しさん2009/04/03(金) 22:57:20
今までの記録

int main(){return 9;} // 21文字
int main(){return 99;} // 22文字
int main(){return 9e9;} // 23文字
int main(){return 9e99;} // 24文字
int main(){return 9<<(9<<(9<<(9<<9999)));} // 42文字
int a=9;int main(){return a--?9<<main():9;} // 43文字

// 77文字
int a(int b,int c){return b*c?a(b-1,a(b,c-1)):c+9;}
int main(){return a(9,9);}

// 100文字
int a(int b,int c,int d){
    return b+c&&d?a(c?b:0,c?c-1:d,a(b,c,d-1)):d+9;
}
int main(){return a(1,9,9);}

大きく空いている44文字〜76文字の作品と、
文字数無制限(ただし1レス以内)の作品を特に募集中。
0098デフォルトの名無しさん2009/04/03(金) 23:33:41
環境依存だけどこんなの思いついた。
int main(){int i;return (int)&i;}//33文字?

思ったより短くないなぁ。。。
0099デフォルトの名無しさん2009/04/04(土) 01:29:05
それだったらこんなのもいいじゃない。
int main(){return (int)main;}
0100982009/04/04(土) 04:02:33
あーそれいいね。
俺よりは環境依存っぽくない。
0101デフォルトの名無しさん2009/04/04(土) 13:48:17
スタックのメモリ空間が独立していたらしょぼい結果になりそうだけど。
ロードアドレスもそうだね。少なくとも、24文字の9e99に勝てそうにないし。
ってことで、24と42の間を無駄に埋めてみる。
int main(){return 9e99*9e99;} // 29文字
0102デフォルトの名無しさん2009/04/04(土) 21:36:26
私の思いつく範囲だと、
たぶん42文字まではこんな感じじゃないかと思うんだけど、
もっと大きいのあるかなあ?

int main(){return 9;} // 21文字
int main(){return 99;} // 22文字
int main(){return 9e9;} // 23文字
int main(){return 9e99;} // 24文字
int main(){return 9e999;} // 25文字
int main(){return 9e9999;} // 26文字
int main(){return 9e99999;} // 27文字
int main(){return 9e999999;} // 28文字
int main(){return 9e9999999;} // 29文字
int main(){return 9<<(9<<99);} // 30文字
int main(){return 9<<(9<<999);} // 31文字
int main(){return 9<<(9<<9999);} // 32文字
int main(){return 9<<(9<<99999);} // 33文字
int main(){return 9<<(9<<999999);} // 34文字
int main(){return 9<<(9<<(9<<99));} // 35文字
int main(){return 9<<(9<<(9<<999));} // 36文字
int main(){return 9<<(9<<(9<<9999));} // 37文字
int main(){return 9<<(9<<(9<<99999));} // 38文字
int main(){return 9<<(9<<(9<<999999));} // 39文字
int main(){return 9<<(9<<(9<<(9<<99)));} // 40文字
int main(){return 9<<(9<<(9<<(9<<999)));} // 41文字
int main(){return 9<<(9<<(9<<(9<<9999)));} // 42文字
0103デフォルトの名無しさん2009/04/04(土) 22:02:53
VC++ 2008でint main(){return 0xffffffff;}相当
cl t.c /link /merge:.text=.data

char main[]={184,-1,-1,-1,15,195}; //34字
_int64 main=0xc30fffffffb8; //27字

今思った。VC++と縛りを入れた以上、INT_MAXの0x7ffffffffのほうがいいのではないかと。

いずれにせよ>>102には遙か及ばない。
0104デフォルトの名無しさん2009/04/04(土) 22:04:06
C++の規約で巨大数を作れとか、圏論をXMLに適応させろとか、
数学ネタのスレは良く分からん。
0105デフォルトの名無しさん2009/04/05(日) 11:56:06
>>1

「int と float は十分な精度があるとします 」
これの意味と

どうやって大きい数と判定しているかを教えてくれ


(ちゃんと勉強している者が)普通に考えたら >>36 がいってることが正しい
0106デフォルトの名無しさん2009/04/05(日) 19:59:50
>>105
> 「int と float は十分な精度があるとします 」
> これの意味と

int に関しては、
>>1 のルールを守ったプログラムの中で、
最大の数を返すプログラムでもオーバーフローしない程大きいと思ってください。
(int のサイズに依存したプログラムで無ければ、1レスで作れる最大の数が定義出来るはず)
これで意味がわからなければ、
どんな整数もあらわせる多倍長の整数クラスみたいなものと思って頂いてもいいです。
(ただし、シフトやビット演算は普通の int のふるまいと同じです。)

float に関しては、
十分大きな数も保持出来るのに加えて、
演算に誤差がないもとのします。
内部的には上のint型2個による有理数みたいなものと思ってください。
C++の言語上はfloatの演算は +-*/ しかないので
有理数の範囲で誤差がない演算ができます。
double 型の定数からも誤差なくfloatに変換できるとします。

----
多倍長整数クラスや多倍長有理数クラスでも結局
普通の環境を想定すると new int[size] のsize が大きくなりすぎるし、
ポインタ型も大きくなりすぎるんだよね。
0107デフォルトの名無しさん2009/04/05(日) 20:21:38
>>105
> どうやって大きい数と判定しているかを教えてくれ

>>1 が責任を持って比較、判定します。
答えになってないか。

1レスで書ける程度のプログラムで、
ただひたすら大きな数を作るようなプログラムなら、
>>1 は大きさを見積もれるのではと思っています。(自信過剰?)
また、逆に >>1 が大きさを見積もれないほど大きな数が作れるならそれも見てみたい。

現代数学では大きさが見積もれないようなプログラムだったとしたら、
(たとえば存在が証明されてないような数を返すプログラム)
比較が出来ないかも知れないけど、
その場合も大きさ判定不能な作品として残したいと思います。
判定不能でも文字を極限まで減らすような努力もできるし。
0108デフォルトの名無しさん2009/04/05(日) 20:23:04
>>105
> (ちゃんと勉強している者が)普通に考えたら >>36 がいってることが正しい

>>9 より力技の >>61 の方が大きいし、
たくさんの人がいろんな発想で挑戦すれば超えられるかも知れない。
文字数が少ないものは数学の知識よりもC++の知識の方が重要だし。
だれかが作ったものに文字を追加してさらに大きな数を作るようなこともできる。
数学がぜんぜんダメな人でも
C++に詳しければ同じ値で文字数を減らすことが出来るかも知れないし。

とにかくいろんな発想で大きな数を作ったり文字を減らすのが見たい。
大きさの比較は >>1 が責任を持って行います。
0109デフォルトの名無しさん2009/04/05(日) 21:05:54
>>108
比較の内容と結果をちゃんと書けよ。
01101052009/04/05(日) 22:11:37
>>106

/*
 File : test.cpp
 Compile : g++ test.cpp -lgmpxx -lgmp
*/
#include <iostream>
#include <gmpxx.h>

typedef mpz_class BigInteger;

BigInteger fact(int n){
  BigInteger ans = 1;
  do { ans *= n; } while( --n );
  return ans;
}

BigInteger f(){
  return fact(100);
}

int main(){
  std::cout << f() << std::endl;
  return 0;
}

「ライブラリ使用不可」ってのを破ってるけど
「int と float は十分な精度があるとします 」
を守るためだけに使いました
この例では単純な factorial(100) を出力するやつを書いてみた
要は上の f() を main() に変えて大きな数を作るってことでOK?
01111052009/04/05(日) 22:12:31
>>107
>>108

> >>1 が責任を持って比較、判定します。
> 答えになってないか。

はい、答えになっていません


> >>1 は大きさを見積もれるのではと思っています。(自信過剰?)
> 大きさの比較は >>1 が責任を持って行います。

たとえば
>>9 と >>61 の桁数を教えてください
本当に >>61 のほうが大きいのですか?
私にはわかりません
(両方とも)とても計算できそうにないので


> C++に詳しければ同じ値で文字数を減らすことが出来るかも知れないし。
きっとそうですが、
「数値の大きさ」と「コードサイズ」を比べるのは
アンマッチな感じがします
0112デフォルトの名無しさん2009/04/05(日) 22:52:17
お前がこのスレにアンマッチなんだろう。
0113デフォルトの名無しさん2009/04/05(日) 23:08:24
>>109
そりゃそうですね。書きます。
その文字数以内で最大の物はそれより小さい文字での最大のものより大きい説明を、
最大でないものはより文字数が小さいものorより値が大きいものとの比較を
書いていきます。

■ >>10-17,40,64,84,86,89,98,99,103
ルール違反

■ >>2
50文字
初期値 n=99 に対して、n<<=n を 100 回行っている。
>>96 の 初期値 x=9 に対し、x=9<<x を9回行ったものより明らかに大きい。
【50文字以下最大】

■ >>9
>>47で同じ数字を86文字で表現

■ >>21
>>28の3行目で同じ数字を53文字で表現している

■ >>22
>>102の方が明らかに大きい

■ >>28
>>56で同じ値を52文字で表現している
0114デフォルトの名無しさん2009/04/05(日) 23:09:06
■ >>32
>>102の方が明らかに大きい

■ >>35
>>102にまとめて記述
41文字以下のどの作品よりも明らかに大きい
【42文字以下現在最大】

■ >>39
これは99の階乗。
99の階乗 < 99の99乗 < 128の99乗 = 2の693乗 < 2の(9<<99)乗 < 9<<(9<<99)

■ >>56
24文字
>>102にまとめて記述
【24文字以下現在最大】

52文字
初期値 i=9e99 に対して、i<<=i を 9e99+1 回行っている。
>>2 の50文字の作品よりも明らかに大きい
【52文字以下現在最大】

■ >>57
>>102にまとめて記述
【23文字以下現在最大】
0115デフォルトの名無しさん2009/04/05(日) 23:10:14
■ >>75
>>77 で同じ値を118文字で表現している

>>77 の k(x,y,1) も xのy乗となる為、
『 >>75 の k(x,y,n) 』= 『 >>77 の k(x,y,n) 』
>>75 の G(w) は 初期値 z=4 に対し z=k(3,3,z) をw回繰り返したものであり、
>>75 と >>77 の118文字は同じ値を返す。

■ >>88
>>102にまとめて記述
【21文字以下現在最大】

■ >>91
96の43文字の方が明らかに大きい

■ >>96
返る値は
9<<(9<<(9<<(9<<(9<<(9<<(9<<(9<<(9<<9))))))))
であり、
42文字以下の >>102 のいずれよりも明らかに大きい
【43文字以下現在最大】

■ >>101
>>102の29文字の方が明らかに大きい
0116デフォルトの名無しさん2009/04/05(日) 23:11:24
>>47,61,77,83,90 の比較はちょっと長いので後ほど。
0117デフォルトの名無しさん2009/04/05(日) 23:12:06
>>110
そんな感じです。
0118デフォルトの名無しさん2009/04/05(日) 23:18:54
Conwayのチェーン表記を書いてみた
ttp://en.wikipedia.org/wiki/Conway_chained_arrow_notation

int p(int x,int y){return y?x*p(x,y-1):1;}
int e(int*a,int n){
if(n==1)return a[0];
if(n==2)return p(a[1],a[0]);
if(a[0]==1)return e(a+1,n-1);
if(a[1]==1)return e(a+2,n-2);
int x,y;
a[0]--;x=a[1]--;a[1]=e(a,n);y=e(a,n);a[0]++;a[1]=x;return y;}
int main(){int a[]={9,9,9,9,9,9,9,9,9};return e(a,9);}
0119デフォルトの名無しさん2009/04/05(日) 23:58:31
無限にintは大きいんだろ??
int main(){return (unsigned)~0;}
012012009/04/06(月) 00:00:26
>>113-115の続き

>>61 の883文字は、
int A(int y, int z){y?z?a(y-1,a(y-1,a(y,z-1)):9:9<<z;}
とすると、
A(1,z) = a(z)
A(2,z) = b(z)
A(3,z) = c(z)
...
A(25,z) = y(z)
となります。

>>77 の118文字は、
int k(int x,int y,int n){return n?y?k(x,k(x,y-1,n),n-1):1:x*y;}
これのxを3に固定し、yとnを入れ替えると
int K(int n,int y){return y?n?k(n-1,k(n,y-1)):1:3*n;}
となります。

>>90 の100文字は、
int a(int b,int c,int d){
return b+c&&d?a(c?b:0,c?c-1:d,a(b,c,d-1)):d+9;
}
これのbを0に固定すると、
int A(int c,int d){return c&&d?a(c-1,a(c,d-1)):d+9;}
となります。
012112009/04/06(月) 00:02:01
それぞれの再帰関数を並べると以下のようになって、
いずれかの引数が0の場合の定義のみ異なり、
どちらも0でない場合の定義はまったく同じであることが分かります。

47-86,77-113
int a(int m,int n){return m?n?a(m-1,a(m,n-1)):a(m-1,1):n+1;}

47-80
int a(int m,int n){return m?n?a(m-1,a(m,n-1)):m:n*9;}

61-883
int A(int y, int z){y?z?a(y-1,a(y-1,a(y,z-1)):9:9<<z;}

77-118
int K(int n,int y){return y?n?k(n-1,k(n,y-1)):1:3*n;}

83-77, 83-103
int a(int b,int c){return b*c?a(b-1,a(b,c-1)):c+9;}

90-100
int A(int c,int d){return c&&d?a(c-1,a(c,d-1)):d+9;}
012212009/04/06(月) 00:03:39
左の引数が0の時の定義は、
47-86 の n+1 と 61-883 の 9<<z で大きく異なるようにみえるが、
実は左の引数を数個増やすだけでこの程度の差は吸収してしまう。

たとえば、
47-86 の場合、
a(0,n) = n+1
a(1,n) = n+2
a(2,n) = n*2+3
a(3,n) = 2の(n+3)乗 -3
となる。

同様に、右の引数が0の時の定義も、
右の引数を数個増やすだけで吸収してしまう。

つまり、>>121 の関数は、引数を数個変えると追いつく程度の差しかなく、
左の引数が9と99では、初期値が上のいずれであっても
左の引数が99である方が大きくなる。
012312009/04/06(月) 00:06:29
90-100 を見てみる。

a(1,0,d) ≧ a(0,d,d) であり、
a(1,1,d) は、初期値x=9 に対し、x=a(1,0,x) を d 回行ったものである。
つまり、
a(1,1,d) は、初期値x=9 に対し、x=A(x,x) を d回行ったものより大きいので、
a(1,1,64) で、77-118 とだいたい同じ数となって、
a(1,1,99) で、77-113 や 83-103 とだいたい同じ数となる。

a(1,2,2) = a(1,1,a(1,1,a(1,2,0))) = a(1,1,a(1,1,9)) >> a(1,1,999)
であるので、
それより大きい a(1,9,9) は 77-118,77-113,83-103 より大きい。
012412009/04/06(月) 00:07:39
■ >>47
86文字
同じレスの80文字の方が大きい

80文字
【80文字以下現在最大】

■ >>61
>>47 の80文字の方が大きい

■ >>77
118文字、113文字とも >>90 の100文字に負けている

■ >>83
77文字
【77文字以下現在最大】

103文字 >>90 の100文字に負けてる

■ >>90
100文字
【100文字以下現在最大】
012512009/04/06(月) 00:11:38
現在の記録をまとめると、

42文字以下
>>102

int a=9;int main(){return a--?9<<main():9;} // 43文字
int main(){int n=99,m=n;while(m--)n<<=n;return n;} // 50文字
int main(){int i=9e99,f=i;while(f--)i<<=i;return i;} // 52文字

// 77文字
int a(int b,int c){return b*c?a(b-1,a(b,c-1)):c+9;}
int main(){return a(9,9);}

// 80文字
int a(int m,int n){return m?n?a(m-1,a(m,n-1)):m:n*9;}
int main(){return a(99,9);}

// 100文字
int a(int b,int c,int d){
return b+c&&d?a(c?b:0,c?c-1:d,a(b,c,d-1)):d+9;
}
int main(){return a(1,9,9);}

※ >>118 はこれから評価します。
0126デフォルトの名無しさん2009/04/06(月) 16:09:42
int main(){ unsigned int i=-1; return (i>>1)-1;}//48文字
環境依存かなぁ。
0127デフォルトの名無しさん2009/04/06(月) 18:55:22
>>118
このままだとあまり大きくなく、
>>125 の80文字 のより小さい。

× a[0]--;x=a[1]--;a[1]=e(a,n);y=e(a,n);a[0]++;a[1]=x;return y;}
○ x=a[1]--;a[1]=e(a,n);a[0]--;y=e(a,n);a[0]++;a[1]=x;return y;}

このように直すと今のところ最大。(290文字)

※この数が290文字で記述できるとは思わなかった
0128デフォルトの名無しさん2009/04/07(火) 01:40:07
減速しちゃったねぇ。。。
0129デフォルトの名無しさん2009/04/07(火) 19:25:18
>>126ってどうなの??
0130デフォルトの名無しさん2009/04/07(火) 22:42:14
>>126
>>2 のダメな例の2個目と同じ発想。
int のサイズや負の数の表現方法に依存する。
激しく既出なルール違反。

ちなみに、
負の数に1の補数表現や2の補数表現を使った処理系の多くは 『{2の(intのビット数-1)乗} -2』 が返り、
負の数に符号ビット+絶対値を使った処理系の多くは 『2の(intのビット数-2)乗』 が返る。
トラップ表現のある実装の場合はトラップ表現が返る場合もあるかも知れないし、
飽和演算の処理系では 0 が返ることがあるかも知れない。
C++の規格上は不定である。
■ このスレッドは過去ログ倉庫に格納されています