未验证 提交 bb08e6c7 编写于 作者: 梦境迷离's avatar 梦境迷离 提交者: GitHub

Merge pull request #38 from sweeneycai/sweeneycai

Sweeneycai
......@@ -9,3 +9,5 @@ Leetcode Scala 实现
## author
[dreamylost](./src/main/scala/io/github/dreamylost/dreamylost.md)
[sweeneycai](./src/main/scala/io/github/sweeneycai/sweeneycai.md)
\ No newline at end of file
package io.github.sweeneycai
/**
* 365. 水壶问题
*/
object WaterPouringProblem extends App {
def canMeasureWater(x: Int, y: Int, z: Int): Boolean = {
val game = new Pouring(Vector(x, y))
game.solutions(z).take(1).nonEmpty
}
class Pouring(capacity: Vector[Int]) {
// States
type State = Vector[Int]
val initialState: Vector[Int] = capacity map (x => 0)
// Moves
trait Move {
def change(state: State): State
}
case class Empty(glass: Int) extends Move {
def change(state: State): State = state updated (glass, 0)
}
case class Fill(glass: Int) extends Move {
def change(state: State): State = state updated (glass, capacity(glass))
}
case class Pour(from: Int, to: Int) extends Move {
def change(state: State): State = {
val amount = state(from) min (capacity(to) - state(to))
state updated (from, state(from) - amount) updated (to, state(to) + amount)
}
}
val glasses: Range = capacity.indices
val moves: Seq[Move] =
(for (g <- glasses) yield Empty(g)) ++
(for (g <- glasses) yield Fill(g)) ++
(for (from <- glasses; to <- glasses if from != to) yield Pour(from, to))
class Path(history: List[Move], val endState: State) {
// def endState: State = (history foldRight initialState) (_ change _)
// def endState: State = (history foldRight initialState)((move, state) => move.change(state))
// private def trackState(xs: List[Move]): State = xs match {
// case Nil => initialState
// case move :: xs1 => move change trackState(xs1)
// }
def extend(move: Move): Path = new Path(move :: history, move change endState)
override def toString: String = (history.reverse mkString " ") + "-->" + endState
}
val initialPath = new Path(Nil, initialState)
def from(paths: Set[Path], explored: Set[State]): Stream[Set[Path]] =
if (paths.isEmpty) Stream.empty
else {
val more = for {
path <- paths
next <- moves map path.extend
if !(explored contains next.endState)
} yield next
paths #:: from(more, explored ++ (more map (_.endState)))
}
val pathSets = from(Set(initialPath), Set(initialState))
def solutions(target: Int): Stream[Path] =
for {
pathSet <- pathSets
path <- pathSet
if (path.endState contains target) || path.endState.sum == target
} yield path
}
val pouring = new Pouring(Vector(3, 5))
println(pouring.solutions(4).take(1))
}
### 其他
- [水壶问题](https://leetcode-cn.com/problems/water-and-jug-problem/)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册