-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmehesz.jl
110 lines (99 loc) · 3.71 KB
/
mehesz.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
@enum Heading east south west north
const moves = Dict(east => CartesianIndex(0, 1),
south => CartesianIndex(1, 0),
west => CartesianIndex(0, -1),
north => CartesianIndex(-1, 0))
forward(p, d) = (p + moves[d], d)
backward(p, d) = (p - moves[d], d)
right(p, d) = (p, Heading((Int(d) + 1) % 4))
left(p, d) = (p, Heading((Int(d) + 3) % 4))
struct Problem
board::Matrix{Char}
start_heading::Heading
avoid::Vector{Char}
gather::Vector{Char}
goal::Char
moves::Vector{Function}
function Problem(; board, start_heading, avoid, gather, goal,
moves = [forward, backward, right, left])
new(board .|> collect |> Base.splat(hcat) |> permutedims,
start_heading,
avoid |> collect,
gather |> collect,
goal,
moves)
end
end
const round1 = Problem(board = ["🐣 🤖 🚪"
" 🤖 🐤 "
"🤖 "
" 🐥🤖 "
"🐔 🐝"],
start_heading = north,
avoid = "🤖",
gather = "🐣🐤🐥🐔",
goal = '🚪')
const round2 = Problem(board = ["🍇 🍒🪵"
" 🪤🫐 🪤 "
" 🪤 "
"🪤 🪤🍓"
"🍑🐝🪤 🍌🪤"],
start_heading = east,
avoid = "🪤",
gather = "🍇🍒🫐🍓🍑🍌",
goal = '🪵')
const round4 = Problem(board = ["📦 "
"⚡ ⚡ 📦"
" ⚡⚡"
" ⚡ 📥"
" ⚡ ⚡"
" "
" ⚡🐝 "],
start_heading = east,
avoid = "⚡",
gather = "📦",
goal = '📥')
const round5 = Problem(board = ["🧸 🐝"
"⚡ ⚡ "
" ⚡⚡"
" ⚡ 📥"
" ⚡ ⚡"
"📦 📦 "
" ⚡ "],
start_heading = west,
avoid = "⚡",
gather = "📦",
goal = '🧸',
moves = [backward, left])
function solve(problem::Problem)
start_position = findfirst(==('🐝'), problem.board)
start = (start_position, problem.start_heading)
gather = findall(∈(problem.gather), problem.board)
gathered = fill(false, length(gather))
states = [(start, gathered)]
queue = [(0, 1)]
for (s, i) in queue
((p, d), g) = states[i]
if problem.board[p] == problem.goal && all(g)
return s
end
for move in problem.moves
(p1, d1) = move(p, d)
if p1 ∉ keys(problem.board) || problem.board[p1] ∈ problem.avoid
continue
end
gi = findfirst(==(p1), gather)
g1 = gi === nothing ? g : let g1 = copy(g)
g1[gi] = true
g1
end
if ((p1, d1), g1) ∉ states
push!(states, ((p1, d1), g1))
push!(queue, (s + 1, length(states)))
end
end
end
end
for r in [1, 2, 4, 5]
println("Round $r: ", solve(getfield(Main, Symbol(:round, r))))
end