Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Account for starting in phase 2 #38

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions lib/solve.js
Original file line number Diff line number Diff line change
Expand Up @@ -776,18 +776,22 @@

// Initialize phase 2 coordinates
init2(top = true) {
if (this.parent === null) {
if (this.parent === null && !top) {
return;
}
// For other states, the phase 2 state is computed based on
// parent's state.
// If parent is null then this is the initial call which must mean
// the cube started in phase 2 so there is no need for this
// Already assigned for the initial state
this.parent.init2(false);
this.URFtoDLF = this.move('URFtoDLF', this.parent.URFtoDLF, this.lastMove);
this.FRtoBR = this.move('FRtoBR', this.parent.FRtoBR, this.lastMove);
this.parity = this.move('parity', this.parent.parity, this.lastMove);
this.URtoUL = this.move('URtoUL', this.parent.URtoUL, this.lastMove);
this.UBtoDF = this.move('UBtoDF', this.parent.UBtoDF, this.lastMove);
if (this.parent !== null) {
// For other states, the phase 2 state is computed based on
// parent's state.
this.parent.init2(false, false);
this.URFtoDLF = this.move('URFtoDLF', this.parent.URFtoDLF, this.lastMove);
this.FRtoBR = this.move('FRtoBR', this.parent.FRtoBR, this.lastMove);
this.parity = this.move('parity', this.parent.parity, this.lastMove);
this.URtoUL = this.move('URtoUL', this.parent.URtoUL, this.lastMove);
this.UBtoDF = this.move('UBtoDF', this.parent.UBtoDF, this.lastMove);
}
if (top) {
// This is the initial phase 2 state. Get the URtoDF coordinate
// by merging URtoUL and UBtoDF
Expand All @@ -813,14 +817,14 @@
solution = null;
phase1search = function(state) {
var depth, m, ref, results;
depth = 0;
results = [];
for (depth = m = 1, ref = maxDepth; (1 <= ref ? m <= ref : m >= ref); depth = 1 <= ref ? ++m : --m) {
for (depth = m = 0, ref = maxDepth; (0 <= ref ? m <= ref : m >= ref); depth = 0 <= ref ? ++m : --m) {
phase1(state, depth);
if (solution !== null) {
break;
} else {
results.push(void 0);
}
results.push(depth++);
}
return results;
};
Expand Down Expand Up @@ -859,12 +863,13 @@
// Initialize phase 2 coordinates
state.init2();
results = [];
for (depth = m = 1, ref = maxDepth - state.depth; (1 <= ref ? m <= ref : m >= ref); depth = 1 <= ref ? ++m : --m) {
for (depth = m = 0, ref = maxDepth - state.depth; (0 <= ref ? m <= ref : m >= ref); depth = 0 <= ref ? ++m : --m) {
phase2(state, depth);
if (solution !== null) {
break;
} else {
results.push(void 0);
}
results.push(depth++);
}
return results;
};
Expand Down Expand Up @@ -904,11 +909,8 @@
state = freeStates.pop().init(this);
phase1search(state);
freeStates.push(state);
// Trim the trailing space
if (solution.length > 0) {
solution = solution.substring(0, solution.length - 1);
}
return solution;
// Trim the trailing space and return
return solution.trim();
};

faceNums = {
Expand Down
22 changes: 19 additions & 3 deletions spec/cube.spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,24 @@ describe 'Cube', ->
moves = Cube.inverse "F B' R"
expect(moves).toBe "R' B F'"

# ignore because Travis is slow
xit 'should solve a solved cube :) ', ->
# It seems Cube init state is reset between tests so we keep it all in one
# Due to Travis being slow we skip this but if you change algorithm you should
# run it locally
xit 'should solve cubes', ->
Cube.initSolver()
# Should solve empty cube
cube = new Cube
expect(cube.solve()).toBe "R L U2 R L F2 R2 U2 R2 F2 R2 U2 F2 L2"
expect(cube.solve()).toBe ""

# Should solve trivial cube efficiently
cube.move("U'")
expect(cube.solve()).toBe "U"

# Should solve random cube
cube = Cube.random()
# Should not be solved initially
expect(cube.isSolved()).toBeFalse
solution = cube.solve()
cube.move(solution)
# Solution should have solved the cube
expect(cube.isSolved()).toBeTrue
26 changes: 15 additions & 11 deletions src/solve.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -579,19 +579,22 @@ Cube::solveUpright = (maxDepth=22) ->

# Initialize phase 2 coordinates
init2: (top=true) ->
if @parent is null
if @parent is null and not top
# Already assigned for the initial state
return

# For other states, the phase 2 state is computed based on
# parent's state.
@parent.init2(false)
# If parent is null then this is the initial call which must mean
# the cube started in phase 2 so there is no need for this
if @parent isnt null
# For other states, the phase 2 state is computed based on
# parent's state.
@parent.init2(false, false)

@URFtoDLF = @move('URFtoDLF', @parent.URFtoDLF, @lastMove)
@FRtoBR = @move('FRtoBR', @parent.FRtoBR, @lastMove)
@parity = @move('parity', @parent.parity, @lastMove)
@URtoUL = @move('URtoUL', @parent.URtoUL, @lastMove)
@UBtoDF = @move('UBtoDF', @parent.UBtoDF, @lastMove)
@URFtoDLF = @move('URFtoDLF', @parent.URFtoDLF, @lastMove)
@FRtoBR = @move('FRtoBR', @parent.FRtoBR, @lastMove)
@parity = @move('parity', @parent.parity, @lastMove)
@URtoUL = @move('URtoUL', @parent.URtoUL, @lastMove)
@UBtoDF = @move('UBtoDF', @parent.UBtoDF, @lastMove)

if top
# This is the initial phase 2 state. Get the URtoDF coordinate
Expand All @@ -616,7 +619,8 @@ Cube::solveUpright = (maxDepth=22) ->
solution = null

phase1search = (state) ->
for depth in [1..maxDepth]

for depth in [0..maxDepth]
phase1(state, depth)
break if solution isnt null

Expand All @@ -641,7 +645,7 @@ Cube::solveUpright = (maxDepth=22) ->
# Initialize phase 2 coordinates
state.init2()

for depth in [1..maxDepth - state.depth]
for depth in [0..maxDepth - state.depth]
phase2(state, depth)
break if solution isnt null

Expand Down