Created
October 8, 2021 14:19
-
-
Save leontabak/02671ffe181429efef7e39d279dc98d1 to your computer and use it in GitHub Desktop.
Solve one part of Playfair Cipher problem in Scala.
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
// This is an effort to solve a problem that | |
// arose in the course of an effort to write | |
// a program that encrypts a message using | |
// the Playfair Cipher. | |
// It divides the plain text into groups of | |
// 2 letters (digrams), ensuring that no | |
// diagram contains 2 identical letters. | |
// I have used grouped(), indexWhere(), reduce(), | |
// splitAt(), and recursion. | |
object Repeats extends App { | |
val s0 = "SEETHEGEESEANDTHEMOOSETHENFLEEORFREEZE" | |
//val s0 = "AACDEFGH" | |
//val s0 = "ILOOKFREELY" | |
println(s"s0 = $s0") | |
println() | |
// f() is not a recursive function | |
def f(noRepeats: String, unsure: String): (String, String) = { | |
// We are going to divide a string into 2-character | |
// strings, so make sure length of string is even. | |
val maybeRepeats = if( unsure.length % 2 == 0) unsure else | |
unsure + "X" | |
var result = (noRepeats, maybeRepeats) | |
// Divide string into pairs of letters | |
val s1 = maybeRepeats.grouped(2).toVector | |
// Find index of first pair of letters (if any) | |
// that contains 2 identical letters | |
// Need to allow repeated X's or infinite recursion | |
// occurs | |
val index = s1.indexWhere((s: String) => (s(0) == s(1)) && | |
(s(0) != 'X')) | |
// Set j to that index if a pair with repeated | |
// letters was found, set j to the number of | |
// pairs otherwise | |
val j = if (index >= 0) index else s1.length | |
// Create 2 smaller Vectors. | |
// * prefix contains pairs with no-identical letters | |
// * suffix contains the first pair with identical | |
// letters plus all pairs that follow | |
val (prefix, suffix) = s1.splitAt(j) | |
//println( s"f:prefix = $prefix") | |
//println( s"f:suffix = $suffix") | |
//println( s"f:s1 = $s1") | |
// Convert the Vector (a sequence of pairs | |
// of letters to a single string. | |
val donePart = if( prefix.size > 0) | |
noRepeats + prefix.reduce(_ + _) else noRepeats | |
if (suffix.size > 0) { | |
//println( "\n -if- \n") | |
// Get that first pair of identical letters | |
val repeatedLetters = suffix(0) | |
// Make a single string out of all of the | |
// remaining pairs in suffix. | |
var remainder = "" | |
if( suffix.size > 1) { | |
val tail = suffix.slice(1, suffix.size) | |
remainder += tail.reduce(_ + _) | |
} // if | |
// Make a new pair that contains the first of the | |
// repeated letters and "X". | |
// Tack it on to the end of the Vector that contains | |
// only pairs with no repeated letters. | |
val allDone = (donePart + repeatedLetters(0) + "X") | |
// Pre-append the second of the repeated letters | |
// to the Vector that might still contain other | |
// pairs with repeated letters. | |
val moreToDo = repeatedLetters(1) + remainder | |
result = (allDone, moreToDo) | |
} // if | |
else { | |
// Did not find any pairs with repeated letters. | |
//println("\n -else- \n") | |
result = (donePart, "") | |
} // else | |
//println() | |
//println( s"f:noRepeats = ${result._1}") | |
//println( s"f:unsure = ${result._2}") | |
//println() | |
result | |
} // end of f() | |
// gHelper() is a recursive function | |
// it calls f() and itself | |
def gHelper( noRepeats:String, unsure:String ):String = { | |
//println( s"gHelper:noRepeats = ($noRepeats)") | |
//println( s"gHelper:unsure = ($unsure)" ) | |
// p means "prefix"---no 2 letter groups with repeats | |
// s means "suffix"---part of message still unchecked | |
val (p, s) = f(noRepeats, unsure) | |
//println( s"gHelper:p = ($p)" ) | |
//println( s"gHelper:s = ($s)" ) | |
//println() | |
if( s.length == 0) p else gHelper(p, s) | |
} // end of g() | |
// g is not a recursive function | |
// it calls gHelper() to get things | |
// started | |
def g(message:String):String = gHelper("", message) | |
val z = g(s0) | |
println( z ) | |
val w = z.grouped(2).toVector | |
println( w ) | |
} // Repeats |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment