How to solve 5 * 5 Cube in efficient easy way

前端 未结 1 2027
旧时难觅i
旧时难觅i 2021-02-10 07:08

There is 5*5 cube puzzle named Happy cube Problem where for given mat , need to make a cube . http://www.mathematische-basteleien.de/cube_its.htm#top

Its like, 6 blue m

1条回答
  •  心在旅途
    2021-02-10 07:19

    I can't believe this, but I actually wrote a set of scripts back in 2009 to brute-force solutions to this exact problem, for the simple cube case. I just put the code on Github: https://github.com/niklasb/3d-puzzle

    Unfortunately the documentation is in German because that's the only language my team understood, but source code comments are in English. In particular, check out the file puzzle_lib.rb.

    The approach is indeed just a straightforward backtracking algorithm, which I think is the way to go. I can't really say it's easy though, as far as I remember the 3-d aspect is a bit challenging. I implemented one optimization: Find all symmetries beforehand and only try each unique orientation of a piece. The idea is that the more characteristic the pieces are, the less options for placing pieces exist, so we can prune early. In the case of many symmetries, there might be lots of possibilities and we want to inspect only the ones that are unique up to symmetry.

    Basically the algorithm works as follows: First, assign a fixed order to the sides of the cube, let's number them 0 to 5 for example. Then execute the following algorithm:

    def check_slots():
        for each edge e:
            if slot adjacent to e are filled:
                if the 1-0 patterns of the piece edges (excluding the corners)
                       have XOR != 0:
                    return false
                if the corners are not "consistent":
                    return false
        return true
    
    def backtrack(slot_idx, pieces_left):
        if slot_idx == 6:
            # finished, we found a solution, output it or whatever
            return
        for each piece in pieces_left:
            for each orientation o of piece:
                fill slot slot_idx with piece in orientation o
                if check_slots():
                    backtrack(slot_idx + 1, pieces_left \ {piece})
                empty slot slot_idx
    

    The corner consistency is a bit tricky: Either the corner must be filled by exactly one of the adjacent pieces or it must be accessible from a yet unfilled slot, i.e. not cut off by the already assigned pieces.

    Of course you can ignore to drop some or all of the consistency checks and only check in the end, seeing as there are only 8^6 * 6! possible configurations overall. If you have more than 6 pieces, it becomes more important to prune early.

    0 讨论(0)
提交回复
热议问题