diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2023-07-28 15:09:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-28 15:09:32 +0100 |
| commit | 4a347d47542debddbd5b1d226c3a747277b9be4f (patch) | |
| tree | fdf00b755389b1f039b033c7e5798354a349cb78 /challenge-227 | |
| parent | d5ce09a67599e62df79105bfe5d87dffe59bb083 (diff) | |
| parent | a26766986545f553a64320f55d0c9ae8fdccf792 (diff) | |
| download | perlweeklychallenge-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-x | challenge-227/andreas-voegele/kotlin/ch-1.kts | 21 | ||||
| -rwxr-xr-x | challenge-227/andreas-voegele/kotlin/ch-2.kts | 119 | ||||
| -rwxr-xr-x | challenge-227/andreas-voegele/perl/ch-1.pl | 20 | ||||
| -rwxr-xr-x | challenge-227/andreas-voegele/perl/ch-2.pl | 125 |
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'); |
