In this article, we will address two engaging tasks from the Perl Weekly Challenge #290: checking for double existence in an array and implementing Luhn's Algorithm for validation. We'll implement solutions in both Perl and Go.
The first task involves finding if there exist two indices $i and $j such that:
1. $i != $j 2. 0 <= ($i, $j) < scalar @ints 3. $ints[i] = 2 * $ints[j]
Input: An array of integers, @ints.
Output: true if the condition is met; otherwise, false.
Examples:
Input: @ints = (6, 2, 3, 3) Output: true For $i = 0, $j = 2 $ints[$i] = 6 => 2 * 3 => 2 * $ints[$j]
Input: @ints = (3, 1, 4, 13) Output: false
Input: @ints = (2, 1, 4, 2) Output: true For $i = 2, $j = 3 $ints[$i] = 4 => 2 * 2 => 2 * $ints[$j]
Perl Implementation
In the Perl implementation, we use a hash to track seen integers and check if either half or double of the current number exists in the hash.
sub double_exist { my %seen; foreach my $num (@_) { return 1 if exists $seen{$num / 2} || exists $seen{$num * 2}; $seen{$num} = 1; } return 0; }
Go Implementation
The Go implementation follows a similar logic, using a map to keep track of unique integers.
func doubleExist(ints []int) bool { seen := make(map[int]bool) for _, num := range ints { if (num%2 == 0 && seen[num/2]) || seen[num*2] { return true } seen[num] = true } return false }
The second task involves implementing Luhn's Algorithm to validate a string of digits, ignoring non-digit characters. The last digit is considered separately as the payload.
You are given a string str containing digits (and possibly other characters which can be ignored). The last digit is considered as the payload and handled separately.
Return true if the payload equals the correct check digit; otherwise, return false.
Examples:
Input: "17893729974" Output: true Payload is 4. Digits from the right: 7 * 2 = 14, sum = 5 9 = 9 9 * 2 = 18, sum = 9 2 = 2 7 * 2 = 14, sum = 5 3 = 3 9 * 2 = 18, sum = 9 8 = 8 7 * 2 = 14, sum = 5 1 = 1 Sum of all values = 56, so 4 must be added to bring the total mod 10 to zero. The payload is indeed 4.
Input: "4137 8947 1175 5904" Output: true
Input: "4137 8974 1175 5904" Output: false
Perl Implementation
The Perl implementation processes the input string to ignore non-digit characters, then applies Luhn's algorithm to validate the number.
sub luhn_check { my ($str) = @_; $str =~ s/[^0-9]//g; my $payload = substr($str, -1); my $sum = 0; my $length = length($str); for (my $i = 0; $i < $length - 1; $i++) { my $digit = substr($str, $length - 2 - $i, 1); if ($i % 2 == 0) { $digit *= 2; $digit -= 9 if $digit > 9; } $sum += $digit; } my $check_digit = (10 - ($sum % 10)) % 10; return $payload == $check_digit ? 1 : 0; }
Go Implementation
The Go version implements the same logic, utilizing the unicode package to filter out non-digit characters.
func luhnCheck(str string) bool { sum := 0 payload := 0 digits := []int{} for _, char := range str { if unicode.IsDigit(char) { digit := int(char - '0') digits = append(digits, digit) } } if len(digits) == 0 { return false } payload = digits[len(digits)-1] for i := 0; i < len(digits)-1; i++ { digit := digits[i] if (len(digits)-2-i)%2 == 0 { digit *= 2 if digit > 9 { digit -= 9 } } sum += digit } checkDigit := (10 - (sum % 10)) % 10 return payload == checkDigit }
In this article, we explored two interesting programming challenges: finding double existence in an array and implementing Luhn's Algorithm for validation. These tasks highlight how different programming languages can tackle similar problems with their own unique approaches. I hope these examples inspire you to delve deeper into both Perl and Go!
You can find the complete code, including tests, on GitHub.
The above is the detailed content of Finding Double Existence and Applying Luhns Algorithm. For more information, please follow other related articles on the PHP Chinese website!