aboutsummaryrefslogtreecommitdiff
path: root/challenge-332
diff options
context:
space:
mode:
authorLubos Kolouch <lubos@kolouch.net>2025-10-14 10:48:22 +0200
committerLubos Kolouch <lubos@kolouch.net>2025-10-14 10:48:22 +0200
commit19ecc1107e225225f0e2306bc4fd403ba40af81f (patch)
tree3f272efc60b66982bd05324b090d57f1b87309cf /challenge-332
parent06f069268faa38d5f1c63c4b99d2cea152029511 (diff)
downloadperlweeklychallenge-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.pl47
-rw-r--r--challenge-332/lubos-kolouch/perl/ch-2.pl50
-rw-r--r--challenge-332/lubos-kolouch/python/ch-1.py49
-rw-r--r--challenge-332/lubos-kolouch/python/ch-2.py44
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()