diff options
| -rw-r--r-- | challenge-270/lubos-kolouch/perl/ch-1.pl | 34 | ||||
| -rw-r--r-- | challenge-270/lubos-kolouch/perl/ch-2.pl | 74 | ||||
| -rw-r--r-- | challenge-270/lubos-kolouch/python/ch-1.py | 44 | ||||
| -rw-r--r-- | challenge-270/lubos-kolouch/python/ch-2.py | 57 | ||||
| -rw-r--r-- | challenge-286/lubos-kolouch/perl/ch-1.pl | 47 | ||||
| -rw-r--r-- | challenge-286/lubos-kolouch/perl/ch-2.pl | 68 | ||||
| -rw-r--r-- | challenge-286/lubos-kolouch/python/ch-1.py | 40 | ||||
| -rw-r--r-- | challenge-286/lubos-kolouch/python/ch-2.py | 64 | ||||
| -rw-r--r-- | challenge-287/lubos-kolouch/perl/ch-1.pl | 71 | ||||
| -rw-r--r-- | challenge-287/lubos-kolouch/perl/ch-2.pl | 79 | ||||
| -rw-r--r-- | challenge-287/lubos-kolouch/python/ch-1.py | 59 | ||||
| -rw-r--r-- | challenge-287/lubos-kolouch/python/ch-2.py | 75 |
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() |
