Last active
August 29, 2015 14:08
-
-
Save nanne007/9f6b12e682d867089e17 to your computer and use it in GitHub Desktop.
这代码写的我一点脾气都没有了
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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