for文を2回重ねておこなうループで
for(y=0;y<100;y++){ for(x=0;x<100;x++){ } } コード
というループ、つまり四角形の領域をラスタスキャンなんですけどこれを
1:(0,0)
2:(1,0)
3:(0,1)
4:(1,1)
5:(2,0)
6:(0,2)
7:(2,1)
8:(1,2)
9:(2,2)
.
.
.
みたいな段々と大きくさせる上手な書き方があれば教えて下さい
どうも自分で考えたアルゴリズムが汚いです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
もう一つ。速度完全無視で。ループは一重、if を使わない縛り。
C
1#include <stdio.h> 2#include <math.h> 3 4int main(void) 5{ 6 int a[2]; 7 for (int i = 0; i < 100; i++) 8 { 9 a[0] = sqrt(i); 10 a[1] = (i - pow(a[0], 2)) / 2; 11 printf("(%d,%d)\n", a[(i - a[0]) & 1], a[(i - a[0] + 1) & 1]); 12 } 13 return 0; 14}
math.h を使わないパターン。少し高速化されるはず。
C
1#include <stdio.h> 2 3int main(void) 4{ 5 int a[2] = { 0, 0 }; 6 for (int i = 0; i < 100; i++) 7 { 8 a[0] += i / (a[0] * (a[0] + 2) + 1); 9 a[1] = (i - a[0] * a[0]) / 2; 10 printf("(%d,%d)\n", a[(i - a[0]) & 1], a[(i - a[0] + 1) & 1]); 11 } 12 return 0; 13}
投稿2016/06/23 23:08
編集2016/06/24 00:15総合スコア28656
0
例えばこんな感じですか?
C
1char* s = "%d,%d\n"; 2for (i = 0; i < 100; i++) 3{ 4 for (j = 0; j < i; j++) 5 { 6 printf(s, i, j); 7 printf(s, j, i); 8 } 9 printf(s, i, i); 10}
###追記
関数はこうやって使います。
C
1void main() 2{ 3 for (i = 0; i < 100; i++) 4 { 5 for (j = 0; j < i; j++) 6 { 7 f(i, j); 8 f(j, i); 9 } 10 f(i, i); 11 } 12} 13 14void f(int i, int j) 15{ 16 // ややこしい処理 17 printf("%d,%d\n", i, j); 18 // 込み入った処理 19}
投稿2016/06/23 14:47
編集2016/06/23 15:29総合スコア28656
0
c でなくて、 ruby でかいてますが、アルゴリズムの意図は伝わると思います。
4 x 4 の四角領域をスキャンして、1.. 16 の数字を埋めていきます。
4つのスキャン方法を書いていますが、最後のものが質問への回答に相当すると思います。
a.rb
ruby
1@count = 1 2@board = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 3 4def show_board 5 @board.each do |vec| 6 puts vec.map { |x| format('%2d', x) }.join(', ') 7 end 8 puts 9end 10 11def action(x, y) 12 @board[y][x] = @count 13 @count += 1 14end 15 16# 水平線でスキャン 17@count = 1 18(0..3).each do |y| 19 (0..3).each do |x| 20 action(x, y) 21 end 22end 23show_board 24 25# 斜め線でスキャン 26@count = 1 27(0..3 * 2).each do |z| 28 (0..z).each do |y| 29 action(z - y, y) if y < 4 && z - y < 4 30 end 31end 32show_board 33 34# J 型でスキャン 35@count = 1 36(0..3).each do |z| 37 (0..z).each do |t| 38 action(z, t) 39 end 40 (1..z).each do |t| 41 action(z - t, z) 42 end 43end 44show_board 45 46# J 型でスキャンの変形 47@count = 1 48(0..3).each do |z| 49 action(z, z) 50 (0..z - 1).each do |t| 51 action(z, t) 52 action(t, z) 53 end 54end 55show_board
実行結果
$ ruby a.rb 1, 2, 3, 4 5, 6, 7, 8 9, 10, 11, 12 13, 14, 15, 16 1, 2, 4, 7 3, 5, 8, 11 6, 9, 12, 14 10, 13, 15, 16 1, 2, 5, 10 4, 3, 6, 11 9, 8, 7, 12 16, 15, 14, 13 1, 3, 6, 11 4, 2, 8, 13 7, 9, 5, 15 12, 14, 16, 10
渦巻状にスキャンしていくという方法もあります。
参考 - JavaScriptで渦巻き上に数字を並べたい https://teratail.com/questions/20868
追記:
順番があっていないとコメントがありました。
次のものではどうでしょう?
ruby
1 @count = 1 2(0..3).each do |z| 3 (0..z - 1).each do |t| 4 action(z, t) 5 action(t, z) 6 end 7 action(z, z) 8end 9show_board
実行結果
1, 2, 5, 10 3, 4, 7, 12 6, 8, 9, 14 11, 13, 15, 16
投稿2016/06/23 19:56
編集2016/06/24 12:12総合スコア22324
0
ベストアンサー
こんな感じかな?
C
1for(int p=0; p<100; p++){ 2 int x = p; 3 int y = 0; 4 5 for(int c=0; ; c++){ 6 7 // ここで(x, y)になんかする 8 9 if(x == y){ 10 break; 11 } 12 13 x += c & 1; 14 15 int t = x; 16 x = y; 17 y = t; 18 } 19}
投稿2016/06/23 17:11
総合スコア2850
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/06/24 09:30
2016/06/24 17:10
2016/06/25 11:35
0
頭の体操で、二重ループを一重ループにしてみました。
条件文が増えているので、効率は落ちてます。
C
1int level = -1; 2int start = -1; 3int end = 0; 4for (int i = 0; i < 100; i++) 5{ 6 int x, y; 7 if (i % 2 == start % 2) 8 { 9 x = (i - start) / 2 - 1; 10 y = level + 1; 11 } 12 else 13 { 14 x = level + 1; 15 y = (i - start - 1) / 2; 16 } 17 f(x, y); 18 if (i == end) 19 { 20 level++; 21 start = end; 22 end = level * (level + 4) + 3; 23 } 24}
投稿2016/06/23 16:28
編集2016/06/23 16:32総合スコア28656
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。