1 #!/usr/bin/perl 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-210/#TASK2 3 # 4 # Task 2: Number Collision 5 # ======================== 6 # 7 # You are given an array of integers which can move in right direction if it is 8 # positive and left direction when negative. If two numbers collide then the 9 # smaller one will explode. And if both are same then they both explode. We 10 # take the absolute value in consideration when comparing. 11 # 12 # All numbers move at the same speed, therefore any 2 numbers moving in the 13 # same direction will never collide. 14 # 15 # Write a script to find out who survives the collision. 16 # 17 ## Example 1: 18 ## 19 ## Input: @list = (2, 3, -1) 20 ## Output: (2, 3) 21 ## 22 ## The numbers 3 and -1 collide and -1 explodes in the end. So we are left with (2, 3). 23 # 24 ## Example 2: 25 ## 26 ## Input: @list = (3, 2, -4) 27 ## Output: (-4) 28 ## 29 ## The numbers 2 and -4 collide and 2 explodes in the end. That gives us (3, -4). 30 ## Now the numbers 3 and -4 collide and 3 explodes. Finally we are left with -4. 31 # 32 ## Example 3: 33 ## 34 ## Input: @list = (1, -1) 35 ## Output: () 36 ## 37 ## The numbers 1 and -1 both collide and explode. Nothing left in the end. 38 # 39 ############################################################ 40 ## 41 ## discussion 42 ############################################################ 43 # 44 # Negative numbers at the left and positive numbers at the right of the array 45 # are finished moving. Numbers can only move if a negative number is right of a 46 # positive number. 47 48 use strict; 49 use warnings; 50 51 number_collision(2, 3, -1); 52 number_collision(3, 2, -4); 53 number_collision(1, -1); 54 55 sub number_collision { 56 my @list = @_; 57 print "Input: (" . join(", ", @list) . ")\n"; 58 my @result = explode(@list); 59 print "Output: (" . join(", ", @result) . ")\n"; 60 } 61 62 sub explode { 63 my @list = @_; 64 my @result = (); 65 while(@list && $list[0] < 0) { 66 push @result, shift @list; 67 } 68 my $exploded = 0; 69 foreach my $i (0..$#list-1) { 70 if($list[$i] >= 0 && $list[$i+1] < 0) { 71 if($list[$i] == abs($list[$i+1])) { 72 # both explode 73 $i++; 74 $exploded = 1; 75 next; 76 } elsif ($list[$i] > abs($list[$i+1])) { 77 push @result, $list[$i]; 78 $i++; 79 $exploded = 1; 80 next; 81 } else { 82 push @result, $list[$i+1]; 83 $i++; 84 $exploded = 1; 85 next; 86 } 87 } elsif ($list[$i] == 0 && $list[$i+1] >= 0) { 88 push @result, $list[$i]; 89 next; 90 } elsif ($list[$i] > 0 && $list[$i+1] == 0) { 91 push @result, $list[$i]; 92 $i++; # skip the following 0 93 $exploded = 1; 94 next; 95 } elsif($list[$i] > 0 && $list[$i+1] > 0) { 96 push @result, $list[$i]; 97 if($i == $#list - 1) { 98 push @result, $list[$i+1]; 99 } 100 next; 101 } else { # $list[$i] < 0 102 push @result, $list[$i]; 103 next; 104 } 105 } 106 if($exploded) { 107 return explode(@result); 108 } else { 109 return @result; 110 } 111 } 112