-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroutes2.tiny
93 lines (77 loc) · 2.49 KB
/
routes2.tiny
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
##################################################################
#
# Tiny script to find routes between European countries.
# (Inspired by a Prolog example.)
#
##################################################################
# Bordering countries 'database'
borderingCountries = [
[ 'Belgium', 'France'],
[ 'France', 'Germany'],
[ 'France', 'Italy'],
[ 'France', 'Spain'],
[ 'Germany', 'Austria'],
[ 'Germany', 'Denmark'],
[ 'Denmark', 'Sweden'],
[ 'Germany', 'Switzerland'],
[ 'Netherlands', 'Belgium'],
[ 'Netherlands', 'Germany'],
[ 'Spain', 'Portugal'],
[ 'Sweden', 'Norway'],
[ 'Sweden', 'Finland'],
[ 'Norway', 'Finland'],
[ 'Italy', 'Switzerland'],
[ 'Italy', 'Austria']
]
#
# Find all of the countries bordering the specified country
#
fn bordering country ->
matchlist borderingCountries
| ^country :: borderingCountry :: _ -> borderingCountry
| borderingCountry :: ^country :: _ -> borderingCountry
#
# Returns true if countries A and B border on each other.
#
fn borders a b -> (matchlist borderingCountries
| ^a :: ^b :: _ | ^b :: ^a :: _ -> true )
.Count > 0
#
# Return the smallest item in a list based on the
# result of executing a lambda.
#
fn minlist list f -> list?.reduce{ if (f(it) < f(it2)) {it} else {it2}}
#
# Find the shortest route between two countries
#
def route a b -> route(a, b, [])
def route a b checked ->
if (a |> borders(b)) {
# If the countries directly border on each other then just return that pair.
[a, b]
}
else {
# Otherwise find all of the candidate routes
routes = foreach (c in a |> bordering |> where {checked !:> it}) {
result = route(c, b, a :+ checked)
if (result) {
a :+ result
}
}
# then pick the shortest routes
minlist (routes, {it.Count})
}
#
# Utility function to print out a route
fn printRoute -> it.Join(' -> ') |> println
###############################################################
#
# Now use the function to get a bunch of routes
#
route('Austria', 'Spain') |> printRoute
route('Denmark', 'Portugal') |> printRoute
route('Portugal', 'Switzerland') |> printRoute
route('Portugal', 'Norway') |> printRoute
route('Belgium', 'Italy') |> printRoute
route('France', 'Austria') |> printRoute
route('France', 'Norway') |> printRoute