水木社区 - Blog - 灵感点滴 http://davies.mysmth.net    
davies 的Blog - 灵感点滴
 灵感的来临,没有任何预兆;灵感的消失,也不会有告别仪式;用文字记下她们吧,让灵感永存……
四色方块问题
作者:davies
发表时间:
2006-08-04 23:04:20
更新时间:
2007-04-23 00:13:35
浏览:1671次
主题:个人空间
评论:2篇
地址:59.66.124.*


:::栏目:::

前几天去公司面试时,要求求解一个四色方块问题,好像是该公司专门为面试设计的,比较有意思,在Employment页中:

Engineering Puzzle

You have four colored cubes. Each side of each cube is a single color, and there are four colors: blue (B), red (R), green (G) and yellow (Y) Describing the six faces as front, back, left, right, top, bottom, the cube colors are:

Cube
Front
Back
Left
Right
Top
Bottom
1
R
B
G
Y
B
Y
2
R
G
G
Y
B
B
3
Y
B
R
G
Y
R
4
Y
G
B
R
R
R

The objective is to find ways to stack the four cubes as a vertical column so that each side of the column is showing all four colors.

大意是将4个四色方块排成一列,使得每一面正好是四种不同颜色。颜色以及盒子数量都不多,直接穷举就可以。每个盒子有24种摆放方位,总共有24^4=331776种。

穷举出每一种组合时,需要检查是否满足颜色各异的要求。如果用整数中1位表示一种颜色,则它们按位与结果为0。四种颜色正好用4位来表示,一个方块的摆放可以用24位来表示,一个32位的整数足以。

先穷举每个方块的所有24种方位,得到24个整数,然后这四组整数进行组合共有331776种情况,后16位两两相与为0的即为所求的解。最后求得1个解,它上下翻转、侧向旋转后可以得到8种摆放方式。

完整的Python程序如下,其中用到了一些函数编程的技巧,效果还不错。

#!/usr/bin/python

AUTHOR = "Davies Liu (davies.liu@gmail.com)"
DATE = "8/2/2006"

"""
Engineering Puzzle

You have four colored cubes. Each side of each cube is a single color,
and there are four colors: blue (B), red (R), green (G) and yellow (Y)
Describing the six faces as front, back, left, right, top, bottom,
the cube colors are:
Cube    Front   Back    Left    Right   Top     Bottom
1       R       B       G       Y       B       Y
2       R       G       G       Y       B       B
3       Y       B       R       G       Y       R
4       Y       G       B       R       R       R

The objective is to find ways to stack the four cubes as a vertical column
so that each side of the column is showing all four colors.
"""

def rotate(n):
    """   rotate four side of a cube    """
    r = [n]
    tb,others = n & 0xff0000, n & 0xffff
    for i in range(3):
        others = ((others&0xf000) >> 12) | ((others&0xff) << 8) | ((others&0xf00) >> 4)
        r.append(tb|others)
    return r

def turnover(n):
    """turn over the cube"""
    return [n,((n&0xf0f000)>>4) | ((n&0x0f0f00)<<4) | (n&0xff) ]

def turn(n, Rotate = True):
    """ turn the cube"""
    r = [n,
         ((n&0x0f)<<20) | ((n&0xf0)<<12) | ((n&0xff0000)>>16) | (n&0xff00),
         ((n&0x0f00)<<12) | ((n&0xf000)<<4) | ((n&0xff0000)>>8) | (n&0xff)]
    if Rotate:
        r = sum(map(turnover,r),[])
        r = sum(map(rotate,r),[])
    return r

def samecolor(aboves,below):
    """check if the below cube has the same color with any of above cubes, on any side"""
    for above in aboves:
        if above & below & 0xffff : return True
    return False

def combine(aboves,below):
    """put a cube below, generate a new sequence"""
    return [a+[b] for a in aboves for b in below if not samecolor(a,b) ]

def solve(cube):
    """solve the puzzle """
    # generate the permunation of the directions of the four cubes
    permunation = [turn(cube[0],False)] + map(turn,cube[1:])
    # put four cubes together, and validate them
    return reduce(combine,permunation,[[]])

def output(result):
    print "Don't change position of four cubes and don't turn them in the same time,"
    print "there are %d way to stack the four cubes, they are listed below:\n" % len(result)
    
    colors = ['']*9
    colors[1],colors[2],colors[4],colors[8] = 'R','G','B','Y'

    print "Cube    Top     Bottom   Front   Back    Left    Right   "
    for r in result:
        for i in range(len(r)):
            print i+1,
            for j in range(6):
                c = 0xf & (r[i] >> ((5-j)*4))
                print "\t%s" % colors[ c ],
            print
        print
                             

def main():
    # use a number to identity the direnction of a cube, four bits per side
    # Top     Bottom   Front  
Back     Left        Right
    # 0x01 R
    # 0x02 G
    # 0x04 B
    # 0x08 Y
    cubes = [ 0x481428,
              0x441228,
              0x818412,
              0x118241]  
    result = solve(cubes)
    output(result)

def test():
    n = 0x123456
    print map(hex,rotate(n))
    print map(hex,turnover(n))
    print map(hex,turn(n))
    
if __name__ == '__main__':
    #test()
    main()

运行结果为:

Don't change position of four cubes and don't turn them in the same time,
there are 1 way to stack the four cubes, they are listed below:

Cube    Top     Bottom   Front   Back    Left    Right  
1     Y     G     R     B     B     Y
2     B     B     G     R     Y     G
3     Y     R     B     Y     G     R
4     R     R     Y     G     R     B

请到davies的blog主站灵感点滴阅读原文和发表评论:四色方块问题

 
上一篇 下一篇 展开所有评论 发表评论 推荐 转载 写信问候 返回目录 快速返回 我的百宝箱

共有 2 条评论
  rotate 函数是不是不太对[Black8 于 2006-08-05 16:43:38 提到] 1  
  注释有误[davies 于 2006-08-23 20:00:50 提到] 2  
上一篇 下一篇 展开所有评论 发表评论 推荐 转载 写信问候 返回目录 快速返回 我的百宝箱  
发表评论 注意:仅有本站登录用户才能发表评论
用户名:    密 码:       


[返回顶部] [刷新] [给davies写信][灵感点滴首页] [Blog首页] [水木社区首页]

Powered By KBS_BBS
Powered By KBS_BBS