Last active
October 18, 2015 10:22
-
-
Save micromeeeter/96ec6a710f41b8028c97 to your computer and use it in GitHub Desktop.
Pascal'sTriangle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//This program is to be drawn by calculating the Pascal's triangle. | |
// | |
//パスカルの三角形を計算,描画するプログラムです. | |
//真面目に計算しているのである程度いくとintに収まりきらず正しくなくなります. | |
//パスカルの三角形で特定の自然数の倍数を塗りつぶしていくと規則的な図形が出てくるよ〜っていう性質を見たいときは | |
//訂正してくださった方のコメントを見てください...ありがとうございます | |
final int rowNum = 300; //Select an arbitrary natural number 任意の自然数を入れる | |
int[] termNum = new int[rowNum]; //Array that contains the number of terms in a row 一列における項数を入れる配列 | |
int[] totalSum = new int[rowNum]; //Array that containts the total number of terms 項の総数を入れる配列 | |
IntList theTerm = new IntList(); //ArrayList that containts the number of terms 項の数を入れる可変長配列 | |
int a, w, h, num, multiple; | |
void beforeValueSetup(){ | |
//termNum | |
for(int i = 0; i < termNum.length; i++){ | |
termNum[i] = i + 1; | |
} | |
//totalSum | |
for(int i = 0; i < totalSum.length; i++){ | |
if(i == 0){ | |
totalSum[i] = 1; | |
}else{ | |
totalSum[i] = totalSum[i - 1] + termNum[i]; | |
} | |
} | |
} | |
void valueSetup(){ | |
//theTerm | |
for(int i = 0; i < rowNum; i++){ | |
for(int j = 0; j < termNum[i]; j++){ | |
if(j == 0 || j == termNum[i] - 1){ | |
num = 1; | |
}else{ | |
num = theTerm.get(totalSum[i - 2] + (j - 1)) + theTerm.get(totalSum[i - 2] + j); | |
} | |
theTerm.append(num); | |
} | |
} | |
} | |
void setup(){ | |
beforeValueSetup(); | |
valueSetup(); | |
size(1000, 850); | |
multiple = 2; //Multiple to fill 塗りつぶす倍数 | |
textAlign(CENTER); | |
textSize(10); | |
a = 0; | |
w = width / termNum[rowNum - 1]; | |
h = height / rowNum; | |
background(255); | |
fill(0); | |
} | |
void draw(){ | |
translate(width / 2 + w / 2, 0); | |
for(int i = 0; i < rowNum; i++){ | |
for(int j = 0; j < termNum[i]; j++){ | |
if(i % 2 == 0){ | |
if(theTerm.get(a) % multiple == 0){ | |
ellipse((i / 2 - j) * w - w / 2, height / (rowNum * 2) + h * i, 2, 2); | |
} | |
//text(theTerm.get(a), (i / 2 - j) * w - w / 2, height / (rowNum * 2) + h * i); | |
}else{ | |
if(theTerm.get(a) % multiple == 0){ | |
ellipse((i / 2 - j) * w, height / (rowNum * 2) + h * i, 2, 2); | |
} | |
//text(theTerm.get(a), (i / 2 - j) * w, height / (rowNum * 2) + h * i); | |
} | |
a++; | |
} | |
} | |
noLoop(); | |
} |
色々足し込んでいって作った数値を theTerm.get(a) % multiple == 0 で剰余を計算していますが、
剰余だけが必要であるのなら合計そのものをまじめに計算する必要はないので
数値が大きくなりすぎないようにいちいち剰余をとりながら theTerm に append するようにしてみました。
それっぽい結果になったようですがこれでいかがでしょうか?
final int rowNum = 300; //Select an arbitrary natural number 任意の自然数を入れる
int[] termNum = new int[rowNum]; //Array that contains the number of terms in a row 一列における項数を入れる配列
int[] totalSum = new int[rowNum]; //Array that containts the total number of terms 項の総数を入れる配列
IntList theTerm = new IntList(); //ArrayList that containts the number of terms 項の数を入れる可変長配列
int a, w, h, num, multiple;
void beforeValueSetup(){
//termNum
for(int i = 0; i < termNum.length; i++){
termNum[i] = i + 1;
}
//totalSum
for(int i = 0; i < totalSum.length; i++){
if(i == 0){
totalSum[i] = 1;
}else{
totalSum[i] = totalSum[i - 1] + termNum[i];
}
}
}
void valueSetup(){
for(int i = 0; i < rowNum; i++){
for(int j = 0; j < termNum[i]; j++){
if(j == 0 || j == termNum[i] - 1){
num = 1;
}else{
num = theTerm.get(totalSum[i-2]+(j-1))+theTerm.get(totalSum[i-2]+j);
num %= multiple; //***** 追加
}
theTerm.append(num);
}
}
}
void setup(){
multiple = 7; //Multiple to fill 塗りつぶす倍数 ***位置を移動
beforeValueSetup();
valueSetup();
size(1000, 850);
textAlign(CENTER);
textSize(10);
a = 0;
w = width / termNum[rowNum - 1];
h = height / rowNum;
background(255);
fill(0);
}
void draw(){
translate(width / 2 + w / 2, 0);
for(int i = 0; i < rowNum; i++){
for(int j = 0; j < termNum[i]; j++){
if(i % 2 == 0){
if(theTerm.get(a) % multiple == 0){
ellipse((i / 2 - j) * w - w / 2, height / (rowNum * 2) + h * i, 2, 2);
}
//text(theTerm.get(a), (i / 2 - j) * w - w / 2, height / (rowNum * 2) + h * i);
}else{
if(theTerm.get(a) % multiple == 0){
ellipse((i / 2 - j) * w, height / (rowNum * 2) + h * i, 2, 2);
}
//text(theTerm.get(a), (i / 2 - j) * w, height / (rowNum * 2) + h * i);
}
//println(theTerm.get(a));
a++;
}
}
noLoop();
}
お礼が遅くなりました、ありがとうございました!オーバーフロー現象に初めて出会って何がどうだかさっぱりだったので本当にありがたいです…!
大きな数を扱う時は何らかの工夫で上限を超えないようにするのが大切なのですね。勉強になりました…
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
draw() で取り出している theTerm.get(a) の値を println で出力させたのを眺めていると、
負の値がところどころ混じっているのに気がつきました。
そこで valueSetupを次のようにして調べてみました。
結果、20000個以上が負の値となっていました。
負の値になっているのはオーバーフローが起きているためであり、塗りつぶしの倍数を3以上にすると結果がおかしくなるのも
オーバーフローが原因だと思います。
試しに以下のようなRubyスクリプトでtermNum, totalSum, theTerm を計算して theTerm の最大値を求めてみたのですが、計算違いがなければ
46879851386413726396596877219532042439616327850040679460236176356487585010919795837930712
となりました。int ではとても収まらない数ですね。
theTermの値を求める計算式がどこからでているのかわかりませんが、オーバーフロー対策をしないといけないのではないでしょうか。