Advertisement
Guest User

Untitled

a guest
May 13th, 2014
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.02 KB | None | 0 0
  1. let findIndex2D (p:'A -> bool) (a:'A [,]) =
  2.   a |> Array2D.mapi (fun x y v -> x,y,v)
  3.     |> Seq.cast<int*int*'A>
  4.    |> Seq.pick (fun (x,y,v) -> if p v then Some (x,y)  else None)
  5.  
  6. let totalManhattanDistance board goal =
  7.    let manhattanDistance (x1, y1) (x2, y2) =
  8.        abs(x1 - x2) + abs (y1 - y2)
  9.    board |> Array2D.mapi (fun x y v -> manhattanDistance (x, y)
  10.                                        <| findIndex2D ((=) v) goal)
  11.          |> Seq.cast<int>         // flatten
  12.          |> Seq.sum
  13.  
  14. let swap (arr : int[,]) i1 i2 =
  15.    let map i j v =
  16.        match (i,j) with
  17.        | t when t = i1 -> arr.[fst i2, snd i2]
  18.        | u when u = i2 -> arr.[fst i1, snd i1]
  19.        | _ -> v
  20.    arr |> Array2D.mapi map
  21.  
  22. let neighbors board (zeroX, zeroY) =
  23.    let (x,y) = findIndex2D ((=) 0) board
  24.    [if x > 0 then yield swap board (zeroX,zeroY) (zeroX - 1, zeroY)
  25.     if x < Array2D.length1 board - 1 then yield swap board (zeroX,zeroY) (zeroX + 1, zeroY)
  26.     if y > 0 then yield swap board (zeroX,zeroY) (zeroX, zeroY - 1)
  27.     if y < Array2D.length2 board - 1 then yield swap board (zeroX,zeroY) (zeroX, zeroY + 1)]
  28.  
  29. let notContainsTuple x list = not (List.forall (fun (b,_,_) ->
  30.                                                    not (b = x)) list)
  31.  
  32. let notContainsList x list = not (List.exists ((=) x) list)
  33.  
  34. let fst3 (x,_,_) = x
  35.  
  36.  
  37. let Astar board goal =
  38.    let gScore = 0
  39.    let fScore = gScore + totalManhattanDistance board goal
  40.    let startState = (board, gScore, fScore)
  41.    let openSet = [startState]
  42.    let closedSet = []
  43.    
  44.    let rec find currentBoard CS OS GS =
  45.        if currentBoard = goal then GS
  46.        else
  47.            let zeroInd = findIndex2D ((=) 0) currentBoard
  48.            let removedCurrent = List.tail OS
  49.            let adjacentBoards = List.filter (fun elem ->
  50.                                                 (notContainsList elem CS) &&
  51.                                                 (notContainsTuple elem removedCurrent))
  52.                                             (neighbors currentBoard zeroInd)
  53.  
  54.            let adjacentStates = List.map (fun x ->
  55.                                                    let newGS = GS + 1
  56.                                                    let newFS = newGS + totalManhattanDistance x goal
  57.                                                    (x, newGS, newFS)) adjacentBoards
  58.  
  59.            let newCS = currentBoard::CS
  60.            let newOS = List.sortBy (fun (b,g,f) -> f)
  61.                            (List.append removedCurrent adjacentStates)
  62.  
  63.            find (fst3 (List.head newOS) newCS newOS (GS + 1)
  64.  
  65.    find board closedSet openSet gScore
  66.  
  67. [<EntryPoint>]
  68. let main argv =
  69.    let startingBoard = array2D [|[|1; 4; 7|];
  70.                                [|6; 3; 5|];
  71.                                [|0; 8; 2|]|]
  72.  
  73.    let goal =  array2D [|[|1; 2; 3|];
  74.                        [|4; 5; 6|];
  75.                        [|7; 8; 0|]|]
  76.    
  77.    printfn "%d" (Astar startingBoard goal)
  78.  
  79.    0 // return an integer exit code
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement