aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-270/lubos-kolouch/perl/ch-1.pl34
-rw-r--r--challenge-270/lubos-kolouch/perl/ch-2.pl74
-rw-r--r--challenge-270/lubos-kolouch/python/ch-1.py44
-rw-r--r--challenge-270/lubos-kolouch/python/ch-2.py57
-rw-r--r--challenge-286/lubos-kolouch/perl/ch-1.pl47
-rw-r--r--challenge-286/lubos-kolouch/perl/ch-2.pl68
-rw-r--r--challenge-286/lubos-kolouch/python/ch-1.py40
-rw-r--r--challenge-286/lubos-kolouch/python/ch-2.py64
-rw-r--r--challenge-287/lubos-kolouch/perl/ch-1.pl71
-rw-r--r--challenge-287/lubos-kolouch/perl/ch-2.pl79
-rw-r--r--challenge-287/lubos-kolouch/python/ch-1.py59
-rw-r--r--challenge-287/lubos-kolouch/python/ch-2.py75
12 files changed, 712 insertions, 0 deletions
diff --git a/challenge-270/lubos-kolouch/perl/ch-1.pl b/challenge-270/lubos-kolouch/perl/ch-1.pl
new file mode 100644
index 0000000000..aeee1e3e99
--- /dev/null
+++ b/challenge-270/lubos-kolouch/perl/ch-1.pl
@@ -0,0 +1,34 @@
+use strict;
+use warnings;
+use List::Util qw(all);
+
+sub num_special_positions {
+ my ($matrix) = @_;
+ my $rows = scalar(@$matrix);
+ my $cols = scalar( @{ $matrix->[0] } );
+ my $special_count = 0;
+
+ for my $i ( 0 .. $rows - 1 ) {
+ for my $j ( 0 .. $cols - 1 ) {
+ if ( $matrix->[$i][$j] == 1 ) {
+ my $row_check = all { $_ == 0 }
+ @{ $matrix->[$i] }[ 0 .. $j - 1, $j + 1 .. $cols - 1 ];
+ my $col_check = all { $_ == 0 }
+ map { $matrix->[$_][$j] } grep { $_ != $i } 0 .. $rows - 1;
+ if ( $row_check && $col_check ) {
+ $special_count++;
+ }
+ }
+ }
+ }
+
+ return $special_count;
+}
+
+# Example 1
+my $matrix1 = [ [ 1, 0, 0 ], [ 0, 0, 1 ], [ 1, 0, 0 ] ];
+print num_special_positions($matrix1) == 1 ? "Pass\n" : "Fail\n";
+
+# Example 2
+my $matrix2 = [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ];
+print num_special_positions($matrix2) == 3 ? "Pass\n" : "Fail\n";
diff --git a/challenge-270/lubos-kolouch/perl/ch-2.pl b/challenge-270/lubos-kolouch/perl/ch-2.pl
new file mode 100644
index 0000000000..519759ae8c
--- /dev/null
+++ b/challenge-270/lubos-kolouch/perl/ch-2.pl
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+use strict;
+use warnings FATAL => 'all';
+
+sub min_cost_to_equal_elements {
+ my ($ints_ref, $x, $y) = @_;
+ my @ints = @$ints_ref;
+
+ my $min_cost = "inf";
+ my $max_val = max(@ints);
+ my $min_val = min(@ints);
+
+ print "Initial array: (@ints)\n";
+ print "Cost for Level 1 (x): $x\n";
+ print "Cost for Level 2 (y): $y\n";
+
+ for my $target ($min_val .. $max_val) {
+ my $cost = 0;
+ print "\nTrying to make all elements equal to: $target\n";
+
+ for my $num (@ints) {
+ my $diff = abs($target - $num);
+ print "Difference for element $num to target $target: $diff\n";
+
+ my $cost_addition;
+ if ($y < 2 * $x) {
+ my $level_2_ops = int($diff / 2);
+ my $level_1_ops = $diff % 2;
+ $cost_addition = ($level_2_ops * $y) + ($level_1_ops * $x);
+ print "Using Level 2 and Level 1. Cost to adjust $num to $target: $cost_addition\n";
+ } else {
+ $cost_addition = $diff * $x;
+ print "Using only Level 1. Cost to adjust $num to $target: $cost_addition\n";
+ }
+
+ $cost += $cost_addition;
+ }
+
+ print "Total cost to make all elements $target: $cost\n";
+ $min_cost = $cost if $cost < $min_cost;
+ }
+
+ return $min_cost;
+}
+
+sub max {
+ my @array = @_;
+ my $max = $array[0];
+ foreach (@array) {
+ $max = $_ if $_ > $max;
+ }
+ return $max;
+}
+
+sub min {
+ my @array = @_;
+ my $min = $array[0];
+ foreach (@array) {
+ $min = $_ if $_ < $min;
+ }
+ return $min;
+}
+
+# Example 1
+my @ints1 = (4, 1);
+my $x1 = 3;
+my $y1 = 2;
+print "Minimum cost: " . min_cost_to_equal_elements(\@ints1, $x1, $y1) . "\n"; # Expected Output: 9
+
+# Example 2
+my @ints2 = (2, 3, 3, 3, 5);
+my $x2 = 2;
+my $y2 = 1;
+print "Minimum cost: " . min_cost_to_equal_elements(\@ints2, $x2, $y2) . "\n"; # Expected Output: 6
diff --git a/challenge-270/lubos-kolouch/python/ch-1.py b/challenge-270/lubos-kolouch/python/ch-1.py
new file mode 100644
index 0000000000..08a785afbd
--- /dev/null
+++ b/challenge-270/lubos-kolouch/python/ch-1.py
@@ -0,0 +1,44 @@
+""" Perl Weekly Challenge 270 LK Task 1 Python """
+
+from typing import List
+
+
+def num_special_positions(matrix: List[List[int]]) -> int:
+ """
+ num_special_positions A position (i, j) is called special if $matrix[i][j] == 1 and all other elements in the row i and column j are 0.
+
+ Args:
+ matrix (List[List[int]]): input matrix
+
+ Returns:
+ int: count of special positions
+ """
+
+ rows = len(matrix)
+ cols = len(matrix[0])
+
+ def is_special(i: int, j: int) -> bool:
+ for x in range(rows):
+ if x != i and matrix[x][j] == 1:
+ return False
+ for y in range(cols):
+ if y != j and matrix[i][y] == 1:
+ return False
+ return True
+
+ special_count = 0
+ for i in range(rows):
+ for j in range(cols):
+ if matrix[i][j] == 1 and is_special(i, j):
+ special_count += 1
+
+ return special_count
+
+
+# Example 1
+matrix1 = [[1, 0, 0], [0, 0, 1], [1, 0, 0]]
+assert num_special_positions(matrix1) == 1
+
+# Example 2
+matrix2 = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
+assert num_special_positions(matrix2) == 3
diff --git a/challenge-270/lubos-kolouch/python/ch-2.py b/challenge-270/lubos-kolouch/python/ch-2.py
new file mode 100644
index 0000000000..23a2d5062a
--- /dev/null
+++ b/challenge-270/lubos-kolouch/python/ch-2.py
@@ -0,0 +1,57 @@
+def min_cost_to_equal_elements(ints, x, y):
+ min_cost = float("inf")
+ max_val = max(ints)
+ min_val = min(ints)
+
+ print(f"Initial array: {ints}")
+ print(f"Cost for Level 1 (x): {x}")
+ print(f"Cost for Level 2 (y): {y}")
+
+ # Try making all elements equal to every value between min_val and max_val
+ for target in range(min_val, max_val + 1):
+ cost = 0
+ print(f"\nTrying to make all elements equal to: {target}")
+
+ for num in ints:
+ diff = abs(target - num)
+ print(f"Difference for element {num} to target {target}: {diff}")
+
+ # Calculate cost using level 2 operations first, then level 1 if needed
+ if y < 2 * x:
+ # Using Level 2 operations where possible
+ level_2_ops = diff // 2
+ level_1_ops = diff % 2
+ cost_addition = (level_2_ops * y) + (level_1_ops * x)
+ print(
+ f"Using Level 2 and Level 1. Cost to adjust {num} to {target}: {cost_addition}"
+ )
+ else:
+ # Using only Level 1 operations
+ cost_addition = diff * x
+ print(
+ f"Using only Level 1. Cost to adjust {num} to {target}: {cost_addition}"
+ )
+
+ cost += cost_addition
+
+ print(f"Total cost to make all elements {target}: {cost}")
+ min_cost = min(min_cost, cost)
+
+ return min_cost
+
+
+# Example 1
+ints1 = [4, 1]
+x1 = 3
+y1 = 2
+print(
+ f"Minimum cost: {min_cost_to_equal_elements(ints1, x1, y1)}"
+) # Expected Output: 9
+
+# Example 2
+ints2 = [2, 3, 3, 3, 5]
+x2 = 2
+y2 = 1
+print(
+ f"Minimum cost: {min_cost_to_equal_elements(ints2, x2, y2)}"
+) # Expected Output: 6
diff --git a/challenge-286/lubos-kolouch/perl/ch-1.pl b/challenge-286/lubos-kolouch/perl/ch-1.pl
new file mode 100644
index 0000000000..cf14677262
--- /dev/null
+++ b/challenge-286/lubos-kolouch/perl/ch-1.pl
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use File::Basename;
+use List::Util 'shuffle';
+use Test::More tests => 1;
+
+=pod
+
+=head1 DESCRIPTION
+
+This script reads its own source code, splits it into words (anything between whitespace), selects one at random, and prints it.
+
+=head1 FUNCTIONS
+
+=head2 get_random_word()
+
+Reads the script's own source code and returns a random word from it.
+
+Returns: A random word as a string.
+
+=cut
+
+sub get_random_word {
+ my $filename = $0; # $0 contains the name of the script
+ open my $fh, '<', $filename or die "Cannot open $filename: $!";
+ my @words;
+ while (my $line = <$fh>) {
+ push @words, split(/\s+/, $line);
+ }
+ close $fh;
+ my $random_word = $words[ rand @words ];
+ return $random_word;
+}
+
+# Main execution
+my $word = get_random_word();
+print "$word\n";
+
+# Test to ensure the word is from the source code
+subtest 'Test if word is from source code' => sub {
+ my $filename = $0;
+ open my $fh, '<', $filename or die "Cannot open $filename: $!";
+ my $content = do { local $/; <$fh> };
+ close $fh;
+ like($content, qr/\b\Q$word\E\b/, 'Word is from source code');
+};
diff --git a/challenge-286/lubos-kolouch/perl/ch-2.pl b/challenge-286/lubos-kolouch/perl/ch-2.pl
new file mode 100644
index 0000000000..646607c2fe
--- /dev/null
+++ b/challenge-286/lubos-kolouch/perl/ch-2.pl
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More tests => 3;
+
+=pod
+
+=head1 DESCRIPTION
+
+This script simulates the Order Game on a given array of integers whose length is a power of 2.
+
+In the Order Game:
+
+- At each round, the array is reduced by pairing elements.
+- For each pair, if it's at an even index (starting from 0), take the minimum of the pair.
+- If it's at an odd index, take the maximum of the pair.
+- This process repeats until only one element remains.
+
+=head1 FUNCTIONS
+
+=head2 order_game(\@ints)
+
+Simulates the Order Game and returns the last remaining element.
+
+=over 4
+
+=item * C<\@ints> - Reference to an array of integers (length is a power of 2).
+
+=back
+
+Returns the last remaining integer after playing the game.
+
+=cut
+
+sub order_game {
+ my ($ints_ref) = @_;
+ my @current_list = @$ints_ref;
+ while (@current_list > 1) {
+ my @next_list;
+ my $n = scalar @current_list;
+ for (my $i = 0; $i < $n / 2; $i++) {
+ if ($i % 2 == 0) {
+ # Even index: take minimum
+ push @next_list, min($current_list[2 * $i], $current_list[2 * $i + 1]);
+ } else {
+ # Odd index: take maximum
+ push @next_list, max($current_list[2 * $i], $current_list[2 * $i + 1]);
+ }
+ }
+ @current_list = @next_list;
+ }
+ return $current_list[0];
+}
+
+sub min {
+ my ($a, $b) = @_;
+ return $a < $b ? $a : $b;
+}
+
+sub max {
+ my ($a, $b) = @_;
+ return $a > $b ? $a : $b;
+}
+
+# Unit Tests
+is(order_game([2, 1, 4, 5, 6, 3, 0, 2]), 1, 'Example 1');
+is(order_game([0, 5, 3, 2]), 0, 'Example 2');
+is(order_game([9, 2, 1, 4, 5, 6, 0, 7, 3, 1, 3, 5, 7, 9, 0, 8]), 2, 'Example 3');
diff --git a/challenge-286/lubos-kolouch/python/ch-1.py b/challenge-286/lubos-kolouch/python/ch-1.py
new file mode 100644
index 0000000000..b47c5340ff
--- /dev/null
+++ b/challenge-286/lubos-kolouch/python/ch-1.py
@@ -0,0 +1,40 @@
+import os
+import random
+import unittest
+from typing import List
+
+
+def get_random_word() -> str:
+ """
+ Reads its own source code, splits it into words, and returns one word at random.
+
+ Returns:
+ str: A random word from the script's source code.
+ """
+ filename: str = os.path.abspath(__file__)
+ with open(filename, 'r') as f:
+ content: str = f.read()
+ words: List[str] = content.split()
+ random_word: str = random.choice(words)
+ return random_word
+
+
+def main() -> None:
+ word: str = get_random_word()
+ print(word)
+
+
+if __name__ == "__main__":
+ main()
+
+ # Unit Test
+ class TestSelfSpammer(unittest.TestCase):
+
+ def test_word_in_source(self):
+ word = get_random_word()
+ filename = os.path.abspath(__file__)
+ with open(filename, 'r') as f:
+ content = f.read()
+ self.assertIn(word, content.split(), "Word is from source code")
+
+ unittest.main(argv=['first-arg-is-ignored'], exit=False)
diff --git a/challenge-286/lubos-kolouch/python/ch-2.py b/challenge-286/lubos-kolouch/python/ch-2.py
new file mode 100644
index 0000000000..212c9ac1da
--- /dev/null
+++ b/challenge-286/lubos-kolouch/python/ch-2.py
@@ -0,0 +1,64 @@
+from typing import List
+import unittest
+
+
+def order_game(ints: List[int]) -> int:
+ """
+ Simulates the Order Game on the given list of integers.
+
+ In the Order Game:
+ - At each round, the array is reduced by pairing elements.
+ - For each pair at an even index (starting from 0), take the minimum of the pair.
+ - For each pair at an odd index, take the maximum of the pair.
+ - Repeat the process until only one element remains.
+
+ Args:
+ ints (List[int]): A list of integers whose length is a power of 2.
+
+ Returns:
+ int: The last remaining integer after playing the game.
+ """
+ current_list = ints.copy()
+ while len(current_list) > 1:
+ next_list = []
+ n = len(current_list)
+ for i in range(n // 2):
+ if i % 2 == 0:
+ # Even index: take minimum
+ next_list.append(
+ min(current_list[2 * i], current_list[2 * i + 1]))
+ else:
+ # Odd index: take maximum
+ next_list.append(
+ max(current_list[2 * i], current_list[2 * i + 1]))
+ current_list = next_list
+ return current_list[0]
+
+
+# Unit Tests
+class TestOrderGame(unittest.TestCase):
+
+ def test_example1(self):
+ ints = [2, 1, 4, 5, 6, 3, 0, 2]
+ self.assertEqual(order_game(ints), 1, 'Example 1')
+
+ def test_example2(self):
+ ints = [0, 5, 3, 2]
+ self.assertEqual(order_game(ints), 0, 'Example 2')
+
+ def test_example3(self):
+ ints = [9, 2, 1, 4, 5, 6, 0, 7, 3, 1, 3, 5, 7, 9, 0, 8]
+ self.assertEqual(order_game(ints), 2, 'Example 3')
+
+ def test_power_of_two_length(self):
+ ints = [1, 2]
+ self.assertEqual(order_game(ints), 1, 'Length 2 array')
+
+ def test_large_array(self):
+ ints = [i for i in range(16)]
+ result = order_game(ints)
+ self.assertIsInstance(result, int, 'Result is an integer')
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/challenge-287/lubos-kolouch/perl/ch-1.pl b/challenge-287/lubos-kolouch/perl/ch-1.pl
new file mode 100644
index 0000000000..f79b745639
--- /dev/null
+++ b/challenge-287/lubos-kolouch/perl/ch-1.pl
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More tests => 5;
+
+=pod
+
+=head1 DESCRIPTION
+
+This script determines the minimum number of steps required to make a given string a strong password based on the following criteria:
+
+- At least 6 characters long.
+- Contains at least one lowercase letter, one uppercase letter, and one digit.
+- Does not contain three repeating characters in a row.
+
+=head1 FUNCTIONS
+
+=head2 strong_password_steps($s)
+
+Calculates the minimum number of steps required to make the string a strong password.
+
+=over 4
+
+=item * C<$s> - The input string.
+
+=back
+
+Returns the minimum number of steps as an integer.
+
+=cut
+
+sub strong_password_steps {
+ my ($s) = @_;
+ my $missing_types = 3;
+ $missing_types-- if $s =~ /[a-z]/;
+ $missing_types-- if $s =~ /[A-Z]/;
+ $missing_types-- if $s =~ /\d/;
+
+ my $repeats_to_fix = 0;
+ my $i = 2;
+ my $n = length($s);
+ while ($i < $n) {
+ if (substr($s, $i, 1) eq substr($s, $i - 1, 1) and substr($s, $i - 1, 1) eq substr($s, $i - 2, 1)) {
+ my $repeat_len = 3;
+ while ($i + 1 < $n and substr($s, $i + 1, 1) eq substr($s, $i, 1)) {
+ $repeat_len++;
+ $i++;
+ }
+ $repeats_to_fix += int($repeat_len / 3);
+ }
+ $i++;
+ }
+
+ my $total_steps;
+ if ($n >= 6) {
+ $total_steps = ($missing_types > $repeats_to_fix) ? $missing_types : $repeats_to_fix;
+ } else {
+ my $insertions_needed = 6 - $n;
+ my $sum = $missing_types + $repeats_to_fix;
+ $total_steps = ($sum > $insertions_needed) ? $sum : $insertions_needed;
+ }
+ return $total_steps;
+}
+
+# Tests
+is(strong_password_steps("a"), 5, 'Example 1');
+is(strong_password_steps("aB2"), 3, 'Example 2');
+is(strong_password_steps("PaaSW0rd"), 0, 'Example 3');
+is(strong_password_steps("Paaasw0rd"), 1, 'Example 4');
+is(strong_password_steps("aaaaa"), 3, 'Example 5');
+
diff --git a/challenge-287/lubos-kolouch/perl/ch-2.pl b/challenge-287/lubos-kolouch/perl/ch-2.pl
new file mode 100644
index 0000000000..f72e9cb595
--- /dev/null
+++ b/challenge-287/lubos-kolouch/perl/ch-2.pl
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More tests => 7;
+
+=pod
+
+=head1 DESCRIPTION
+
+This script determines if the given string is a valid number based on specific rules.
+
+A valid number is defined as:
+
+- An integer number followed by an optional exponent.
+- A decimal number followed by an optional exponent.
+
+An integer number is defined with an optional sign '-' or '+' followed by digits.
+
+=head1 DEFINITIONS
+
+=head2 Decimal Number
+
+A decimal number is defined with an optional sign '-' or '+' followed by one of the following:
+
+- Digits followed by a dot '.'.
+- Digits followed by a dot '.' followed by digits.
+- A dot '.' followed by digits.
+
+=head2 Exponent
+
+An exponent is defined with an exponent notation 'e' or 'E' followed by an integer number.
+
+=head1 FUNCTIONS
+
+=head2 is_valid_number($s)
+
+Determines if the given string is a valid number.
+
+=over 4
+
+=item * C<$s> - The input string.
+
+=back
+
+Returns 1 if valid, 0 otherwise.
+
+=cut
+
+sub is_valid_number {
+ my ($s) = @_;
+ my $pattern = qr/
+ ^ # Start of string
+ [+-]? # Optional sign
+ (
+ ( # Decimal numbers
+ \d+\.\d* # Digits followed by dot and optional digits
+ |
+ \.\d+ # Dot followed by digits
+ |
+ \d+\. # Digits followed by dot
+ )
+ |
+ \d+ # Integer numbers
+ )
+ ([eE][+-]?\d+)? # Optional exponent
+ $ # End of string
+ /x;
+ return $s =~ $pattern ? 1 : 0;
+}
+
+# Unit Tests
+is(is_valid_number("1"), 1, 'Example 1');
+is(is_valid_number("a"), 0, 'Example 2');
+is(is_valid_number("."), 0, 'Example 3');
+is(is_valid_number("1.2e4.2"),0, 'Example 4');
+is(is_valid_number("-1."), 1, 'Example 5');
+is(is_valid_number("+1E-8"), 1, 'Example 6');
+is(is_valid_number(".44"), 1, 'Example 7');
+
diff --git a/challenge-287/lubos-kolouch/python/ch-1.py b/challenge-287/lubos-kolouch/python/ch-1.py
new file mode 100644
index 0000000000..9593c70beb
--- /dev/null
+++ b/challenge-287/lubos-kolouch/python/ch-1.py
@@ -0,0 +1,59 @@
+import unittest
+
+
+def strong_password_steps(s: str) -> int:
+ """
+ Calculates the minimum number of steps required to make the given string a strong password.
+
+ A strong password must:
+ - Be at least 6 characters long.
+ - Contain at least one lowercase letter, one uppercase letter, and one digit.
+ - Not contain three repeating characters in a row.
+
+ Args:
+ s (str): The input password string.
+
+ Returns:
+ int: The minimum number of steps required to make the password strong.
+ """
+ import re
+ missing_types = 3
+ if re.search(r'[a-z]', s):
+ missing_types -= 1
+ if re.search(r'[A-Z]', s):
+ missing_types -= 1
+ if re.search(r'\d', s):
+ missing_types -= 1
+
+ repeats_to_fix = 0
+ i = 2
+ n = len(s)
+ while i < n:
+ if s[i] == s[i - 1] == s[i - 2]:
+ repeat_len = 3
+ while i + 1 < n and s[i + 1] == s[i]:
+ repeat_len += 1
+ i += 1
+ repeats_to_fix += repeat_len // 3
+ i += 1
+
+ if n >= 6:
+ total_steps = max(missing_types, repeats_to_fix)
+ else:
+ total_steps = max(missing_types + repeats_to_fix, 6 - n)
+ return total_steps
+
+
+# Unit Tests
+class TestStrongPassword(unittest.TestCase):
+
+ def test_examples(self):
+ self.assertEqual(strong_password_steps("a"), 5, 'Example 1')
+ self.assertEqual(strong_password_steps("aB2"), 3, 'Example 2')
+ self.assertEqual(strong_password_steps("PaaSW0rd"), 0, 'Example 3')
+ self.assertEqual(strong_password_steps("Paaasw0rd"), 1, 'Example 4')
+ self.assertEqual(strong_password_steps("aaaaa"), 3, 'Example 5')
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/challenge-287/lubos-kolouch/python/ch-2.py b/challenge-287/lubos-kolouch/python/ch-2.py
new file mode 100644
index 0000000000..f302b7360a
--- /dev/null
+++ b/challenge-287/lubos-kolouch/python/ch-2.py
@@ -0,0 +1,75 @@
+import re
+from typing import Any
+import unittest
+
+
+def is_valid_number(s: str) -> bool:
+ """
+ Determines if the given string is a valid number based on specific rules.
+
+ A valid number is defined as:
+ - An integer number followed by an optional exponent.
+ - A decimal number followed by an optional exponent.
+
+ An integer number is defined with an optional sign '-' or '+' followed by digits.
+
+ Decimal Number:
+ - An optional sign '-' or '+' followed by one of the following:
+ - Digits followed by a dot '.'.
+ - Digits followed by a dot '.' followed by digits.
+ - A dot '.' followed by digits.
+
+ Exponent:
+ - An exponent is defined with an exponent notation 'e' or 'E' followed by an integer number.
+
+ Args:
+ s (str): The input string.
+
+ Returns:
+ bool: True if the string is a valid number, False otherwise.
+ """
+ pattern = r"""
+ ^ # Start of string
+ [+-]? # Optional sign
+ (
+ ( # Decimal numbers
+ \d+\.\d* # Digits followed by dot and optional digits
+ |
+ \.\d+ # Dot followed by digits
+ |
+ \d+\. # Digits followed by dot
+ )
+ |
+ \d+ # Integer numbers
+ )
+ ([eE][+-]?\d+)? # Optional exponent
+ $ # End of string
+ """
+ regex = re.compile(pattern, re.VERBOSE)
+ return bool(regex.match(s))
+
+
+# Unit Tests
+class TestValidNumber(unittest.TestCase):
+
+ def test_examples(self):
+ self.assertEqual(is_valid_number("1"), True, 'Example 1')
+ self.assertEqual(is_valid_number("a"), False, 'Example 2')
+ self.assertEqual(is_valid_number("."), False, 'Example 3')
+ self.assertEqual(is_valid_number("1.2e4.2"), False, 'Example 4')
+ self.assertEqual(is_valid_number("-1."), True, 'Example 5')
+ self.assertEqual(is_valid_number("+1E-8"), True, 'Example 6')
+ self.assertEqual(is_valid_number(".44"), True, 'Example 7')
+
+ def test_additional(self):
+ self.assertEqual(is_valid_number("6e6.5"), False,
+ 'Exponent with decimal')
+ self.assertEqual(is_valid_number(""), False, 'Empty string')
+ self.assertEqual(is_valid_number("123"), True, 'Integer number')
+ self.assertEqual(is_valid_number("-."), False,
+ 'Negative dot without digits')
+ self.assertEqual(is_valid_number("1e"), False, 'Incomplete exponent')
+
+
+if __name__ == "__main__":
+ unittest.main()