aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoud <noud.aldenhoven@gmail.com>2019-07-12 21:32:13 +0200
committerNoud <noud.aldenhoven@gmail.com>2019-07-12 21:32:13 +0200
commit20209a71a14eca47912acf92f82a353075e5eeae (patch)
treea06f607e1ff03db7294703f4ab8a09ae7e890917
parent1b28f6a10620b3c4f8812ef0d80073be63a4803e (diff)
downloadperlweeklychallenge-club-20209a71a14eca47912acf92f82a353075e5eeae.tar.gz
perlweeklychallenge-club-20209a71a14eca47912acf92f82a353075e5eeae.tar.bz2
perlweeklychallenge-club-20209a71a14eca47912acf92f82a353075e5eeae.zip
Solutions to challenge 016 problem 1 and 2 in perl6 by Noud
-rw-r--r--challenge-016/noud/perl6/ch-1.p625
-rw-r--r--challenge-016/noud/perl6/ch-2.p656
2 files changed, 81 insertions, 0 deletions
diff --git a/challenge-016/noud/perl6/ch-1.p6 b/challenge-016/noud/perl6/ch-1.p6
new file mode 100644
index 0000000000..fd2a6c3c8b
--- /dev/null
+++ b/challenge-016/noud/perl6/ch-1.p6
@@ -0,0 +1,25 @@
+# Pythagoras Pie Puzzle, proposed by Jo Christian Oterhals.
+#
+# At a party a pie is to be shared by 100 guest. The first guest gets 1% of the
+# pie, the second guest gets 2% of the remaining pie, the third gets 3% of the
+# remaining pie, the fourth gets 4% and so on.
+#
+# Write a script that figures out which guest gets the largest piece of pie.
+
+# Factorial function, create prefix !. I.e. 2! = 2, 3! = 3*2, 4! = 4*3*2, ...
+sub postfix:<!>(Int $n) { [*] 1..$n };
+
+# A straightforward calculation gives that person n gets
+#
+# 99 / 100 * 98 / 100 * ... * (99 - n + 1) / 100 * n / 100
+# = 99! / (100 - n)! * n / 100^n
+#
+# -th piece of the pie.
+my @pieces = (1..100).map(-> Int \n { 99! / (100 - n)! * n / 100**n });
+
+# Find the person with the biggest piece.
+my $person_no = @pieces.maxpairs()[0].key + 1;
+
+# Print the number of the person with the biggest piece.
+say "The person that gets the biggest piece is person $person_no.";
+
diff --git a/challenge-016/noud/perl6/ch-2.p6 b/challenge-016/noud/perl6/ch-2.p6
new file mode 100644
index 0000000000..f4e60d096c
--- /dev/null
+++ b/challenge-016/noud/perl6/ch-2.p6
@@ -0,0 +1,56 @@
+# Write a script to validate a given bitcoin address. Most Bitcoin addresses
+# are 34 characters. They consist of random digits and uppercase and lowercase
+# letters, with the exception that the uppercase letter “O”, uppercase letter
+# “I”, lowercase letter “l”, and the number “0” are never used to prevent
+# visual ambiguity. A bitcoin address encodes 25 bytes. The last four bytes are
+# a checksum check. They are the first four bytes of a double SHA-256 digest of
+# the previous 21 bytes. For more information, please refer wiki page. Here are
+# some valid bitcoin addresses:
+#
+# 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2
+# 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy
+#
+
+use Digest::SHA;
+
+sub valid_bitcoin(Str $bc) {
+ # Check that the bitcoin hash is of the correct size.
+ if ($bc.chars > 34 || $bc.chars < 24) {
+ return False;
+ }
+
+ # The bitcoinhash should start with 1 or 3 and should not contain an
+ # O, I, l, or 0.
+ if (! $bc ~~ / ^(1|3)(<[1..9A..HJ..NP..Za..km..z]>+)$ / ) {
+ return False;
+ }
+
+ # Convert Bitcoin hash base 58 to base 10.
+ # Example: [1, 2, 3].reduce(* * 58 + *) = (1 * 58 + 2) * 58 + 3
+ # = 1 * 58^2 + 2 * 58 + 3
+ my %base58 = (1..9, 'A'..'H', 'J'..'N', 'P'..'Z', 'a'..'k', 'm'..'z')
+ .flat.pairs.invert.hash;
+ my $dec = %base58{$bc.comb}.reduce(* * 58 + *);
+
+ # Compute the double sha-256 hash of the first 21 bytes.
+ my $bin_blob = Blob.new($dec.polymod(2 ** 8 xx 24).reverse);
+ my $bc_hash = sha256(sha256($bin_blob.subbuf(0, 21)));
+
+ # The last 4 bytes of the hash should be equal to the first 4 bytes of the
+ # double sha-256 hash.
+ return $bin_blob.subbuf(21, 4) eqv $bc_hash.subbuf(0, 4);
+}
+
+
+# Two valid bitcoin hashes.
+my $bc1 = '1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2';
+my $bc2 = '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy';
+
+# Two invalid bitcoin hashes.
+my $bc3 = '1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN3';
+my $bc4 = '3J99t1WpEZ73CNmQviecrnyiWrnqRhWNLy';
+
+valid_bitcoin($bc1).say; # Returns: True
+valid_bitcoin($bc2).say; # Returns: True
+valid_bitcoin($bc3).say; # Returns: False
+valid_bitcoin($bc4).say; # Returns: False