Skip to content

Instantly share code, notes, and snippets.

@maasg
Last active December 18, 2015 18:39
Show Gist options
  • Save maasg/5827815 to your computer and use it in GitHub Desktop.
Save maasg/5827815 to your computer and use it in GitHub Desktop.
Scala solution to TopCoder practice problem "Decipher": http://community.topcoder.com/stat?c=problem_statement&pm=4674&rd=7227
import scala.collection.SortedSet
import scala.collection.SortedMap
// Attempts to decipher an encripted message by matching the frequency of letters in the message vs an ordered frequency key
object Decipher {
// calculates a decoding table in the form (encoded->decoded)
def codex(encoded:String, freq: String):Map[Char,Char] = {
// Transforms the encoded string in a frequency map char->frequecy(int). Note that white spaces are removed
val charFreqMap = encoded.filter(_!=' ').foldLeft(Map[Char,Int]())((x,y) => {val freq = x.getOrElse(y,0)+1; x + ((y,freq))})
// Transforms the character frequency map into a Map of frequencies into the order set of chars with that frequency
// E.g. 2->('A','B'), 3->'Z',...
val freqMap = charFreqMap.foldLeft(Map[Int,SortedSet[Char]]())((map,elem) => elem match {case (k,v) => {val sameCharFreq = map.getOrElse(v,SortedSet[Char]()) + k; map + ((v, sameCharFreq))}})
//Creates a sequence of characters ordered by their frequency in descendent order.
//Characters with the same frequency are ordered alphabetically (by virtue of the SortedSet they where collected into)
val orderedByFrequency = freqMap.keys.toList.sortWith(_>_).map(freqMap).flatten
//Returns a decoding map by matching the ordered-by-frequency char sequence with the provided key.
//Space support is added to this map
(orderedByFrequency zip freq).toMap + (' ' -> ' ')
}
def decipher(encoded:Array[String], frequencyOrder:String):Array[String] = {
// Creates a single string concatenating the String array provided. Used to calculate the decoding function
val stringConcat = encoded.mkString("")
// Creates a decoding map from the single string and the frequency key (also a string)
val decoder = codex(stringConcat, frequencyOrder)
// Decode every string in the input array with the calculated decoding map
encoded.map(st => st.map(decoder))
}
val encoded = Array("RAZVLHAR KNW CNR", "HEA HNFMNSAR NFAK")
decipher( encoded ,"EORTPNFHSCDIWG") // res0: Array[String] = Array(REGISTER NOW FOR, THE TOPCODER OPEN)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment