Ich habe versucht, Soma Cube mit Python zu lösen

Mokuji

  1. Zuallererst
  2. Was ist Soma Cube?
  3. Vergangene Geschichte
  4. Einfallsreichtum zur Verbesserung der Verarbeitungsgeschwindigkeit
  5. Schwierigkeiten, um den Erfolg zu bestimmen
  6. Über Algorithmus und Quellcode
  7. Schließlich

Einführung

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

Was ist Soma Cube?

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.

Vergangene Geschichte

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.

Einfallsreichtum zur Verbesserung der Verarbeitungsgeschwindigkeit

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.

Verwenden Sie set anstelle von list

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)

Beschneiden in der Mitte der for-Anweisung

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

Schwierigkeiten, den Erfolg zu bestimmen

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

Über Algorithmus und Quellcode

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)))

(1) Die Drehung des "L-förmigen" Würfels ist auf ein Muster festgelegt, da sechs Richtungen als ein Muster gezählt werden.

if idxC == 0:
	lengthL = 1

(2) Bewegen Sie den gedrehten Würfel parallel von 0 nach 3 in Bezug auf die x-, y- und z-Koordinaten, um die Koordinate zu erhalten, die nicht hervorsteht.

notOverCubeList = cubeSetter.createNotOverCubeList(cloneC)

(3) In einen Berechnungswürfel konvertieren, um die Verarbeitungsgeschwindigkeit zu verbessern

calc4Cube = cubeExchanger.convToCalcCube(notOverCube)

(4) Überlappende Würfel entfernen

calc4CubeList = cubeExchanger.removeDupCubes(calc4CubeList, pNum)

Schließlich

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

Ich habe versucht, Soma Cube mit Python zu lösen
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
Ich habe versucht, die Anfängerausgabe des Ameisenbuchs mit Python zu lösen
Ich habe versucht, eine CSV-Datei mit Python zu berühren
Ich habe versucht, AOJs Integer-Theorie mit Python zu lösen
Ich habe versucht, die Entropie des Bildes mit Python zu finden
Ich habe versucht zu simulieren, wie sich die Infektion mit Python ausbreitet
Ich wollte den Panasonic Programming Contest 2020 mit Python lösen
Ich wollte ABC160 mit Python lösen
Ich habe versucht, TSP mit QAOA zu lösen
Ich wollte ABC172 mit Python lösen
Beim 15. Offline-Echtzeitversuch habe ich versucht, das Problem des Schreibens mit Python zu lösen
Ich wollte das ABC164 A ~ D-Problem mit Python lösen
Ich habe versucht, die Effizienz der täglichen Arbeit mit Python zu verbessern
Ich habe versucht, das Bild mit Python + OpenCV zu "glätten"
Ich wollte den NOMURA Contest 2020 mit Python lösen
Ich habe versucht, das Bild mit Python + OpenCV zu "differenzieren"
Ich habe versucht, die Daten mit Zwietracht zu speichern
Versuchen Sie, das Mensch-Maschine-Diagramm mit Python zu lösen
Ich habe versucht, CloudWatch-Daten mit Python abzurufen
Ich habe versucht, LLVM IR mit Python auszugeben
Ich habe versucht, das Bild mit Python + OpenCV zu "binarisieren"
Ich habe versucht, die Herstellung von Sushi mit Python zu automatisieren
Ich möchte APG4b mit Python lösen (Kapitel 2)
Ich habe versucht, das Problem von F02 zu lösen, wie man mit Python offline in Echtzeit schreibt
Ich habe fp-Wachstum mit Python versucht
[Python] Ich habe versucht, die Nacht der Galaxienbahn mit WordCloud zu visualisieren!
Wie man offline in Echtzeit schreibt Ich habe versucht, E11 mit Python zu lösen
Ich habe versucht, den Authentifizierungscode der Qiita-API mit Python abzurufen.
Ich habe es mit den Top 100 PyPI-Paketen versucht.> Ich habe versucht, die auf Python installierten Pakete grafisch darzustellen
Ich habe versucht, die Standardrolle neuer Mitarbeiter mit Python zu optimieren
Ich habe gRPC mit Python ausprobiert
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, die Filminformationen der TMDb-API mit Python abzurufen
Wie man offline in Echtzeit schreibt Ich habe versucht, E12 mit Python zu lösen
Ich habe versucht, die erste Frage der Mathematik-Aufnahmeprüfung 2019 der Universität Tokio mit Python Sympy zu lösen
Ich habe versucht, die Sündenfunktion mit Chainer zu trainieren
Ich habe versucht, die in Python installierten Pakete grafisch darzustellen
Versuchen Sie, das Programmier-Herausforderungsbuch mit Python3 zu lösen
Ich habe versucht, mit Blenders Python script_Part 01 zu beginnen
Versuchen Sie, das Problem der Zuweisung von Schulungsärzten mit Python zu lösen
Ich habe versucht, mit Blenders Python script_Part 02 zu beginnen
Ich habe versucht, künstliches Perzeptron mit Python zu implementieren
Ich möchte mit Python-Datenklasse nach hinten erben
[Python] Ich habe versucht, die Top 10 der Lidschatten grafisch darzustellen
Ich habe versucht, die API mit dem Python-Client von echonest zu erreichen
Ich habe versucht, die String-Operationen von Python zusammenzufassen
Ich habe versucht, die Tweets von JAWS DAYS 2017 mit Python + ELK einfach zu visualisieren
Ich habe versucht, die Literatur des neuen Corona-Virus mit Python automatisch an LINE zu senden
Ich habe versucht, WebScraping mit Python.
Ich mochte den Tweet mit Python. ..
Ich möchte mit Python debuggen
Ich habe versucht, Prolog mit Python 3.8.2 auszuführen.
Ich habe die SMTP-Kommunikation mit Python versucht
Ich habe versucht, den Ball zu bewegen
Ich habe versucht, den Abschnitt zu schätzen.