aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-340/lubos-kolouch/perl/ch-1.pl52
-rw-r--r--challenge-340/lubos-kolouch/perl/ch-2.pl64
-rw-r--r--challenge-340/lubos-kolouch/python/ch-1.py53
-rw-r--r--challenge-340/lubos-kolouch/python/ch-2.py54
4 files changed, 223 insertions, 0 deletions
diff --git a/challenge-340/lubos-kolouch/perl/ch-1.pl b/challenge-340/lubos-kolouch/perl/ch-1.pl
new file mode 100644
index 0000000000..f466e17a75
--- /dev/null
+++ b/challenge-340/lubos-kolouch/perl/ch-1.pl
@@ -0,0 +1,52 @@
+#!/usr/bin/env perl
+use v5.38;
+use warnings;
+use feature 'signatures';
+
+=pod
+
+=head1 PURPOSE
+
+Implementation for The Weekly Challenge 340, Task 1: remove adjacent duplicate
+characters repeatedly until the string stabilises.
+
+=head1 ALGORITHM
+
+We walk the input string from left to right, using an array as a stack. Whenever
+we encounter a character matching the current stack top, we pop the stack,
+effectively discarding the duplicate pair. Otherwise, we push the character.
+When the scan completes, the stack content is the fully reduced string.
+
+=cut
+
+sub duplicate_removals ($str) {
+ _assert_plain_string($str);
+
+ my @stack;
+ for my $char ( split //, $str ) {
+ if ( @stack && $stack[-1] eq $char ) {
+ pop @stack;
+ }
+ else {
+ push @stack, $char;
+ }
+ }
+
+ return join q(), @stack;
+}
+
+sub _assert_plain_string ($value) {
+ die 'Input must be a defined, non-reference string'
+ if !defined $value || ref $value;
+}
+
+unless (caller) {
+ require Test::More;
+ Test::More->import( tests => 5 );
+
+ Test::More::is( duplicate_removals('abbaca'), 'ca', 'Example 1' );
+ Test::More::is( duplicate_removals('azxxzy'), 'ay', 'Example 2' );
+ Test::More::is( duplicate_removals('aaaaaaaa'), q(), 'Example 3' );
+ Test::More::is( duplicate_removals('aabccba'), 'a', 'Example 4' );
+ Test::More::is( duplicate_removals('abcddcba'), q(), 'Example 5' );
+}
diff --git a/challenge-340/lubos-kolouch/perl/ch-2.pl b/challenge-340/lubos-kolouch/perl/ch-2.pl
new file mode 100644
index 0000000000..3fe212b5c0
--- /dev/null
+++ b/challenge-340/lubos-kolouch/perl/ch-2.pl
@@ -0,0 +1,64 @@
+#!/usr/bin/env perl
+use v5.38;
+use warnings;
+use feature 'signatures';
+
+=pod
+
+=head1 PURPOSE
+
+Implementation for The Weekly Challenge 340, Task 2: decide whether the numeric
+values embedded in a space-separated token stream form a strictly increasing
+sequence.
+
+=head1 ALGORITHM
+
+We split the input on single spaces and process each token. Tokens matching the
+pattern for non-negative integers without leading zeros are interpreted as
+numbers. Each number is compared with the previously seen numeric value; the
+sequence fails if we ever see a decrease or plateau. If no violation occurs, the
+sequence is strictly increasing.
+
+=cut
+
+sub ascending_numbers ($str) {
+ _assert_plain_string($str);
+
+ my $last;
+ for my $token ( split / /, $str ) {
+ next unless _is_valid_integer_token($token);
+
+ my $value = 0 + $token;
+ return 0 if defined $last && $value <= $last;
+ $last = $value;
+ }
+
+ return 1;
+}
+
+sub _is_valid_integer_token ($token) {
+ return $token eq '0' || $token =~ /\A[1-9]\d*\z/;
+}
+
+sub _assert_plain_string ($value) {
+ die 'Input must be a defined, non-reference string'
+ if !defined $value || ref $value;
+}
+
+sub _bool_to_text ($bool) {
+ return $bool ? 'true' : 'false';
+}
+
+unless (caller) {
+ require Test::More;
+ Test::More->import( tests => 5 );
+
+ Test::More::is( _bool_to_text( ascending_numbers('The cat has 3 kittens 7 toys 10 beds') ),
+ 'true', 'Example 1' );
+ Test::More::is( _bool_to_text( ascending_numbers('Alice bought 5 apples 2 oranges 9 bananas') ),
+ 'false', 'Example 2' );
+ Test::More::is( _bool_to_text( ascending_numbers('I ran 1 mile 2 days 3 weeks 4 months') ),
+ 'true', 'Example 3' );
+ Test::More::is( _bool_to_text( ascending_numbers('Bob has 10 cars 10 bikes') ), 'false', 'Example 4' );
+ Test::More::is( _bool_to_text( ascending_numbers('Zero is 0 one is 1 two is 2') ), 'true', 'Example 5' );
+}
diff --git a/challenge-340/lubos-kolouch/python/ch-1.py b/challenge-340/lubos-kolouch/python/ch-1.py
new file mode 100644
index 0000000000..ba06cfdf20
--- /dev/null
+++ b/challenge-340/lubos-kolouch/python/ch-1.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+"""Solutions for The Weekly Challenge 340, Task 1 (Duplicate Removals).
+
+The task asks for repeatedly deleting adjacent identical characters from a
+lowercase string until no such pair remains. This implementation exposes the
+core routine for reuse and embeds unit tests based solely on the official
+examples.
+"""
+
+from __future__ import annotations
+
+import unittest
+
+
+def duplicate_removals(text: str) -> str:
+ """Return the fully reduced form of *text* after removing adjacent duplicates.
+
+ The algorithm processes the characters left to right while maintaining a
+ stack (implemented as a Python list). A character equal to the current stack
+ top cancels out the pair; otherwise the character is added to the stack. The
+ final stack contents yield the reduced string.
+ """
+
+ stack: list[str] = []
+ for char in text:
+ if stack and stack[-1] == char:
+ stack.pop()
+ else:
+ stack.append(char)
+ return "".join(stack)
+
+
+class DuplicateRemovalsTests(unittest.TestCase):
+ """Exercises the routine against the provided examples."""
+
+ def test_example_1(self) -> None:
+ self.assertEqual(duplicate_removals("abbaca"), "ca")
+
+ def test_example_2(self) -> None:
+ self.assertEqual(duplicate_removals("azxxzy"), "ay")
+
+ def test_example_3(self) -> None:
+ self.assertEqual(duplicate_removals("aaaaaaaa"), "")
+
+ def test_example_4(self) -> None:
+ self.assertEqual(duplicate_removals("aabccba"), "a")
+
+ def test_example_5(self) -> None:
+ self.assertEqual(duplicate_removals("abcddcba"), "")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/challenge-340/lubos-kolouch/python/ch-2.py b/challenge-340/lubos-kolouch/python/ch-2.py
new file mode 100644
index 0000000000..554e36abd5
--- /dev/null
+++ b/challenge-340/lubos-kolouch/python/ch-2.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+"""Solutions for The Weekly Challenge 340, Task 2 (Ascending Numbers).
+
+The challenge provides a space-separated string containing words and positive
+integers without leading zeros. The goal is to determine whether the numeric
+subsequence appears in strictly increasing order. Only the official examples
+are used for verification, as required.
+"""
+
+from __future__ import annotations
+
+import unittest
+
+
+def ascending_numbers(text: str) -> bool:
+ """Return ``True`` if the numbers inside *text* increase strictly."""
+
+ last_value: int | None = None
+ for token in text.split(" "):
+ if not token.isdigit():
+ continue
+
+ value = int(token)
+ if last_value is not None and value <= last_value:
+ return False
+ last_value = value
+
+ return True
+
+
+class AscendingNumbersTests(unittest.TestCase):
+ """Exercises the routine against the provided examples."""
+
+ def test_example_1(self) -> None:
+ self.assertTrue(
+ ascending_numbers("The cat has 3 kittens 7 toys 10 beds"))
+
+ def test_example_2(self) -> None:
+ self.assertFalse(
+ ascending_numbers("Alice bought 5 apples 2 oranges 9 bananas"))
+
+ def test_example_3(self) -> None:
+ self.assertTrue(
+ ascending_numbers("I ran 1 mile 2 days 3 weeks 4 months"))
+
+ def test_example_4(self) -> None:
+ self.assertFalse(ascending_numbers("Bob has 10 cars 10 bikes"))
+
+ def test_example_5(self) -> None:
+ self.assertTrue(ascending_numbers("Zero is 0 one is 1 two is 2"))
+
+
+if __name__ == "__main__":
+ unittest.main()