15 puzzle solver: Difference between revisions

Content added Content deleted
m (→‎{{header|Uiua}}: Improved algorithm)
(Added Dart Solution)
 
Line 4,574: Line 4,574:
| 13 | 14 | 15 | 0 |
| 13 | 14 | 15 | 0 |
====================</pre>
====================</pre>
=={{header|Dart}}==
{{trans|C++}}
<syntaxhighlight lang="dart">
import 'package:collection/collection.dart';

typedef OffsetFunction = int Function(int a, int b);
Function eq = const ListEquality().equals;

/// Solve Random 15 Puzzles
class FifteenSolver {
static const target = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0];
static const trN = [3, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3];
static const tcN = [3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2];
var pos0 = List.filled(100, 0);
var moves = List.filled(100, 0);
var dirs = List.filled(100, '');
int step = 0, best = 0;
var board = List.generate(100, (int i) => List.filled(16, 0));

bool isFinished() {
if (moves[step] < best) return nextMove();
if (eq(board[step], target)) {
print("Solution found in $step moves :${dirs.join('')}");
return true;
}
return (moves[step] == best) ? nextMove() : false;
}

var passNumber = 0;

/// Try all valid moves from here, but don't retrace your steps.
/// Return true if a solution is found.
bool nextMove() {
// if (passNumber++ ~/ 100000 == 0) print("${dirs.join('')}");
return (dirs[step] != 'u' && pos0[step] ~/ 4 < 3 && down()) ||
(dirs[step] != 'd' && pos0[step] ~/ 4 > 0 && up()) ||
(dirs[step] != 'l' && pos0[step] % 4 < 3 && right()) ||
(dirs[step] != 'r' && pos0[step] % 4 > 0 && left()) ||
false;
}

bool move(int offset, String dir, List<int> rcArray, OffsetFunction rcFunc) {
final int ix = pos0[step] + offset;
final n = board[step][ix];
pos0[step + 1] = pos0[step] + offset;
board[step + 1] = board[step].toList()
..[pos0[step]] = n
..[ix] = 0;
dirs[step + 1] = dir;
moves[step + 1] = moves[step] + rcFunc(rcArray[n], pos0[step]);
step++;
if (isFinished()) return true;
step--;
return false;
}

bool right() => move(1, 'r', tcN, (a, b) => (a <= b % 4 ? 0 : 1));
bool left() => move(-1, 'l', tcN, (a, b) => (a >= b % 4 ? 0 : 1));
bool down() => move(4, 'd', trN, (a, b) => (a <= b ~/ 4 ? 0 : 1));
bool up() => move(-4, 'u', trN, (a, b) => (a >= b ~/ 4 ? 0 : 1));

void solve(List<int> initBoard) {
pos0[0] = initBoard.indexOf(0);
board[0] = initBoard;
while (!isFinished()) best++;
}
}

void main(List<String> args) {
print("running");
// test values
// final start = [5, 1, 2, 3, 6, 10, 7, 4, 13, 9, 11, 8, 14, 0, 15, 12];
// final start = [9, 1, 2, 4, 13, 6, 5, 7, 3, 11, 14, 15, 10, 0, 8, 12];
// final start = [10, 3, 1, 4, 13, 5, 8, 7, 9, 6, 0, 11, 14, 15, 12, 2];
// required solution
final start = [15, 14, 1, 6, 9, 11, 4, 12, 0, 10, 7, 3, 13, 8, 5, 2];
// Extra credit
// final start = [0, 12, 9, 13, 15, 11, 10, 14, 3, 7, 2, 5, 4, 8, 6, 1];
print(start);
FifteenSolver().solve(start);
}
</syntaxhighlight>
{{out}}
<pre>
running
Solution found in 52 moves :rrrulddluuuldrurdddrullulurrrddldluurddlulurruldrdrd
</pre>


=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
===The Function===
===The Function===