「オフラインリアルタイムどう書くF05の問題」の解答

「オフラインリアルタイムどう書くF04の問題 - ブロックを回す」の解答
http://nabetani.sakura.ne.jp/hena/ordf05rotblo/

会場では間に合わず。全部で2時間ぐらい。
電車の中でまさかのPythonのiPhoneアプリを発見。
それ使ってデバッグ。


現場で動かなかった原因は以下。

- 四捨五入のロジックが間違っていた。roundを使わず、0.5プラスしていた。マイナスの数字の場合意図しない結果になる。
- 回転角が間違っていた。 -90度にすべきだが、90度だった。
- 多重配列rowのi と jの使い方が逆だった




```python:main.py

## yhpg F05

import math

W = H = 5

def rotate(x, y):
    d = - math.pi / 2
    xd = x * math.cos(d) - y * math.sin(d)
    yd = x * math.sin(d) + y * math.cos(d)
    return (int(round(xd)), int(round(yd)))

def make_key(x, y):
   return str(x) + "," +str(y)

def resolve(data):
    center, rows = data.split(":")
    row = rows.split("/")

    ax = [-1, 0, 1, 2, 3]
    ay = [2, 1, 0, -1, -2]
    bx = [-2, -1, 1, 2, 3]
    by = [2, 1, -1, -2, -3]

    field = {}

    locx, locy = None, None
    if center == 'a':
        locx, locy = ax, ay
    else:
        locx, locy = bx, by

    for i in range(W):
        for j in range(H):
            field[make_key(locx[i], locy[j])] = '0'

    for i in range(W):
        for j in range(H):
            if row[j][i] == '1':
                key = make_key(*rotate(locx[i], locy[j]))
                if field.has_key(key):
                    field[key] = row[j][i]
                else:
                    return '-'        

    result = ['']*H
    for i in range(W):
        for j in range(H):
            result[j] += field[make_key(locx[i], locy[j])]

    return '/'.join(result)


## test logic
class Result:
    def __init__(self):
        self.success = 0
        self.fail = 0

RESULT = Result()
RESULT.success = RESULT.fail = 0

def test(data, expect):
    print("actual:" + resolve(data) + " expected:" + expect)
    if resolve(data) == expect:
        RESULT.success += 1
    else:
        RESULT.fail += 1

## ---- tests ----

test( "a:00000/00110/00100/00100/00000", "00000/00000/00000/11100/00100" )   
test( "b:00000/00000/00000/00011/00011", "-" )
test( "a:00000/00000/00000/00011/00011", "-" )
test( "b:00000/00000/00100/00000/00000", "00000/00000/01000/00000/00000" )
test( "a:00000/00000/00100/00000/00000", "00000/00000/00000/01000/00000" )
test( "b:00000/00110/00100/00100/00000", "00000/00000/11100/00100/00000" )
test( "b:00000/00000/00011/00011/00000", "00000/00000/00000/11000/11000" )
test( "a:00000/00000/00011/00011/00000", "-" )
test( "a:01110/00100/00000/00000/00000", "00000/00000/00010/00110/00010" )
test( "b:01110/00100/00000/00000/00000", "00000/00010/00110/00010/00000" )
test( "a:00000/11110/00000/00000/00000", "00000/00100/00100/00100/00100" )
test( "b:00000/11110/00000/00000/00000", "00100/00100/00100/00100/00000" )
test( "a:00000/00011/00110/00000/00000", "-" )
test( "b:00000/00011/00110/00000/00000", "00000/00000/01000/01100/00100" )
test( "a:00000/11100/11100/11100/00000", "00000/11100/11100/11100/00000" )
test( "b:00000/11100/11100/11100/00000", "11100/11100/11100/00000/00000" )
test( "a:01000/00000/00101/10010/10001", "-" )
test( "b:01000/00000/00101/10010/10001", "-" )
test( "b:10000/00000/10010/00000/00000", "01010/00000/00000/01000/00000" )
test( "a:10000/00000/10010/00000/00000", "00000/01010/00000/00000/01000" )
test( "a:00000/10101/11010/11010/01000", "-" )
test( "b:00000/10101/11010/11010/01000", "-" )
test( "b:01101/00011/01101/00000/00000", "00000/01010/01010/00100/01110" )
test( "a:01101/00011/01101/00000/00000", "-" )
test( "a:00001/00000/00000/00100/00010", "-" )
test( "b:00001/00000/00000/00100/00010", "-" )
test( "b:00100/00000/00100/01000/00000", "00000/10000/01010/00000/00000" )
test( "a:00100/00000/00100/01000/00000", "00000/00000/10000/01010/00000" )
test( "a:00010/00100/00000/10000/00000", "00000/10000/00000/00100/00010" )
test( "b:00010/00100/00000/10000/00000", "10000/00000/00100/00010/00000" )
test( "b:11010/00011/10101/00001/00001", "-" )
test( "a:11010/00011/10101/00001/00001", "-" )
test( "a:00100/00010/00000/11000/00000", "00000/10000/10000/00010/00100" )
test( "b:00100/00010/00000/11000/00000", "10000/10000/00010/00100/00000" )
test( "b:01010/00000/00000/01000/00000", "00000/10010/00000/00010/00000" )
test( "a:01010/00000/00000/01000/00000", "00000/00000/10010/00000/00010" )
test( "a:00000/00000/00100/10100/00000", "00000/10000/00000/11000/00000" )
test( "b:00000/00000/00100/10100/00000", "10000/00000/11000/00000/00000" )
test( "b:10000/01101/01000/01100/10011", "-" )
test( "a:10000/01101/01000/01100/10011", "-" )
test( "a:00010/00000/00110/01000/10001", "-" )
test( "b:00010/00000/00110/01000/10001", "-" )
test( "b:00000/01000/01100/00000/00000", "00000/01100/01000/00000/00000" )
test( "a:00000/01000/01100/00000/00000", "00000/00000/01100/01000/00000" )
test( "a:01000/00000/00000/10000/00000", "00000/10000/00010/00000/00000" )
test( "b:01000/00000/00000/10000/00000", "10000/00010/00000/00000/00000" )
test( "b:00000/01101/00000/01010/11010", "-" )
test( "a:00000/01101/00000/01010/11010", "-" )
test( "a:00110/00101/00000/10100/00100", "-" )
test( "b:00110/00101/00000/10100/00100", "-" )
test( "b:11000/10110/00000/00110/00000", "00110/00010/10100/10100/00000" )
test( "a:11000/10110/00000/00110/00000", "00000/00110/00010/10100/10100" )
test( "a:00000/00000/00000/00001/00110", "-" )
test( "b:00000/00000/00000/00001/00110", "-" )
test( "b:01011/10001/00000/00000/00000", "00100/00010/00000/00010/00110" )
test( "a:01011/10001/00000/00000/00000", "-" )
## --------------

print("Success: {0.success}, Fail: {0.fail}".format(RESULT))

```