ぐるぐるスクエア
締め切りが 2017/02/17 10:00 AM なので,その 1 分後に投稿されるように予約
【概要】
下図のように四角形のマスに数が入っています。
マスは無限に広がっており、全てのマスに数が入っています。
数を指定するので、その数が書かれているマスに隣接する(つまり、辺を共有する)4つのマスに書かれている数を、小さい順に出力してください。
※法則は図から読み取ってください
【入出力】
入力は
12
のように、普通に 10進数で来ます。
出力は、
3,11,13,29
のような感じです。
4つの数をコンマ区切りで昇順に並べてください。
【例】
入力 出力
12 3,11,13,29
34 15,33,35,61
77 46,76,78,116
【補足】
不正な入力に対処する必要はありません。
入力は、1以上、1000以下です。
================================================
規則性を利用してプログラム
「入力は、1以上、1000以下」の意味は何なのだろうか?上限は幾つだろうと計算時間はほとんど瞬殺。
ru = function(n) 4 * n^2 + 4 * n + 1 # 右上 1,9,25,49,81,... の数列 n=0,1,2,3,4,...
lu = function(n) 4 * n^2 + 6 * n + 3 # 左上 1,3,13,31,57,... の数列
ld = function(n) 4 * n^2 + 8 * n + 5 # 左下 1,5,17,37,65,... の数列
rd = function(n) 4 * n^2 + 10 * n + 7 # 右下 1,7,21,43,73,... の数列
up = function(n) 8 * n + 9 # 上のサイクルへの差分 例えば 2(サイクル0) から 11(サイクル1) への差分
left = function(n) 8 * n + 11 # 左のサイクルへの差分 例えば 3(サイクル0) から 14(サイクル1) への差分
down = function(n) 8 * n + 13 # 下のサイクルへの差分 例えば 6(サイクル0) から 19(サイクル1) への差分
right = function(n) 8 * n + 15 # 右のサイクルへの差分 例えば 8(サイクル0) から 23(サイクル1) への差分
f = function(N) {
n = 0 # どのサイクルにあるか検出s
repeat { # サイクルは (1-8), (9-24), (25-48), ... をサイクル 0, 1, 2, ... とする
if (N >= ru(n) && ru(n + 1) > N) {
break
}
n = n + 1
}
RU = ru(n) # サイクルの開始点
LU = lu(n) # サイクルの左折点(左向きから下向きへ)
LD = ld(n) # サイクルの左折点(下向きから右向きへ)
RD = rd(n) # サイクルの左折点(右向きから上向きへ)
a = if (N == 1) { # N = 1 は特別
N + c(up(-1), left(-1), down(-1), right(-1)) # (2, 4, 6, 8)
} else if (N == RU) { # N = RU = 49
c(ru(n - 1) + 1, N - 1, N + 1, ru(n + 1) - 1) # (26, 48, 50, 80)
} else if (N == RU + 1) { # N = RU+1 = 50
c(N - 1, N + 1, ru(n + 1), ru(n + 1) + 2) # (49, 51, 81, 83)
} else if (N > RU + 1 && LU - 1 > N) { # N = 51 thru 55
c(N - up(n - 1), N - 1, N + 1, N + up(n)) # N = 51; (26, 50, 52, 84)
} else if (N == LU - 1) { # N = 56
c(lu(n - 1), N - 1, N + 1, lu(n + 1) - 2) # (31, 55, 57, 89)
} else if (N == LU) { # N = LU = 57
c(N - 1, N + 1, lu(n + 1) - 1, lu(n + 1) + 1) # (56, 58, 90, 92)
} else if (N > LU && LD > N) { # N = 58 thru 64
c(N - left(n - 1), N - 1, N + 1, N + left(n)) # N = 58; (31, 57, 59, 93)
} else if (N == LD) { # N = 65
c(N - 1, N + 1, ld(n + 1) - 1, ld(n + 1) + 1) # (64, 66, 100, 102)
} else if (N > LD && RD > N) { # N = 66 thru 72
c(N - down(n - 1), N - 1, N + 1, N + down(n)) # N = 66; (37, 65, 67, 103)
} else if (N == RD) { # N = 73
c(N - 1, N + 1, rd(n + 1) - 1, rd(n + 1) + 1) # (72, 74, 110, 112)
} else if (N > RD && ru(n + 1) > N) { # N = 74 thru 81
c(N - right(n - 1), N - 1, N + 1, N + right(n)) # n = 74; (43,73,75,113)
}
cat(a, sep = ",")
}
> f(1)
2,4,6,8
> f(2)
1,3,9,11
> f(3)
2,4,12,14
> f(4)
1,3,5,15
> f(5)
4,6,16,18
> f(6)
1,5,7,19
> f(7)
6,8,20,22
> f(8)
1,7,9,23
> f(9)
2,8,10,24
> f(10)
9,11,25,27
> f(100000)
98739,99999,100001,101269