[英]List possible train routes on a given model railway
I want to calculate the available routes on a given model railway.我想计算给定 model 铁路上的可用路线。
Assumptions:假设:
The start position and the end position of all trains are stored in a map.所有列车的开始 position 和结束 position 存储在 map 中。 All permutations are stored in a list.
所有排列都存储在一个列表中。 Example:
例子:
iex(1)> Trains.list_routes(["ICE"], ["Hamburg", "Frankfurt"])
[
%{end: %{"ICE" => "Hamburg"}, start: %{"ICE" => "Hamburg"}},
%{end: %{"ICE" => "Frankfurt"}, start: %{"ICE" => "Frankfurt"}},
%{end: %{"ICE" => "Frankfurt"}, start: %{"ICE" => "Hamburg"}},
%{end: %{"ICE" => "Hamburg"}, start: %{"ICE" => "Frankfurt"}}
]
A model railway could look like this (the red numbers indicate the train stations): model 铁路可能如下所示(红色数字表示火车站):
For two trains on that model railway the function would be called this way:对于 model 铁路上的两列火车,function 将以这种方式调用:
Trains.list_routes([:red_train, :blue_train], ["1", "2", "3", "4", "5"])
Here's my current code:这是我当前的代码:
defmodule Trains do
@moduledoc """
Documentation for `Trains`.
"""
@doc """
Returns a list of all possible routes.
## Examples
iex> Trains.list_routes([:red_train, :blue_train], ["Station 1", "Station 2"])
[
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
},
%{
end: %{blue_train: "Station 1", red_train: "Station 2"},
start: %{blue_train: "Station 2", red_train: "Station 1"}
},
%{
end: %{blue_train: "Station 2", red_train: "Station 1"},
start: %{blue_train: "Station 1", red_train: "Station 2"}
}
]
"""
def list_routes([], []) do
[]
end
def list_routes([train], [station]) do
[
%{start: %{train => station}, end: %{train => station}}
]
end
def list_routes([train], [station1, station2]) do
[
%{start: %{train => station1}, end: %{train => station1}},
%{start: %{train => station2}, end: %{train => station2}},
%{start: %{train => station1}, end: %{train => station2}},
%{start: %{train => station2}, end: %{train => station1}}
]
end
def list_routes([train1, train2], [station1, station2]) do
[
%{
start: %{train1 => station1, train2 => station2},
end: %{train1 => station1, train2 => station2}
},
%{
start: %{train1 => station2, train2 => station1},
end: %{train1 => station2, train2 => station1}
},
%{
start: %{train1 => station1, train2 => station2},
end: %{train1 => station2, train2 => station1}
},
%{
start: %{train1 => station2, train2 => station1},
end: %{train1 => station1, train2 => station2}
}
]
end
def list_routes(trains, train_stations) do
# ???
end
end
How can I loop through all combinations with list_routes(trains, train_stations)
when the number of trains
and the number of train_stations
is bigger than 1?当
trains
数量和train_stations
数量大于 1 时,如何循环使用list_routes(trains, train_stations)
的所有组合?
It is unclear why the same start and end station is allowed for the case of one train %{start: %{train => station1}, end: %{train => station1}}
but not allowed for two trains, according to the code you've posted.不清楚为什么一列火车
%{start: %{train => station1}, end: %{train => station1}}
允许相同的起点和终点站,但不允许两列火车使用相同的起点和终点站,根据您发布的代码。
The good start would be somewhat along these lines:好的开始会有点沿着这些路线:
iex|1 ▶ {trains, stations} =
{~w|red_train blue_train|a, ~w|1 2|}
#⇒ {[:red_train, :blue_train], ["1", "2"]}
iex|2 ▶ (for t1 <- trains, t2<- trains, t1 != t2,
s1 <- stations, s2 <- stations,
do: Enum.sort([{t1, s1}, {t2, s2}])
) |> Enum.uniq()
#⇒ [
# [blue_train: "1", red_train: "1"],
# [blue_train: "2", red_train: "1"],
# [blue_train: "1", red_train: "2"],
# [blue_train: "2", red_train: "2"]
# ]
In any case,Kernel.SpecialForms.for/1
comprehension is your best friend here.无论如何,
Kernel.SpecialForms.for/1
理解是你最好的朋友。 Whether you need combinations and/or permutations, you might want to take a look at my Formulae
library, specifically at Formulae.Combinators
.无论您需要组合和/或排列,您可能想看看我的
Formulae
库,特别是在Formulae.Combinators
。
Here's a solution for the problem.这是该问题的解决方案。 It uses Formulae .
它使用公式。
mix.exs混合.exs
def deps do
[{:formulae, "~> 0.8"}]
end
lib/trains.ex lib/trains.ex
def list_routes([], []) do
[]
end
def list_routes(trains, train_stations)
when is_list(trains) and
is_list(train_stations) and
length(train_stations) >= length(trains) do
possible_states =
Enum.map(Formulae.permutations(train_stations, length(trains)), &Enum.zip(trains, &1))
for state_start <- possible_states, state_end <- possible_states do
%{start: state_start, end: state_end}
end
end
The result:结果:
iex(1)> Trains.list_routes([:red_train, :blue_train], ["Station 1", "Station 2"])
[
%{
end: [red_train: "Station 1", blue_train: "Station 2"],
start: [red_train: "Station 1", blue_train: "Station 2"]
},
%{
end: [red_train: "Station 2", blue_train: "Station 1"],
start: [red_train: "Station 1", blue_train: "Station 2"]
},
%{
end: [red_train: "Station 1", blue_train: "Station 2"],
start: [red_train: "Station 2", blue_train: "Station 1"]
},
%{
end: [red_train: "Station 2", blue_train: "Station 1"],
start: [red_train: "Station 2", blue_train: "Station 1"]
}
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.