aboutsummaryrefslogtreecommitdiff
path: root/challenge-011/aaron-sherman
diff options
context:
space:
mode:
Diffstat (limited to 'challenge-011/aaron-sherman')
-rw-r--r--challenge-011/aaron-sherman/README1
-rw-r--r--challenge-011/aaron-sherman/perl6/ch-1.p676
-rw-r--r--challenge-011/aaron-sherman/perl6/ch-2.p676
3 files changed, 153 insertions, 0 deletions
diff --git a/challenge-011/aaron-sherman/README b/challenge-011/aaron-sherman/README
new file mode 100644
index 0000000000..14ec31f570
--- /dev/null
+++ b/challenge-011/aaron-sherman/README
@@ -0,0 +1 @@
+Solutions by Aaron Sherman.
diff --git a/challenge-011/aaron-sherman/perl6/ch-1.p6 b/challenge-011/aaron-sherman/perl6/ch-1.p6
new file mode 100644
index 0000000000..d61cb697bc
--- /dev/null
+++ b/challenge-011/aaron-sherman/perl6/ch-1.p6
@@ -0,0 +1,76 @@
+#!/usr/bin/env perl6
+
+# From : https://perlweeklychallenge.org/blog/perl-weekly-challenge-011/
+
+# Challenge #1
+# Write a script that computes the equal point in the Fahrenheit and
+# Celsius scales, knowing that the freezing point of water is 32 °F and
+# 0 °C, and that the boiling point of water is 212 °F and 100 °C. This
+# challenge was proposed by Laurent Rosenfeld.
+
+# The challenge was a bit bland, so I jazzed it up.
+# --help for more info
+
+use v6.c;
+
+# Note that this is the only place we keep the
+# units, so everything else except comments has
+# to derive even the abbreviations from this lookup.
+our %knowns = (
+ unit => <F C>,
+ freezing => [32, 0],
+ boiling => [212, 100] );
+
+proto MAIN($input?) {*}
+
+multi MAIN(
+ #= Convert the given value e.g. 37C
+ Str $input where m/<after \d><alpha>$/
+) {
+ my $value = +$input.substr(0,*-1);
+ my $from = $input.substr(*-1);
+ my $units = %knowns<unit>.join('/');
+ die "$from is not one of $units" if !%knowns<unit>.grep: * eq $from;
+ my $to = %knowns<unit>.grep({$_ ne $input}).first;
+ say "$value$from in $to: {convert($value, :$to)}";
+}
+
+multi MAIN(
+ #= Show conversion for given unit e.g. C
+ Str $input where $input eq [|] |%knowns<unit>
+) {
+ my $to = %knowns<unit>.grep({$_ ne $input}).first;
+ my $conversion = conversion(:$to);
+ my $scale = $conversion<scale>.nude.join('/');
+ say "Conversion to $to: {$input}*{$scale} + {$conversion<offset>}";
+}
+
+#= by default show crossover for units
+multi MAIN() {
+ my $units = %knowns<unit>.join('/');
+ say "$units cross over at {crossover}";
+}
+
+sub other-unit($unit) { return %knowns<unit>.grep({$_ ne $unit}).first }
+
+sub convert($value, :$to where $to eq [|] |%knowns<unit>) {
+ my $conv = conversion(:$to);
+ return $value*$conv<scale> + $conv<offset>;
+}
+
+sub crossover() {
+ my $conv = conversion(:to<F>);
+ return $conv<offset>/(1-$conv<scale>);
+}
+
+sub conversion(:$to where $to eq [|] |%knowns<unit>) {
+ my $to-index = %knowns<unit>.first: * eq $to, :k;
+ # Get the offset between the two
+ my $offset = [-] |%knowns<freezing>;
+ my $scale = [/] (|%knowns<boiling> <<->> |%knowns<freezing>);
+ if !$to-index {
+ return { scale => $scale, offset => $offset, index => $to-index };
+ } else {
+ return { scale => 1/$scale, offset => -$offset, index => $to-index };
+ }
+}
diff --git a/challenge-011/aaron-sherman/perl6/ch-2.p6 b/challenge-011/aaron-sherman/perl6/ch-2.p6
new file mode 100644
index 0000000000..d61cb697bc
--- /dev/null
+++ b/challenge-011/aaron-sherman/perl6/ch-2.p6
@@ -0,0 +1,76 @@
+#!/usr/bin/env perl6
+
+# From : https://perlweeklychallenge.org/blog/perl-weekly-challenge-011/
+
+# Challenge #1
+# Write a script that computes the equal point in the Fahrenheit and
+# Celsius scales, knowing that the freezing point of water is 32 °F and
+# 0 °C, and that the boiling point of water is 212 °F and 100 °C. This
+# challenge was proposed by Laurent Rosenfeld.
+
+# The challenge was a bit bland, so I jazzed it up.
+# --help for more info
+
+use v6.c;
+
+# Note that this is the only place we keep the
+# units, so everything else except comments has
+# to derive even the abbreviations from this lookup.
+our %knowns = (
+ unit => <F C>,
+ freezing => [32, 0],
+ boiling => [212, 100] );
+
+proto MAIN($input?) {*}
+
+multi MAIN(
+ #= Convert the given value e.g. 37C
+ Str $input where m/<after \d><alpha>$/
+) {
+ my $value = +$input.substr(0,*-1);
+ my $from = $input.substr(*-1);
+ my $units = %knowns<unit>.join('/');
+ die "$from is not one of $units" if !%knowns<unit>.grep: * eq $from;
+ my $to = %knowns<unit>.grep({$_ ne $input}).first;
+ say "$value$from in $to: {convert($value, :$to)}";
+}
+
+multi MAIN(
+ #= Show conversion for given unit e.g. C
+ Str $input where $input eq [|] |%knowns<unit>
+) {
+ my $to = %knowns<unit>.grep({$_ ne $input}).first;
+ my $conversion = conversion(:$to);
+ my $scale = $conversion<scale>.nude.join('/');
+ say "Conversion to $to: {$input}*{$scale} + {$conversion<offset>}";
+}
+
+#= by default show crossover for units
+multi MAIN() {
+ my $units = %knowns<unit>.join('/');
+ say "$units cross over at {crossover}";
+}
+
+sub other-unit($unit) { return %knowns<unit>.grep({$_ ne $unit}).first }
+
+sub convert($value, :$to where $to eq [|] |%knowns<unit>) {
+ my $conv = conversion(:$to);
+ return $value*$conv<scale> + $conv<offset>;
+}
+
+sub crossover() {
+ my $conv = conversion(:to<F>);
+ return $conv<offset>/(1-$conv<scale>);
+}
+
+sub conversion(:$to where $to eq [|] |%knowns<unit>) {
+ my $to-index = %knowns<unit>.first: * eq $to, :k;
+ # Get the offset between the two
+ my $offset = [-] |%knowns<freezing>;
+ my $scale = [/] (|%knowns<boiling> <<->> |%knowns<freezing>);
+ if !$to-index {
+ return { scale => $scale, offset => $offset, index => $to-index };
+ } else {
+ return { scale => 1/$scale, offset => -$offset, index => $to-index };
+ }
+}