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.";
}
}
Related
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
This can be done in python / javascript:
# Python:
a = ""
b = "test"
c = a or b # test
// javascript
a = "";
b = "test";
c = a || b; // test
Can the same be accomplished in go without doing some conditional block? The only way I'm able to do this so far is with conditional blocks...
a := ""
b := "test"
var c
if a {
c = a
} else {
c = b
}
I think this is answer is going to be "no, this cannot be done", but I figured I would ask just in case I'm wrong. The example here is simplified. The variables a and b could have been defined long ago...
From golang FAQ, There is no ternary testing operation in Go. You may use the following to achieve the same result:
if expr {
n = trueVal
} else {
n = falseVal
}
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'm trying to get a directory listing and sort it into last modified time order using Vala.
I've got the directory listing part into a List < FileInfo >.
But I cannot figure out how to sort the list.
This is done via the the sort(CompareFunc<G> compare_func) method in the List class. You can read more about it here.
A basic example for strings would be:
list.sort((a,b) => {
return a.ascii_casecmp(b);
});
The return value of the function passed to sort() is the same as the ISO C90 qsort(3) function:
The comparison function must return an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
As you're interested in modify time, the FileAttribute you're looking for is TIME_MODIFIED which you would get by calling the appropriate get_attribute_* method of FileInfo.
static int main (string[] args) {
var directory = File.new_for_path ("/var/db/pkg");
var glib_list = new GLib.List<FileInfo> ();
try {
var enumerator = directory.enumerate_children (FileAttribute.TIME_MODIFIED, FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
FileInfo file_info;
while ((file_info = enumerator.next_file()) != null) {
glib_list.append(file_info);
}
} catch(Error e) {
stderr.printf ("Error: %s\n", e.message);
}
// Lets sort it.
CompareFunc<FileInfo> my_compare_func = (a, b) => {
long c = a.get_modification_time().tv_sec;
long d = b.get_modification_time().tv_sec;
return (int) (c > d) - (int) (c < d);
};
glib_list.sort(my_compare_func);
foreach (FileInfo file_info in glib_list) {
stdout.printf ("%s\n", file_info.get_name());
}
return 0;
}
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.