1

「 EscapefromZurg」パズルを解くためのF#プログラムを書きました

私のコードは次のとおりです。しかし、パズルが解かれたときにブール値を返す方法に何らかの問題があります。

ライン上

retVal = Move (cost + (MoveCost toy1 toy2)) Right remainingElements

警告が表示されます

式のタイプは「unit」である必要がありますが、タイプは「bool」です。プロパティを割り当てる場合は、構文'obj.Prop<-expr'を使用します

パズルを解くと関数がtrueに戻っても、それがわかります。それが戻るとき、retValはfalseのままです。

以下は私のコードです。

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
4

1 に答える 1

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

編集:リファレンス実装が必要な場合は、要点に完全なソリューションを投稿しました。

于 2012-07-17T20:19:07.527 に答える