perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 344 - Task 1: Array Form Compute

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-344/#TASK1
 3 #
 4 # Task 1: Array Form Compute
 5 # ==========================
 6 #
 7 # You are given an array of integers, @ints and an integer, $x.
 8 #
 9 # Write a script to add $x to the integer in the array-form.
10 #
11 ###   The array form of an integer is a digit-by-digit representation stored as
12 ###   an array, where the most significant digit is at the 0th index.
13 #
14 ## Example 1
15 ##
16 ## Input: @ints = (1, 2, 3, 4), $x = 12
17 ## Output: (1, 2, 4, 6)
18 #
19 #
20 ## Example 2
21 ##
22 ## Input: @ints = (2, 7, 4), $x = 181
23 ## Output: (4, 5, 5)
24 #
25 #
26 ## Example 3
27 ##
28 ## Input: @ints = (9, 9, 9), $x = 1
29 ## Output: (1, 0, 0, 0)
30 #
31 #
32 ## Example 4
33 ##
34 ## Input: @ints = (1, 0, 0, 0, 0), $x = 9999
35 ## Output: (1, 9, 9, 9, 9)
36 #
37 #
38 ## Example 5
39 ##
40 ## Input: @ints = (0), $x = 1000
41 ## Output: (1, 0, 0, 0)
42 #
43 ############################################################
44 ##
45 ## discussion
46 ##
47 ############################################################
48 #
49 # We need to add from the end of the array, so we just reverse
50 # the array and the array we get out of splitting $x into digits.
51 # Then we add the current digits from both reverse arrays, plus any
52 # carry over that we get from the previous digits. We keep the last
53 # digit for our result array, and if there is a second digit, we keep
54 # it as our new carry over. In the end, if there is a carry over, but
55 # no more digits, we need to add this carry over to the result.
56 
57 use v5.36;
58 
59 array_form_compute([1, 2, 3, 4], 12);
60 array_form_compute([2, 7, 4], 181);
61 array_form_compute([9, 9, 9], 1);
62 array_form_compute([1, 0, 0, 0, 0], 9999);
63 array_form_compute([0], 1000);
64 
65 sub array_form_compute($ints, $x) {
66     say "Input: (" . join(", ", @$ints) . "), $x";
67     my @rev_ints = reverse @$ints;
68     my @rev_x = reverse split //, $x;
69     my $carry = 0;
70     my @result = ();
71     while(@rev_ints or @rev_x) {
72         my $tmp = $carry;
73         $tmp += shift @rev_ints if @rev_ints;
74         $tmp += shift @rev_x if @rev_x;
75         if($tmp > 9) {
76             $carry = int($tmp / 10);
77         } else {
78             $carry = 0;
79         }
80         unshift @result, $tmp % 10;
81     }
82     unshift @result, $carry if $carry;
83     say "Output: (" . join(", ", @result) . ")";
84 }