From 09354a370b75d7fc91c86d6b40b94866f9797569 Mon Sep 17 00:00:00 2001 From: Simon Proctor Date: Wed, 15 Apr 2020 14:15:05 +0100 Subject: A bit OTT and it doen't pretty print but it's kinda cool and does the job --- challenge-056/simon-proctor/raku/ch-2.p6 | 130 +++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 challenge-056/simon-proctor/raku/ch-2.p6 diff --git a/challenge-056/simon-proctor/raku/ch-2.p6 b/challenge-056/simon-proctor/raku/ch-2.p6 new file mode 100644 index 0000000000..29475428b1 --- /dev/null +++ b/challenge-056/simon-proctor/raku/ch-2.p6 @@ -0,0 +1,130 @@ +#!/usr/bin/env raku + +use v6; + +# BTree as string nodevalue[child1,child2] +# Example tree 5(4(11(7)(2)))(8(13)(9(1))) + +grammar BTreeGrammar { + token TOP { }; + token tree { ["(" $= ")"]? ["(" $= ")"]? }; + regex value { <-[()]>+ } +} + +role BTree[::T] { + has T $.value is required; + has BTree[T] $.left; + has BTree[T] $.right; + + method Str( ) { + $!value ~ ( $!left ?? "({$!left.Str()})" !! "" ) ~ ( $!right ?? "({$!right.Str()})" !! "" ); + } + + method gist() { + self.Str(); + } + + method traverse() { + gather { + if $!left { + for $!left.traverse -> @t { + take ($!value, |@t); + } + } + if $!right { + for $!right.traverse -> @t { + take ($!value, |@t); + } + } + if ! $!left && ! $!right { + take ( $!value, ); + } + } + } + + multi method from-Str('') { } + + multi method from-Str( ::?CLASS:U: Str $in ) { + my $match = BTreeGrammar.parse( $in ); + if ( $match ) { + self.new( + value => $match.Str, + left => self.from-Str( $match ?? $match.Str !! '' ), + right => self.from-Str( $match ?? $match.Str !! '' ) + ); + } else { + die "Unable to Parse $in"; + } + + } +} + +class UBTree does BTree[UInt] { + submethod BUILD ( :$value, :$left = UBTree, :$right = UBTree ) { + $!value = $value.UInt(); + $!left = $left; + $!right = $right; + } +} + +#| Display the example Tree in Str and gist representations +#| also displays all traversals +multi sub MAIN ( 'example' ) { + my $example = example-tree; + say $example; + UBTree.from-Str( $example.Str ).say; + + for $example.traverse -> @row { + @row.join("->").say + } +} + +#| Traverses the example tree and prints any routes that add up to the target. +multi sub MAIN ( UInt $target, 'example' ) { + my $example = example-tree; + + for $example.traverse -> @row { + @row.join("->").say if ( [+] @row ) == $target; + } +} + +#| Given a target number and a tree string find all the traversals that add up to is +#| Note the Tree string is in the format "number (left tree) (right tree)" spaces are optional +multi sub MAIN ( UInt $target, *@rest ) { + my $tree = UBTree.from-Str( @rest.join("") ); + + for $tree.traverse -> @row { + @row.join("->").say if ( [+] @row ) == $target; + } +} + + +sub example-tree() { + return UBTree.new( + value => 5, + left => UBTree.new( + value => 4, + left => UBTree.new( + value => 11, + left => UBTree.new( + value => 7, + ), + right => UBTree.new( + value => 2, + ) + ) + ), + right => UBTree.new( + value => 8, + left => UBTree.new( + value => 13, + ), + right => UBTree.new( + value => 9, + right => UBTree.new( + value => 1 + ) + ) + ) + ); +} -- cgit