正六角形ブロックの回転
締め切りが 2017/10/06 10:00 AM なので,その 1 分後に投稿されるように予約
【概要】
下図のような、正六角形マス目の集まりがあります。
マス目のうちのいくつかにブロックが入っています。
中心を指定するので、そこを中心にブロックを時計回りに 120度回したらどうなるのかを計算して下さい。
【入出力】
入力は
a 000/0110/00000/0000/000
のようになっています。
空白の前は中心を示す記号です。
a, b のいずれかで、図の a点、b点に対応しています。
空白のあとは、マス目の状況を示しています。
スラッシュ区切りで各行の状況を上から順にならべています。
「1」がブロックあり、「0」がブロックなしのマスを示します。
出力は、回転したあとのブロックの状況を
000/0000/00000/0100/100
のような感じで。
入力の時と同様、各行の状況を上から順にスラッシュ区切りでならべて下さい。
ただし、
b 111/0101/00000/0100/111
のように、回転するともとのマス目からはみ出してしまう場合は
-
を出力して下さい。
【例】
入力 出力
a 000/0110/00000/0000/000 000/0000/00000/0100/100
b 111/0101/00000/0100/111 -
b 010/0011/01010/0100/000 011/0000/00111/0010/000
================================================================================
f = function(s) {
type = substr(s, 1, 1) # a か b
s = gsub("/", "", substr(s, 3, 25))
pos = as.integer(unlist(strsplit(s, ""))) # 黒塗りされた正六角形場所左上から右・下へ 1〜19
r3 = sqrt(3)/2
# a を中心としたときの,それぞれの正六角形の中心の座標(x, y)
x = c( 0.0, 1.0, 2.0,
-0.5, 0.5, 1.5, 2.5,
-1.0, 0.0, 1.0, 2.0, 3.0,
-0.5, 0.5, 1.5, 2.5,
0.0, 1.0, 2.0)
y = rep(r3*(2:-2), c(3, 4, 5, 4, 3))
if (type == "b") { b を中心としたときの,それぞれの正六角形の中心の座標(x, y)
x = x-1.5
y = y-sqrt(3)/6
}
n = sum(pos)
x2 = x[pos==1] # 黒塗りされた正六角形の中心の座標(x, y)
y2 = y[pos==1]
xy = cbind(x2, y2)
theta = pi*2/3 # 120度座標軸を回転
rot.xy = xy %*% matrix(c(cos(theta), sin(theta), -sin(theta), cos(theta)), 2)
ans = integer(19)
for (i in seq_len(n)) { # はみ出すかどうかチェック
ok = FALSE
for (j in seq_along(x)) {
if (isTRUE(all.equal(rot.xy[i, 1], x[j])) && isTRUE(all.equal(rot.xy[i, 2], y[j]))) {
ok = TRUE
ans[j] = 1 # はみ出さない正六角形の位置に 1 をセット
break
}
}
if (ok == FALSE) {
break
}
}
if (ok == FALSE) { # はみ出す正六角形があるとき
cat("-")
} else { # 全部内部にあるとき
cat(ans[1:3], "/", ans[4:7], "/", ans[8:12], "/", ans[13:16], "/", ans[17:19], sep="")
}
}
# f(readLines(file("stdin", "r")))
f("a 110/1010/11100/1100/000") # 000/1100/11100/1010/110
f("b 000/0011/01101/0001/010") # 101/0010/01010/0110/000
f("a 000/0100/01100/0000/000") # 000/0000/01000/1100/000
f("b 000/0011/00111/0011/010") # 100/0110/01110/0110/000
f("a 100/0100/10100/0100/000") # 000/0100/10000/1110/000
f("b 000/0100/00110/0000/011") # 100/1011/00100/0000/000
f("a 000/1100/01100/0000/000") # 000/0000/01100/1100/000
f("b 000/0011/00000/0010/010") # 100/0100/00010/0010/000
f("a 010/0111/11000/0000/101") # -
f("b 110/0000/10000/0110/010") # -
f("a 110/1101/01001/1010/000") # -
f("b 011/1111/10000/0110/111") # -
※コメント投稿者のブログIDはブログ作成者のみに通知されます