Scala/functional/without libs - check if string permutation of other - algorithm

How could you check to see if one string is a permutation of another using scala/functional programming with out complex pre-built functions like sorted()?
I'm a Python dev and what I think trips me up the most is that you can't just iterate through a dictionary of character counts comparing to another dictionary of character counts, then just exit when there isn't a match, you can't just call break.

Assume this is the starting point, based on your description:
val a = "aaacddba"
val b = "aabaacdd"
def counts(s: String) = s.groupBy(identity).mapValues(_.size)
val aCounts = counts(a)
val bCounts = counts(b)
This is the simplest way:
aCounts == bCounts // true
This is precisely what you described:
def isPerm(aCounts: Map[Char,Int], bCounts: Map[Char,Int]): Boolean = {
if (aCounts.size != bCounts.size)
return false
for ((k,v) <- aCounts) {
if (bCounts.getOrElse(k, 0) != v)
return false
}
return true
}
This is your method, but more scala-ish. (It also breaks as soon as a mismatch is found, because of how foreach is implemented):
(aCounts.size == bCounts.size) &&
aCounts.forall { case (k,v) => bCounts.getOrElse(k, 0) == v }
(Also, Scala does have break.)
Also, also: you should read the answer to this question.

Another option using recursive function, which will also 'break' immediately once mismatch is detected:
import scala.annotation.tailrec
#tailrec
def isPerm1(a: String, b: String): Boolean = {
if (a.length == b.length) {
a.headOption match {
case Some(c) =>
val i = b.indexOf(c)
if (i >= 0) {
isPerm1(a.tail, b.substring(0, i) + b.substring(i + 1))
} else {
false
}
case None => true
}
} else {
false
}
}
Out of my own curiosity I also create two more versions which use char counts map for matching:
def isPerm2(a: String, b: String): Boolean = {
val cntsA = a.groupBy(identity).mapValues(_.size)
val cntsB = b.groupBy(identity).mapValues(_.size)
cntsA == cntsB
}
and
def isPerm3(a: String, b: String): Boolean = {
val cntsA = a.groupBy(identity).mapValues(_.size)
val cntsB = b.groupBy(identity).mapValues(_.size)
(cntsA == cntsB) && cntsA.forall { case (k, v) => cntsB.getOrElse(k, 0) == v }
}
and roughly compare their performance by:
def time[R](block: => R): R = {
val t0 = System.nanoTime()
val result = block // call-by-name
val t1 = System.nanoTime()
println("Elapsed time: " + (t1 - t0) + "ns")
result
}
// Match
time((1 to 10000).foreach(_ => isPerm1("apple"*100,"elppa"*100)))
time((1 to 10000).foreach(_ => isPerm2("apple"*100,"elppa"*100)))
time((1 to 10000).foreach(_ => isPerm3("apple"*100,"elppa"*100)))
// Mismatch
time((1 to 10000).foreach(_ => isPerm1("xpple"*100,"elppa"*100)))
time((1 to 10000).foreach(_ => isPerm2("xpple"*100,"elppa"*100)))
time((1 to 10000).foreach(_ => isPerm3("xpple"*100,"elppa"*100)))
and the result is:
Match cases
isPerm1 = 2337999406ns
isPerm2 = 383375133ns
isPerm3 = 382514833ns
Mismatch cases
isPerm1 = 29573489ns
isPerm2 = 381622225ns
isPerm3 = 417863227ns
As can be expected, the char counts map speeds up positive cases but can slow down negative cases (overhead on building the char counts map).

Related

How to make Reverse polish notation in Scala with Recursion?

I tried to make RPN in scala but i got Exception in console
Exception in thread "main" scala.MatchError: 1 (of class
java.lang.Character)
and i stop here because Intelij don't show where is problem . I think that i 'am wrong making
if (!expr.isEmpty) {
expr.head match
but i spend some hours thinking how to exchange this and i din't invent anything
i make this program in Java but in functional programming i don't know how to correctly use this match with tail Recursive
object RPN extends App {
print(evaluate("123++"))
def evaluate( expr : String) {
val stack = Stack[Double]()
var a,b :Int=0
#tailrec
def helper ( asset : String){
if (!expr.isEmpty) {
expr.head match {
case it if 0 until 9 contains it => stack.push(expr.head); helper(asset.tail)
case '+' => b = stack.pop.toString().toInt; a = stack.pop.toString().toInt; stack.push(a + b)
case '-' => b = stack.pop.toString().toInt; a = stack.pop.toString().toInt; stack.push(a - b)
case '*' => b = stack.pop.toString().toInt; a = stack.pop.toString().toInt; stack.push(a * b)
case '/' => b = stack.pop.toString().toInt; a = stack.pop.toString().toInt; stack.push(a / b)
}
}
else return stack.pop
}
helper(expr)
}
}
Your code is referencing expr inside of helper(), where you probably want to reference asset instead.
Also, you don't need the return or the vars.
def evaluate(expr :String) :Double = {
val stack = collection.mutable.Stack[Double]()
#annotation.tailrec
def helper(asset :String) :Double =
if (asset.isEmpty) stack.pop
else {
asset.head match {
case c if c.isDigit =>
stack.push(c.asDigit)
case '+' => stack.push(stack.pop + stack.pop)
case '-' => stack.push(-stack.pop + stack.pop)
case '*' => stack.push(stack.pop * stack.pop)
case '/' => stack.push(1/stack.pop * stack.pop)
case c => throw new Error(s"Bad Char: $c")
}
helper(asset.tail)
}
helper(expr)
}
testing:
evaluate("123++") //res0: Double = 6.0
evaluate("954--") //res1: Double = 8.0
evaluate("423*+") //res2: Double = 10.0
evaluate("28/") //res3: Double = 0.25
evaluate("73/") //res4: Double = 2.333333333333333

Scala pattern matching performance

I encountered this problem while doing homework from coursera "scala specialization" (this is simplified version and doesn't contain any homework details, it's just array traversal)
val chars: Array[Char] = some array
def fun1(idx:Int):Int = {
some code here (including the stop condition)
val c = chars(idx)
c match{
case '(' => fun1(idx+1)
case _ => fun1(idx+1)
}
}
This code is 4 times slower than
def fun2(idx: Int):Int = {
some code here (including the stop condition)
val c = chars(idx)
(c == '(') match{
case true => fun2(idx+1)
case _ => fun2(idx+1)
}
}
All I am doing is changing the pattern matching
(I am running it using ScalMeter so I believe in the statistics).
Can anyone explain this behavior?
I can only confirm that the first match is ~50% slower, not 4x (2.11.8). Anyway if you look at the bytecode you can find that the first match is translated to tableswitch instruction, which is normally used for Java switch statement with multiple choices and is basically a lookup goto, while the second one is translated to if. So the second match is simply:
if (c == '(') fun2(idx+1) else fun2(idx+1)
Update the below is wrong (the majority of time in these tests was spent generating the data, so the difference in actual traversal times was not noticeable. Running this same benchmark with constant input shows ~125ms per 100 million entries for case ')' case vs. ~35ms for the other case.)
I am not seeing the difference you are describing. Not sure how ScalaMeter does it, but running it in repl (after letting "warm up" by running "dry" a few times), I get virtually the same performance:
def func(s: Seq[Char], idx: Int): String =
if(idx == s.length) "foo" else s(idx) match {
case ')' => func(s, idx+1)
case _ => func(s, idx+1)
}
def func1(s: Seq[Char], idx: Int): String =
if(idx == s.length) "foo" else (s(idx) == '(') match {
case true => func(s, idx+1)
case _ => func(s, idx+1)
}
import scala.util.Random
def randy = Stream.continually(Random.nextPrintableChar)
def doit(n: Int)(f: (Seq[Char], Int) => String) = {
val start = System.currentTimeMillis;
f(randy.take(n).toIndexedSeq, 0);
System.currentTimeMillis - start
}
scala> doit(1000000)(func)
res9: Long = 231
scala> doit(1000000)(func1)
res10: Long = 238
scala> doit(1000000)(func)
res11: Long = 234
scala> doit(1000000)(func1)
res12: Long = 201
Etc. As you can see, no sizable difference.

Lua - how to sort a table by the value chain

I'm looking for a method of sorting a Lua table by its values chain. Say, the table:
local vals = {
{ id = "checkpoint4" },
{ id = "checkpoint1", nextid = "checkpoint2" },
{ id = "checkpoint3", nextid = "checkpoint4" },
{ id = "checkpoint2", nextid = "checkpoint3" },
}
Should transform into this after sorting:
local vals = {
{ id = "checkpoint1", nextid = "checkpoint2" },
{ id = "checkpoint2", nextid = "checkpoint3" },
{ id = "checkpoint3", nextid = "checkpoint4" },
{ id = "checkpoint4" },
}
It's not essentially with the exact same names, they might vary. I wanted to make the comparison of numbers after "checkpoint", but it turned out that I have to work with dynamic things like this (already sorted the way I want it to be):
local vals = {
{ id = "checkpoint1", nextid = "cp" },
{ id = "cp", nextid = "chp" },
{ id = "chp", nextid = "mynextcheckpoint" },
{ id = "mynextcheckpoint"},
}
Thanks.
What you are describing is called topological sorting. However, since this is a restricted case, we do not have to implement a complete topological sorting algorithm:
function sort_list(tbl)
local preceding = {}
local ending
local sorted = {}
for i, e in ipairs(tbl) do
if e.nextid == nil then
ending = e
else
preceding[e.nextid] = i
end
end
if ending == nil then
return nil, "no ending"
end
local j = #tbl
while ending ~= nil do
sorted[j] = ending
ending = tbl[preceding[ending.id]]
j = j - 1
end
if sorted[1] == nil then
return nil, "incomplete list"
end
return sorted
end
Usage:
local sorted = sort_list(vals)
local id2val, tailsizes = {}, {}
for _, val in ipairs(vals) do id2val[val.id] = val end
local function tailsize(val) -- memoized calculation of tails sizes
if not tailsizes[val] then
tailsizes[val] = 0 -- cycle-proof
if val.nextid and id2val[val.nextid] then -- dangling nextid proof
tailsizes[val] = tailsize(id2val[val.nextid]) + 1
end
end
return tailsizes[val]
end
-- sorting according to tails sizes
table.sort(vals, function(a,b) return tailsize(a) > tailsize(b) end)

Algorithm to generate all variants of a word

i would like to explain my problem by the following example.
assume the word: abc
a has variants: ä, à
b has no variants.
c has variants: ç
so the possible words are:
abc
äbc
àbc
abç
äbç
àbç
now i am looking for the algorithm that prints all word variantions for abritray words with arbitray lettervariants.
I would recommend you to solve this recursively. Here's some Java code for you to get started:
static Map<Character, char[]> variants = new HashMap<Character, char[]>() {{
put('a', new char[] {'ä', 'à'});
put('b', new char[] { });
put('c', new char[] { 'ç' });
}};
public static Set<String> variation(String str) {
Set<String> result = new HashSet<String>();
if (str.isEmpty()) {
result.add("");
return result;
}
char c = str.charAt(0);
for (String tailVariant : variation(str.substring(1))) {
result.add(c + tailVariant);
for (char variant : variants.get(c))
result.add(variant + tailVariant);
}
return result;
}
Test:
public static void main(String[] args) {
for (String str : variation("abc"))
System.out.println(str);
}
Output:
abc
àbç
äbc
àbc
äbç
abç
A quickly hacked solution in Python:
def word_variants(variants):
print_variants("", 1, variants);
def print_variants(word, i, variants):
if i > len(variants):
print word
else:
for variant in variants[i]:
print_variants(word + variant, i + 1, variants)
variants = dict()
variants[1] = ['a0', 'a1', 'a2']
variants[2] = ['b0']
variants[3] = ['c0', 'c1']
word_variants(variants)
Common part:
string[] letterEquiv = { "aäà", "b", "cç", "d", "eèé" };
// Here we make a dictionary where the key is the "base" letter and the value is an array of alternatives
var lookup = letterEquiv
.Select(p => p.ToCharArray())
.SelectMany(p => p, (p, q) => new { key = q, values = p }).ToDictionary(p => p.key, p => p.values);
A recursive variation written in C#.
List<string> resultsRecursive = new List<string>();
// I'm using an anonymous method that "closes" around resultsRecursive and lookup. You could make it a standard method that accepts as a parameter the two.
// Recursive anonymous methods must be declared in this way in C#. Nothing to see.
Action<string, int, char[]> recursive = null;
recursive = (str, ix, str2) =>
{
// In the first loop str2 is null, so we create the place where the string will be built.
if (str2 == null)
{
str2 = new char[str.Length];
}
// The possible variations for the current character
var equivs = lookup[str[ix]];
// For each variation
foreach (var eq in equivs)
{
// We save the current variation for the current character
str2[ix] = eq;
// If we haven't reached the end of the string
if (ix < str.Length - 1)
{
// We recurse, increasing the index
recursive(str, ix + 1, str2);
}
else
{
// We save the string
resultsRecursive.Add(new string(str2));
}
}
};
// We launch our function
recursive("abcdeabcde", 0, null);
// The results are in resultsRecursive
A non-recursive version
List<string> resultsNonRecursive = new List<string>();
// I'm using an anonymous method that "closes" around resultsNonRecursive and lookup. You could make it a standard method that accepts as a parameter the two.
Action<string> nonRecursive = (str) =>
{
// We will have two arrays, of the same length of the string. One will contain
// the possible variations for that letter, the other will contain the "current"
// "chosen" variation of that letter
char[][] equivs = new char[str.Length][];
int[] ixes = new int[str.Length];
for (int i = 0; i < ixes.Length; i++)
{
// We start with index -1 so that the first increase will bring it to 0
equivs[i] = lookup[str[i]];
ixes[i] = -1;
}
// The current "workin" index of the original string
int ix = 0;
// The place where the string will be built.
char[] str2 = new char[str.Length];
// The loop will break when we will have to increment the letter with index -1
while (ix >= 0)
{
// We select the next possible variation for the current character
ixes[ix]++;
// If we have exausted the possible variations of the current character
if (ixes[ix] == equivs[ix].Length)
{
// Reset the current character to -1
ixes[ix] = -1;
// And loop back to the previous character
ix--;
continue;
}
// We save the current variation for the current character
str2[ix] = equivs[ix][ixes[ix]];
// If we are setting the last character of the string, then the string
// is complete
if (ix == str.Length - 1)
{
// And we save it
resultsNonRecursive.Add(new string(str2));
}
else
{
// Otherwise we have to do everything for the next character
ix++;
}
}
};
// We launch our function
nonRecursive("abcdeabcde");
// The results are in resultsNonRecursive
Both heavily commented.

Simple ranking algorithm in Groovy

I have a short groovy algorithm for assigning rankings to food based on their rating. This can be run in the groovy console. The code works perfectly, but I'm wondering if there is a more Groovy or functional way of writing the code. Thinking it would be nice to get rid of the previousItem and rank local variables if possible.
def food = [
[name:'Chocolate Brownie',rating:5.5, rank:null],
[name:'Fudge', rating:2.1, rank:null],
[name:'Pizza',rating:3.4, rank:null],
[name:'Icecream', rating:2.1, rank:null],
[name:'Cabbage', rating:1.4, rank:null]]
food.sort { -it.rating }
def previousItem = food[0]
def rank = 1
previousItem.rank = rank
food.each { item ->
if (item.rating == previousItem.rating) {
item.rank = previousItem.rank
} else {
item.rank = rank
}
previousItem = item
rank++
}
assert food[0].rank == 1
assert food[1].rank == 2
assert food[2].rank == 3
assert food[3].rank == 3 // Note same rating = same rank
assert food[4].rank == 5 // Note, 4 skipped as we have two at rank 3
Suggestions?
This is my solution:
def rank = 1
def groupedByRating = food.groupBy { -it.rating }
groupedByRating.sort().each { rating, items ->
items.each { it.rank = rank }
rank += items.size()
}
I didn't try it, but maybe this could work.
food.eachWithIndex { item, i ->
if( i>0 && food[i-1].rating == item.rating )
item.rank = food[i-1].rank
else
item.rank = i + 1
}
Here's another alternative that doesn't use "local defs" with the groovy inject method:
food.sort { -it.rating }.inject([index: 0]) { map, current ->
current.rank = (current.rating == map.lastRating ? map.lastRank : map.index + 1)
[ lastRating: current.rating, lastRank: current.rank, index: map.index + 1 ]
}

Resources