diff options
| author | Lubos Kolouch <lubos@kolouch.net> | 2025-10-14 10:48:22 +0200 |
|---|---|---|
| committer | Lubos Kolouch <lubos@kolouch.net> | 2025-10-14 10:48:22 +0200 |
| commit | 19ecc1107e225225f0e2306bc4fd403ba40af81f (patch) | |
| tree | 3f272efc60b66982bd05324b090d57f1b87309cf /challenge-332 | |
| parent | 06f069268faa38d5f1c63c4b99d2cea152029511 (diff) | |
| download | perlweeklychallenge-club-19ecc1107e225225f0e2306bc4fd403ba40af81f.tar.gz perlweeklychallenge-club-19ecc1107e225225f0e2306bc4fd403ba40af81f.tar.bz2 perlweeklychallenge-club-19ecc1107e225225f0e2306bc4fd403ba40af81f.zip | |
Add Task 332 solutions for lubos-kolouch
Diffstat (limited to 'challenge-332')
| -rw-r--r-- | challenge-332/lubos-kolouch/perl/ch-1.pl | 47 | ||||
| -rw-r--r-- | challenge-332/lubos-kolouch/perl/ch-2.pl | 50 | ||||
| -rw-r--r-- | challenge-332/lubos-kolouch/python/ch-1.py | 49 | ||||
| -rw-r--r-- | challenge-332/lubos-kolouch/python/ch-2.py | 44 |
4 files changed, 190 insertions, 0 deletions
diff --git a/challenge-332/lubos-kolouch/perl/ch-1.pl b/challenge-332/lubos-kolouch/perl/ch-1.pl new file mode 100644 index 0000000000..f3ffb1fec2 --- /dev/null +++ b/challenge-332/lubos-kolouch/perl/ch-1.pl @@ -0,0 +1,47 @@ +#!/usr/bin/env perl +use v5.38; +use strict; +use warnings; +use feature 'signatures'; +no warnings 'experimental::signatures'; + +use Type::Params qw(compile); +use Types::Standard qw(StrMatch); +use Test::More; + +=pod + +=head1 NAME + +ch-1 - Binary Date converter + +=head1 SYNOPSIS + + perl ch-1.pl + +=head1 DESCRIPTION + +The script implements Task 1 (Binary Date) from The Weekly Challenge #332. +It exposes L</binary_date> that validates an ISO-8601 date string +and returns the corresponding binary representation for the year, +month, and day components joined with hyphens. + +=cut + +my $ISO_DATE = StrMatch [qr/\A\d{4}-\d{2}-\d{2}\z/]; +my $date_check = compile($ISO_DATE); + +## no critic (Subroutines::ProhibitSubroutinePrototypes) +sub binary_date ($date) { + ($date) = $date_check->($date); + my ( $year, $month, $day ) = split /-/xms, $date; + return join q{-}, map { sprintf '%b', $_ + 0 } ( $year, $month, $day ); +} +## use critic + +# Unit tests (Examples provided by the challenge) +is binary_date('2025-07-26'), '11111101001-111-11010', 'Example 1'; +is binary_date('2000-02-02'), '11111010000-10-10', 'Example 2'; +is binary_date('2024-12-31'), '11111101000-1100-11111', 'Example 3'; + +done_testing(); diff --git a/challenge-332/lubos-kolouch/perl/ch-2.pl b/challenge-332/lubos-kolouch/perl/ch-2.pl new file mode 100644 index 0000000000..1db92c3ed6 --- /dev/null +++ b/challenge-332/lubos-kolouch/perl/ch-2.pl @@ -0,0 +1,50 @@ +#!/usr/bin/env perl +use v5.38; +use strict; +use warnings; +use feature 'signatures'; +no warnings 'experimental::signatures'; + +use List::Util qw(all); +use Type::Params qw(compile); +use Types::Standard qw(StrMatch); +use Test::More; + +=pod + +=head1 NAME + +ch-2 - Odd Letters frequency checker + +=head1 SYNOPSIS + + perl ch-2.pl + +=head1 DESCRIPTION + +The script implements Task 2 (Odd Letters) from The Weekly Challenge #332. +It provides L</odd_letters> that accepts an ASCII alphabetic string and +returns a boolean indicating whether every distinct letter occurs an odd +number of times. + +=cut + +my $AlphaWord = StrMatch [qr/\A[a-zA-Z]+\z/]; +my $string_check = compile($AlphaWord); + +## no critic (Subroutines::ProhibitSubroutinePrototypes) +sub odd_letters ($word) { + ($word) = $string_check->($word); + my %tally; + $tally{$_}++ for split //, lc $word; + my $all_odd = all { $_ % 2 == 1 } values %tally; + return $all_odd ? 1 : 0; +} +## use critic + +# Unit tests (Examples provided by the challenge) +ok !odd_letters('weekly'), 'Example 1'; +ok odd_letters('perl'), 'Example 2'; +ok !odd_letters('challenge'), 'Example 3'; + +done_testing(); diff --git a/challenge-332/lubos-kolouch/python/ch-1.py b/challenge-332/lubos-kolouch/python/ch-1.py new file mode 100644 index 0000000000..3d8a96fdae --- /dev/null +++ b/challenge-332/lubos-kolouch/python/ch-1.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +"""Task 1 - Binary Date converter for The Weekly Challenge #332.""" +from __future__ import annotations + +import re +import unittest +from typing import Final + +DATE_PATTERN: Final[re.Pattern[str]] = re.compile(r"^\d{4}-\d{2}-\d{2}$") + + +def binary_date(date: str) -> str: + """ + Return the binary representation of the year, month, and day components. + + Args: + date: An ISO-8601 date string in the form YYYY-MM-DD. + + Returns: + The converted date with each component rendered in base 2. + + Raises: + ValueError: If *date* is not a well-formed ISO-8601 date. + """ + if DATE_PATTERN.fullmatch(date) is None: + msg = f"Invalid ISO date: {date!r}" + raise ValueError(msg) + year_text, month_text, day_text = date.split("-") + year = int(year_text, 10) + month = int(month_text, 10) + day = int(day_text, 10) + return f"{year:b}-{month:b}-{day:b}" + + +class BinaryDateExamples(unittest.TestCase): + """Unit tests using the official examples.""" + + def test_example_1(self) -> None: + self.assertEqual(binary_date("2025-07-26"), "11111101001-111-11010") + + def test_example_2(self) -> None: + self.assertEqual(binary_date("2000-02-02"), "11111010000-10-10") + + def test_example_3(self) -> None: + self.assertEqual(binary_date("2024-12-31"), "11111101000-1100-11111") + + +if __name__ == "__main__": + unittest.main() diff --git a/challenge-332/lubos-kolouch/python/ch-2.py b/challenge-332/lubos-kolouch/python/ch-2.py new file mode 100644 index 0000000000..c37c90eeea --- /dev/null +++ b/challenge-332/lubos-kolouch/python/ch-2.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +"""Task 2 - Odd Letters checker for The Weekly Challenge #332.""" +from __future__ import annotations + +import unittest +from collections import Counter + + +def has_odd_letter_counts(text: str) -> bool: + """ + Return True if every distinct letter in *text* appears an odd number of times. + + Args: + text: A string containing only alphabetic characters. + + Returns: + True when each distinct letter appears an odd number of times, otherwise False. + + Raises: + ValueError: If *text* contains non-alphabetic characters or is empty. + """ + if not text.isalpha(): + msg = f"Input must contain only alphabetic characters: {text!r}" + raise ValueError(msg) + normalized = text.lower() + counts = Counter(normalized) + return all(value % 2 == 1 for value in counts.values()) + + +class OddLettersExamples(unittest.TestCase): + """Unit tests derived from the supplied examples.""" + + def test_example_1(self) -> None: + self.assertFalse(has_odd_letter_counts("weekly")) + + def test_example_2(self) -> None: + self.assertTrue(has_odd_letter_counts("perl")) + + def test_example_3(self) -> None: + self.assertFalse(has_odd_letter_counts("challenge")) + + +if __name__ == "__main__": + unittest.main() |
