aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-210/bob-lied/perl/ch-2.pl84
1 files changed, 84 insertions, 0 deletions
diff --git a/challenge-210/bob-lied/perl/ch-2.pl b/challenge-210/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..e24099670d
--- /dev/null
+++ b/challenge-210/bob-lied/perl/ch-2.pl
@@ -0,0 +1,84 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge 210 Task 2 Number Collision
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# You are given an array of integers which can move in right direction if it
+# is positive and left direction when negative. If two numbers collide then
+# the smaller one will explode. And if both are same then they both explode.
+# We take the absolute value in consideration when comparing.
+# All numbers move at the same speed, therefore any 2 numbers moving in the
+# same direction will never collide.
+# Write a script to find out who survives the collision.
+# Example 1: Input: @list = (2, 3, -1) Output: (2, 3)
+# The numbers 3 and -1 collide and -1 explodes in the end.
+# So we are left with (2, 3).
+# Only positive numbers are left, so no more collisions will happen.
+# Example 2: Input: @list = (3, 2, -4) Output: (-4)
+# The numbers 2 and -4 collide and 2 explodes in the end.
+# That gives us (3, -4).
+# Now the numbers 3 and -4 collide and 3 explodes.
+# Finally we are left with -4.
+# Example 3: Input: @list = (1, -1) Output: ()
+# The numbers 1 and -1 both collide and explode. Nothing left in the end.
+#=============================================================================
+
+use v5.36;
+
+use builtin qw/true false/; no warnings "experimental::builtin";
+
+use Getopt::Long;
+my $Verbose = 0;
+my $DoTest = 0;
+
+GetOptions("test" => \$DoTest, "verbose" => \$Verbose);
+exit(!runTest()) if $DoTest;
+
+say "(", join(',', numberCollision(@ARGV)->@*), ")";
+
+sub numberCollision(@list)
+{
+ my $collision = true;
+ while ( $collision )
+ {
+ $collision = false;
+ for ( my $i = 0 ; $i < $#list ; $i++ )
+ {
+ my ($left, $right) = @list[$i, $i+1];
+ next unless ( $left >= 0 && $right < 0 );
+
+ $collision = true;
+ if ( abs($left) == abs($right) )
+ {
+ # Both explode
+ splice(@list, $i, 2);
+ }
+ else
+ {
+ my $keep = ( abs($left) > abs($right) ? $left : $right );
+ # Replace the pair with the larger one
+ splice(@list, $i, 2, $keep);
+ }
+ }
+ }
+ return [ @list ];
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( numberCollision(2,3,-1), [2,3], "Example 1");
+ is( numberCollision(3,2,-4), [ -4], "Example 2");
+ is( numberCollision(1, -1), [ ], "Example 3");
+
+ is( numberCollision(1 ), [ 1 ], "Singleton");
+ is( numberCollision(1,2,3 ), [ 1,2,3 ], "No collision positive");
+ is( numberCollision(-1,-2,-3 ), [ -1,-2,-3 ], "No collision negative");
+ is( numberCollision(-1,-2,3,4 ), [ -1,-2,3,4 ], "No collision");
+
+ done_testing;
+}
+