A* search algorithm: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
Line 35: | Line 35: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=11l>F AStarSearch(start, end, barriers) |
||
F heuristic(start, goal) |
F heuristic(start, goal) |
||
V D = 1 |
V D = 1 |
||
Line 107: | Line 107: | ||
V (result, cost) = AStarSearch((0, 0), (7, 7), [[(2, 4), (2, 5), (2, 6), (3, 6), (4, 6), (5, 6), (5, 5), (5, 4), (5, 3), (5, 2), (4, 2), (3, 2)]]) |
V (result, cost) = AStarSearch((0, 0), (7, 7), [[(2, 4), (2, 5), (2, 6), (3, 6), (4, 6), (5, 6), (5, 5), (5, 4), (5, 3), (5, 2), (4, 2), (3, 2)]]) |
||
print(‘route ’result) |
print(‘route ’result) |
||
print(‘cost ’cost)</ |
print(‘cost ’cost)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 116: | Line 116: | ||
=={{header|C}}== |
=={{header|C}}== |
||
<syntaxhighlight lang=c> |
|||
<lang c> |
|||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
Line 367: | Line 367: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 396: | Line 396: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
< |
<syntaxhighlight lang=csharp> |
||
using System; |
using System; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
Line 646: | Line 646: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 663: | Line 663: | ||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang=cpp> |
||
#include <list> |
#include <list> |
||
#include <algorithm> |
#include <algorithm> |
||
Line 828: | Line 828: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 847: | Line 847: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang=lisp>;; * Using external libraries with quicklisp |
||
(eval-when (:load-toplevel :compile-toplevel :execute) |
(eval-when (:load-toplevel :compile-toplevel :execute) |
||
(ql:quickload '("pileup" "iterate"))) |
(ql:quickload '("pileup" "iterate"))) |
||
Line 1,003: | Line 1,003: | ||
(a* start goal heuristics #'next-positions 0) |
(a* start goal heuristics #'next-positions 0) |
||
(format t "Found the shortest path from Start (●) to Goal (◆) in ~D steps with cost: ~D~%" steps cost) |
(format t "Found the shortest path from Start (●) to Goal (◆) in ~D steps with cost: ~D~%" steps cost) |
||
(print-path path start goal)))</ |
(print-path path start goal)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,023: | Line 1,023: | ||
=={{header|D}}== |
=={{header|D}}== |
||
ported from c++ code |
ported from c++ code |
||
<syntaxhighlight lang=D> |
|||
<lang D> |
|||
import std.stdio; |
import std.stdio; |
||
Line 1,180: | Line 1,180: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,198: | Line 1,198: | ||
=={{Header|FreeBASIC}}== |
=={{Header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang=freebasic> |
||
'############################### |
'############################### |
||
'### A* search algorithm ### |
'### A* search algorithm ### |
||
Line 1,446: | Line 1,446: | ||
end if |
end if |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,465: | Line 1,465: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang=go>// Package astar implements the A* search algorithm with minimal constraints |
||
// on the graph representation. |
// on the graph representation. |
||
package astar |
package astar |
||
Line 1,577: | Line 1,577: | ||
h[last].fx = -1 |
h[last].fx = -1 |
||
return h[last] |
return h[last] |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang=go>package main |
||
import ( |
import ( |
||
Line 1,633: | Line 1,633: | ||
fmt.Println("Route:", route) |
fmt.Println("Route:", route) |
||
fmt.Println("Cost:", cost) |
fmt.Println("Cost:", cost) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,643: | Line 1,643: | ||
The simplest standalone FIFO priority queue is implemented after Sleator and Tarjan in Louis Wasserman's ''"Playing with Priority Queues"''[https://themonadreader.files.wordpress.com/2010/05/issue16.pdf]. |
The simplest standalone FIFO priority queue is implemented after Sleator and Tarjan in Louis Wasserman's ''"Playing with Priority Queues"''[https://themonadreader.files.wordpress.com/2010/05/issue16.pdf]. |
||
< |
<syntaxhighlight lang=haskell>{-# language DeriveFoldable #-} |
||
module PQueue where |
module PQueue where |
||
Line 1,669: | Line 1,669: | ||
deque q = case q of |
deque q = case q of |
||
EmptyQueue -> Nothing |
EmptyQueue -> Nothing |
||
Node (_, x) l r -> Just (x, l <> r)</ |
Node (_, x) l r -> Just (x, l <> r)</syntaxhighlight> |
||
The simple graph combinators: |
The simple graph combinators: |
||
< |
<syntaxhighlight lang=haskell>import PQueue |
||
import Data.Map (Map(..)) |
import Data.Map (Map(..)) |
||
import qualified Data.Map as Map |
import qualified Data.Map as Map |
||
Line 1,693: | Line 1,693: | ||
if x `elem` ns |
if x `elem` ns |
||
then Map.empty |
then Map.empty |
||
else foldr Map.delete (g x) ns </ |
else foldr Map.delete (g x) ns </syntaxhighlight> |
||
Finally, the search algorythm, as given in Wikipedia. |
Finally, the search algorythm, as given in Wikipedia. |
||
< |
<syntaxhighlight lang=haskell>get :: (Ord k, Bounded a) => Map k a -> k -> a |
||
get m x = Map.findWithDefault maxBound x m |
get m x = Map.findWithDefault maxBound x m |
||
Line 1,737: | Line 1,737: | ||
getPath m = reverse $ goal : unfoldr go goal |
getPath m = reverse $ goal : unfoldr go goal |
||
where go n = (\x -> (x,x)) <$> Map.lookup n m</ |
where go n = (\x -> (x,x)) <$> Map.lookup n m</syntaxhighlight> |
||
Example |
Example |
||
< |
<syntaxhighlight lang=haskell>distL1 (x,y) (a,b) = max (abs $ x-a) (abs $ y-b) |
||
main = let |
main = let |
||
Line 1,758: | Line 1,758: | ||
print path |
print path |
||
mapM_ putStrLn picture |
mapM_ putStrLn picture |
||
putStrLn $ "Path score: " <> show (length path) </ |
putStrLn $ "Path score: " <> show (length path) </syntaxhighlight> |
||
<pre>λ> main |
<pre>λ> main |
||
[(1,1),(2,1),(3,1),(4,1),(5,1),(6,2),(6,3),(6,4),(6,5),(6,6),(7,7)] |
[(1,1),(2,1),(3,1),(4,1),(5,1),(6,2),(6,3),(6,4),(6,5),(6,6),(7,7)] |
||
Line 1,776: | Line 1,776: | ||
Implementation: |
Implementation: |
||
<syntaxhighlight lang=J> |
|||
<lang J> |
|||
barrier=: 2 4,2 5,2 6,3 6,4 6,5 6,5 5,5 4,5 3,5 2,4 2,:3 2 |
barrier=: 2 4,2 5,2 6,3 6,4 6,5 6,5 5,5 4,5 3,5 2,4 2,:3 2 |
||
price=: _,.~_,~100 barrier} 8 8$1 |
price=: _,.~_,~100 barrier} 8 8$1 |
||
Line 1,804: | Line 1,804: | ||
end. |
end. |
||
((<end){values) ; (<end){best |
((<end){values) ; (<end){best |
||
}}</ |
}}</syntaxhighlight> |
||
Task example: |
Task example: |
||
< |
<syntaxhighlight lang=J> Asrch'' |
||
┌──┬───┐ |
┌──┬───┐ |
||
│11│0 0│ |
│11│0 0│ |
||
Line 1,834: | Line 1,834: | ||
...xxxxx |
...xxxxx |
||
</syntaxhighlight> |
|||
</lang> |
|||
Note that this is based on a literal reading of the task, where we are paying a cost to move into a new square -- here, we are not paying for the cost of the start square, because we never move into that square. If we paid to move into the start square, the final cost would have to include that price. |
Note that this is based on a literal reading of the task, where we are paying a cost to move into a new square -- here, we are not paying for the cost of the start square, because we never move into that square. If we paid to move into the start square, the final cost would have to include that price. |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
< |
<syntaxhighlight lang=java> |
||
package astar; |
package astar; |
||
Line 2,080: | Line 2,080: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,097: | Line 2,097: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
Animated.<br />To see how it works on a random map go [http://paulo-jorente.de/tests/astar/ here] |
Animated.<br />To see how it works on a random map go [http://paulo-jorente.de/tests/astar/ here] |
||
< |
<syntaxhighlight lang=javascript> |
||
var ctx, map, opn = [], clsd = [], start = {x:1, y:1, f:0, g:0}, |
var ctx, map, opn = [], clsd = [], start = {x:1, y:1, f:0, g:0}, |
||
goal = {x:8, y:8, f:0, g:0}, mw = 10, mh = 10, neighbours, path; |
goal = {x:8, y:8, f:0, g:0}, mw = 10, mh = 10, neighbours, path; |
||
Line 2,209: | Line 2,209: | ||
path = []; createMap(); opn.push( start ); solveMap(); |
path = []; createMap(); opn.push( start ); solveMap(); |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}}<pre> |
{{out}}<pre> |
||
Path: 11 |
Path: 11 |
||
Line 2,215: | Line 2,215: | ||
</pre> |
</pre> |
||
Implementation using recursive strategy |
Implementation using recursive strategy |
||
< |
<syntaxhighlight lang=javascript> |
||
function manhattan(x1, y1, x2, y2) { |
function manhattan(x1, y1, x2, y2) { |
||
return Math.abs(x1 - x2) + Math.abs(y1 - y2); |
return Math.abs(x1 - x2) + Math.abs(y1 - y2); |
||
Line 2,288: | Line 2,288: | ||
console.log(aStar(board, 0,0, 7,7)); |
console.log(aStar(board, 0,0, 7,7)); |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{output}} <pre> |
{{output}} <pre> |
||
[ [ 0, 0 ], [ 1, 1 ], [ 2, 2 ], [ 3, 1 ], [ 4, 1 ], [ 5, 1 ], [ 6, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ] ] |
[ [ 0, 0 ], [ 1, 1 ], [ 2, 2 ], [ 3, 1 ], [ 4, 1 ], [ 5, 1 ], [ 6, 1 ], [ 7, 2 ], [ 7, 3 ], [ 7, 4 ], [ 7, 5 ], [ 7, 6 ], [ 7, 7 ] ] |
||
Line 2,294: | Line 2,294: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
The graphic in this solution is displayed in the more standard orientation of origin at bottom left and goal at top right. |
The graphic in this solution is displayed in the more standard orientation of origin at bottom left and goal at top right. |
||
< |
<syntaxhighlight lang=Julia>using LightGraphs, SimpleWeightedGraphs |
||
const chessboardsize = 8 |
const chessboardsize = 8 |
||
Line 2,332: | Line 2,332: | ||
println() |
println() |
||
end |
end |
||
end</ |
end</syntaxhighlight> {{output}} <pre> |
||
Solution has cost 11: |
Solution has cost 11: |
||
Tuple{Int64,Int64}[(0, 0), (1, 1), (2, 2), (3, 1), (4, 1), (5, 1), (6, 2), (7, 3), (7, 4), (6, 5), (6, 6), (7, 7)] |
Tuple{Int64,Int64}[(0, 0), (1, 1), (2, 2), (3, 1), (4, 1), (5, 1), (6, 2), (7, 3), (7, 4), (6, 5), (6, 6), (7, 7)] |
||
Line 2,346: | Line 2,346: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang=kotlin> |
||
import java.lang.Math.abs |
import java.lang.Math.abs |
||
Line 2,457: | Line 2,457: | ||
println("Cost: $cost Path: $path") |
println("Cost: $cost Path: $path") |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}}<pre> |
{{out}}<pre> |
||
Cost: 11 |
Cost: 11 |
||
Line 2,464: | Line 2,464: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang=lua> |
||
-- QUEUE ----------------------------------------------------------------------- |
-- QUEUE ----------------------------------------------------------------------- |
||
Queue = {} |
Queue = {} |
||
Line 2,664: | Line 2,664: | ||
print( "can not find a path!" ) |
print( "can not find a path!" ) |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,683: | Line 2,683: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
Implementation of the Wikipedia pseudocode. |
Implementation of the Wikipedia pseudocode. |
||
< |
<syntaxhighlight lang=Nim> |
||
# A* search algorithm. |
# A* search algorithm. |
||
Line 2,814: | Line 2,814: | ||
else: |
else: |
||
printSolution(path, cost) |
printSolution(path, cost) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 2,839: | Line 2,839: | ||
A very close/straightforward implementation of the Wikipedia pseudocode. |
A very close/straightforward implementation of the Wikipedia pseudocode. |
||
< |
<syntaxhighlight lang=ocaml> |
||
module IntPairs = |
module IntPairs = |
||
struct |
struct |
||
Line 2,968: | Line 2,968: | ||
print_newline () |
print_newline () |
||
) _board; |
) _board; |
||
print_newline ()</ |
print_newline ()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,997: | Line 2,997: | ||
=={{header|Ol}}== |
=={{header|Ol}}== |
||
< |
<syntaxhighlight lang=scheme> |
||
; level: list of lists, any except 1 means the cell is empty |
; level: list of lists, any except 1 means the cell is empty |
||
; from: start cell in (x . y) mean |
; from: start cell in (x . y) mean |
||
Line 3,063: | Line 3,063: | ||
(cons (+ x 1) y))))) |
(cons (+ x 1) y))))) |
||
(step1 (- n 1) c-list-set o-list-set)))))))) |
(step1 (- n 1) c-list-set o-list-set)))))))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang=scheme> |
||
(define level '( |
(define level '( |
||
(1 1 1 1 1 1 1 1 1 1) |
(1 1 1 1 1 1 1 1 1 1) |
||
Line 3,121: | Line 3,121: | ||
(for-each print solved) |
(for-each print solved) |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
Line 3,167: | Line 3,167: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang=perl>#!/usr/bin/perl |
||
use strict; # https://rosettacode.org/wiki/A*_search_algorithm |
use strict; # https://rosettacode.org/wiki/A*_search_algorithm |
||
Line 3,214: | Line 3,214: | ||
unshift @path, $pos = $from{$pos}; |
unshift @path, $pos = $from{$pos}; |
||
} |
} |
||
print "$grid\nvalue $values{$finish} path @path\n";</ |
print "$grid\nvalue $values{$finish} path @path\n";</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,230: | Line 3,230: | ||
===Extra Credit=== |
===Extra Credit=== |
||
< |
<syntaxhighlight lang=perl>#!/usr/bin/perl |
||
use strict; # https://rosettacode.org/wiki/A*_search_algorithm |
use strict; # https://rosettacode.org/wiki/A*_search_algorithm |
||
Line 3,307: | Line 3,307: | ||
abs($r1 - $r2) + abs($c1 - $c2) |
abs($r1 - $r2) + abs($c1 - $c2) |
||
} @tiles; |
} @tiles; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,326: | Line 3,326: | ||
Note that the 23 visited nodes does not count walls, but with them this algorithm exactly matches the 35 of Racket. |
Note that the 23 visited nodes does not count walls, but with them this algorithm exactly matches the 35 of Racket. |
||
<!--< |
<!--<syntaxhighlight lang=Phix>(phixonline)--> |
||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">grid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""" |
<span style="color: #004080;">sequence</span> <span style="color: #000000;">grid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""" |
||
x::::::: |
x::::::: |
||
Line 3,398: | Line 3,398: | ||
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">grid</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">))</span> |
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">grid</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">))</span> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
Line 3,421: | Line 3,421: | ||
lowest cost and a simple dictionary to avoid re-examination/inifinte recursion. |
lowest cost and a simple dictionary to avoid re-examination/inifinte recursion. |
||
<!--< |
<!--<syntaxhighlight lang=Phix>(phixonline)--> |
||
<span style="color: #000080;font-style:italic;">--set_rand(3) -- (for consistent output)</span> |
<span style="color: #000080;font-style:italic;">--set_rand(3) -- (for consistent output)</span> |
||
<span style="color: #008080;">constant</span> <span style="color: #000000;">optimal</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">,</span> |
<span style="color: #008080;">constant</span> <span style="color: #000000;">optimal</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">,</span> |
||
Line 3,566: | Line 3,566: | ||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"count:%d, seen:%d, queue:%d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">count</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">dict_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seen</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">pq_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">todo</span><span style="color: #0000FF;">)})</span> |
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"count:%d, seen:%d, queue:%d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">count</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">dict_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">seen</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">pq_size</span><span style="color: #0000FF;">(</span><span style="color: #000000;">todo</span><span style="color: #0000FF;">)})</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
Line 3,603: | Line 3,603: | ||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
< |
<syntaxhighlight lang=powershell>function CreateGrid($h, $w, $fill) { |
||
$grid = 0..($h - 1) | ForEach-Object { , (, $fill * $w) } |
$grid = 0..($h - 1) | ForEach-Object { , (, $fill * $w) } |
||
return $grid |
return $grid |
||
Line 3,715: | Line 3,715: | ||
Write-Output "Cost: $cost" |
Write-Output "Cost: $cost" |
||
$routeString = ($route | ForEach-Object { "($($_[0]), $($_[1]))" }) -join ', ' |
$routeString = ($route | ForEach-Object { "($($_[0]), $($_[1]))" }) -join ', ' |
||
Write-Output "Route: $routeString"</ |
Write-Output "Route: $routeString"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,731: | Line 3,731: | ||
=={{header|Picat}}== |
=={{header|Picat}}== |
||
< |
<syntaxhighlight lang=Picat>% Picat's tabling system uses an algorithm like Dijkstra's to find an optimal solution. |
||
% Picat's planner supports A* search with heuristics. |
% Picat's planner supports A* search with heuristics. |
||
% See the program for the 15-puzzle at https://rosettacode.org/wiki/15_puzzle_solver#Picat |
% See the program for the 15-puzzle at https://rosettacode.org/wiki/15_puzzle_solver#Picat |
||
Line 3,761: | Line 3,761: | ||
Neibs = [(R1,C1) : Dr in [-1,0,1], Dc in [-1,0,1], R1 = R+Dr, C1 = C+Dc, |
Neibs = [(R1,C1) : Dr in [-1,0,1], Dc in [-1,0,1], R1 = R+Dr, C1 = C+Dc, |
||
R1 >= 1, R1 <= 8, C1 >= 1, C1 <= 8, (R,C) != (R1,C1)]. |
R1 >= 1, R1 <= 8, C1 >= 1, C1 <= 8, (R,C) != (R1,C1)]. |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,770: | Line 3,770: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang=python>from __future__ import print_function |
||
import matplotlib.pyplot as plt |
import matplotlib.pyplot as plt |
||
Line 3,871: | Line 3,871: | ||
plt.xlim(-1,8) |
plt.xlim(-1,8) |
||
plt.ylim(-1,8) |
plt.ylim(-1,8) |
||
plt.show()</ |
plt.show()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,880: | Line 3,880: | ||
This code is lifted from: [https://jeapostrophe.github.io/2013-04-15-astar-post.html this blog post]. Read it, it's very good. |
This code is lifted from: [https://jeapostrophe.github.io/2013-04-15-astar-post.html this blog post]. Read it, it's very good. |
||
< |
<syntaxhighlight lang=racket>#lang scribble/lp |
||
@(chunk |
@(chunk |
||
<graph-sig> |
<graph-sig> |
||
Line 4,103: | Line 4,103: | ||
<path-display> |
<path-display> |
||
(path-image random-M random-path))</ |
(path-image random-M random-path))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,116: | Line 4,116: | ||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
{{trans|Sidef}} |
{{trans|Sidef}} |
||
< |
<syntaxhighlight lang=perl6># 20200427 Raku programming solution |
||
class AStarGraph { |
class AStarGraph { |
||
Line 4,208: | Line 4,208: | ||
.join.say for @grid ; |
.join.say for @grid ; |
||
say "Path cost : ", cost, " and route : ", route;</ |
say "Path cost : ", cost, " and route : ", route;</syntaxhighlight> |
||
{{out}}<pre>██████████ |
{{out}}<pre>██████████ |
||
█x.......█ |
█x.......█ |
||
Line 4,222: | Line 4,222: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
< |
<syntaxhighlight lang=rexx>/*REXX program solves the A* search problem for a (general) NxN grid. */ |
||
parse arg N sCol sRow . /*obtain optional arguments from the CL*/ |
parse arg N sCol sRow . /*obtain optional arguments from the CL*/ |
||
if N=='' | N=="," then N=8 /*No grid size specified? Use default.*/ |
if N=='' | N=="," then N=8 /*No grid size specified? Use default.*/ |
||
Line 4,304: | Line 4,304: | ||
say ind translate(L'│', , .) /*display a " " " " */ |
say ind translate(L'│', , .) /*display a " " " " */ |
||
end /*c*/ /*a 19x19 grid can be shown 80 columns.*/ |
end /*c*/ /*a 19x19 grid can be shown 80 columns.*/ |
||
say ind translate('└'_"┘",'┴',"┼"); return /*display the very bottom of the grid. */</ |
say ind translate('└'_"┘",'┴',"┼"); return /*display the very bottom of the grid. */</syntaxhighlight> |
||
{{out|output|text= when using the default input:}} |
{{out|output|text= when using the default input:}} |
||
<pre> |
<pre> |
||
Line 4,329: | Line 4,329: | ||
=={{header|SequenceL}}== |
=={{header|SequenceL}}== |
||
< |
<syntaxhighlight lang=sequencel> |
||
import <Utilities/Set.sl>; |
import <Utilities/Set.sl>; |
||
import <Utilities/Math.sl>; |
import <Utilities/Math.sl>; |
||
Line 4,429: | Line 4,429: | ||
value when point.x = i and point.y = j else |
value when point.x = i and point.y = j else |
||
map[i,j] foreach i within 1 ... size(map), j within 1 ... size(map[1]); |
map[i,j] foreach i within 1 ... size(map), j within 1 ... size(map[1]); |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out|Output|text= }} |
{{out|Output|text= }} |
||
<pre> |
<pre> |
||
Line 4,447: | Line 4,447: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=ruby>class AStarGraph { |
||
has barriers = [ |
has barriers = [ |
||
Line 4,551: | Line 4,551: | ||
grid.each { .join.say } |
grid.each { .join.say } |
||
say "Path cost #{cost}: #{route}"</ |
say "Path cost #{cost}: #{route}"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,570: | Line 4,570: | ||
{{works with|Bourne Again SHell}} |
{{works with|Bourne Again SHell}} |
||
< |
<syntaxhighlight lang=bash> |
||
#!/bin/bash |
#!/bin/bash |
||
Line 4,943: | Line 4,943: | ||
main "$@" |
main "$@" |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,960: | Line 4,960: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|Sidef}} |
{{trans|Sidef}} |
||
< |
<syntaxhighlight lang=ecmascript>var Equals = Fn.new { |p1, p2| p1[0] == p2[0] && p1[1] == p2[1] } |
||
var Contains = Fn.new { |pairs, p| |
var Contains = Fn.new { |pairs, p| |
||
Line 5,076: | Line 5,076: | ||
} |
} |
||
for (line in grid) System.print(line.join()) |
for (line in grid) System.print(line.join()) |
||
System.print("\npath cost %(cost): %(route)")</ |
System.print("\npath cost %(cost): %(route)")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,096: | Line 5,096: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=zkl> // we use strings as hash keys: (x,y)-->"x,y", keys are a single pair |
||
fcn toKey(xy){ xy.concat(",") } |
fcn toKey(xy){ xy.concat(",") } |
||
Line 5,150: | Line 5,150: | ||
} // while |
} // while |
||
throw(Exception.AssertionError("A* failed to find a solution")); |
throw(Exception.AssertionError("A* failed to find a solution")); |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang=zkl>class [static] AStarGraph{ # Define a class board like grid with barriers |
||
var [const] barriers = |
var [const] barriers = |
||
T( T(3,2),T(4,2),T(5,2), // T is RO List |
T( T(3,2),T(4,2),T(5,2), // T is RO List |
||
Line 5,177: | Line 5,177: | ||
1 # Normal movement cost |
1 # Normal movement cost |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang=zkl>graph:=AStarGraph; |
||
route,cost := AStarSearch(T(0,0), T(7,7), graph); |
route,cost := AStarSearch(T(0,0), T(7,7), graph); |
||
println("Route: ", route.apply(fcn(xy){ String("(",toKey(xy),")") }).concat(",")); |
println("Route: ", route.apply(fcn(xy){ String("(",toKey(xy),")") }).concat(",")); |
||
Line 5,188: | Line 5,188: | ||
foreach x,y in (route){ grid[x][y]="+" } |
foreach x,y in (route){ grid[x][y]="+" } |
||
grid[0][0] = "S"; grid[7][7] = "E"; |
grid[0][0] = "S"; grid[7][7] = "E"; |
||
foreach line in (grid){ println(line.concat()) }</ |
foreach line in (grid){ println(line.concat()) }</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |