aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarnesom <arne@bbop.org>2021-09-12 10:01:52 +0200
committerarnesom <arne@bbop.org>2021-09-12 10:01:52 +0200
commit1ae7eac6ad01123be45c5189c8e75378d0698acc (patch)
tree157015ff7a8bf80816feb25ba73a8941e7fc8681
parentad47946738a42f6c711d1f905c4b16d00fea3572 (diff)
downloadperlweeklychallenge-club-1ae7eac6ad01123be45c5189c8e75378d0698acc.tar.gz
perlweeklychallenge-club-1ae7eac6ad01123be45c5189c8e75378d0698acc.tar.bz2
perlweeklychallenge-club-1ae7eac6ad01123be45c5189c8e75378d0698acc.zip
Arne Sommer
-rw-r--r--challenge-129/arne-sommer/blog.txt1
-rwxr-xr-xchallenge-129/arne-sommer/raku/add-linked-list27
-rwxr-xr-xchallenge-129/arne-sommer/raku/add-linked-list225
-rwxr-xr-xchallenge-129/arne-sommer/raku/add-linked-list320
-rwxr-xr-xchallenge-129/arne-sommer/raku/ch-1.raku64
-rwxr-xr-xchallenge-129/arne-sommer/raku/ch-2.raku20
-rw-r--r--challenge-129/arne-sommer/raku/lib/LinkedList1.rakumod37
-rw-r--r--challenge-129/arne-sommer/raku/lib/LinkedList2.rakumod44
-rw-r--r--challenge-129/arne-sommer/raku/lib/LinkedList3.rakumod66
-rwxr-xr-xchallenge-129/arne-sommer/raku/linked-list-method40
-rwxr-xr-xchallenge-129/arne-sommer/raku/linked-list-module16
-rwxr-xr-xchallenge-129/arne-sommer/raku/linked-list-sub32
-rwxr-xr-xchallenge-129/arne-sommer/raku/linked-list-sub240
-rwxr-xr-xchallenge-129/arne-sommer/raku/root-distance64
-rwxr-xr-xchallenge-129/arne-sommer/raku/root-distance-all64
15 files changed, 560 insertions, 0 deletions
diff --git a/challenge-129/arne-sommer/blog.txt b/challenge-129/arne-sommer/blog.txt
new file mode 100644
index 0000000000..70907b688e
--- /dev/null
+++ b/challenge-129/arne-sommer/blog.txt
@@ -0,0 +1 @@
+https://raku-musings.com/linked-roots.html
diff --git a/challenge-129/arne-sommer/raku/add-linked-list b/challenge-129/arne-sommer/raku/add-linked-list
new file mode 100755
index 0000000000..ed7df063fe
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/add-linked-list
@@ -0,0 +1,27 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use LinkedList1;
+
+unit sub MAIN (Str $string1 = '1 2 3', Str $string2 = '3 2 1', :z(:$zero), :v(:$verbose));
+
+my @values1 = $string1.words;
+my @values2 = $string2.words;
+
+$zero
+ ?? ( die "Must be 0..9 only" unless all((@values1, @values2).flat) ~~ /^<[0..9]>$/ )
+ !! ( die "Must be 1..9 only" unless all((@values1, @values2).flat) ~~ /^<[1..9]>$/ );
+
+my $l1 = LinkedList1.add-elems(@values1>>.Int);
+my $l2 = LinkedList1.add-elems(@values2>>.Int);
+
+say "L1: ", $l1.nice if $verbose;
+say "L2: ", $l2.nice if $verbose;
+
+my @values3 = ( $l1.nice("") + $l2.nice("") ).comb>>.Int;
+
+my $l3 = LinkedList1.add-elems(@values3);
+
+say "L1+L2: ", $l3.nice if $verbose;
+
+say $l3.nice; \ No newline at end of file
diff --git a/challenge-129/arne-sommer/raku/add-linked-list2 b/challenge-129/arne-sommer/raku/add-linked-list2
new file mode 100755
index 0000000000..3c32ca211a
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/add-linked-list2
@@ -0,0 +1,25 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use LinkedList2;
+
+unit sub MAIN (Str $string1 = '1 2 3', Str $string2 = '3 2 1', :z(:$zero), :v(:$verbose));
+
+my @values1 = $string1.words;
+my @values2 = $string2.words;
+
+$zero
+ ?? ( die "Must be 0..9 only" unless all((@values1, @values2).flat) ~~ /^<[0..9]>$/ )
+ !! ( die "Must be 1..9 only" unless all((@values1, @values2).flat) ~~ /^<[1..9]>$/ );
+
+my $l1 = LinkedList2.add-elems(@values1>>.Int);
+my $l2 = LinkedList2.add-elems(@values2>>.Int);
+
+say "L1: ", $l1.nice if $verbose;
+say "L2: ", $l2.nice if $verbose;
+
+my $l3 = LinkedList2.sum($l1, $l2);
+
+say "L1+L2: ", $l3.nice if $verbose;
+
+say $l3.nice;
diff --git a/challenge-129/arne-sommer/raku/add-linked-list3 b/challenge-129/arne-sommer/raku/add-linked-list3
new file mode 100755
index 0000000000..b9295535ff
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/add-linked-list3
@@ -0,0 +1,20 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use LinkedList3;
+
+unit sub MAIN (Str $string1 = '1 2 3', Str $string2 = '3 2 1', :z(:$zero), :v(:$verbose));
+
+my $l1 = LinkedList3.from-string($string1, :$zero);
+my $l2 = LinkedList3.from-string($string2, :$zero);
+
+my $l3 = LinkedList3.sum($l1, $l2);
+
+if $verbose
+{
+ say "L1: ", $l1.nice;
+ say "L2: ", $l2.nice;
+ say "L1+L2: ", $l3.nice;
+}
+
+say $l3.nice;
diff --git a/challenge-129/arne-sommer/raku/ch-1.raku b/challenge-129/arne-sommer/raku/ch-1.raku
new file mode 100755
index 0000000000..afb2f3b65c
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/ch-1.raku
@@ -0,0 +1,64 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (Str $tree = "1 | 2 3 | * * * 4 | 5 6", Str $node = '6', :a(:$all), :v(:$verbose));
+
+class BinaryNode
+{
+ has Int $.value;
+ has BinaryNode $.left;
+ has BinaryNode $.right;
+}
+
+my @btree = $tree.split("|")>>.words;
+
+my @old-nodes;
+my @new-nodes;
+
+for @btree.reverse -> $row
+{
+ my @current = @$row;
+ @old-nodes = @new-nodes;
+ @new-nodes = ();
+
+ for @current -> $value
+ {
+ if $value eq "*"
+ {
+ @new-nodes.push("*");
+ next;
+ }
+
+ my $left = @old-nodes.shift // "*"; $left = Nil if $left eq "*";
+ my $right = @old-nodes.shift // "*"; $right = Nil if $right eq "*";
+
+ @new-nodes.push(BinaryNode.new(value => $value.Int,
+ left => $left // Nil,
+ right => $right // Nil));
+ }
+}
+
+my $btree = @new-nodes[0];
+
+my @distance;
+
+traverse2($btree, $node, ());
+
+say @distance.join(" ");
+
+sub traverse2 ($current, $target, @path is copy)
+{
+ @path.push: $current.value;
+
+ if $current.value == $target
+ {
+ say ": Path: { @path.join(" > ") }" if $verbose;
+ @distance.push(@path.elems -1);
+ return unless $all;
+ }
+
+ if ($current.left || $current.right)
+ {
+ traverse2($current.left, $target, @path) if $current.left;
+ traverse2($current.right, $target, @path) if $current.right;
+ }
+}
diff --git a/challenge-129/arne-sommer/raku/ch-2.raku b/challenge-129/arne-sommer/raku/ch-2.raku
new file mode 100755
index 0000000000..b9295535ff
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/ch-2.raku
@@ -0,0 +1,20 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use LinkedList3;
+
+unit sub MAIN (Str $string1 = '1 2 3', Str $string2 = '3 2 1', :z(:$zero), :v(:$verbose));
+
+my $l1 = LinkedList3.from-string($string1, :$zero);
+my $l2 = LinkedList3.from-string($string2, :$zero);
+
+my $l3 = LinkedList3.sum($l1, $l2);
+
+if $verbose
+{
+ say "L1: ", $l1.nice;
+ say "L2: ", $l2.nice;
+ say "L1+L2: ", $l3.nice;
+}
+
+say $l3.nice;
diff --git a/challenge-129/arne-sommer/raku/lib/LinkedList1.rakumod b/challenge-129/arne-sommer/raku/lib/LinkedList1.rakumod
new file mode 100644
index 0000000000..0d29a7bf56
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/lib/LinkedList1.rakumod
@@ -0,0 +1,37 @@
+class LinkedList1
+{
+ has Int $.value;
+ has LinkedList1 $.next is rw;
+
+ method add-elems (@values, :r(:$replace-next))
+ {
+ my $list = self;
+ my $first = @values[0];
+ my $obj = LinkedList1.new(value => $first);
+
+ if $list ~~ LinkedList1:D
+ {
+ unless $replace-next { $list = $list.next while $list.next; }
+ $list.next = $obj;
+ }
+ else
+ {
+ $list = $obj;
+ }
+
+ $obj.add-elems(@values[1 .. *-1]) if @values.elems > 1;
+
+ return $obj;
+ }
+
+ method recursive-value
+ {
+ return flat(self.value, self.next.recursive-value) if self.next;
+ return self.value;
+ }
+
+ method nice (Str $sep = ' => ')
+ {
+ return self.recursive-value.join($sep);
+ }
+}
diff --git a/challenge-129/arne-sommer/raku/lib/LinkedList2.rakumod b/challenge-129/arne-sommer/raku/lib/LinkedList2.rakumod
new file mode 100644
index 0000000000..fd92098b20
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/lib/LinkedList2.rakumod
@@ -0,0 +1,44 @@
+class LinkedList2
+{
+ has Int $.value;
+ has LinkedList2 $.next is rw;
+
+ method add-elems (@values, :r(:$replace-next))
+ {
+ my $list = self;
+ my $first = @values[0];
+ my $obj = LinkedList2.new(value => $first);
+
+ if $list ~~ LinkedList2:D
+ {
+ unless $replace-next { $list = $list.next while $list.next; }
+ $list.next = $obj;
+ }
+ else
+ {
+ $list = $obj;
+ }
+
+ $obj.add-elems(@values[1 .. *-1]) if @values.elems > 1;
+
+ return $obj;
+ }
+
+ method recursive-value
+ {
+ return flat(self.value, self.next.recursive-value) if self.next;
+ return self.value;
+ }
+
+ method nice (Str $sep = ' => ')
+ {
+ return self.recursive-value.join($sep);
+ }
+
+ method sum (LinkedList2 $l1, LinkedList2 $l2)
+ {
+ die "Do not call on an object" if self ~~ LinkedList2:D;
+
+ return LinkedList2.add-elems( ( $l1.nice("") + $l2.nice("") ).comb>>.Int );
+ }
+}
diff --git a/challenge-129/arne-sommer/raku/lib/LinkedList3.rakumod b/challenge-129/arne-sommer/raku/lib/LinkedList3.rakumod
new file mode 100644
index 0000000000..c65add7e8b
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/lib/LinkedList3.rakumod
@@ -0,0 +1,66 @@
+class LinkedList3
+{
+ has Int $.value;
+ has LinkedList3 $.next is rw;
+
+ method from-string ($string, :z(:$zero))
+ {
+ die "Do not call on an object" if self ~~ LinkedList3:D;
+
+ my @values = $string.comb.grep({ /\S/ });
+
+ _validate(@values, :$zero);
+
+ return LinkedList3.add-elems(@values>>.Int, :$zero);
+ }
+
+ method add-elems (@values, :r(:$replace-next), :z(:$zero))
+ {
+ _validate(@values, :$zero);
+
+ my $list = self;
+ my $first = @values[0];
+ my $obj = LinkedList3.new(value => $first);
+
+ if $list ~~ LinkedList3:D
+ {
+ unless $replace-next { $list = $list.next while $list.next; }
+ $list.next = $obj;
+ }
+ else
+ {
+ $list = $obj;
+ }
+
+ $obj.add-elems(@values[1 .. *-1], :$zero) if @values.elems > 1;
+
+ return $obj;
+ }
+
+ method recursive-value
+ {
+ return flat(self.value, self.next.recursive-value) if self.next;
+ return self.value;
+ }
+
+ method nice (Str $sep = ' => ')
+ {
+ return self.recursive-value.join($sep);
+ }
+
+ method sum (LinkedList3 $l1, LinkedList3 $l2)
+ {
+ die "Do not call on an object" if self ~~ LinkedList3:D;
+
+ return LinkedList3.from-string( ( $l1.nice("") + $l2.nice("") ), :zero );
+ }
+
+ sub _validate(@values, :z(:$zero))
+ {
+ $zero
+ ?? ( die "Must be 0..9 only" unless all(@values) ~~ /^<[0..9]>$/ )
+ !! ( die "Must be 1..9 only" unless all(@values) ~~ /^<[1..9]>$/ );
+
+ return True;
+ }
+}
diff --git a/challenge-129/arne-sommer/raku/linked-list-method b/challenge-129/arne-sommer/raku/linked-list-method
new file mode 100755
index 0000000000..c26ac462da
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/linked-list-method
@@ -0,0 +1,40 @@
+#! /usr/bin/env raku
+
+unit sub MAIN ($values = "1 2 3 4", :z($zero));
+
+my @values = $values.words;
+
+$zero
+ ?? ( die "Must be 0..9 only" unless all(@values) ~~ /^<[0..9]>$/ )
+ !! ( die "Must be 1..9 only" unless all(@values) ~~ /^<[1..9]>$/ );
+
+class LinkedList
+{
+ has Int $.value;
+ has LinkedList $.next is rw;
+
+ method add-elems (@values is copy)
+ {
+ my $list = self;
+ my $first = @values.shift;
+ my $obj = LinkedList.new(value => $first);
+
+ ($list ~~ LinkedList:D)
+ ?? ( $list.next = $obj )
+ !! ( $list = $obj );
+
+ $obj.add-elems(@values) if @values.elems;
+
+ return $obj;
+ }
+
+ method recursive-value
+ {
+ return flat(self.value, self.next.recursive-value) if self.next;
+ return self.value;
+ }
+}
+
+my $ll = LinkedList.add-elems(@values>>.Int);
+
+say $ll.recursive-value.join(" -> ");
diff --git a/challenge-129/arne-sommer/raku/linked-list-module b/challenge-129/arne-sommer/raku/linked-list-module
new file mode 100755
index 0000000000..34b4a0a867
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/linked-list-module
@@ -0,0 +1,16 @@
+#! /usr/bin/env raku
+
+use lib "lib";
+use LinkedList;
+
+unit sub MAIN ($values = "1 2 3 4", :z(:$zero));
+
+my @values = $values.words;
+
+$zero
+ ?? ( die "Must be 0..9 only" unless all(@values) ~~ /^<[0..9]>$/ )
+ !! ( die "Must be 1..9 only" unless all(@values) ~~ /^<[1..9]>$/ );
+
+my $ll = LinkedList.add-elems(@values>>.Int);
+
+say $ll.nice;
diff --git a/challenge-129/arne-sommer/raku/linked-list-sub b/challenge-129/arne-sommer/raku/linked-list-sub
new file mode 100755
index 0000000000..7b04262d70
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/linked-list-sub
@@ -0,0 +1,32 @@
+#! /usr/bin/env raku
+
+unit sub MAIN ($values = "1 2 3 4");
+
+my @values = $values.words;
+
+die "Must be 1..9 only" unless all(@values) ~~ /^<[1..9]>$/;
+
+class LinkedList
+{
+ has Int $.value;
+ has LinkedList $.next is rw;
+}
+
+sub create_linked_list (@values is copy)
+{
+ my $value = @values.shift;
+ my $top = LinkedList.new(value => $value);
+ my $current = $top;
+
+ for @values -> $value
+ {
+ $current.next = LinkedList.new(value => $value);
+ $current = $current.next;
+ }
+
+ return $top;
+}
+
+my $ll = create_linked_list(@values>>.Int);
+
+say $ll.raku;
diff --git a/challenge-129/arne-sommer/raku/linked-list-sub2 b/challenge-129/arne-sommer/raku/linked-list-sub2
new file mode 100755
index 0000000000..d39def74d8
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/linked-list-sub2
@@ -0,0 +1,40 @@
+#! /usr/bin/env raku
+
+unit sub MAIN ($values = "1 2 3 4", :z(:$zero));
+
+my @values = $values.words;
+
+$zero
+ ?? ( die "Must be 0..9 only" unless all(@values) ~~ /^<[0..9]>$/ )
+ !! ( die "Must be 1..9 only" unless all(@values) ~~ /^<[1..9]>$/ );
+
+class LinkedList
+{
+ has Int $.value;
+ has LinkedList $.next is rw;
+
+ method recursive-value
+ {
+ return flat(self.value, self.next.recursive-value) if self.next;
+ return self.value;
+ }
+}
+
+sub create_linked_list (@values is copy)
+{
+ my $value = @values.shift;
+ my $top = LinkedList.new(value => $value);
+ my $current = $top;
+
+ for @values -> $value
+ {
+ $current.next = LinkedList.new(value => $value);
+ $current = $current.next;
+ }
+
+ return $top;
+}
+
+my $ll = create_linked_list(@values>>.Int);
+
+say $ll.recursive-value.join(" -> ");
diff --git a/challenge-129/arne-sommer/raku/root-distance b/challenge-129/arne-sommer/raku/root-distance
new file mode 100755
index 0000000000..4aaf7846bc
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/root-distance
@@ -0,0 +1,64 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (Str $tree = "1 | 2 3 | * * * 4 | 5 6", Str $node = '6', :v(:$verbose));
+
+class BinaryNode
+{
+ has Int $.value;
+ has BinaryNode $.left;
+ has BinaryNode $.right;
+}
+
+my @btree = $tree.split("|")>>.words;
+
+my @old-nodes;
+my @new-nodes;
+
+for @btree.reverse -> $row
+{
+ my @current = @$row;
+ @old-nodes = @new-nodes;
+ @new-nodes = ();
+
+ for @current -> $value
+ {
+ if $value eq "*"
+ {
+ @new-nodes.push("*");
+ next;
+ }
+
+ my $left = @old-nodes.shift // "*"; $left = Nil if $left eq "*";
+ my $right = @old-nodes.shift // "*"; $right = Nil if $right eq "*";
+
+ @new-nodes.push(BinaryNode.new(value => $value.Int,
+ left => $left // Nil,
+ right => $right // Nil));
+ }
+}
+
+my $btree = @new-nodes[0];
+
+my $distance = -1;
+
+traverse2($btree, $node, ());
+
+say $distance;
+
+sub traverse2 ($current, $target, @path is copy)
+{
+ @path.push: $current.value;
+
+ if $current.value == $target
+ {
+ say ": Path: { @path.join(" > ") }" if $verbose;
+ $distance = @path.elems -1;
+ return;
+ }
+
+ if ($current.left || $current.right)
+ {
+ traverse2($current.left, $target, @path) if $current.left;
+ traverse2($current.right, $target, @path) if $current.right;
+ }
+}
diff --git a/challenge-129/arne-sommer/raku/root-distance-all b/challenge-129/arne-sommer/raku/root-distance-all
new file mode 100755
index 0000000000..afb2f3b65c
--- /dev/null
+++ b/challenge-129/arne-sommer/raku/root-distance-all
@@ -0,0 +1,64 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (Str $tree = "1 | 2 3 | * * * 4 | 5 6", Str $node = '6', :a(:$all), :v(:$verbose));
+
+class BinaryNode
+{
+ has Int $.value;
+ has BinaryNode $.left;
+ has BinaryNode $.right;
+}
+
+my @btree = $tree.split("|")>>.words;
+
+my @old-nodes;
+my @new-nodes;
+
+for @btree.reverse -> $row
+{
+ my @current = @$row;
+ @old-nodes = @new-nodes;
+ @new-nodes = ();
+
+ for @current -> $value
+ {
+ if $value eq "*"
+ {
+ @new-nodes.push("*");
+ next;
+ }
+
+ my $left = @old-nodes.shift // "*"; $left = Nil if $left eq "*";
+ my $right = @old-nodes.shift // "*"; $right = Nil if $right eq "*";
+
+ @new-nodes.push(BinaryNode.new(value => $value.Int,
+ left => $left // Nil,
+ right => $right // Nil));
+ }
+}
+
+my $btree = @new-nodes[0];
+
+my @distance;
+
+traverse2($btree, $node, ());
+
+say @distance.join(" ");
+
+sub traverse2 ($current, $target, @path is copy)
+{
+ @path.push: $current.value;
+
+ if $current.value == $target
+ {
+ say ": Path: { @path.join(" > ") }" if $verbose;
+ @distance.push(@path.elems -1);
+ return unless $all;
+ }
+
+ if ($current.left || $current.right)
+ {
+ traverse2($current.left, $target, @path) if $current.left;
+ traverse2($current.right, $target, @path) if $current.right;
+ }
+}