素数を渦巻き状に並べて、素数に色を付けていくと対角線や水平線
が現れるようです。

これがウラムの螺旋。
こういう視覚情報を伴ったプログラミングはprocessingと相場が決まっていますので、processingでプログラミングしてみましょう。
ウラムの螺旋 wikipedia
wikipediaを見ると左回りですが、右回りでも良さそうです。
プログラミングをすると下の図のように感じになります。数字6000までやってみました。
確かに対角線っぽいものが現れる。

processing 3.01で動作確認しています。
次はyoutubeで見つけた吉原宏治さんの素数はスパイラル上にきれいに並んでいた、面白そうでなのプログラミングしてみます。

このスパイラルを再現してみたいと思います。
ただの素数ではなくて、ここからnを求めるようです。

nの求め方
素数11の場合、n = ((11^2) - 1) / 24
n = 5となります。 5の数字で色を塗ります。
もう一つ 素数13の場合、 n = ((13^2) - 1) / 24
n = 7 7の数字で色を塗ります。
400までやってみた結果が下の図。

数字4600までやってみたのが下の図。
確かに綺麗にスパイラルになっています。

探偵ナイトスクープで素数をやっていました。これを見たのがきっかけです。
これも簡単にprocessingでできてしまいます。やってみましょう。
が現れるようです。

これがウラムの螺旋。
こういう視覚情報を伴ったプログラミングはprocessingと相場が決まっていますので、processingでプログラミングしてみましょう。
ウラムの螺旋 wikipedia
wikipediaを見ると左回りですが、右回りでも良さそうです。
プログラミングをすると下の図のように感じになります。数字6000までやってみました。
確かに対角線っぽいものが現れる。

processing 3.01で動作確認しています。
//素数らせんプログラム
final int maxx = 800;
final int maxy = 800;
int i = 0;
int[][] cell = new int[80][80];
int[][] flag = new int[80][80];
int[][] prime = new int[80][80];
int tmpX, tmpY;
int x = 40;
int y = 40;
//数字の進む方向 右 -> 下 -> 左 -> 上 の順に進む
int direction = 0;
void setup(){
size(800, 800);
//frameRate(20);
background(255);
noLoop();
}
boolean isPrime(int num) {
int x;
if ( num < 2){
return false;
} else if (num == 2 || num == 3) {
return true;
} else if (num % 2 == 0 || num % 3 == 0) {
return false;
} else {
for ( x = 5; x * x <= num; x+= 6) {
if(num % 5 == 0|| num %(x + 2) == 0) {
return false;
}
}
}
return true;
}
void mouseMoved() {
if(tmpX != (mouseX / 10) || tmpY != (mouseY / 10)) {
println(cell[mouseX / 10][mouseY / 10] + " " + prime[mouseX / 10][mouseY / 10]);
tmpX = mouseX / 10;
tmpY = mouseY / 10;
}
}
void draw() {
fill(255, 0, 0);
for ( i = 0; i < (maxx / 10); i++) {
line( i * 10, 0, i * 10, 800);
}
for ( i = 0; i < (maxy / 10); i++) {
line(0, i * 10, 800, i * 10);
}
for (i = 0; i < 6000; i++) {
if(isPrime(i)) { //素数のとき
rect(x * 10, y * 10, 10, 10);
prime[x][y] = 1;
}
cell[x][y] = i;
flag[x][y] = 1;
if(direction == 0) { //右に進む
if(flag[x + 1][y] == 0) {
x += 1;
direction = 1;
} else {
y += -1;
}
}else if(direction == 1) {//下に進む
if(flag[x][y + 1] == 0) {
y += 1;
direction = 2;
} else {
x += 1;
}
}else if(direction == 2) { //左に進む
if(flag[x - 1][y] == 0) {
x += -1;
direction = 3;
} else {
y += 1;
}
}else if(direction == 3) { //上に進む
if(flag[x][y - 1] == 0) {
y += -1;
direction = 0;
}else {
x += -1;
}
}
}
}
次はyoutubeで見つけた吉原宏治さんの素数はスパイラル上にきれいに並んでいた、面白そうでなのプログラミングしてみます。

このスパイラルを再現してみたいと思います。
ただの素数ではなくて、ここからnを求めるようです。

nの求め方
素数11の場合、n = ((11^2) - 1) / 24
n = 5となります。 5の数字で色を塗ります。
もう一つ 素数13の場合、 n = ((13^2) - 1) / 24
n = 7 7の数字で色を塗ります。
400までやってみた結果が下の図。

//素数らせんプログラム
// [20, 20]のマスを用意、スタート地点[10, 10]から右回りに進む。
final int maxx = 400;
final int maxy = 400;
int maxnumber = 400; //最大値
int[] color4 = new int[maxnumber * maxnumber];
int[] primeflag = new int[maxnumber * maxnumber];
int n;
int i = 0;
int[][] cell = new int[40][40];
int[][] flag = new int[40][40];
int[][] prime = new int[40][40];
int tmpX, tmpY;
int x = 10; //スタート地点x
int y = 10; //スタート地点y
int cellsize = 20;
//数字の進む方向 右 -> 下 -> 左 -> 上 の順に進む
int direction = 0;
void setup(){
size(400, 400);
//frameRate(20);
background(255);
noLoop();
for (i = 0; i < maxnumber; i++) {
if(isPrime(i)) {
n = ((i * i) - 1) / 24;
primeflag[n] = 1;
if(i % 10 == 1) {
color4[n] = 1;
} else if (i % 10 == 3) {
color4[n] = 3;
} else if (i % 10 == 7) {
color4[n] = 7;
} else if (i % 10 == 9) {
color4[n] = 9;
}
}
}
}
boolean isPrime(int num) {
int x;
if ( num < 2){
return false;
} else if (num == 2 || num == 3) {
return true;
} else if (num % 2 == 0 || num % 3 == 0) {
return false;
} else {
for ( x = 5; x * x <= num; x+= 6) {
if(num % 5 == 0|| num %(x + 2) == 0) {
return false;
}
}
}
return true;
}
void mouseMoved() {
if(tmpX != (mouseX / cellsize) || tmpY != (mouseY / cellsize)) {
println(cell[mouseX / cellsize][mouseY / cellsize] + " " + prime[mouseX / cellsize][mouseY / cellsize]);
tmpX = mouseX / cellsize;
tmpY = mouseY / cellsize;
}
}
void draw() {
fill(255, 0, 0);
for ( i = 0; i < (maxx / cellsize); i++) {
line( i * cellsize, 0, i * cellsize, 400);
}
for ( i = 0; i < (maxy / cellsize); i++) {
line(0, i * cellsize, 800, i * cellsize);
}
for (i = 0; i < maxnumber; i++) {
if(primeflag[i] == 1) { //素数のとき
//print (i);
if(color4[i] == 1) {
fill(255, 0, 0);
} else if (color4[i] == 3) {
fill(255, 255, 0);
} else if (color4[i] == 7) {
fill(255, 0, 255);
} else if (color4[i] == 9) {
fill(0, 255, 255);
}
rect(x * cellsize, y * cellsize, cellsize, cellsize);
prime[x][y] = 1;
}
cell[x][y] = i;
flag[x][y] = 1;
if(direction == 0) { //右に進む
if(flag[x + 1][y] == 0) {
x += 1;
direction = 1;
} else {
y += -1;
}
}else if(direction == 1) {//下に進む
if(flag[x][y + 1] == 0) {
y += 1;
direction = 2;
} else {
x += 1;
}
}else if(direction == 2) { //左に進む
if(flag[x - 1][y] == 0) {
x += -1;
direction = 3;
} else {
y += 1;
}
}else if(direction == 3) { //上に進む
if(flag[x][y - 1] == 0) {
y += -1;
direction = 0;
}else {
x += -1;
}
}
}
}
数字4600までやってみたのが下の図。
確かに綺麗にスパイラルになっています。

//素数らせんプログラム
// [80, 80]のマスを用意、スタート地点[40, 40]から右回りに進む。
//一つ進むごとに右 -> 下 -> 左 -> 上と進行方向を変える。
//既に数字が埋まっている場合には、方向を変えず直進する。これを繰り返す。
final int maxx = 800;
final int maxy = 800;
final int cellsize = 10;
int x = 40; //スタート地点x
int y = 40; //スタート地点y
int maxnumber = 4600; //最大値
int[] color4 = new int[maxnumber * maxnumber];
int[] primeflag = new int[maxnumber * maxnumber];
int n;
int i = 0;
int[][] cell = new int[80][80];
int[][] flag = new int[80][80];
int[][] prime = new int[80][80];
int tmpX, tmpY;
//数字の進む方向 右 -> 下 -> 左 -> 上 の順に進む
int direction = 0;
void setup(){
size(800, 800);
//frameRate(20);
background(255);
noLoop();
//最初に素数からnを求める
for (i = 0; i < maxnumber; i++) {
if(isPrime(i)) {
n = ((i * i) - 1) / 24;
primeflag[n] = 1;
if(i % 10 == 1) {
color4[n] = 1;
} else if (i % 10 == 3) {
color4[n] = 3;
} else if (i % 10 == 7) {
color4[n] = 7;
} else if (i % 10 == 9) {
color4[n] = 9;
}
}
}
}
//素数判定
boolean isPrime(int num) {
int x;
if ( num < 2){
return false;
} else if (num == 2 || num == 3) {
return true;
} else if (num % 2 == 0 || num % 3 == 0) {
return false;
} else {
for ( x = 5; x * x <= num; x+= 6) {
if(num % 5 == 0|| num %(x + 2) == 0) {
return false;
}
}
}
return true;
}
//マウスが動いたらコンソールに数字を表示
void mouseMoved() {
if(tmpX != (mouseX / cellsize) || tmpY != (mouseY / cellsize)) {
println(cell[mouseX / cellsize][mouseY / cellsize] + " " + prime[mouseX / cellsize][mouseY / cellsize]);
tmpX = mouseX / cellsize;
tmpY = mouseY / cellsize;
}
}
void draw() {
fill(255, 0, 0);
for ( i = 0; i < (maxx / cellsize); i++) {
line( i * cellsize, 0, i * cellsize, 800);
}
for ( i = 0; i < (maxy / cellsize); i++) {
line(0, i * cellsize, 800, i * cellsize);
}
for (i = 0; i < maxnumber; i++) {
//nの数字のとき、色でマスを塗る。
if(primeflag[i] == 1) {
//print (i);
if(color4[i] == 1) {//赤
fill(255, 0, 0);
} else if (color4[i] == 3) {//黄色
fill(255, 255, 0);
} else if (color4[i] == 7) {//紫
fill(255, 0, 255);
} else if (color4[i] == 9) {//水色
fill(0, 255, 255);
}
rect(x * cellsize, y * cellsize, cellsize, cellsize);
prime[x][y] = 1;
}
cell[x][y] = i;
flag[x][y] = 1;
if(direction == 0) { //右に進む
if(flag[x + 1][y] == 0) {
x += 1;
direction = 1;
} else {
y += -1;
}
}else if(direction == 1) {//下に進む
if(flag[x][y + 1] == 0) {
y += 1;
direction = 2;
} else {
x += 1;
}
}else if(direction == 2) { //左に進む
if(flag[x - 1][y] == 0) {
x += -1;
direction = 3;
} else {
y += 1;
}
}else if(direction == 3) { //上に進む
if(flag[x][y - 1] == 0) {
y += -1;
direction = 0;
}else {
x += -1;
}
}
}
}
探偵ナイトスクープで素数をやっていました。これを見たのがきっかけです。
これも簡単にprocessingでできてしまいます。やってみましょう。