aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-02-03 11:15:57 +0000
committerGitHub <noreply@github.com>2025-02-03 11:15:57 +0000
commitb700b52fba41b64aaae9e234d3f56f0f2817806a (patch)
tree51d014cfabeb1779ea668fa642076fc9d1b29433
parentf73777c1c1e9c7a3491acbf060191c245f9fc534 (diff)
parent1c8596d40a325a56de55b1c1f1e06f530041efc0 (diff)
downloadperlweeklychallenge-club-b700b52fba41b64aaae9e234d3f56f0f2817806a.tar.gz
perlweeklychallenge-club-b700b52fba41b64aaae9e234d3f56f0f2817806a.tar.bz2
perlweeklychallenge-club-b700b52fba41b64aaae9e234d3f56f0f2817806a.zip
Merge pull request #11523 from LubosKolouch/master
LK: Perl and Python solutions for Challenge 307
-rw-r--r--challenge-307/lubos-kolouch/perl/ch-1.pl58
-rw-r--r--challenge-307/lubos-kolouch/perl/ch-2.pl62
-rw-r--r--challenge-307/lubos-kolouch/python/ch-1.py56
-rw-r--r--challenge-307/lubos-kolouch/python/ch-2.py57
4 files changed, 233 insertions, 0 deletions
diff --git a/challenge-307/lubos-kolouch/perl/ch-1.pl b/challenge-307/lubos-kolouch/perl/ch-1.pl
new file mode 100644
index 0000000000..ded26ca1cb
--- /dev/null
+++ b/challenge-307/lubos-kolouch/perl/ch-1.pl
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More tests => 4;
+
+=head1 NAME
+
+check_order.pl - Rearrange an array in increasing order and return differing indices
+
+=head1 SYNOPSIS
+
+ perl check_order.pl
+
+=head1 DESCRIPTION
+
+This script defines a function that accepts an array reference of integers.
+It sorts the array in increasing order and returns the indices where the sorted array
+differs from the original.
+
+=head2 check_order
+
+ my $diff_indices_ref = check_order($ints_ref);
+
+This function takes an array reference of integers and returns an array reference
+containing the indices at which the sorted array differs from the original.
+
+=cut
+
+sub check_order {
+ my ($ints_ref) = @_;
+ my @original = @$ints_ref;
+ my @sorted = sort { $a <=> $b } @original;
+ my @diff_indices;
+ for my $i ( 0 .. $#original ) {
+ if ( $original[$i] != $sorted[$i] ) {
+ push @diff_indices, $i;
+ }
+ }
+ return \@diff_indices;
+}
+
+# Unit tests
+
+my $result;
+
+$result = check_order( [ 5, 2, 4, 3, 1 ] );
+is_deeply( $result, [ 0, 2, 3, 4 ], 'Test example 1' );
+
+$result = check_order( [ 1, 2, 1, 1, 3 ] );
+is_deeply( $result, [ 1, 3 ], 'Test example 2' );
+
+$result = check_order( [ 3, 1, 3, 2, 3 ] );
+is_deeply( $result, [ 0, 1, 3 ], 'Test example 3' );
+
+$result = check_order( [ 1, 2, 3, 4, 5 ] );
+is_deeply( $result, [], 'Test already sorted' );
+
+done_testing();
diff --git a/challenge-307/lubos-kolouch/perl/ch-2.pl b/challenge-307/lubos-kolouch/perl/ch-2.pl
new file mode 100644
index 0000000000..8ef06deec6
--- /dev/null
+++ b/challenge-307/lubos-kolouch/perl/ch-2.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More tests => 4;
+
+=head1 NAME
+
+find_anagrams.pl - Drop consecutive anagrams and return the count of the final list
+
+=head1 DESCRIPTION
+
+This script applies the rule: whenever two consecutive words are anagrams,
+drop the first word and keep the second. This is repeated until no such pair exists.
+According to this rule, any contiguous block of anagrams will collapse to a single word.
+
+=head2 sorted_word
+
+ my $sorted = sorted_word($word);
+
+Returns the characters of the word sorted in increasing order.
+
+=head2 find_anagrams
+
+ my $final_count = find_anagrams(\@words);
+
+Processes the list iteratively and returns the count of words remaining.
+=cut
+
+sub sorted_word {
+ my ($word) = @_;
+ return join '', sort split //, $word;
+}
+
+sub find_anagrams {
+ my ($words_ref) = @_;
+ my @list = @$words_ref;
+ my $changed = 1;
+ while ($changed) {
+ $changed = 0;
+ for ( my $i = 0 ; $i < @list - 1 ; $i++ ) {
+ if ( sorted_word( $list[$i] ) eq sorted_word( $list[ $i + 1 ] ) ) {
+
+ # drop the first word of the pair
+ splice( @list, $i, 1 );
+ $changed = 1;
+ last; # restart scanning from beginning
+ }
+ }
+ }
+ return scalar @list;
+}
+
+# Unit tests for the iterative (fully applied) rule:
+is( find_anagrams( [ "acca", "dog", "god", "perl", "repl" ] ),
+ 3, 'Test example 1' );
+is( find_anagrams( [ "abba", "baba", "aabb", "ab", "ab" ] ),
+ 2, 'Test example 2' );
+is( find_anagrams( [ "abc", "cab", "bca" ] ), 1, 'Test simple chain' );
+is( find_anagrams( [ "word", "drow", "word", "word" ] ),
+ 1, 'Test repeating words' );
+
+done_testing();
diff --git a/challenge-307/lubos-kolouch/python/ch-1.py b/challenge-307/lubos-kolouch/python/ch-1.py
new file mode 100644
index 0000000000..256255aeba
--- /dev/null
+++ b/challenge-307/lubos-kolouch/python/ch-1.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+"""
+Module to check the order of an integer list.
+"""
+
+import unittest
+
+IntList = list[int]
+
+
+def check_order(ints: IntList) -> list[int]:
+ """
+ Rearranges the list in increasing order and returns the indices where the sorted list
+ differs from the original list.
+
+ Args:
+ ints (List[int]): The list of integers.
+
+ Returns:
+ List[int]: A list of indices where the sorted list differs from the original.
+ """
+ sorted_ints = sorted(ints)
+ differences: list[int] = []
+ for i, (orig, sorted_val) in enumerate(zip(ints, sorted_ints)):
+ if orig != sorted_val:
+ differences.append(i)
+ return differences
+
+
+if __name__ == "__main__":
+
+ class TestCheckOrder(unittest.TestCase):
+
+ def test_example1(self):
+ input_list = [5, 2, 4, 3, 1]
+ expected = [0, 2, 3, 4]
+ self.assertEqual(check_order(input_list), expected)
+
+ def test_example2(self):
+ input_list = [1, 2, 1, 1, 3]
+ expected = [1, 3]
+ self.assertEqual(check_order(input_list), expected)
+
+ def test_example3(self):
+ input_list = [3, 1, 3, 2, 3]
+ expected = [0, 1, 3]
+ self.assertEqual(check_order(input_list), expected)
+
+ def test_already_sorted(self):
+ input_list = [1, 2, 3, 4, 5]
+ expected = []
+ self.assertEqual(check_order(input_list), expected)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/challenge-307/lubos-kolouch/python/ch-2.py b/challenge-307/lubos-kolouch/python/ch-2.py
new file mode 100644
index 0000000000..a7124d14d6
--- /dev/null
+++ b/challenge-307/lubos-kolouch/python/ch-2.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+"""
+Module to process a list of words by dropping consecutive anagrams.
+Applies the rule iteratively:
+if two consecutive words are anagrams, drop the first word.
+A contiguous block of anagrams will collapse to a single word.
+"""
+
+import unittest
+
+
+def sorted_word(word: str) -> str:
+ return ''.join(sorted(word))
+
+
+def find_anagrams(words: list[str]) -> int:
+ """
+ Iteratively remove the first word from any consecutive pair of anagrams.
+
+ Args:
+ words (List[str]): The list of words.
+
+ Returns:
+ int: The count of words remaining after processing.
+ """
+ lst = words[:] # work on a copy
+ changed = True
+ while changed:
+ changed = False
+ for i in range(len(lst) - 1):
+ if sorted_word(lst[i]) == sorted_word(lst[i + 1]):
+ lst.pop(i)
+ changed = True
+ break # restart from beginning
+ return len(lst)
+
+
+if __name__ == "__main__":
+
+ class TestFindAnagrams(unittest.TestCase):
+
+ def test_example1(self):
+ self.assertEqual(
+ find_anagrams(["acca", "dog", "god", "perl", "repl"]), 3)
+
+ def test_example2(self):
+ self.assertEqual(
+ find_anagrams(["abba", "baba", "aabb", "ab", "ab"]), 2)
+
+ def test_simple_chain(self):
+ self.assertEqual(find_anagrams(["abc", "cab", "bca"]), 1)
+
+ def test_repeating_words(self):
+ self.assertEqual(find_anagrams(["word", "drow", "word", "word"]),
+ 1)
+
+ unittest.main()