Advertisement
Guest User

Untitled

a guest
Mar 30th, 2015
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 1.99 KB | None | 0 0
  1. object WaterPouringProblem {
  2.  
  3.  
  4.   def main(args: Array[String]) = println (new Pouring(Vector(2,9,3)).solution(8))
  5.   class Pouring(capac: Vector[Int]) {
  6.     type State = Vector[Int]
  7.     val initialState = capac map (_ => 0)
  8.     trait Move {
  9.       def change(state: State): State;
  10.     }
  11.     case class Empty(glass: Int) extends Move {
  12.       def change(state: State): State =
  13.         state updated (glass, 0)
  14.     }
  15.     case class Fill(glass: Int) extends Move {
  16.       def change(state: State): State =
  17.         state updated (glass, capac(glass))
  18.     }
  19.     case class Pour(from: Int, to: Int) extends Move {
  20.       def change(state: State): State = {
  21.         val amount = state(from) min (capac(to) - state(to))
  22.         state updated (from, state(from) - amount) updated (to, state(to) + amount)
  23.       }
  24.     }
  25.  
  26.     val glasses = 0 until capac.length
  27.    
  28.    
  29.     val moves =
  30.       (for (g <- glasses) yield Empty(g)) ++
  31.         (for (g <- glasses) yield Fill(g)) ++
  32.         (for (g1 <- glasses; g2 <- glasses if (g2 != g1)) yield Pour(g1, g2));
  33.  
  34.     class Path(history: List[Move], val finalState: State) {
  35.       def extend(move: Move) = new Path(move :: history, move.change(finalState))
  36.       override def toString =
  37.         (history.reverse mkString " -> ") + " => " + finalState
  38.     }
  39.     val initialPath = new Path(Nil, initialState);
  40.  
  41.     def from(paths: Set[Path], explored: Set[State]): Stream[Set[Path]] = {
  42.       if (paths.isEmpty) Stream.empty
  43.       else {
  44.         val more = for {
  45.           path <- paths
  46.           next <- moves map path.extend
  47.           if !explored.contains(next.finalState)
  48.         } yield next
  49.         paths #:: from(more, explored ++ more.map(_.finalState))
  50.       }
  51.     }
  52.  
  53.     val pathSets: Stream[Set[Path]] = from(Set(initialPath), Set(initialState));
  54.  
  55.     def solution(target: Int): Stream[Path] = {
  56.       for {
  57.         pathSet <- pathSets
  58.         path <- pathSet
  59.         if (path.finalState contains target)
  60.       } yield path
  61.     }
  62.   }
  63. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement