aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-241/ianrifkin/perl/ch-1.pl37
-rw-r--r--challenge-241/ianrifkin/perl/ch-2.pl142
2 files changed, 179 insertions, 0 deletions
diff --git a/challenge-241/ianrifkin/perl/ch-1.pl b/challenge-241/ianrifkin/perl/ch-1.pl
new file mode 100644
index 0000000000..2fdc858d18
--- /dev/null
+++ b/challenge-241/ianrifkin/perl/ch-1.pl
@@ -0,0 +1,37 @@
+use v5.30.3;
+use warnings;
+use strict;
+
+# Task 1: Arithmetic Triplets
+# You are given an array (3 or more members) of integers in increasing order and a positive integer.
+# Write a script to find out the number of unique Arithmetic Triplets satisfying the following rules:
+# a) i < j < k
+# b) nums[j] - nums[i] == diff
+# c) nums[k] - nums[j] == diff
+
+# Example 1
+my @nums = (0, 1, 4, 6, 7, 10);
+my $diff = 3;
+find_triplets($diff, \@nums);
+
+# Example 2
+@nums = (4, 5, 6, 7, 8, 9);
+$diff = 2;
+find_triplets($diff, \@nums);
+
+sub find_triplets {
+ my ($diff, $nums) = @_;
+ my $nums_length = scalar @{$nums};
+ my $total_finds = 0;
+ for (my $i = 0; $i < $nums_length - 2; $i++) {
+ for (my $j = $i + 1; $j < $nums_length - 1; $j++) {
+ for (my $k = $j + 1; $k < $nums_length; $k++) {
+ if (@{$nums}[$j] - @{$nums}[$i] eq $diff && @{$nums}[$k] - @{$nums}[$j] eq $diff) {
+ $total_finds++;
+ }
+ }
+ }
+ }
+ print "$total_finds\n";
+}
+
diff --git a/challenge-241/ianrifkin/perl/ch-2.pl b/challenge-241/ianrifkin/perl/ch-2.pl
new file mode 100644
index 0000000000..95e484fb96
--- /dev/null
+++ b/challenge-241/ianrifkin/perl/ch-2.pl
@@ -0,0 +1,142 @@
+use v5.30.3;
+use warnings;
+use strict;
+use Getopt::Long;
+use Pod::Usage;
+
+#accept cmd line input
+my $man = 0;
+my $help = 0;
+my $str_input;
+GetOptions ('help|?' => \$help, man => \$man,
+ "int_input=s" => \$str_input)
+ or pod2usage(2);
+
+pod2usage(1) if $help;
+pod2usage(-exitstatus => 0, -verbose => 2) if $man;
+
+# Prepare input array
+my @int_input;
+# if values provided at cmd line split on comma
+if ( $str_input ) {
+ @int_input = (split(/,/, $str_input) );
+}
+# else set default values from example if no cmd line input
+else {
+ @int_input = (11, 8, 27, 4) unless @int_input;
+}
+
+# run the program
+prime_order(\@int_input);
+
+
+sub prime_order {
+ my ($int_input) = @_;
+
+ my %results;
+ # Let's calcuate how many prime factors of each input number
+ foreach (@{$int_input}) {
+ my $num = $_;
+ $num =~ s/^\s+//; #remove whitespace is provided at cmd line just for prettiness
+
+ die("Invalid input") if $num <= 2; #This shouldn't happen based on task instructions
+
+ #Every number will have at least one prime (self)
+ $results{$num} = 1;
+
+ # Find the first prime factor (or self if it is prime)
+ my $find_prime = prime_finder($num);
+
+ next unless $find_prime; # go to next num if no prime found (e.g. input is 3)
+
+ next if ($find_prime == $num); # go to next $num in loop if input number was prime
+
+ # since input num was not prime, increment for smallest factor
+ # then we will loop below to find the other factors
+ $results{$num}++;
+
+ # Calc all remaining prime factors
+ my $smallest = $num / $find_prime; #the smallest prime so loop knows when to stop
+ while ($find_prime > $smallest) {
+ my $new_find_prime = prime_finder($find_prime); #calc next prime
+ last unless $new_find_prime; #exit loop if no prime found
+ last if $find_prime == $new_find_prime; #exit loop if prime found is same
+ $results{$num}++; #incr. if prime found
+ $find_prime = $new_find_prime; #start next loop or exit loop
+ }
+
+ next; #expclitly showing that we're going to next $num (just for clarity)
+ }
+
+ # Now we need to prepare the ouptut
+ # Create a sorted array from the results hash
+ my @sorted_output;
+ # This should should by the count first ($results{$a} <=> $results{$b}) then the input numbers ($b cmp $a)
+ foreach my $ordered_num (sort { $results{$a} <=> $results{$b} or $a <=> $b } keys %results) {
+ push(@sorted_output, $ordered_num);
+ }
+
+ # Finally, print the sorted output
+ say "(" . join(", ", @sorted_output) . ")";
+}
+
+# This subroutine outputs a prime number from the provided input $num
+sub prime_finder {
+ my ($num) = @_;
+ my $num_was_prime;
+ for (my $i = 2; $i <= sqrt($num); $i++) {
+ if ($num % $i == 0) {
+ return $num / $i;
+ $num_was_prime = 0;
+ last;
+ }
+ else {
+ $num_was_prime = 1;
+ }
+
+ }
+ return $num if $num_was_prime;
+}
+
+
+__END__
+
+=head1 Challenge 241, Task 2, by IanRifkin: Prime Order
+
+See https://theweeklychallenge.org/blog/perl-weekly-challenge-241/#TASK2 for more information on this challenge
+
+=head1 SYNOPSIS
+
+perl ./ch-2.pl [options]
+
+=head1 OPTIONS
+
+=over 8
+
+=item B<-help>
+
+Print a brief help message and exits.
+
+=item B<-man>
+
+Prints the manual page and exits.
+
+=item B<-int_input>
+
+An optional comma separated list of numbers (else defaults to values from example 1)
+
+=back
+
+=head1 DESCRIPTION
+
+Task 2 in Challenge 241 states:
+
+ - You are given an array of unique positive integers greater than 2.
+
+ - Write a script to sort them in ascending order of the count of their prime factors, tie-breaking by ascending value.
+
+This program accepts an optional comma separated list of numbers else defaults to the provided numbers from example 1.
+
+Note: There is an assumption that "tie-breaking by ascending value" means the value of the input number (vs. the value of their prime factor)
+
+=cut