aboutsummaryrefslogtreecommitdiff
path: root/challenge-227
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-07-28 15:09:32 +0100
committerGitHub <noreply@github.com>2023-07-28 15:09:32 +0100
commit4a347d47542debddbd5b1d226c3a747277b9be4f (patch)
treefdf00b755389b1f039b033c7e5798354a349cb78 /challenge-227
parentd5ce09a67599e62df79105bfe5d87dffe59bb083 (diff)
parenta26766986545f553a64320f55d0c9ae8fdccf792 (diff)
downloadperlweeklychallenge-club-4a347d47542debddbd5b1d226c3a747277b9be4f.tar.gz
perlweeklychallenge-club-4a347d47542debddbd5b1d226c3a747277b9be4f.tar.bz2
perlweeklychallenge-club-4a347d47542debddbd5b1d226c3a747277b9be4f.zip
Merge pull request #8452 from voegelas/challenge-227
Challenge 227 by Andreas Vögele
Diffstat (limited to 'challenge-227')
-rwxr-xr-xchallenge-227/andreas-voegele/kotlin/ch-1.kts21
-rwxr-xr-xchallenge-227/andreas-voegele/kotlin/ch-2.kts119
-rwxr-xr-xchallenge-227/andreas-voegele/perl/ch-1.pl20
-rwxr-xr-xchallenge-227/andreas-voegele/perl/ch-2.pl125
4 files changed, 285 insertions, 0 deletions
diff --git a/challenge-227/andreas-voegele/kotlin/ch-1.kts b/challenge-227/andreas-voegele/kotlin/ch-1.kts
new file mode 100755
index 0000000000..6d9b367920
--- /dev/null
+++ b/challenge-227/andreas-voegele/kotlin/ch-1.kts
@@ -0,0 +1,21 @@
+#!/usr/bin/env kotlin
+
+/*
+ * You are given a year number in the range 1753 to 9999. Write a script to
+ * find out how many dates in the year are Friday 13th. Assume that the
+ * current Gregorian calendar applies.
+ */
+
+import java.time.DayOfWeek
+import java.time.LocalDate
+
+fun friday13th(year: Int): List<LocalDate> =
+ (1..12).map { month ->
+ LocalDate.of(year, month, 13)
+ }.filter { date ->
+ date.dayOfWeek == DayOfWeek.FRIDAY
+ }
+
+println(friday13th(1753).size)
+println(friday13th(2023).size)
+println(friday13th(9999).size)
diff --git a/challenge-227/andreas-voegele/kotlin/ch-2.kts b/challenge-227/andreas-voegele/kotlin/ch-2.kts
new file mode 100755
index 0000000000..fd9d4f3e7a
--- /dev/null
+++ b/challenge-227/andreas-voegele/kotlin/ch-2.kts
@@ -0,0 +1,119 @@
+#!/usr/bin/env kotlin
+
+/*
+ * Write a script to handle a 2-term arithmetic operation expressed in Roman
+ * numeral.
+ *
+ * Example
+ *
+ * IV + V to IX
+ * M - I to CMXCIX
+ * X / II to V
+ * XI * VI to LXVI
+ * VII ** III to CCCXLIII
+ * V - V to nulla (they knew about zero but didn't have a symbol)
+ * V / II to non potest (they didn't do fractions)
+ * MMM + M to non potest (they only went up to 3999)
+ * V - X to non potest (they didn't do negative numbers)
+ */
+
+class Roman private constructor(val number: Double) {
+ companion object {
+ private val numberFor = mapOf(
+ 'I' to 1,
+ 'V' to 5,
+ 'X' to 10,
+ 'L' to 50,
+ 'C' to 100,
+ 'D' to 500,
+ 'M' to 1000,
+ )
+
+ private val numeralFor = listOf(
+ 1000 to "M",
+ 900 to "CM",
+ 500 to "D",
+ 400 to "CD",
+ 100 to "C",
+ 90 to "XC",
+ 50 to "L",
+ 40 to "XL",
+ 10 to "X",
+ 9 to "IX",
+ 5 to "V",
+ 4 to "IV",
+ 1 to "I",
+ )
+
+ fun decodeRoman(string: String): Int {
+ val pair = string.map {
+ numberFor.getOrDefault(it, 0)
+ }.fold(0 to 0) { (sum, prev), next ->
+ if (next <= prev) sum + prev to next else sum - prev to next
+ }
+ return pair.first + pair.second
+ }
+
+ fun encodeRoman(number: Int): String {
+ if (number < 0 || number > 3999) {
+ return "non potest"
+ }
+ if (number == 0) {
+ return "nulla"
+ }
+ var string = ""
+ var n = number
+ for ((multiple, numeral) in numeralFor) {
+ while (n >= multiple) {
+ n -= multiple
+ string += numeral
+ }
+ }
+ return string
+ }
+
+ private fun encodeRoman(number: Double): String {
+ val n = number.toInt()
+ if (number.compareTo(n) != 0) {
+ return "non potest"
+ }
+ return encodeRoman(n)
+ }
+ }
+
+ constructor(string: String) : this(decodeRoman(string))
+
+ constructor(number: Int) : this(number.toDouble())
+
+ operator fun plus(other: Roman) = Roman(number + other.number)
+
+ operator fun minus(other: Roman) = Roman(number - other.number)
+
+ operator fun times(other: Roman) = Roman(number * other.number)
+
+ operator fun div(other: Roman) = Roman(number / other.number)
+
+ operator fun rem(other: Roman) = Roman(number % other.number)
+
+ fun pow(other: Roman) = Roman(Math.pow(number, other.number))
+
+ operator fun compareTo(other: Roman) = number.compareTo(other.number)
+
+ operator fun inc() = Roman(number + 1.0)
+
+ operator fun dec() = Roman(number - 1.0)
+
+ fun toInt() = number.toInt()
+
+ override fun toString() = encodeRoman(number)
+}
+
+println(Roman("IV") + Roman("V"))
+println(Roman("M") - Roman("I"))
+println(Roman("X") / Roman("II"))
+println(Roman("XI") * Roman("VI"))
+println(Roman("VII").pow(Roman("III")))
+println(Roman("V") - Roman("V"))
+println(Roman("V") / Roman("II"))
+println(Roman("MMM") + Roman("M"))
+println(Roman("V") - Roman("X"))
diff --git a/challenge-227/andreas-voegele/perl/ch-1.pl b/challenge-227/andreas-voegele/perl/ch-1.pl
new file mode 100755
index 0000000000..df2b8f2b9b
--- /dev/null
+++ b/challenge-227/andreas-voegele/perl/ch-1.pl
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+
+# You are given a year number in the range 1753 to 9999. Write a script to
+# find out how many dates in the year are Friday 13th. Assume that the
+# current Gregorian calendar applies.
+
+use 5.036;
+use utf8;
+
+use POSIX qw(mktime);
+
+sub friday_13th ($year) {
+ my $_year = $year - 1900;
+ my $mkdate = sub ($month) { mktime(0, 0, 0, 13, $month, $_year) };
+ return grep { (localtime $_)[6] == 5 } map { $mkdate->($_) } 0 .. 11;
+}
+
+say scalar friday_13th(1753);
+say scalar friday_13th(2023);
+say scalar friday_13th(9999);
diff --git a/challenge-227/andreas-voegele/perl/ch-2.pl b/challenge-227/andreas-voegele/perl/ch-2.pl
new file mode 100755
index 0000000000..0c253aa7cb
--- /dev/null
+++ b/challenge-227/andreas-voegele/perl/ch-2.pl
@@ -0,0 +1,125 @@
+#!/usr/bin/perl
+
+# Write a script to handle a 2-term arithmetic operation expressed in Roman numeral.
+#
+# Example
+#
+# IV + V => IX
+# M - I => CMXCIX
+# X / II => V
+# XI * VI => LXVI
+# VII ** III => CCCXLIII
+# V - V => nulla (they knew about zero but didn't have a symbol)
+# V / II => non potest (they didn't do fractions)
+# MMM + M => non potest (they only went up to 3999)
+# V - X => non potest (they didn't do negative numbers)
+
+use 5.036;
+use utf8;
+
+package Roman;
+
+use experimental qw(for_list);
+
+use List::Util qw(reduce);
+
+my %number_for = (
+ I => 1,
+ V => 5,
+ X => 10,
+ L => 50,
+ C => 100,
+ D => 500,
+ M => 1000,
+);
+
+my @numeral_for = (
+ 1000 => 'M',
+ 900 => 'CM',
+ 500 => 'D',
+ 400 => 'CD',
+ 100 => 'C',
+ 90 => 'XC',
+ 50 => 'L',
+ 40 => 'XL',
+ 10 => 'X',
+ 9 => 'IX',
+ 5 => 'V',
+ 4 => 'IV',
+ 1 => 'I',
+);
+
+sub decode_roman ($string) {
+ my @numbers = map { $number_for{$_} // 0 } split //, $string;
+ my $pair = reduce {
+ my ($sum, $prev) = @{$a};
+ $b <= $prev ? [$sum + $prev, $b] : [$sum - $prev, $b]
+ } [0, 0], @numbers;
+ return $pair->[0] + $pair->[1];
+}
+
+sub encode_roman ($number) {
+ if ( !defined $number
+ || $number < 0
+ || $number > 3999
+ || $number != int $number) {
+ return 'non potest ';
+ }
+ if ($number == 0) {
+ return 'nulla';
+ }
+ my $string = q{};
+ for my ($multiple, $numeral) (@numeral_for) {
+ while ($number >= $multiple) {
+ $number -= $multiple;
+ $string .= $numeral;
+ }
+ }
+ return $string;
+}
+
+sub new ($class, $string) {
+ my $number = decode_roman($string);
+ return bless \$number, $class;
+}
+
+sub from_number ($class, $number) {
+ return bless \$number, $class;
+}
+
+sub _other ($value) {
+ my $type = ref $value;
+ if ($type eq 'Roman') {
+ return ${$value};
+ }
+ return $value;
+}
+
+use overload
+ '+' => sub { Roman->from_number(${$_[0]} + _other($_[1])) },
+ '-' => sub { Roman->from_number(${$_[0]} - _other($_[1])) },
+ '*' => sub { Roman->from_number(${$_[0]} * _other($_[1])) },
+ '/' => sub { Roman->from_number(${$_[0]} / _other($_[1])) },
+ '%' => sub { Roman->from_number(${$_[0]} % _other($_[1])) },
+ '**' => sub { Roman->from_number(${$_[0]}**_other($_[1])) },
+ '<=>' => sub { ${$_[0]} <=> _other($_[1]) },
+ '++' => sub { ++${$_[0]} },
+ '--' => sub { --${$_[0]} },
+ 'int' => sub { int ${$_[0]} },
+ '""' => sub { encode_roman(${$_[0]}) };
+
+package main;
+
+sub roman ($string) {
+ return Roman->new($string);
+}
+
+say roman('IV') + roman('V');
+say roman('M') - roman('I');
+say roman('X') / roman('II');
+say roman('XI') * roman('VI');
+say roman('VII')**roman('III');
+say roman('V') - roman('V');
+say roman('V') / roman('II');
+say roman('MMM') + roman('M');
+say roman('V') - roman('X');