Skip to content

Instantly share code, notes, and snippets.

@kholodilov
Last active July 16, 2016 16:34
Show Gist options
  • Save kholodilov/e70b0611369ae0cb839f8f86702007f4 to your computer and use it in GitHub Desktop.
Save kholodilov/e70b0611369ae0cb839f8f86702007f4 to your computer and use it in GitHub Desktop.
compress string
// simple
def compressSimple(s: String): String = {
s.headOption.map { head =>
var current = head
var count = 1
val compressed = new StringBuilder()
s.tail.foreach { next =>
if (current == next) {
count = count + 1
} else {
compressed.append(current + count.toString)
current = next
count = 1
}
}
compressed.append(current + count.toString).toString
}.getOrElse("")
}
// functional
case class CompressedItem(item: Char, count: Int) {
override def toString: String = item + count.toString
def increment: CompressedItem = this.copy(count = count + 1)
}
case class Compressed(buffer: String, nextItem: CompressedItem) {
def increment: Compressed = this.copy(nextItem = nextItem.increment)
def append(next: Char): Compressed = Compressed(buffer + nextItem, CompressedItem(next, 1))
override def toString: String = buffer + nextItem
}
def compressNext(compressed: Compressed, next: Char): Compressed = {
if (compressed.nextItem.item == next) {
compressed.increment
} else {
compressed.append(next)
}
}
def compressFunctional(s: String): String = {
s.headOption.map(head =>
s.tail.foldLeft(Compressed("", CompressedItem(head, 1)))(compressNext).toString
).getOrElse("")
}
// functional mutable
case class MutableCompressedItem(var item: Char, var count: Int) {
override def toString: String = item + count.toString
def increment: Unit = { count = count + 1 }
}
case class MutableCompressed(buffer: StringBuilder, var nextItem: MutableCompressedItem) {
def increment: Unit = { nextItem.increment }
def append(next: Char): Unit = {
buffer.append(nextItem.toString)
nextItem.item = next
nextItem.count = 1
}
override def toString: String = buffer.toString + nextItem.toString
}
def compressNext(compressed: MutableCompressed, next: Char): MutableCompressed = {
if (compressed.nextItem.item == next) {
compressed.increment
} else {
compressed.append(next)
}
compressed
}
def compressFunctionalMutable(s: String): String = {
s.headOption.map { head =>
val init = MutableCompressed(new StringBuilder(), MutableCompressedItem(head, 1))
s.tail.foldLeft(init)(compressNext).toString
}.getOrElse("")
}
// test
compressSimple("abbaaabcbbc")
compressSimple("a")
compressSimple("")
compressFunctional("abbaaabcbbc")
compressFunctional("a")
compressFunctional("")
compressFunctionalMutable("abbaaabcbbc")
compressFunctionalMutable("a")
compressFunctionalMutable("")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment