Skip to content

Instantly share code, notes, and snippets.

@adamcrussell
Created August 11, 2019 15:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamcrussell/d220c9f02d7a65607fdd6beb88c3f2ce to your computer and use it in GitHub Desktop.
Save adamcrussell/d220c9f02d7a65607fdd6beb88c3f2ce to your computer and use it in GitHub Desktop.
Perl Weekly Challenge 020
use strict;
use warnings;
##
# Write a script to accept a string from command line and split it on change of character.
##
my $string = $ARGV[0];
my @letters = split(//, $string);
my $letter;
my $letter_previous = shift @letters;
do{
$letter = shift @letters;
print $letter_previous if($letter eq $letter_previous);
print "$letter_previous\n" if($letter ne $letter_previous);
$letter_previous = $letter;
}while(@letters);
print $letter_previous if($letter eq $letter_previous);
print "$letter_previous\n" if($letter ne $letter_previous);
print "\n";
##
# Write a script to accept a string from command line and split it on change of character.
##
my $string = @*ARGS[0];
my @letters = split(/""/, $string);
my $letter;
@letters.shift();
my $letter_previous = @letters.shift();
repeat {
$letter = @letters.shift();
print $letter_previous if ($letter eq $letter_previous);
print "$letter_previous\n" if ($letter ne $letter_previous);
$letter_previous = $letter;
}while (@letters);
print $letter_previous if ($letter eq $letter_previous);
print "$letter_previous\n" if ($letter ne $letter_previous);
use strict;
use warnings;
##
# Write a script to print the smallest pair of Amicable Numbers.
##
use boolean;
use Thread;
use constant RANGE_SIZE => 50;
use constant THREAD_COUNT => 4;
sub factor_sum{
my(@numbers) = @_;
my %number_sof;
foreach my $n (@numbers){
my @factors = (1);
foreach my $j (2..sqrt($n)){
push @factors, $j if $n % $j == 0;
push @factors, ($n / $j) if $n % $j == 0 && $j ** 2 != $n;
}
$number_sof{$n}=unpack("%32C*", pack("C*", @factors));
}
return \%number_sof;
}
MAIN:{
my %number_sof;
my @threads;
my $range_start = 1;
my $range_end = RANGE_SIZE;
my $found = false;
do{
for(0 .. (THREAD_COUNT - 1)){
my $t = Thread->new(\&factor_sum, ($range_start .. $range_end));
push @threads, $t;
$range_start = $range_end + 1;
$range_end = $range_start + RANGE_SIZE;
}
foreach my $t (@threads){
my $sof = $t->join();
@number_sof{keys %{$sof}} = values %{$sof};
foreach my $k (values %{$sof}){
if($number_sof{$k}){
if($number_sof{$number_sof{$k}} &&
$number_sof{$number_sof{$k}} == $k &&
$number_sof{$k} != $k && !$found){
print "First amicable pair of numbers: $k " . $number_sof{$k} . " \n";
$found = true;
}
}
}
}
@threads = ();
}while(!$found);
}
##
# Write a script to print the smallest pair of Amicable Numbers.
##
constant RANGE_SIZE = 50;
sub factor-sum(@numbers){
my %number_sof;
for @numbers -> $n {
my @factors = (1);
for (2 .. sqrt($n)) -> $j {
@factors.push($j) if $n %% $j;
@factors.push($n / $j) if $n %% $j && $j ** 2 != $n;
}
my $sum = [+] @factors;
%number_sof{$n} = $sum;
}
return %number_sof;
}
my $range_start = 1;
my $range_end = RANGE_SIZE;
my $found = Bool::False;
my %number_sof;
my @promises;
while (!$found) {
@promises = ();
for (0 .. 3) {
@promises.push(Promise.start( {
factor-sum($range_start .. $range_end);
}));
$range_start = $range_end + 1;
$range_end = $range_start + RANGE_SIZE;
}
await(|@promises);
for @promises -> $p {
%number_sof{ keys $p.result} = values $p.result;
for (values $p.result) -> $k {
if (%number_sof{$k}) {
if (%number_sof{%number_sof{$k}} &&
%number_sof{%number_sof{$k}} == $k &&
%number_sof{$k} != $k && !$found) {
say "First amicable pair of numbers: $k " ~ %number_sof{$k};
$found = Bool::True;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment