Skip to content

Instantly share code, notes, and snippets.

@nanne007
Last active August 29, 2015 14:08
Show Gist options
  • Save nanne007/9f6b12e682d867089e17 to your computer and use it in GitHub Desktop.
Save nanne007/9f6b12e682d867089e17 to your computer and use it in GitHub Desktop.
这代码写的我一点脾气都没有了
object Stream {
private def interleave[T](s1: Stream[T], s2: Stream[T]): Stream[T] = {
if (s1.isEmpty) s2
else s1.head #:: interleave(s2, s1.tail)
}
private def pairs[S, T](s: Stream[S], t: Stream[T]): Stream[(S, T)] = {
if (s.isEmpty || t.isEmpty) Stream.empty[(S, T)]
(s.head, t.head) #:: interleave(t.tail map ((s.head, _)), pairs(s.tail, t.tail))
}
private def weightMerge[T, That<% Ordered[That]](s1: Stream[T], s2: Stream[T],
weight: T => That): Stream[T] = {
if (s1.isEmpty) s2
else if (s2.isEmpty) s1
else {
val (s1Head, s2Head) = (s1.head, s2.head)
if (weight(s1Head) <= weight(s2Head)) s1Head #:: weightMerge(s1.tail, s2, weight)
else s2Head #:: weightMerge(s1, s2.tail, weight)
}
}
def weightPairs[S, T, That <% Ordered[That]](s: Stream[S], t: Stream[T],
weight: ((S, T)) => That): Stream[(S, T)] = {
if (s.isEmpty || t.isEmpty) Stream.empty[(S, T)]
else {
val sideMerge = weightMerge(t.tail map ((s.head, _)), s.tail map ((_, t.head)), weight)
(s.head, t.head) #:: weightMerge(sideMerge, weightPairs(s.tail, t.tail, weight), weight)
}
}
def triples[X, Y, Z](x: Stream[X], y: Stream[Y], z: Stream[Z]): Stream[(X, Y, Z)] = {
(x.head, y.head, z.head) #:: interleave(pairs(y, z).tail map (t => (x.head, t._1, t._2)), triples(x.tail, y.tail, z.tail))
}
def weightTriples[X, Y, Z, That <% Ordered[That]](x: Stream[X], y: Stream[Y], z: Stream[Z],
weight: ((X, Y, Z)) => That): Stream[(X, Y, Z)] = {
if (x.isEmpty || y.isEmpty || z.isEmpty) Stream.empty[(X, Y, Z)]
else {
// FIXBUG: remove duplicate elem
val w1 = { hold: (Y, Z) => weight((x.head, hold._1, hold._2)) }
val w2 = { hold: (X, Z) => weight((hold._1, y.head, hold._2)) }
val w3 = { hold: (X, Y) => weight((hold._1, hold._2, z.head)) }
val sideMerge = weightMerge(weightPairs(y, z, w1).tail map (t => (x.head, t._1, t._2)),
weightMerge(weightPairs(x, z, w2).tail map (t => (t._1, y.head, t._2)),
weightPairs(x, y, w3).tail map (t => (t._1, t._2, z.head)),
weight),
weight)
(x.head, y.head, z.head) #:: weightMerge(sideMerge, weightTriples(x.tail, y.tail, z.tail, weight), weight)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment