Skip to content

Instantly share code, notes, and snippets.

@Hajto
Created June 24, 2015 09:27
Show Gist options
  • Save Hajto/e6e9d41f902710ca7078 to your computer and use it in GitHub Desktop.
Save Hajto/e6e9d41f902710ca7078 to your computer and use it in GitHub Desktop.
objesets
package objsets
import common._
import TweetReader._
/**
* A class to represent tweets.
*/
class Tweet(val user: String, val text: String, val retweets: Int) {
override def toString: String =
"User: " + user + "\n" +
"Text: " + text + " [" + retweets + "]"
}
abstract class TweetSet {
/**
* This method takes a predicate and returns a subset of all the elements
* in the original set for which the predicate is true.
*
* Question: Can we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def filter(p: Tweet => Boolean): TweetSet = filterAcc(p, new Empty)
/**
* This is a helper method for `filter` that propagetes the accumulated tweets.
*/
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet
/**
* Returns a new `TweetSet` that is the union of `TweetSet`s `this` and `that`.
*
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def union(that: TweetSet): TweetSet
/**
* Returns the tweet from this set which has the greatest retweet count.
*
* Calling `mostRetweeted` on an empty set should throw an exception of
* type `java.util.NoSuchElementException`.
*
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def mostRetweeted: Tweet
def mostRetweetedAcc(currentMost: Tweet): Tweet
/**
* Returns a list containing all tweets of this set, sorted by retweet count
* in descending order. In other words, the head of the resulting list should
* have the highest retweet count.
*
* Hint: the method `remove` on TweetSet will be very useful.
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
def isEmpty: Boolean
def descendingByRetweet: TweetList = {
if (isEmpty)
Nil
else {
val most = mostRetweeted
new Cons(most, remove(most).descendingByRetweet)
}
}
def incl(tweet: Tweet): TweetSet
def remove(tweet: Tweet): TweetSet
def contains(tweet: Tweet): Boolean
def foreach(f: Tweet => Unit): Unit
}
class Empty extends TweetSet {
def isEmpty = true
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = acc
override def union(that: TweetSet): TweetSet = that
override def mostRetweeted: Tweet = throw new NoSuchElementException
def mostRetweetedAcc(currentMost: Tweet) = currentMost
/**
* The following methods are already implemented
*/
def contains(tweet: Tweet): Boolean = false
def incl(tweet: Tweet): TweetSet = new NonEmpty(tweet, new Empty, new Empty)
def remove(tweet: Tweet): TweetSet = this
def foreach(f: Tweet => Unit): Unit = ()
}
class NonEmpty(elem: Tweet, left: TweetSet, right: TweetSet) extends TweetSet {
def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = {
if (p(elem))
left.filterAcc(p, right.filterAcc(p, acc.incl(elem)))
else
left.filterAcc(p, right.filterAcc(p, acc))
}
/**
* Returns the tweet from this set which has the greatest retweet count.
*
* Calling `mostRetweeted` on an empty set should throw an exception of
* type `java.util.NoSuchElementException`.
*
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
override def mostRetweeted: Tweet = mostRetweetedAcc(elem)
override def mostRetweetedAcc(currentMost: Tweet) = {
println(currentMost.retweets)
def test(first: Tweet, second: Tweet): Tweet =
if (first.retweets > second.retweets)
first
else
second
val leftMost = test(left.mostRetweetedAcc(currentMost), currentMost)
println(leftMost.retweets)
test(leftMost, right.mostRetweetedAcc(leftMost))
}
/**
* Returns a list containing all tweets of this set, sorted by retweet count
* in descending order. In other words, the head of the resulting list should
* have the highest retweet count.
*
* Hint: the method `remove` on TweetSet will be very useful.
* Question: Should we implment this method here, or should it remain abstract
* and be implemented in the subclasses?
*/
override def isEmpty: Boolean = false
override def union(that: TweetSet): TweetSet = {
((left union right) union that) incl elem
}
def contains(x: Tweet): Boolean =
if (x.text < elem.text) left.contains(x)
else if (elem.text < x.text) right.contains(x)
else true
def incl(x: Tweet): TweetSet = {
if (x.text < elem.text) new NonEmpty(elem, left.incl(x), right)
else if (elem.text < x.text) new NonEmpty(elem, left, right.incl(x))
else this
}
def remove(tw: Tweet): TweetSet =
if (tw.text < elem.text) new NonEmpty(elem, left.remove(tw), right)
else if (elem.text < tw.text) new NonEmpty(elem, left, right.remove(tw))
else left.union(right)
def foreach(f: Tweet => Unit): Unit = {
f(elem)
left.foreach(f)
right.foreach(f)
}
}
trait TweetList {
def head: Tweet
def tail: TweetList
def isEmpty: Boolean
def foreach(f: Tweet => Unit): Unit =
if (!isEmpty) {
f(head)
tail.foreach(f)
}
}
object Nil extends TweetList {
def head = throw new java.util.NoSuchElementException("head of EmptyList")
def tail = throw new java.util.NoSuchElementException("tail of EmptyList")
def isEmpty = true
}
class Cons(val head: Tweet, val tail: TweetList) extends TweetList {
def isEmpty = false
}
object GoogleVsApple {
val google = List("android", "Android", "galaxy", "Galaxy", "nexus", "Nexus")
val apple = List("ios", "iOS", "iphone", "iPhone", "ipad", "iPad")
println("Zaczynam filtrowanie")
lazy val googleTweets: TweetSet = TweetReader.allTweets.filter(t => google.exists(p => t.text.contains(p)))
println(googleTweets.mostRetweeted.user)
lazy val appleTweets: TweetSet = TweetReader.allTweets.filter(t => apple.exists(p => t.text.contains(p)))
println(appleTweets.mostRetweeted.user)
/**
* A list of all tweets mentioning a keyword from either apple or google,
* sorted by the number of retweets.
*/
lazy val trending: TweetList = (googleTweets union appleTweets).descendingByRetweet
}
object Main extends App {
// Print the trending tweets
println("Poszlo")
GoogleVsApple.trending foreach println
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment