diff options
| author | Cliff Click <cliffc@acm.org> | 2026-08-10 11:11:18 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-11-13 16:17:13 -0800 |
| commit | 236a9b50ffe5c13f33027dbf5fef38f9fc58a8f9 (patch) | |
| tree | 9fe5d79a2d0c7b12e1317b737857065fff5093a5 /docs/chapter31/examples/Dijkstra.smp | |
| parent | 2cb35c65bde63f90d7afc3d7a8a985b0c6ea15d7 (diff) | |
| download | Simple-236a9b50ffe5c13f33027dbf5fef38f9fc58a8f9.tar.gz Simple-236a9b50ffe5c13f33027dbf5fef38f9fc58a8f9.zip | |
Chapter 31: Software Drawing, Time, and Graphical Gameslinear
Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com>
Co-authored-by: fuhsnn <66062782+fuhsnn@users.noreply.github.com>
Co-authored-by: Symious <14933944+symious@users.noreply.github.com>
Co-authored-by: Jun Kawasaki <jun784@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'docs/chapter31/examples/Dijkstra.smp')
| -rw-r--r-- | docs/chapter31/examples/Dijkstra.smp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/docs/chapter31/examples/Dijkstra.smp b/docs/chapter31/examples/Dijkstra.smp new file mode 100644 index 00000000..a8fcf3da --- /dev/null +++ b/docs/chapter31/examples/Dijkstra.smp @@ -0,0 +1,71 @@ + +// An implementation of +// https://sampleprograms.io/projects/dijkstra/ + +val shortestPath = { !sys.aryi64 matrix, int nodes, int src, int dst -> + i64 infinity = sys.integer.MAX_I64; + var visited = new sys.adt.bitset(); + // All nodes are infinitely far from each other, except the starting point + var dist = new i64[nodes]{ int i -> i==src ? 0 : infinity; }; + + i64 result = -1; + int count = 0; + while( count < nodes && result < 0 ) { + int nearest = -1; + i64 best = infinity; + for( int node=0; node<nodes; node++ ) + if( !visited.get(node) && dist[node] < best ) { + nearest = node; + best = dist[node]; + } + if( nearest < 0 ) count = nodes; + else { + if( nearest == dst ) return best; + visited.set(nearest); + for( int node=0; node<nodes; node++ ) { + u32 index=nearest*nodes + node; + i64 weight = matrix.get(index); + if( weight > 0 && !visited.get(node) && best+weight < dist[node] ) + dist[node] = best+weight; + } + } + count++; + } + return result; +}; + +val usage = { -> + sys.io.p("Usage: please provide three inputs: a serialized matrix, a source node and a destination node\n"); + return 0; +}; + +val main = { u8[~][] args -> + // Exactly 3 args + if( args# != 4 ) return usage(); + // First is a serialized square matrix of positive numbers + var matrix = sys.aryi64.parseAryI64(args[1]); + if( !matrix ) return usage(); + if( !matrix.len ) return usage(); + // All numbers are positive + for( u32 i=0; i<matrix.len; i++ ) + if( matrix.get(i) < 0 ) return usage(); + // Matrix is square + int nodes = 0; + while( nodes*nodes < matrix.len ) nodes++; + if( nodes*nodes != matrix.len ) + return usage(); // Not a square matrix + + // src,dst are values within the matrix + i64 src = sys.aryu8.atoi(args[2]); + i64 dst = sys.aryu8.atoi(args[3]); + if( src < 0 || src >= nodes || dst < 0 || dst >= nodes ) + return usage(); // Source and destination land within the graph + + int source=src, destination=dst; + i64 cost = shortestPath(matrix,nodes,source,destination); + if( cost >= 0 ) { + new sys.aryu8().num(cost).add('\n').write(1); + return 0; + } + return usage(); +}; |
