langs a-z
This commit is contained in:
parent
db842d013d
commit
d066446780
11389 changed files with 98361 additions and 1020 deletions
130
Task/Maze-solving/Perl-6/maze-solving.pl6
Normal file
130
Task/Maze-solving/Perl-6/maze-solving.pl6
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
constant mapping = :OPEN(' '),
|
||||
:N< ╵ >,
|
||||
:E< ╶ >,
|
||||
:NE< └ >,
|
||||
:S< ╷ >,
|
||||
:NS< │ >,
|
||||
:ES< ┌ >,
|
||||
:NES< ├ >,
|
||||
:W< ╴ >,
|
||||
:NW< ┘ >,
|
||||
:EW< ─ >,
|
||||
:NEW< ┴ >,
|
||||
:SW< ┐ >,
|
||||
:NSW< ┤ >,
|
||||
:ESW< ┬ >,
|
||||
:NESW< ┼ >,
|
||||
:TODO< x >,
|
||||
:TRIED< · >;
|
||||
|
||||
enum Code (mapping.map: *.key);
|
||||
my @code = mapping.map: *.value;
|
||||
|
||||
enum Direction <DeadEnd Up Right Down Left>;
|
||||
|
||||
sub gen_maze ( $X,
|
||||
$Y,
|
||||
$start_x = (^$X).pick * 2 + 1,
|
||||
$start_y = (^$Y).pick * 2 + 1 )
|
||||
{
|
||||
my @maze;
|
||||
push @maze, [ ES, -N, (ESW, EW) xx $X - 1, SW ];
|
||||
push @maze, [ (NS, TODO) xx $X, NS ];
|
||||
for 1 ..^ $Y {
|
||||
push @maze, [ NES, EW, (NESW, EW) xx $X - 1, NSW ];
|
||||
push @maze, [ (NS, TODO) xx $X, NS ];
|
||||
}
|
||||
push @maze, [ NE, (EW, NEW) xx $X - 1, -NS, NW ];
|
||||
@maze[$start_y][$start_x] = OPEN;
|
||||
|
||||
my @stack;
|
||||
my $current = [$start_x, $start_y];
|
||||
loop {
|
||||
if my $dir = pick_direction( $current ) {
|
||||
@stack.push: $current;
|
||||
$current = move( $dir, $current );
|
||||
}
|
||||
else {
|
||||
last unless @stack;
|
||||
$current = @stack.pop;
|
||||
}
|
||||
}
|
||||
return @maze;
|
||||
|
||||
sub pick_direction([$x,$y]) {
|
||||
my @neighbors =
|
||||
(Up if @maze[$y - 2][$x]),
|
||||
(Down if @maze[$y + 2][$x]),
|
||||
(Left if @maze[$y][$x - 2]),
|
||||
(Right if @maze[$y][$x + 2]);
|
||||
@neighbors.pick or DeadEnd;
|
||||
}
|
||||
|
||||
sub move ($dir, @cur) {
|
||||
my ($x,$y) = @cur;
|
||||
given $dir {
|
||||
when Up { @maze[--$y][$x] = OPEN; @maze[$y][$x-1] -= E; @maze[$y--][$x+1] -= W; }
|
||||
when Down { @maze[++$y][$x] = OPEN; @maze[$y][$x-1] -= E; @maze[$y++][$x+1] -= W; }
|
||||
when Left { @maze[$y][--$x] = OPEN; @maze[$y-1][$x] -= S; @maze[$y+1][$x--] -= N; }
|
||||
when Right { @maze[$y][++$x] = OPEN; @maze[$y-1][$x] -= S; @maze[$y+1][$x++] -= N; }
|
||||
}
|
||||
@maze[$y][$x] = 0;
|
||||
[$x,$y];
|
||||
}
|
||||
}
|
||||
|
||||
sub display (@maze) {
|
||||
for @maze -> @y {
|
||||
for @y -> $w, $c {
|
||||
print @code[abs $w];
|
||||
if $c >= 0 { print @code[$c] x 3 }
|
||||
else { print ' ', @code[abs $c], ' ' }
|
||||
}
|
||||
say @code[@y[*-1]];
|
||||
}
|
||||
}
|
||||
|
||||
sub solve (@maze is copy, @from = [1, 1], @to = [@maze[0] - 2, @maze - 2]) {
|
||||
my ($x, $y) = @from;
|
||||
my ($xto, $yto) = @to;
|
||||
my @stack;
|
||||
|
||||
sub drop-crumb($x,$y,$c) { @maze[$y][$x] = -$c }
|
||||
drop-crumb($x,$y,N);
|
||||
|
||||
loop {
|
||||
my $dir = pick_direction([$x,$y]);
|
||||
if $dir {
|
||||
($x, $y) = move($dir, [$x,$y]);
|
||||
return @maze if $x == $xto and $y == $yto;
|
||||
}
|
||||
else {
|
||||
@maze[$y][$x] = -TRIED;
|
||||
($x,$y) = @stack.pop[];
|
||||
@maze[$y][$x] = -TRIED;
|
||||
($x,$y) = @stack.pop[];
|
||||
}
|
||||
}
|
||||
|
||||
sub pick_direction([$x,$y]) {
|
||||
my @neighbors =
|
||||
(Up unless @maze[$y - 1][$x]),
|
||||
(Down unless @maze[$y + 1][$x]),
|
||||
(Left unless @maze[$y][$x - 1]),
|
||||
(Right unless @maze[$y][$x + 1]);
|
||||
@neighbors.pick or DeadEnd;
|
||||
}
|
||||
|
||||
sub move ($dir, @cur) {
|
||||
my ($x,$y) = @cur;
|
||||
given $dir {
|
||||
when Up { for ^2 { push @stack, [$x,$y--]; drop-crumb $x,$y,S; } }
|
||||
when Down { for ^2 { push @stack, [$x,$y++]; drop-crumb $x,$y,N; } }
|
||||
when Left { for ^2 { push @stack, [$x--,$y]; drop-crumb $x,$y,E; } }
|
||||
when Right { for ^2 { push @stack, [$x++,$y]; drop-crumb $x,$y,W; } }
|
||||
}
|
||||
$x,$y;
|
||||
}
|
||||
}
|
||||
|
||||
display solve gen_maze( 29, 19 );
|
||||
110
Task/Maze-solving/PureBasic/maze-solving.purebasic
Normal file
110
Task/Maze-solving/PureBasic/maze-solving.purebasic
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
;code from the maze generation task is place here in its entirety before the rest of the code
|
||||
|
||||
Procedure displayMazePath(Array maze(2), List Path.POINT())
|
||||
Protected x, y, vWall.s, hWall.s
|
||||
Protected mazeWidth = ArraySize(maze(), 1), mazeHeight = ArraySize(maze(), 2)
|
||||
Protected Dim mazeOutput.mazeOutput(mazeHeight)
|
||||
Protected Dim mazeRow.mazeOutput(0)
|
||||
Static pathChars.s = "@^>v<"
|
||||
|
||||
For y = 0 To mazeHeight
|
||||
makeDisplayMazeRow(mazeRow(), maze(), y): mazeOutput(y) = mazeRow(0)
|
||||
Next
|
||||
|
||||
If ListSize(path())
|
||||
FirstElement(path())
|
||||
Protected prevPath.POINT = path()
|
||||
|
||||
While NextElement(path())
|
||||
x = path()\x - prevPath\x
|
||||
y = path()\y - prevPath\y
|
||||
Select x
|
||||
Case -1: dirTaken = #dir_W
|
||||
Case 1: dirTaken = #dir_E
|
||||
Default
|
||||
If y < 0
|
||||
dirTaken = #dir_N
|
||||
Else
|
||||
dirTaken = #dir_S
|
||||
EndIf
|
||||
EndSelect
|
||||
hWall = mazeOutput(prevPath\y)\hWall
|
||||
mazeOutput(prevPath\y)\hWall = Left(hWall, prevPath\x * #cellDWidth + 2) + Mid(pathChars, dirTaken + 1, 1) + Right(hWall, Len(hWall) - (prevPath\x * #cellDWidth + 3))
|
||||
prevPath = path()
|
||||
Wend
|
||||
hWall = mazeOutput(prevPath\y)\hWall
|
||||
mazeOutput(prevPath\y)\hWall = Left(hWall, prevPath\x * #cellDWidth + 2) + Mid(pathChars, #dir_ID + 1, 1) + Right(hWall, Len(hWall) - (prevPath\x * #cellDWidth + 3))
|
||||
|
||||
For y = 0 To mazeHeight
|
||||
PrintN(mazeOutput(y)\vWall): PrintN(mazeOutput(y)\hWall)
|
||||
Next
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
Procedure solveMaze(Array maze(2), *start.POINT, *finish.POINT, List Path.POINT())
|
||||
Protected mazeWidth = ArraySize(maze(), 1), mazeHeight = ArraySize(maze(), 2)
|
||||
Dim visited(mazeWidth + 1, mazeHeight + 1) ;includes padding for easy border detection
|
||||
|
||||
Protected i
|
||||
;mark outside border as already visited (off limits)
|
||||
For i = 1 To mazeWidth
|
||||
visited(i, 0) = #True: visited(i, mazeHeight + 1) = #True
|
||||
Next
|
||||
For i = 1 To mazeHeight
|
||||
visited(0, i) = #True: visited(mazeWidth + 1, i) = #True
|
||||
Next
|
||||
|
||||
Protected x = *start\x, y = *start\y, nextCellDir
|
||||
visited(x + offset(#visited, #dir_ID)\x, y + offset(#visited, #dir_ID)\y) = #True
|
||||
|
||||
ClearList(path())
|
||||
Repeat
|
||||
If x = *finish\x And y = *finish\y
|
||||
AddElement(path())
|
||||
path()\x = x: path()\y = y
|
||||
Break ;success
|
||||
EndIf
|
||||
|
||||
nextCellDir = #firstDir - 1
|
||||
For i = #firstDir To #numDirs
|
||||
If Not visited(x + offset(#visited, i)\x, y + offset(#visited, i)\y)
|
||||
If maze(x + offset(#wall, i)\x, y + offset(#wall, i)\y) & wallvalue(i) <> #Null
|
||||
nextCellDir = i: Break ;exit for/next search
|
||||
EndIf
|
||||
EndIf
|
||||
Next
|
||||
|
||||
If nextCellDir >= #firstDir
|
||||
visited(x + offset(#visited, nextCellDir)\x, y + offset(#visited, nextCellDir)\y) = #True
|
||||
|
||||
AddElement(path())
|
||||
path()\x = x: path()\y = y
|
||||
|
||||
x + offset(#maze, nextCellDir)\x: y + offset(#maze, nextCellDir)\y
|
||||
ElseIf ListSize(path()) > 0
|
||||
x = path()\x: y = path()\y
|
||||
DeleteElement(path())
|
||||
Else
|
||||
Break
|
||||
EndIf
|
||||
ForEver
|
||||
|
||||
EndProcedure
|
||||
|
||||
;demonstration
|
||||
If OpenConsole()
|
||||
Define.POINT start, finish
|
||||
start\x = Random(mazeWidth - 1): start\y = Random(mazeHeight - 1)
|
||||
finish\x = Random(mazeWidth - 1): finish\y = Random(mazeHeight - 1)
|
||||
NewList Path.POINT()
|
||||
solveMaze(maze(), start, finish, path())
|
||||
If ListSize(path()) > 0
|
||||
PrintN("Solution found for path between (" + Str(start\x) + ", " + Str(start\y) + ") and (" + Str(finish\x) + ", " + Str(finish\y) + ")")
|
||||
displayMazePath(maze(), path())
|
||||
Else
|
||||
PrintN("No solution found for path between (" + Str(start\x) + ", " + Str(start\y) + ") and (" + Str(finish\x) + ", " + Str(finish\y) + ")")
|
||||
EndIf
|
||||
|
||||
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
|
||||
CloseConsole()
|
||||
EndIf
|
||||
Loading…
Add table
Add a link
Reference in a new issue