(FORKED) Rubiks Cube solver for NxNxN cubes https://github.com/dwalton76/rubiks-cube-NxNxN-solver

lt_builder_exp.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #!/usr/bin/env python3
  2. """
  3. experiment to see how long it takes to build the 4x4x4 centers staging
  4. lookup tables for a scrambled cube. If you only go 4-deep it takes about
  5. 20s. Going deeper than that chews through too much memory on the workq.
  6. The workq needs to be stored in a file.
  7. We need to build 6 or 7 deep.
  8. """
  9. from collections import deque
  10. import logging
  11. import os
  12. import sys
  13. from rubikscubennnsolver import reverse_steps
  14. from rubikscubennnsolver.rotate_xxx import rotate_444
  15. from rubikscubennnsolver.RubiksCube444 import (
  16. moves_4x4x4,
  17. solved_4x4x4,
  18. RubiksCube444,
  19. LookupTableIDA444ULFRBDCentersStage,
  20. LookupTable444UDCentersStage,
  21. LookupTable444LRCentersStage,
  22. LookupTable444FBCentersStage,
  23. )
  24. def build_state_table():
  25. cube = RubiksCube444('DRFDFRUFDURDDLLUFLDLLBLULFBUUFRBLBFLLUDDUFRBURBBRBDLLDURFFBBRUFUFDRFURBUDLDBDUFFBUDRRLDRBLFBRRLB', 'URFDLB')
  26. cube.nuke_corners()
  27. cube.nuke_edges()
  28. original_state = cube.state[:]
  29. log.info("cache start")
  30. for side in (cube.sideU, cube.sideL, cube.sideF, cube.sideR, cube.sideB, cube.sideD):
  31. for pos in side.center_pos:
  32. if cube.state[pos] in ('U', 'D'):
  33. cube.state[pos] = 'U'
  34. elif cube.state[pos] in ('L', 'R'):
  35. cube.state[pos] = 'L'
  36. elif cube.state[pos] in ('F', 'B'):
  37. cube.state[pos] = 'F'
  38. cube.lt_UD_centers_stage = LookupTable444UDCentersStage(cube)
  39. cube.lt_LR_centers_stage = LookupTable444LRCentersStage(cube)
  40. cube.lt_FB_centers_stage = LookupTable444FBCentersStage(cube)
  41. lt_ULFRBD_centers_stage = LookupTableIDA444ULFRBDCentersStage(cube)
  42. workq = deque()
  43. explored = set()
  44. UD_explored = {}
  45. LR_explored = {}
  46. FB_explored = {}
  47. count = 0
  48. for step in moves_4x4x4:
  49. workq.append(([step,], cube.state[:]))
  50. while workq:
  51. (steps, prev_state) = workq.popleft()
  52. cube.state = rotate_444(prev_state, steps[-1])
  53. state = lt_ULFRBD_centers_stage.state()
  54. UD_state = cube.lt_UD_centers_stage.state()
  55. LR_state = cube.lt_LR_centers_stage.state()
  56. FB_state = cube.lt_FB_centers_stage.state()
  57. count += 1
  58. if count % 100000 == 0:
  59. UD_count = len(UD_explored)
  60. LR_count = len(LR_explored)
  61. FB_count = len(FB_explored)
  62. log.info("%d UD states, %d LR state, %d FB states, %d on workq" % (UD_count, LR_count, FB_count, len(workq)))
  63. if UD_count == 735471 and LR_count == 735471 and FB_count == 735471:
  64. break
  65. if state in explored:
  66. continue
  67. else:
  68. explored.add(state)
  69. keep_going = False
  70. if UD_state not in UD_explored:
  71. UD_explored[UD_state] = ' '.join(reverse_steps(steps))
  72. keep_going = True
  73. if LR_state not in LR_explored:
  74. LR_explored[LR_state] = ' '.join(reverse_steps(steps))
  75. keep_going = True
  76. if FB_state not in FB_explored:
  77. FB_explored[FB_state] = ' '.join(reverse_steps(steps))
  78. keep_going = True
  79. if not keep_going:
  80. continue
  81. # Only build the table 4-deep for now
  82. if len(steps) == 4:
  83. continue
  84. prev_step = steps[-1]
  85. for step in moves_4x4x4:
  86. # U2 followed by U2 is a no-op
  87. if step == prev_step and step.endswith("2"):
  88. continue
  89. # U' followed by U is a no-op
  90. if prev_step.endswith("'") and not step.endswith("'") and step == prev_step[0:-1]:
  91. continue
  92. # U followed by U' is a no-op
  93. if not prev_step.endswith("'") and step.endswith("'") and step[0:-1] == prev_step:
  94. continue
  95. workq.append((steps + [step,], cube.state[:]))
  96. log.info("cache end")
  97. log.info("write start")
  98. with open('UD_state.txt', 'w') as fh:
  99. for key in sorted(UD_explored.keys()):
  100. value = UD_explored[key]
  101. fh.write("%s:%s\n" % (key, value))
  102. with open('LR_state.txt', 'w') as fh:
  103. for key in sorted(LR_explored.keys()):
  104. value = LR_explored[key]
  105. fh.write("%s:%s\n" % (key, value))
  106. with open('FB_state.txt', 'w') as fh:
  107. for key in sorted(FB_explored.keys()):
  108. value = FB_explored[key]
  109. fh.write("%s:%s\n" % (key, value))
  110. log.info("write end")
  111. if __name__ == '__main__':
  112. # setup logging
  113. logging.basicConfig(level=logging.INFO,
  114. format='%(asctime)s %(filename)16s %(levelname)8s: %(message)s')
  115. log = logging.getLogger(__name__)
  116. build_state_table()