この年ならではパズルの解法(力任せ)

娘のじーちゃんが作ったパズル。中途半端なヒントが気になって一度ばらしたら組み立てる気が起こらない。ていうか正直組み立てられなくなってしまった orz

でも1年放置したまま帰省するのもなんなので、組み立てるためのプログラムを書く事にする。
小学生の俺にはできなかった事だ。強いぞ俺!

import sys

blocks = [
    [ (0,0,0), (1,0,0),
      (0,1,0), 
      (0,2,0), (1,2,0),
      (0,3,0), (1,3,0) ],
    [ (0,0,0), (1,0,0), (0,0,1), (1,0,1), 
      (0,1,0), (1,1,0),
      (1,2,0),
      (1,3,0), (1,3,1) ],
    [ (1,0,0), (1,0,1),
      (1,1,0),
      (0,2,0), (1,2,0),
      (0,3,0), (1,3,0), (1,3,1) ],
    [ (0,0,0), (0,0,1),
      (0,1,0), (0,1,1),
      (0,2,0), (1,2,0), (0,2,1), (1,2,1),
      (0,3,0), (0,3,1) ],
    [ (0,0,0), (0,0,1),
      (0,1,0),
      (0,2,0),
      (0,3,0), (0,3,1) ],
    [ (0,0,0), (1,0,0), (0,0,1), (1,0,1),
      (0,1,0), (1,1,0), (0,1,1), (1,1,1),
      (0,2,0), (1,2,0), (0,2,1), (1,2,1),
      (0,3,0), (1,3,0), (0,3,1), (1,3,1) ]
    ]

def rotate(pArray, p = 0):
    def roll(pArray):
        rolled = [ (-z, y, x) for x,y,z in pArray ]
        return [ (x + 1, y, z) for x,y,z in rolled ]

    def rev(pArray):
        pArray = [ (x, -y, -z) for x,y,z in pArray ]
        return [ (x, y + 3, z + 1) for x,y,z in pArray ]

    if p == 0:
        return pArray
    elif p == 1:
        return roll(pArray)
    elif p == 2:
        return roll(roll(pArray))
    elif p == 3:
        return roll(roll(roll(pArray)))
    elif p == 4:
        return rev(pArray)
    elif p == 5:
        return roll(rev(pArray))
    elif p == 6:
        return roll(roll(rev(pArray)))
    elif p == 7:
        return roll(roll(roll(rev(pArray))))


def position(pArray, num):
    if num == 0:
        return pArray
    elif num == 1:
        return [ (x + 2, y, z) for x,y,z in pArray ]
    elif num == 2:
        pArray = [ (y, -x, z ) for x,y,z in pArray ]
        return [ (x + 0, y + 2, z - 1 ) for x,y,z in pArray ]
    elif num == 3:
        pArray = [ (y, -x, z ) for x,y,z in pArray ]
        return [ (x + 0, y + 2, z + 1 ) for x,y,z in pArray ]
    elif num == 4:
        pArray = [ (x, -z, y ) for x,y,z in pArray ]
        return [ (x + 1, y + 1, z - 1 ) for x,y,z in pArray ]
    elif num == 5:
        pArray = [ (x, -z, y ) for x,y,z in pArray ]
        return [ (x + 1, y + 3, z - 1 ) for x,y,z in pArray ]

board = set()
used = []
rots = []

def perm(blks):
    global board, used, rots

    # print "current blocks:", used
    if len(blks) == 0:
        print "board:", board
        print "last blocks:", [x + 1 for x in used]
        print "rotation:", [x + 1 for x in rots]
        # sys.exit()

    for i in range(0, len(blks)):
        me, left = blks[i], blks[:i] + blks[i+1:]
        for p in range(0,8):
            cubes = set(position(rotate(blocks[me], p), len(used)))
            if len(board & cubes) == 0:
                board |= cubes
                used.append(me)
                rots.append(p)
                perm(left)
                rots.pop()
                used.pop()
                board -= cubes

perm([0,1,2,3,4,5])

はてなのデザインによっては右が切れてしまうのか、、、。それはそれで考えるとして、要するに総当たりで。

順列?組み合わせってどう書けば?回転行列て聞いたような?とか高校の授業をすっかり忘れていることに気がついた。
いままで忘れてても生きてこれたんだね。べつに思い出さなくても死なないような気はするけど。
さらには、うまく動く前(デバッグ中)に本題のパズルを組み立てる事ができてしまった。弱い俺w

うーん。楽しかったけど役に立たない。