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
Related
for my project I need to build a tree structure. I am looking for a way to grow it at the leaves. I have simplified my failed attempt by using a listy structure:
my $root = a => (b => (c=> Nil));
my $here := $root;
while $here.value ~~ Pair {
$here := $here.value;
}
$here = d => Nil;
which does not work, because I cannot change Nil, of course.
Cannot assign to an immutable value
How can I make this work?
Thanks,
Theo van den Heuvel
I think the error message you get "Cannot assign to an immutable value" is because the value is not a container. Here is an example where I make the leaf node a container:
my $root = a => (b => (my $ = (c => Nil)));
my $here := $root;
while $here.value ~~ Pair {
$here := $here.value;
}
$here = d => Nil;
Now, there is no error message.
You are using binding, not assignment for $here
my $root = a => (b => (c=> Nil));
my $here = $root;
while $here.value ~~ Pair {
$here = $here.value;
}
$here = d => Nil;
When you use bind, the left and the right-hand side are the same object. And once they are the same object, well, they can't change (if the bound object is immutable, that is). They're immutable:
my $bound := 3; $bound = 'þorn'; say $bound;
# OUTPUT: «Cannot assign to an immutable value»
3 above is immutable, so you can't assign to it. In the code you have provided, you could change the value by rebinding until you arrived to an immutable value, the last Pair, which explains the message.
Just use ordinary assignment and you're good to go. If what you want is to keep the original value of $root somewhere, just do this and use $root to do the tree navigation
my $root = a => (b => (c=> Nil));
my $here = $root;
while $root.value ~~ Pair {
$root = $root.value;
}
$here = d => Nil;
say $here;
say $root;
$here will still be equal to the original root, and $root will have navigated to the last branch and leaf.
On the basis of valuable input from #Elizabeth, #Håkon and #jjmerelo I have created an example tree implementation.
my #paths = <<aap-noot-mies aap-noot-hut aap-juf tuin>>;
my %root;
for #paths -> $fn {
my #path = $fn.split: '-';
add-to-tree(#path);
}
print_tree(0, %root);
sub add-to-tree(#path) {
my %tmp := %root;
for #path -> $step {
unless %tmp{$step}:exists {
my %newtmp;
%tmp{$step} = %newtmp;
}
%tmp := %tmp{$step};
}
}
sub print_tree($ind, %from) {
my $margin = ' ' x $ind;
if %from {
for %from.kv -> $k, $v {
say "$margin$k:";
print_tree($ind + 1, %$v);
}
} else {
say "$margin.";
}
}
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).
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.
I need to build a where clause at runtime but I need to do an OR with the where clause. Is this possible?
Here is my code. Basically "filter" is a enum Bitwise, son hence filter could be equal to more than 1 of the following. Hence I need to build up the where clause.
If I execute the WHEREs separately then imagine if I do the Untested first, and it returns 0 records that means I can't execute a where on the Tested because its now 0 records.
I will put some pseudo-code below:
string myWhere = "";
if ((filter & Filters.Tested) == Filters.Tested)
{
if (myWhere != "" ) myWhere =myWhere + "||";
myWhere = myWhere " Status == "Tested";
}
if ((filter & Filters.Untested) == Filters.Untested)
{
if (myWhere != "" ) myWhere =myWhere + "||";
myWhere = myWhere " Status == "Untested";
}
if ((filter & Filters.Failed) == Filters.Failed)
{
if (myWhere != "" ) myWhere =myWhere + "||";
myWhere = myWhere " Status == "Failed";
}
// dataApplications = a List of items that include Tested,Failed and Untested.
// dataApplication.Where ( myWhere) --- Confused here!
Is this possible?
I don't want to include lots of "IFs" because there are lots of combinations i.e. no filter, filter= tested Only, filter = Untested and Tested ... and lots more.
If you have this:
IEnumerable<MyType> res = from p in myquery select p;
You can define a
var conditions = new List<Func<MyType, bool>>();
conditions.Add(p => p.PropertyOne == 1);
conditions.Add(p => p.PropertyTwo == 2);
res = res.Where(p => conditions.Any(q => q(p)));
And now the trick to make Lists of Funcs of anonymous objects (and you can easily change it to "extract" the type of anonymous objects)
static List<Func<T, bool>> MakeList<T>(IEnumerable<T> elements)
{
return new List<Func<T, bool>>();
}
You call it by passing the result of a LINQ query. So
var res = from p in elements select new { Id = p.Id, Val = p.Value };
var conditions = MakeList(res);
var statusTexts = new List<string>(); // Add desired status texts
dataApplication.Where(item =>
statusTexts.Any(status => item.Status == status))
Use HashSet<> for statuses, then .Contains will be O(1) instead of usual O(n) for List<>:
var statuses = new HashSet<string>() {"a", "b", "c"};
var list = new[] {
new { Id = 1, status = "a"},
new { Id = 2, status = "b"},
new { Id = 3, status = "z"}
};
var filtered = list.Where(l => statuses.Contains(s => l.status == s));
Taking a look at my question HERE, I now want to return the next recommendation object (after) the one that matches the criteria.
So say I found item 6 out of 10, I'd like the query to return item 7 instead.
Or is there a better way?
Here's my current best method:
MyList.SkipWhile(item => item.Name != "someName").Skip(1).FirstOrDefault()
An earlier answer uses Skip(1).Take(1) which works, but returns a list of one result. In my case (and perhaps the OP's case), we're looking for the actual item. So my code skips until it gets to the one we're looking for (a Where would return a subset so we wouldn't have access to the next item) then skips one more and then gets the item.
Try this one
NEXT Item
MyList.SkipWhile(x => x != value).Skip(1).FirstOrDefault();
PREVIOUS Item note:Reverse() will not work for LINQ to SQL
var MyList2 = MyList.ToList();
MyList2.Reverse();
MyList2.SkipWhile(x => x != value).Skip(1).FirstOrDefault();
Since you have a List<T> object you can use its FindIndex method instead of Where to get the index of the first matching item rather than the item itself:
int index = recommendations.FindIndex(rp =>
rp.Products.Any(p => p.Product.Code == "A")
&& rp.Products.Any(p => p.Product.Code == "B")
);
Once you have the index you can get the next item or previous item or whatever you want.
How about something like this:
public static class Extension
{
public static T Next<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
bool flag = false;
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (flag) return enumerator.Current;
if(predicate(enumerator.Current))
{
flag = true;
}
}
}
return default(T);
}
}
You could then call it like you would for Where
Products.Next(x => x.Whatever);
This should do it. I haven't constructed a test for it specifically.
var nextProducts = from item1 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
join item2 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
on item1.Index equals item2.Index - 1
where item1.Rec.Products.Any(p => p.Code == "A")
&& item1.Rec.Products.Any(p => p.Code == "B")
select item2.Rec;
If you needed both records, the select statement could be
select new { MatchingItem = item1.Rec, NextItem = item2.Rec };
But then you would have to do a grouping to account for a matching item being the last item in the list (there would not be a next item in that case).
var nextProducts = from item1 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
join item2 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
on item1.Index equals item2.Index - 1
into groupjoin
from i2 in groupjoin.DefaultIfEmpty ()
where item1.Rec.Products.Any(p => p.Code == "A")
&& item1.Rec.Products.Any(p => p.Code == "B")
select new { MatchingItem = item1.Rec, NextItem = i2 == null ? null : i2.Rec };
The code I did test was something similar with a list of strings.
List<string> list = new List<string>() { "a", "b", "c", "a", "d", "a", "e" };
var query = from item1 in list.Select((s, idx) => new { Item = s, Index = idx })
join item2 in list.Select((s, idx) => new { Item = s, Index = idx })
on item1.Index equals item2.Index - 1
where item1.Item == "a"
select item2.Item;
Which returns b, d, and e.
If you are sure that:
the item is unique in the list
the item is gotten from the same list
there is the next item
you can get the next item this way
myList[myList.IndexOf(item) + 1];
// or
myList.ElementAt(myList.IndexOf(item) + 1);
If you're not sure there is the next item you can use try + catch or:
myList.ElementAtOrDefault(myList.IndexOf(item) + 1);
Is item 7 a match to your Where clause? If so, use the Skip() and Take() extension methods:
var myProducts =
from rp in recommendations
where
cp.Products.Any(p => p.Product.Code == "A") &&
cp.Products.Any(p => p.Product.Code == "B")
select rp;
var nextProduct = myProducts.Skip(1).Take(1);