diff options
| author | Simon Green <mail@simon.green> | 2020-07-20 15:05:03 +1000 |
|---|---|---|
| committer | Simon Green <mail@simon.green> | 2020-07-20 15:05:03 +1000 |
| commit | 8cef174a65b89e1e2a3d844cea7d7b51abe123a1 (patch) | |
| tree | 65d24f7a4d8521715b3682e91dc4f740eff01ca5 /challenge-070/sgreen | |
| parent | 18a47cdd093ec8335cc7faa919f2f63c20e31ac3 (diff) | |
| download | perlweeklychallenge-club-8cef174a65b89e1e2a3d844cea7d7b51abe123a1.tar.gz perlweeklychallenge-club-8cef174a65b89e1e2a3d844cea7d7b51abe123a1.tar.bz2 perlweeklychallenge-club-8cef174a65b89e1e2a3d844cea7d7b51abe123a1.zip | |
PWC 070 by Simon Green
Diffstat (limited to 'challenge-070/sgreen')
| -rw-r--r-- | challenge-070/sgreen/README.md | 45 | ||||
| -rw-r--r-- | challenge-070/sgreen/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-070/sgreen/perl/ch-1.pl | 28 | ||||
| -rwxr-xr-x | challenge-070/sgreen/perl/ch-2.pl | 26 |
4 files changed, 71 insertions, 29 deletions
diff --git a/challenge-070/sgreen/README.md b/challenge-070/sgreen/README.md index a4a45d0687..0f43e97b94 100644 --- a/challenge-070/sgreen/README.md +++ b/challenge-070/sgreen/README.md @@ -1,40 +1,27 @@ -Solution by Simon Green -# Perl Weekly Challenge 069 +# Perl Weekly Challenge 070 -## TASK #1 › Strobogrammatic Number +Solution by Simon Green. -This is a lot harder than it looks. My first thought is to just do a foreach loop between `$a` and `$b` and add it to the list if the number is strobogrammatic. However when I ran + +## TASK #1 › Character Swapping - perl -E '$b = 0; foreach my $a (0 .. 10**10) { $b++ } say $b;' +For this I used the fact that `($a, $b) = ($b, a)` does what it should. Therefore it was a simple exercise of doing this for `$C` times, and then display the output. -on my PC, that took nearly 3 minutes. With $b being up to 10<sup>15</sup> this was not a feasible approach. Even if I only had all the numbers between 1 and 10<sup>15</sup> containing only the digits 0, 6, 8, 9 that was still going to be in the billions. +The task states that `$C + $O <= $O`. This however is not possible. When `$C + $O = $N`, you will get a `substr outside of string` error. For this reason, I've only allowed `$C + $O < $N` to be valid. -So I took a different approach. I calculated the first half of all valid numbers, and then generated the second half. The logic is pretty simple. The first digit must be 6, 8 or 9 (as 0 isn't valid as a first digit). If the number of digits is odd, the middle number can only be 0 or 8. +### Example -Taking this approach, I can generate all 49,150 strobogrammatic numbers between 1 and 10<sup>15</sup> in less than half a second. + » ./ch-1.pl perlandraku 3 4 + pndraerlaku -### Examples - » ./ch-1.pl 50 100 - 69 88 96 + » perl/ch-1.pl helloworld 8 1 + hlloworlde - » ./ch-1.pl 50 900 - 69 88 96 609 689 808 888 +## TASK 2 › Gray Code Sequence -## TASK #2 › 0/1 String +Not really much to say about this task, as it is string forward. Given that `$N` can not be greater than five, I simply stored the array in memory. Even at 24 bits, it will run without any issues. -After the first task, these seemed a lot easier. But it wasn't entirely straight forward. I thought I had a bug in my code when it was spewing out digits on my screen. It turns out that is expected. The length of a number is twice the length of a previous number plus one. This meant the expected length was: +## Example - 1st 1 - 2nd 3 - 3rd 7 - 4th 15 - 5th 31 - 10th 1,023 - 15th 32,767 - 20th 1,048,575 - 25th 33,554,431 - 30th 1,073,741,823 - -No wonder the task was changed from 1,000 iterations to 30! It goes without saying I'm not posting an example here, as the final line is 1,073,741,823 characters long. - -Thankfully perl has a built in [reverse](https://perldoc.pl/functions/reverse) operator which does what you expect to do on a scalar (string). For the switch I used `tr/01/10/` which [translates](https://perldoc.pl/perlop#tr/SEARCHLIST/REPLACEMENTLIST/cdsr) the zeros to one and visa versa.
\ No newline at end of file + » ./ch-2.pl 4 + 0 1 3 2 6 7 5 4 12 13 15 14 10 11 9 8 diff --git a/challenge-070/sgreen/blog.txt b/challenge-070/sgreen/blog.txt new file mode 100644 index 0000000000..35640c6242 --- /dev/null +++ b/challenge-070/sgreen/blog.txt @@ -0,0 +1 @@ +https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-070/sgreen/README.md diff --git a/challenge-070/sgreen/perl/ch-1.pl b/challenge-070/sgreen/perl/ch-1.pl new file mode 100755 index 0000000000..6af3741c93 --- /dev/null +++ b/challenge-070/sgreen/perl/ch-1.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use 5.10.1; + +sub main (@) { + my ( $string, $count, $offset ) = @_; + + # Sanity checks + my $length = length $string; + die "A string must be supplied\n" unless $string; + die "The count must be a postive integer\n" + unless $count =~ /^[0-9]+$/ and $count >= 1; + die "The offset must be a postive integer\n" + unless $offset =~ /^[0-9]+$/ and $offset >= 1; + die "The count + offset must be less than the length of the string\n" + unless $count + $offset < $length; + + for my $i ( 1 .. $count ) { + ( substr( $string, $i, 1 ), substr( $string, $i + $offset, 1 ) ) = + ( substr( $string, $i + $offset, 1 ), substr( $string, $i, 1 ) ); + } + + say $string; +} + +main(@ARGV); diff --git a/challenge-070/sgreen/perl/ch-2.pl b/challenge-070/sgreen/perl/ch-2.pl new file mode 100755 index 0000000000..381699e096 --- /dev/null +++ b/challenge-070/sgreen/perl/ch-2.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use 5.10.1; + +sub main (@) { + my ($bits) = @_; + + # Sanity check + die "Bits must be a postive integer between 2 and 5" + unless $bits =~ /^[2-5]$/; + + # Seed the array + my @values = (0); + + # Double the array for each required bit + for my $bit ( 1 .. $bits ) { + my $half = 2**( $bit - 1 ); + push @values, reverse map { $half + $_ } @values; + } + + say join ' ', @values; +} + +main(@ARGV); |
