Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
73
Task/Maze-solving/Ada/maze-solving.adb
Normal file
73
Task/Maze-solving/Ada/maze-solving.adb
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
with Ada.Text_IO;
|
||||
|
||||
procedure Maze_Solver is
|
||||
|
||||
X_Size: constant Natural := 45;
|
||||
Y_Size: constant Natural := 17;
|
||||
|
||||
subtype X_Range is Natural range 1 .. X_Size;
|
||||
subtype Y_Range is Natural range 1 .. Y_Size;
|
||||
|
||||
East: constant X_Range := 2;
|
||||
South: constant Y_Range := 1;
|
||||
|
||||
X_Start: constant X_Range := 3; -- start at the upper left
|
||||
Y_Start: constant Y_Range := 1;
|
||||
X_Finish: constant X_Range := X_Size-East; -- go to the lower right
|
||||
Y_Finish: constant Y_Range := Y_Size;
|
||||
|
||||
type Maze_Type is array (Y_Range) of String(X_Range);
|
||||
|
||||
function Solved(X: X_Range; Y: Y_Range) return Boolean is
|
||||
begin
|
||||
return (X = X_Finish) and (Y = Y_Finish);
|
||||
end Solved;
|
||||
|
||||
procedure Output_Maze(M: Maze_Type; Message: String := "") is
|
||||
begin
|
||||
if Message /= "" then
|
||||
Ada.Text_IO.Put_Line(Message);
|
||||
end if;
|
||||
for I in M'Range loop
|
||||
Ada.Text_IO.Put_Line(M(I));
|
||||
end loop;
|
||||
end Output_Maze;
|
||||
|
||||
procedure Search(M: in out Maze_Type; X: X_Range; Y:Y_Range) is
|
||||
begin
|
||||
M(Y)(X) := '*';
|
||||
if Solved(X, Y) then
|
||||
Output_Maze(M, "Solution found!");
|
||||
else
|
||||
if Integer(Y)-South >= 1 and then M(Y-South)(X) = ' ' then
|
||||
Search(M, X, Y-South);
|
||||
end if;
|
||||
if Integer(Y)+South <= Y_Size and then M(Y+South)(X) = ' ' then
|
||||
Search(M, X, Y+South);
|
||||
end if;
|
||||
if Integer(X)-East >= 1 and then M(Y)(X-East) = ' ' then
|
||||
Search(M, X-East, Y);
|
||||
end if;
|
||||
if Integer(Y)+East <= Y_Size and then M(Y)(X+East) = ' ' then
|
||||
Search(M, X+East, Y);
|
||||
end if;
|
||||
end if;
|
||||
M(Y)(X) := ' ';
|
||||
end Search;
|
||||
|
||||
Maze: Maze_Type;
|
||||
X: X_Range := X_Start;
|
||||
Y: Y_Range := Y_Start;
|
||||
|
||||
begin
|
||||
for I in 1 .. Y_Size loop
|
||||
Maze(I) := Ada.Text_IO.Get_Line;
|
||||
end loop;
|
||||
Maze(Y_Start)(X_Start) := ' '; -- Start from
|
||||
Maze(Y_Finish)(X_Finish) := ' '; -- Go_To
|
||||
Output_Maze(Maze, "The Maze:");
|
||||
Ada.Text_IO.New_Line;
|
||||
|
||||
Search(Maze, X, Y) ; -- Will output *all* Solutions.
|
||||
-- If there is no output, there is no solution.
|
||||
end Maze_Solver;
|
||||
|
|
@ -24,7 +24,7 @@ proc m_maze pos .
|
|||
show_maze
|
||||
d[] = [ 1 2 3 4 ]
|
||||
for i = 4 downto 1
|
||||
d = random i
|
||||
d = random 1 i
|
||||
dir = offs[d[d]]
|
||||
d[d] = d[i]
|
||||
if m[pos + dir] = 1 and m[pos + 2 * dir] = 1
|
||||
|
|
@ -35,16 +35,14 @@ proc m_maze pos .
|
|||
.
|
||||
endpos = n * n - 1
|
||||
proc make_maze .
|
||||
for i = 1 to len m[]
|
||||
m[i] = 1
|
||||
.
|
||||
for i = 1 to len m[] : m[i] = 1
|
||||
for i = 1 to n
|
||||
m[i] = 2
|
||||
m[n * i] = 2
|
||||
m[n * i - n + 1] = 2
|
||||
m[n * n - n + i] = 2
|
||||
.
|
||||
h = 2 * random 15 - n + n * 2 * random 15
|
||||
h = 2 * random 1 size - n + n * 2 * random 1 size
|
||||
m_maze h
|
||||
m[endpos] = 0
|
||||
.
|
||||
|
|
@ -66,7 +64,7 @@ proc solve dir0 pos .
|
|||
found = 1
|
||||
return
|
||||
.
|
||||
of = random 4 - 1
|
||||
of = random 0 3
|
||||
for h = 1 to 4
|
||||
dir = (h + of) mod1 4
|
||||
posn = pos + offs[dir]
|
||||
|
|
|
|||
193
Task/Maze-solving/Emacs-Lisp/maze-solving.el
Normal file
193
Task/Maze-solving/Emacs-Lisp/maze-solving.el
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
(require 'cl-lib)
|
||||
|
||||
(cl-defstruct maze rows cols data)
|
||||
|
||||
(defmacro maze-pt (w r c)
|
||||
`(+ (* (mod ,r (maze-rows ,w)) (maze-cols ,w))
|
||||
(mod ,c (maze-cols ,w))))
|
||||
|
||||
(defmacro maze-ref (w r c)
|
||||
`(aref (maze-data ,w) (maze-pt ,w ,r ,c)))
|
||||
|
||||
(defun new-maze (rows cols)
|
||||
(setq rows (1+ rows)
|
||||
cols (1+ cols))
|
||||
(let ((m (make-maze :rows rows :cols cols :data (make-vector (* rows cols) nil))))
|
||||
|
||||
(dotimes (r rows)
|
||||
(dotimes (c cols)
|
||||
(setf (maze-ref m r c) (copy-sequence '(wall ceiling)))))
|
||||
|
||||
(dotimes (r rows)
|
||||
(maze-set m r (1- cols) 'visited))
|
||||
|
||||
(dotimes (c cols)
|
||||
(maze-set m (1- rows) c 'visited))
|
||||
|
||||
(maze-unset m 0 0 'ceiling) ;; Maze Entrance
|
||||
(maze-unset m (1- rows) (- cols 2) 'ceiling) ;; Maze Exit
|
||||
|
||||
m))
|
||||
|
||||
(defun maze-is-set (maze r c v)
|
||||
(member v (maze-ref maze r c)))
|
||||
|
||||
(defun maze-set (maze r c v)
|
||||
(let ((cell (maze-ref maze r c)))
|
||||
(when (not (member v cell))
|
||||
(setf (maze-ref maze r c) (cons v cell)))))
|
||||
|
||||
(defun maze-unset (maze r c v)
|
||||
(setf (maze-ref maze r c) (delete v (maze-ref maze r c))))
|
||||
|
||||
(defun print-maze (maze &optional marks)
|
||||
(dotimes (r (1- (maze-rows maze)))
|
||||
|
||||
(dotimes (c (1- (maze-cols maze)))
|
||||
(princ (if (maze-is-set maze r c 'ceiling) "+---" "+ ")))
|
||||
(princ "+")
|
||||
(terpri)
|
||||
|
||||
(dotimes (c (1- (maze-cols maze)))
|
||||
(princ (if (maze-is-set maze r c 'wall) "|" " "))
|
||||
(princ (if (member (cons r c) marks) " * " " ")))
|
||||
(princ "|")
|
||||
(terpri))
|
||||
|
||||
(dotimes (c (1- (maze-cols maze)))
|
||||
(princ (if (maze-is-set maze (1- (maze-rows maze)) c 'ceiling) "+---" "+ ")))
|
||||
(princ "+")
|
||||
(terpri))
|
||||
|
||||
(defun shuffle (lst)
|
||||
(sort lst (lambda (a b) (= 1 (random 2)))))
|
||||
|
||||
(defun to-visit (maze row col)
|
||||
(let (unvisited)
|
||||
(dolist (p '((0 . +1) (0 . -1) (+1 . 0) (-1 . 0)))
|
||||
(let ((r (+ row (car p)))
|
||||
(c (+ col (cdr p))))
|
||||
(unless (maze-is-set maze r c 'visited)
|
||||
(push (cons r c) unvisited))))
|
||||
unvisited))
|
||||
|
||||
(defun make-passage (maze r1 c1 r2 c2)
|
||||
(if (= r1 r2)
|
||||
(if (< c1 c2)
|
||||
(maze-unset maze r2 c2 'wall) ; right
|
||||
(maze-unset maze r1 c1 'wall)) ; left
|
||||
(if (< r1 r2)
|
||||
(maze-unset maze r2 c2 'ceiling) ; up
|
||||
(maze-unset maze r1 c1 'ceiling)))) ; down
|
||||
|
||||
(defun dig-maze (maze row col)
|
||||
(let (backup
|
||||
(run 0))
|
||||
(maze-set maze row col 'visited)
|
||||
(push (cons row col) backup)
|
||||
(while backup
|
||||
(setq run (1+ run))
|
||||
(when (> run (/ (+ row col) 3))
|
||||
(setq run 0)
|
||||
(setq backup (shuffle backup)))
|
||||
(setq row (caar backup)
|
||||
col (cdar backup))
|
||||
(let ((p (shuffle (to-visit maze row col))))
|
||||
(if p
|
||||
(let ((r (caar p))
|
||||
(c (cdar p)))
|
||||
(make-passage maze row col r c)
|
||||
(maze-set maze r c 'visited)
|
||||
(push (cons r c) backup))
|
||||
(pop backup)
|
||||
(setq backup (shuffle backup))
|
||||
(setq run 0))))))
|
||||
|
||||
(defun generate (rows cols)
|
||||
(let* ((m (new-maze rows cols)))
|
||||
(dig-maze m (random rows) (random cols))
|
||||
(print-maze m)))
|
||||
|
||||
(defun parse-ceilings (line)
|
||||
(let (rtn
|
||||
(i 1))
|
||||
(while (< i (length line))
|
||||
(push (eq ?- (elt line i)) rtn)
|
||||
(setq i (+ i 4)))
|
||||
(nreverse rtn)))
|
||||
|
||||
(defun parse-walls (line)
|
||||
(let (rtn
|
||||
(i 0))
|
||||
(while (< i (length line))
|
||||
(push (eq ?| (elt line i)) rtn)
|
||||
(setq i (+ i 4)))
|
||||
(nreverse rtn)))
|
||||
|
||||
(defun parse-maze (file-name)
|
||||
(let ((rtn)
|
||||
(lines (with-temp-buffer
|
||||
(insert-file-contents-literally file-name)
|
||||
(split-string (buffer-string) "\n" t))))
|
||||
(while lines
|
||||
(push (parse-ceilings (pop lines)) rtn)
|
||||
(push (parse-walls (pop lines)) rtn))
|
||||
(nreverse rtn)))
|
||||
|
||||
(defun read-maze (file-name)
|
||||
(let* ((raw (parse-maze file-name))
|
||||
(rows (1- (/ (length raw) 2)))
|
||||
(cols (length (car raw)))
|
||||
(maze (new-maze rows cols)))
|
||||
(dotimes (r rows)
|
||||
(let ((ceilings (pop raw)))
|
||||
(dotimes (c cols)
|
||||
(unless (pop ceilings)
|
||||
(maze-unset maze r c 'ceiling))))
|
||||
(let ((walls (pop raw)))
|
||||
(dotimes (c cols)
|
||||
(unless (pop walls)
|
||||
(maze-unset maze r c 'wall)))))
|
||||
maze))
|
||||
|
||||
(defun find-exits (maze row col)
|
||||
(let (exits)
|
||||
(dolist (p '((0 . +1) (0 . -1) (-1 . 0) (+1 . 0)))
|
||||
(let ((r (+ row (car p)))
|
||||
(c (+ col (cdr p))))
|
||||
(unless
|
||||
(cond
|
||||
((equal p '(0 . +1)) (maze-is-set maze r c 'wall))
|
||||
((equal p '(0 . -1)) (maze-is-set maze row col 'wall))
|
||||
((equal p '(+1 . 0)) (maze-is-set maze r c 'ceiling))
|
||||
((equal p '(-1 . 0)) (maze-is-set maze row col 'ceiling)))
|
||||
(push (cons r c) exits))))
|
||||
exits))
|
||||
|
||||
(defun drop-visited (maze points)
|
||||
(let (not-visited)
|
||||
(while points
|
||||
(unless (maze-is-set maze (caar points) (cdar points) 'visited)
|
||||
(push (car points) not-visited))
|
||||
(pop points))
|
||||
not-visited))
|
||||
|
||||
(defun solve-maze (maze)
|
||||
(let (solution
|
||||
(exit (cons (- (maze-rows maze) 2) (- (maze-cols maze) 2)))
|
||||
(pt (cons 0 0)))
|
||||
(while (not (equal pt exit))
|
||||
(maze-set maze (car pt) (cdr pt) 'visited)
|
||||
(let ((exits (drop-visited maze (find-exits maze (car pt) (cdr pt)))))
|
||||
(if (null exits)
|
||||
(setq pt (pop solution))
|
||||
(push pt solution)
|
||||
(setq pt (pop exits)))))
|
||||
(push pt solution)))
|
||||
|
||||
(defun solve (file-name)
|
||||
(let* ((maze (read-maze file-name))
|
||||
(solution (solve-maze maze)))
|
||||
(print-maze maze solution)))
|
||||
|
||||
(solve "maze.txt")
|
||||
189
Task/Maze-solving/V-(Vlang)/maze-solving.v
Normal file
189
Task/Maze-solving/V-(Vlang)/maze-solving.v
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
import rand
|
||||
import os
|
||||
|
||||
struct Direction {
|
||||
bit int
|
||||
dx int
|
||||
dy int
|
||||
}
|
||||
|
||||
type Maze = [][]int
|
||||
|
||||
struct MazeGenerator {
|
||||
x int
|
||||
y int
|
||||
mut:
|
||||
maze Maze
|
||||
directions []Direction
|
||||
opposites map[int]Direction
|
||||
solution [][]bool
|
||||
}
|
||||
|
||||
fn new_maze_generator(x int, y int) MazeGenerator {
|
||||
mut maze := [][]int{len: x}
|
||||
for i in 0 .. x {
|
||||
maze[i] = []int{len: y, init: 0}
|
||||
}
|
||||
mut solution := [][]bool{len: x}
|
||||
for i in 0 .. x {
|
||||
solution[i] = []bool{len: y, init: false}
|
||||
}
|
||||
directions := [
|
||||
Direction{bit: 1, dx: 0, dy: -1}, // N
|
||||
Direction{bit: 2, dx: 0, dy: 1}, // S
|
||||
Direction{bit: 4, dx: 1, dy: 0}, // E
|
||||
Direction{bit: 8, dx: -1, dy: 0}, // W
|
||||
]
|
||||
opposites := {
|
||||
1: directions[1] // N.opposite = S
|
||||
2: directions[0] // S.opposite = N
|
||||
4: directions[3] // E.opposite = W
|
||||
8: directions[2] // W.opposite = E
|
||||
}
|
||||
return MazeGenerator{
|
||||
x: x
|
||||
y: y
|
||||
maze: maze
|
||||
directions: directions
|
||||
opposites: opposites
|
||||
solution: solution
|
||||
}
|
||||
}
|
||||
|
||||
fn (mg MazeGenerator) between(v int, upper int) bool {
|
||||
return v >= 0 && v < upper
|
||||
}
|
||||
|
||||
fn (mg MazeGenerator) directions_shuffled() ![]Direction {
|
||||
mut dirs := mg.directions.clone()
|
||||
rand.shuffle(mut dirs) or { return error("Shuffle failed") }
|
||||
return dirs
|
||||
}
|
||||
|
||||
fn (mut mg MazeGenerator) generate(cx int, cy int) {
|
||||
mut shuf := mg.directions_shuffled() or { panic("Shuffle in generate failed") }
|
||||
for dir in shuf {
|
||||
nx := cx + dir.dx
|
||||
ny := cy + dir.dy
|
||||
if mg.between(nx, mg.x) && mg.between(ny, mg.y) && mg.maze[nx][ny] == 0 {
|
||||
mg.maze[cx][cy] |= dir.bit
|
||||
opp := mg.opposites[dir.bit] or { panic("Opposite direction not found") }
|
||||
mg.maze[nx][ny] |= opp.bit
|
||||
mg.generate(nx, ny)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mg MazeGenerator) to_char_maze() [][]rune {
|
||||
width := mg.x * 2 + 1
|
||||
height := mg.y * 2 + 1
|
||||
mut char_maze := [][]rune{len: height, init: []rune{len: width, init: `#`}}
|
||||
for y in 0 .. mg.y {
|
||||
for x in 0 .. mg.x {
|
||||
px := x * 2 + 1
|
||||
py := y * 2 + 1
|
||||
char_maze[py][px] = ` `
|
||||
cell := mg.maze[x][y]
|
||||
if (cell & 1) != 0 { char_maze[py - 1][px] = ` ` } // N
|
||||
if (cell & 2) != 0 { char_maze[py + 1][px] = ` ` } // S
|
||||
if (cell & 4) != 0 { char_maze[py][px + 1] = ` ` } // E
|
||||
if (cell & 8) != 0 { char_maze[py][px - 1] = ` ` } // W
|
||||
}
|
||||
}
|
||||
return char_maze
|
||||
}
|
||||
|
||||
fn solve_maze_recursively(mut maze [][]rune, x int, y int, from_dir int) bool {
|
||||
mut ok := false
|
||||
for i := 0; i < 4 && !ok; i++ {
|
||||
if i != from_dir {
|
||||
match i {
|
||||
0 {
|
||||
if y > 0 && maze[y - 1][x] == ` ` {
|
||||
ok = solve_maze_recursively(mut maze, x, y - 2, 2)
|
||||
} // up
|
||||
}
|
||||
1 {
|
||||
if x + 1 < maze[0].len && maze[y][x + 1] == ` ` {
|
||||
ok = solve_maze_recursively(mut maze, x + 2, y, 3)
|
||||
} // right
|
||||
}
|
||||
2 {
|
||||
if y + 1 < maze.len && maze[y + 1][x] == ` ` {
|
||||
ok = solve_maze_recursively(mut maze, x, y + 2, 0)
|
||||
} // down
|
||||
}
|
||||
3 {
|
||||
if x > 0 && maze[y][x - 1] == ` ` {
|
||||
ok = solve_maze_recursively(mut maze, x - 2, y, 1)
|
||||
} // left
|
||||
}
|
||||
else {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if x == 1 && y == 1 { ok = true }
|
||||
if ok {
|
||||
maze[y][x] = `*`
|
||||
match from_dir {
|
||||
0 { maze[y - 1][x] = `*` }
|
||||
1 { maze[y][x + 1] = `*` }
|
||||
2 { maze[y + 1][x] = `*` }
|
||||
3 { maze[y][x - 1] = `*` }
|
||||
else {}
|
||||
}
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
// solve maze then link to original grid
|
||||
fn (mut mg MazeGenerator) solve() {
|
||||
mut char_maze := mg.to_char_maze()
|
||||
solve_maze_recursively(mut char_maze, char_maze[0].len - 2, char_maze.len - 2, -1)
|
||||
for y in 0 .. mg.y {
|
||||
for x in 0 .. mg.x {
|
||||
px := x * 2 + 1
|
||||
py := y * 2 + 1
|
||||
mg.solution[x][y] = char_maze[py][px] == `*`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// display maze solution on original grid copy
|
||||
fn (mg MazeGenerator) display() {
|
||||
for i in 0 .. mg.y {
|
||||
for j in 0 .. mg.x {
|
||||
// North edge
|
||||
if (mg.maze[j][i] & 1) == 0 { print("+---") }
|
||||
else { print("+ ") }
|
||||
}
|
||||
println("+")
|
||||
|
||||
for j in 0 .. mg.x {
|
||||
mut cell_char := " "
|
||||
if mg.solution[j][i] { cell_char = "*" }
|
||||
if (mg.maze[j][i] & 8) == 0 { print("| $cell_char ") }
|
||||
else { print(" $cell_char ") }
|
||||
}
|
||||
println("|")
|
||||
}
|
||||
for _ in 0 .. mg.x {
|
||||
print("+---")
|
||||
}
|
||||
println("+")
|
||||
}
|
||||
|
||||
fn main() {
|
||||
args := os.args
|
||||
mut x := 8
|
||||
mut y := 8
|
||||
mut mg := new_maze_generator(x, y)
|
||||
if args.len >= 2 { x = args[1].int() }
|
||||
if args.len >= 3 { y = args[2].int() }
|
||||
mg.generate(0, 0)
|
||||
println("Generated Maze:")
|
||||
mg.display()
|
||||
mg.solve()
|
||||
println("\nSolved Maze:")
|
||||
mg.display()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue