From 58541a2f0aa3b98156e6ca6e6d250524a7e95097 Mon Sep 17 00:00:00 2001 From: Flavio Poletti Date: Fri, 31 Mar 2023 16:16:23 +0200 Subject: Add polettix's solution to challenge-210 --- challenge-210/polettix/blog.txt | 1 + challenge-210/polettix/blog1.txt | 1 + challenge-210/polettix/perl/ch-1.pl | 30 +++++++++++++++++++++++++ challenge-210/polettix/perl/ch-2.pl | 42 +++++++++++++++++++++++++++++++++++ challenge-210/polettix/raku/ch-1.raku | 29 ++++++++++++++++++++++++ challenge-210/polettix/raku/ch-2.raku | 38 +++++++++++++++++++++++++++++++ 6 files changed, 141 insertions(+) create mode 100644 challenge-210/polettix/blog.txt create mode 100644 challenge-210/polettix/blog1.txt create mode 100644 challenge-210/polettix/perl/ch-1.pl create mode 100644 challenge-210/polettix/perl/ch-2.pl create mode 100644 challenge-210/polettix/raku/ch-1.raku create mode 100644 challenge-210/polettix/raku/ch-2.raku diff --git a/challenge-210/polettix/blog.txt b/challenge-210/polettix/blog.txt new file mode 100644 index 0000000000..d01e1098a2 --- /dev/null +++ b/challenge-210/polettix/blog.txt @@ -0,0 +1 @@ +https://etoobusy.polettix.it/2023/03/30/pwc210-kill-and-win/ diff --git a/challenge-210/polettix/blog1.txt b/challenge-210/polettix/blog1.txt new file mode 100644 index 0000000000..d916718554 --- /dev/null +++ b/challenge-210/polettix/blog1.txt @@ -0,0 +1 @@ +https://etoobusy.polettix.it/2023/03/31/pwc210-number-collision/ diff --git a/challenge-210/polettix/perl/ch-1.pl b/challenge-210/polettix/perl/ch-1.pl new file mode 100644 index 0000000000..d024720630 --- /dev/null +++ b/challenge-210/polettix/perl/ch-1.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl +use v5.24; +use warnings; +use experimental 'signatures'; + +say kill_and_win(@ARGV); + +sub kill_and_win (@args) { + my $best_score = 0; + my $score = 0; + my $previous = 0; + my $n_streak = 0; + my $close_streak = sub { + return if $n_streak < 1; # should not happen + $score = $previous if $n_streak == 1; # "singleton" + $best_score = $score if $score > $best_score; + $score = 0; + $n_streak = 0; + }; + + for my $item (sort { $a <=> $b } @args) { + $close_streak->() if $item > $previous + 1; + $n_streak++ if $item > $previous; + $score += $item; + $previous = $item; + } + $close_streak->(); + + return $best_score; +} diff --git a/challenge-210/polettix/perl/ch-2.pl b/challenge-210/polettix/perl/ch-2.pl new file mode 100644 index 0000000000..475feba5a6 --- /dev/null +++ b/challenge-210/polettix/perl/ch-2.pl @@ -0,0 +1,42 @@ +#!/usr/bin/env perl +use v5.24; +use warnings; +use experimental 'signatures'; + +my @nc = number_collision(@ARGV); +{ local $" = ', '; say "(@nc)" } + +sub number_collision (@list) { + my (@pre, @post); # safe items on the left and on the right + + while ('necessary') { + push @pre, shift @list while @list && $list[0] < 0; + unshift @post, pop @list while @list && $list[-1] > 0; + last if scalar(@list) == 0; + + my @mid; + INDEX: + for my $i (0 .. $#list) { + my $item = $list[$i]; + if ($item > 0) { # try to move right + push @mid, $item if $item + $list[$i + 1] > 0; + } + elsif ($item < 0) { # try to move left + push @mid, $item if $item + $list[$i - 1] < 0; + } + else { # try to stay put + my $safe_left = ($i == 0) || ($list[$i - 1] <= 0); + my $safe_right = ($i == $#list) || ($list[$i + 1] >= 0); + push @mid, 0 if $safe_left && $safe_right; + } + } + + # stop simulation if nothing changed in this pass + last if scalar(@list) == scalar(@mid); + + # go to next iteration with surviving items in the middle + @list = @mid; + } + + return (@pre, @list, @post) +} diff --git a/challenge-210/polettix/raku/ch-1.raku b/challenge-210/polettix/raku/ch-1.raku new file mode 100644 index 0000000000..8b8e3ad975 --- /dev/null +++ b/challenge-210/polettix/raku/ch-1.raku @@ -0,0 +1,29 @@ +#!/usr/bin/env raku +use v6; +sub MAIN (*@args) { put kill-and-win(@args) } + +sub kill-and-win-basic (@args) { return @args.sum } + +sub kill-and-win (@args) { + my $best-score = 0; + my $score = 0; + my $previous = 0; + my $n-streak = 0; + sub close-streak { + return if $n-streak < 1; + $score = $previous if $n-streak == 1; # "singleton" + $best-score = $score if $score > $best-score; + $score = 0; + $n-streak = 0; + } + + for @args.sort({$^a <=> $^b}) -> $item { + close-streak() if $item > $previous + 1; + $n-streak++ if $item > $previous; + $score += $item; + $previous = $item; + } + close-streak(); + + return $best-score; +} diff --git a/challenge-210/polettix/raku/ch-2.raku b/challenge-210/polettix/raku/ch-2.raku new file mode 100644 index 0000000000..7125640fda --- /dev/null +++ b/challenge-210/polettix/raku/ch-2.raku @@ -0,0 +1,38 @@ +#!/usr/bin/env raku +use v6; +sub MAIN (*@args) { put '(', number-collision(@args).join(', '), ')' } + +sub number-collision (@list is copy) { + my (@pre, @post); # safe items on the left and on the right + + loop { + @pre.push: @list.shift while @list && @list[0] < 0; + @post.unshift: @list.pop while @list && @list[*-1] > 0; + last if @list == 0; + + my @mid; + INDEX: + for ^@list -> $i { + my $item = @list[$i]; + if $item > 0 { # try to move right + @mid.push: $item if $item + @list[$i + 1] > 0; + } + elsif $item < 0 { # try to move left + @mid.push: $item if $item + @list[$i - 1] < 0; + } + else { # try to stay put + my $safe-left = ($i == 0) || (@list[$i - 1] <= 0); + my $safe-right = ($i == @list.end) || (@list[$i + 1] >= 0); + @mid.push: 0 if $safe-left && $safe-right; + } + } + + # stop simulation if nothing changed in this pass + last if @list.elems == @mid.elems; + + # go to next iteration with surviving items in the middle + @list = @mid; + } + + return (@pre, @list, @post).flat.Array; +} -- cgit