Skip to content

Instantly share code, notes, and snippets.

@zbstof
Last active April 18, 2019 09:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zbstof/ad46ac8faf8ef9a13dce9353613cb5cb to your computer and use it in GitHub Desktop.
Save zbstof/ad46ac8faf8ef9a13dce9353613cb5cb to your computer and use it in GitHub Desktop.
Dumb zip
import scala.collection.mutable.ArrayBuffer
def merge1Immutable(ls: Array[Char]): Array[Char] = {
if (ls.isEmpty) ls
else {
var size = 1
var globalCh: Char = ls.head
val resLs = ArrayBuffer[Char]()
for (i <- 1 until ls.length) {
val ch: Char = ls(i)
if (globalCh == ch) {
size = size + 1
} else {
if (size == 1) {
resLs += globalCh
} else {
resLs += globalCh
resLs ++= size.toString.toCharArray
size = 1
}
globalCh = ch
}
}
if (size == 1) resLs += globalCh
else {
resLs += globalCh
resLs ++= size.toString.toCharArray
}
val r: Seq[Char] = ls.takeRight(ls.length - resLs.size)
(resLs ++ r).toArray
}
}
def merge2Mutable(chars: Array[Char]): Array[Char] = {
var currentOutputIndex: Int = 0
def writeChar(toWrite: Char): Unit = {
chars(currentOutputIndex) = toWrite
currentOutputIndex += 1
}
var curCount: Int = 1
def writeCount(): Unit = {
for (source: Char <- curCount.toString.toCharArray) {
writeChar(source)
}
}
var previousChar: Char = '\u0000'
for (currentChar: Char <- chars) {
if (previousChar != currentChar) {
if (curCount > 1) {
writeCount()
}
previousChar = currentChar
writeChar(currentChar)
curCount = 1
} else {
curCount += 1
}
}
if (!chars.isEmpty && previousChar == chars.last && curCount > 1) {
writeCount()
}
chars
}
def merge3Recursive(chars: Array[Char]): Array[Char] = {
def intToChars(count: Int): Seq[Char] = if (count > 1) Seq(count.toString.toCharArray: _*) else Seq()
def mergeRec(inputToCompress: Seq[Char], prevChar: Char, count: Int): Seq[Char] = {
inputToCompress match {
case Nil => Seq(prevChar) ++ intToChars(count) // last element
case head :: tail if head == prevChar => mergeRec(tail, prevChar, count + 1) // counting up
case head :: tail if head != prevChar => Seq(prevChar) ++ intToChars(count) ++ mergeRec(tail, head, 1)
}
}
val res: Seq[Char] = (chars.toSeq: Seq[Char]) match {
case Nil => Seq()
case head :: tail => mergeRec(tail, head, 1)
}
val remainder: Seq[Char] = chars.takeRight(chars.length - res.length)
res.toArray ++ remainder
}
def myassert(input: String, expected: String): Unit = {
println(s"Evaluating '$input'")
val actual = new String(merge2Mutable(input.toCharArray))
assert(actual == expected, actual)
}
myassert("", "")
myassert("a", "a")
myassert("aa", "a2")
myassert("ab", "ab")
myassert("aaa", "a3a")
myassert("aab", "a2b")
myassert("abc", "abc")
myassert("aabbb", "a2b3b")
myassert("aabbbcdddd", "a2b3cd4ddd")
myassert("aaaaaaaaaab", "a10baaaaaab")
myassert("aaaaaaaaaabb", "a10b2aaaaabb")
println("Done!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment