aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-027/markus-holzer/README5
-rw-r--r--challenge-027/markus-holzer/perl6/ch-1.pl627
-rw-r--r--challenge-027/markus-holzer/perl6/ch-2.pl69
-rw-r--r--challenge-027/markus-holzer/perl6/lib/Scalar/History.pm693
4 files changed, 134 insertions, 0 deletions
diff --git a/challenge-027/markus-holzer/README b/challenge-027/markus-holzer/README
index 64aaa503e7..2000655be2 100644
--- a/challenge-027/markus-holzer/README
+++ b/challenge-027/markus-holzer/README
@@ -1 +1,6 @@
Solutions by Markus Holzer.
+
+Solution #2 only works on the current developer branch and uses a module I wrote
+Please see https://github.com/holli-holzer/perl6-Scalar-History
+To be on CPAN soon
+
diff --git a/challenge-027/markus-holzer/perl6/ch-1.pl6 b/challenge-027/markus-holzer/perl6/ch-1.pl6
new file mode 100644
index 0000000000..4c7e3b5448
--- /dev/null
+++ b/challenge-027/markus-holzer/perl6/ch-1.pl6
@@ -0,0 +1,27 @@
+multi sub MAIN( Int:D $x1, Int:D $y1, Int:D $x2, Int:D $y2, Int:D $x3, Int:D $y3, Int:D $x4, Int:D $y4 )
+{
+ with intersection( $x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4 ) -> ($x, $y)
+ {
+ say "The intersection is at $x, $y.";
+ }
+ else
+ {
+ say .exception.message;
+ }
+}
+
+
+sub intersection( Int \x1, Int \y1, Int \x2, Int \y2, Int \x3, Int \y3, Int \x4, Int \y4 )
+{
+ CATCH { default { fail "Lines are parallel or identical" } }
+
+ return (
+ eager # potential for division by zero,
+ ( (x1 * y2 - y1 * x2 ) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3*x4) ) div
+ ( (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) ),
+
+ eager # without eager, laziness will bite us later
+ ( (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 -y2) * (x3*y4 - y3 * x4) ) div
+ ( (x1 - x2) * (y3 - y4) - (y1 - y2) * (x2 - x4) )
+ );
+}
diff --git a/challenge-027/markus-holzer/perl6/ch-2.pl6 b/challenge-027/markus-holzer/perl6/ch-2.pl6
new file mode 100644
index 0000000000..d3bea23017
--- /dev/null
+++ b/challenge-027/markus-holzer/perl6/ch-2.pl6
@@ -0,0 +1,9 @@
+use Test;
+use Scalar::History; # See the README
+
+my Int $x := Scalar::History.create(10, Int);
+$x = 20;
+$x -= 5;
+
+ok( $x == 15 );
+is-deeply( $x.VAR.get-history, (10, 20) ); \ No newline at end of file
diff --git a/challenge-027/markus-holzer/perl6/lib/Scalar/History.pm6 b/challenge-027/markus-holzer/perl6/lib/Scalar/History.pm6
new file mode 100644
index 0000000000..13c8346424
--- /dev/null
+++ b/challenge-027/markus-holzer/perl6/lib/Scalar/History.pm6
@@ -0,0 +1,93 @@
+use Test;
+
+my $minumum-version = Version.new('2019.07.1.357.gd.00674.b.31');
+
+die "Scalar::History requires $minumum-version or later"
+ if ( $*PERL.compiler.version cmp $minumum-version ) == Less;
+
+class Scalar::History::Proxy is Proxy
+{
+ has @!history;
+ has $!position;
+
+ # This is needed for now since the standard ways
+ # like assigning in the `has` statement, TWEAK
+ # and BUILD don't work with `Proxy`
+
+ method new( :&FETCH!, :&STORE!, *%_ ) is raw
+ {
+ my $self := self.Proxy::new( :&FETCH, :&STORE );
+ $self.VAR.TWEAK( |%_ );
+ $self
+ }
+
+ method TWEAK( :$!position = 0 ) {
+ # yadayada
+ }
+
+ method current-value( \SELF: )
+ {
+ @!history[ $!position ]
+ }
+
+ method latest-value( \SELF: )
+ {
+ @!history[ *-1 ]
+ }
+
+ method get-history( \SELF: Bool :$all = False )
+ {
+ my $to-index = $all ?? @!history.elems - 1 !! $!position;
+ @!history[ ^$to-index ]
+ }
+
+ method reset-history( \SELF: )
+ {
+ @!history = ();
+ $!position = 0;
+ }
+
+ method forward-history( \SELF: $steps )
+ {
+ $!position = $!position + $steps;
+ $!position = @!history.elems - 1
+ if $!position >= @!history.elems;
+ $!position;
+ }
+
+ method rewind-history( \SELF: $steps )
+ {
+ $!position = $!position - $steps;
+ $!position = 0
+ if $!position < 0;
+ $!position;
+ }
+
+ method store-value( \SELF: $new-value, $register-duplicates )
+ {
+ # Forget stuff after rewind
+ if @!history.elems > $!position + 1
+ {
+ @!history.splice( $!position + 1 );
+ }
+
+ if !($new-value eqv SELF.current-value) || $register-duplicates
+ {
+ @!history.push( $new-value );
+ $!position = @!history.elems - 1;
+ }
+ }
+}
+
+class Scalar::History
+{
+ method create( $value, ::T $type = Any, Bool :$register-duplicates = False )
+ {
+ return-rw Scalar::History::Proxy.new(
+ FETCH => method ( \SELF: ) {
+ SELF.current-value() },
+ STORE => method ( \SELF: T $new-value ) {
+ SELF.store-value( $new-value, $register-duplicates ); }
+ ) = $value;
+ }
+} \ No newline at end of file