我写了一个F#程序来解决“Escape from Zurg”难题
我的代码如下。但是当解决谜题时,我返回布尔值的方式出了问题。
在线
retVal = Move (cost + (MoveCost toy1 toy2)) Right remainingElements
我收到警告
表达式应该具有'unit'类型,但类型为'bool'。如果指定属性,请使用语法'obj.Prop< - expr'
并且我看到即使该函数在谜题被推翻时该函数返回true。当它返回时,retVal仍为假。
以下是我的代码。
open System
type Direction =
| Left
| Right
type Toy = {Name: string; Cost: int}
let toys = [
{Name="Buzz"; Cost=5};
{Name="Woody"; Cost=10};
{Name="Rex"; Cost=20};
{Name="Hamm"; Cost=25};
]
let MoveCost toy1 toy2 =
if (toy1.Cost > toy2.Cost) then
toy1.Cost
else
toy2.Cost
let rec Move cost direction group =
match group with
| [] -> if (cost > 60) then
false
else
Console.WriteLine("Solution Found!")
true
| _ ->
match direction with
| Left ->
let retVal = false
let combinations = Set.ofSeq (seq {for i in group do for j in group do if i <> j then if i < j then yield i, j else yield j, i})
for pair in combinations do
let (toy1, toy2) = pair
let remainingElements = List.filter (fun t-> t.Name <> toy1.Name && t.Name <> toy2.Name) group
retVal = Move (cost + (MoveCost toy1 toy2)) Right remainingElements
if (retVal) then
Console.WriteLine ("Move " + toy1.Name + " and " + toy2.Name + " with the total cost of " + cost.ToString())
retVal
| Right ->
let retVal = false
let toysOnRightBank = List.filter (fun t-> not(List.exists (fun g-> g = t) group)) toys
for toy in toysOnRightBank do
let cost = cost + toy.Cost
let retVal = Move cost Left (toy :: group)
if (retVal) then
Console.WriteLine("Move " + toy.Name + " back with the cost of " + toy.Cost.ToString())
retVal
[<EntryPoint>]
let main args =
let x = Move 0 Left toys
0
答案 0 :(得分:4)
您无法重新分配let
绑定。它应该是:
let mutable retVal = false
...
retVal <- Move (cost + (MoveCost toy1 toy2)) Right remainingElements
但是,您可以轻松地重写它,以便不需要mutable
:
let res =
[
for i in group do
for j in group do
if i < j then yield i, j elif i > j then yield j, i
]
|> List.filter (fun (toy1, toy2) ->
let remainingElements = List.filter (fun t-> t.Name <> toy1.Name && t.Name <> toy2.Name) group
Move (cost + (MoveCost toy1 toy2)) Right remainingElements)
match res with
| [] -> false
| _ ->
res |> List.iter (fun (toy1, toy2) ->
Console.WriteLine ("Move " + toy1.Name + " and " + toy2.Name + " with the total cost of " + cost.ToString()))
true
编辑:如果您需要参考实施,我发布了complete solution on gist。