裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

正六角形ブロックの回転

2017年10月06日 | ブログラミング

正六角形ブロックの回転

締め切りが 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") # -

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村