Ich habe versucht, den Soma-Würfel mit Python zu lösen. Als Ergebnis konnten wir 480 verschiedene Würfelerstellungsmuster lösen. Obwohl es sich um ein Puzzle handelte, konnte ich in der Phase der Implementierung des Puzzles verschiedene Dinge lernen. Ich werde das Know-how zu diesem Zeitpunkt im Artikel belassen. Ich hoffe dieser Artikel hilft jemandem.
Klicken Sie hier für den Quellcode
Soma Cube ist ein dreidimensionales Puzzle, das sieben dreidimensionale Puzzles zu einem Würfel kombiniert. Siehe unten für Details.
[Soma Cube](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%BC%E3%83%9E%E3%82%AD%E3%83%A5%E3% 83% BC% E3% 83% 96)
Sie können verschiedene andere 3D-Figuren als den Würfel erstellen, aber dieses Mal haben wir den 3x3-Würfel zum ausgefüllten Formular gemacht. Offensichtlich ändert sich das Aussehen des Würfels nicht, selbst wenn er gedreht wird. Da es um 6 Richtungen gedreht werden kann, werden diese 6 Muster als 1 Muster gezählt.
Tatsächlich ist dies nicht das erste Mal, dass der Soma-Würfel programmgesteuert gelöst wird. Das erste Mal war ich ein Student, der vor ungefähr 13 Jahren nicht einmal die "Iroha" des Programmierens kannte. Zu dieser Zeit, während der Lehrer mir das Programmieren beibringt, ist die Erklärung auch Ameise Ich erinnere mich, dass ich es über mehrere Monate getan habe. Am Ende konnte ich es lösen, aber die Bearbeitungszeit betrug ca. 2 Stunden Ich denke es hat gedauert. Ich frage mich, ob ich es ehrlich verstanden habe. Das zweite Mal war vor ungefähr einem Jahr. Ich habe es auf dem Weg satt und aufgehört.
Wie oben erwähnt, erinnere ich mich, dass ich in der Vergangenheit Probleme mit der Verarbeitungszeit hatte, diesmal also mit der Verarbeitungsgeschwindigkeit Ich war besorgter als gewöhnlich.
Python hat auch ein Java-ähnliches Set. Es ist viel schneller als Liste. (Es gibt keine Garantie für die Bestellung) Dieses Mal wurde das Stückobjekt auf halber Strecke als Liste und als Set aus der Mitte behandelt.
# ==================================================
# CUBE
# ==================================================
class Cube:
def __init__(self, label, pList):
# label
self.label = label
# pieseList
self.pList = pList
# ==================================================
# COORDINATE
# ==================================================
class XYZ:
def __init__(self, x, y, z):
# x
self.x = x
# y
self.y = y
# z
self.z = z
# ==================================================
# Cube for calc
# ==================================================
class Cube4Calc:
def __init__(self, label, pList):
# label
self.label = label
# piese list sets
self.pList = set(pList)
# ==================================================
# convertToCalcCube
# ==================================================
def convToCalcCube(cube):
calcCube = cc.Cube4Calc(cube.label, [])
for p in cube.pList:
calcCube.pList.add(convPToPIdx(p))
return calcCube
# ==================================================
# convertPieseToPieseIndex
# ==================================================
def convPToPIdx(p):
return p.x + (p.z * 3) + (p.y * 9)
Das Ausprobieren aller Kombinationen aller sieben Teile erfordert einen enormen Verarbeitungsaufwand. Ich habe die Kombinationen von Anfang an in der richtigen Reihenfolge ausprobiert, und wenn es NG war, schrieb ich, dass die nachfolgende Verarbeitung nicht durchgeführt werden würde.
# ==================================================
# getResolveCubeList
# ==================================================
def getResolveCubeList(cube4CalcLList, cube4CalcZList, cube4CalcTList, cube4CalcAList, cube4CalcBList, cube4CalcPList, cube4CalcVList):
resolveCubeList = []
for cube4CalcL in cube4CalcLList:
for cube4CalcZ in cube4CalcZList:
sumCube4Calc_LZ = createSumCube4Calc(cube4CalcL, cube4CalcZ, 8)
if not sumCube4Calc_LZ is None:
for cube4CalcT in cube4CalcTList:
sumCube4Calc_LZT = createSumCube4Calc(sumCube4Calc_LZ, cube4CalcT, 12)
if not sumCube4Calc_LZT is None:
for cube4CalcA in cube4CalcAList:
sumCube4Calc_LZTA = createSumCube4Calc(sumCube4Calc_LZT, cube4CalcA, 16)
if not sumCube4Calc_LZTA is None:
for cube4CalcB in cube4CalcBList:
sumCube4Calc_LZTAB = createSumCube4Calc(sumCube4Calc_LZTA, cube4CalcB, 20)
if not sumCube4Calc_LZTAB is None:
for cube4CalcP in cube4CalcPList:
sumCube4Calc_LZTABP = createSumCube4Calc(sumCube4Calc_LZTAB, cube4CalcP, 24)
if not sumCube4Calc_LZTABP is None:
for cube4CalcV in cube4CalcVList:
sumCube4Calc_LZTABPV = createSumCube4Calc(sumCube4Calc_LZTABP, cube4CalcV, 27)
if not sumCube4Calc_LZTABPV is None:
resolveCubeList.append(sumCube4Calc_LZTABPV)
return resolveCubeList
# ==================================================
# createSumCube4Calc
# ==================================================
def createSumCube4Calc(cube4Calc_1, cube4Calc_2, length):
sumPList = cube4Calc_1.pList | cube4Calc_2.pList
if len(sumPList) == length:
# print(">>> END createSumCube4Calc")
return cc.Cube4Calc(cube4Calc_1.label + cube4Calc_2.label, sumPList)
return None
Wenn Sie beispielsweise ein Puzzle drehen, ist es schwierig zu erkennen, ob es sich wie erwartet dreht, indem Sie nur die xyz-Koordinaten anzeigen. Wir haben eine Methode vorbereitet, um Stücke als Bild in einem ASCII-Kunststil anzuzeigen, und diese bei der Durchführung methodenbasierter Tests verwendet.
# ==================================================
# printGraphicCube
# ==================================================
def printGraphicCube(cube):
# create 2*2 list
graphic = [[0] * 23 for i in range(27)]
for idxZ in range(0, 3)[::-1]:
for p in cube.pList:
if p.z == idxZ:
printGraphicPiese(p.x, p.y, p.z, graphic)
for y in range(23)[::-1]:
rowStr = ""
for x in range(27):
rowStr = rowStr + str(graphic[x][y])
print(rowStr)
# ==================================================
# printGraphicPiese
# ==================================================
def printGraphicPiese(x, y, z, graphic):
baseX = x * 5 + z * 2
baseY = y * 3 + z * 2
printRow(graphic, baseX, baseY + 5, 2, "+----+")
printRow(graphic, baseX, baseY + 4, 1, "/ /|")
printRow(graphic, baseX, baseY + 3, 0, "+----+ |")
printRow(graphic, baseX, baseY + 2, 0, "| | /")
printRow(graphic, baseX, baseY + 1, 0, "| |/")
printRow(graphic, baseX, baseY + 0, 0, "+----+")
# ==================================================
# printRow
# ==================================================
def printRow(graphic, x, y, shiftX, graphicStr):
startX = x + shiftX
graphicStrList = list(graphicStr)
cntStr = 0
for posX in range(startX, startX + len(graphicStr)):
graphic[posX][y] = graphicStrList[cntStr]
cntStr = cntStr + 1
Lassen Sie mich kurz die Punkte der Hauptverarbeitung erläutern.
# ==================================================
# resolve
# ==================================================
def resolve():
calc4CubeListList = []
for idxC in range(7):
cube = cubeCreater.createBasicCube(idxC)
calc4CubeList = []
# lotationLength = vectol * latation = 6 * 4 = 24
lengthL = 24
# fix pattern first cube (1)
if idxC == 0:
lengthL = 1
for idxL in range(lengthL):
cloneC = copy.deepcopy(cube)
cubeRotationer.lotation(cloneC, idxL)
notOverCubeList = cubeSetter.createNotOverCubeList(cloneC) (2)
for notOverCube in notOverCubeList:
calc4Cube = cubeExchanger.convToCalcCube(notOverCube) (3)
calc4CubeList.append(calc4Cube)
pNum = 4
# only cubeV's pieseNum is 3
if idxC == 6:
pNum = 3
calc4CubeList = cubeExchanger.removeDupCubes(calc4CubeList, pNum) (4)
calc4CubeListList.append(calc4CubeList)
resolveCubeList = cubeResolver.getResolveCubeList(calc4CubeListList[0], calc4CubeListList[1], calc4CubeListList[2], calc4CubeListList[3], calc4CubeListList[4], calc4CubeListList[5], calc4CubeListList[6])
print("finish. ptn = " + str(len(resolveCubeList)))
if idxC == 0:
lengthL = 1
notOverCubeList = cubeSetter.createNotOverCubeList(cloneC)
calc4Cube = cubeExchanger.convToCalcCube(notOverCube)
calc4CubeList = cubeExchanger.removeDupCubes(calc4CubeList, pNum)
Diesmal habe ich versucht, den Soma-Würfel zu lösen. In der Phase der Implementierung konnte ich verschiedene Dinge lernen, was eine Lernerfahrung war. Immerhin hat die beste Ernte viel Spaß gemacht.
Ich hoffe dieser Artikel hilft jemandem.
Recommended Posts