Perl Weekly Challenge 314

Equal Strings and Sort Column

Published: 24 Mar 2025

Task 1: Equal Strings

You are given three strings.

You are allowed to remove the rightmost character of a string to make all equals.

Write a script to return the number of operations to make it equal otherwise -1.

Logic

To make three strings equal by only removing characters from the right:

  1. Find the length of the shortest string.
  2. Compare characters from the left (index 0) across all three strings until a mismatch is found.
  3. The number of matching characters from the start is the length of the common prefix.
  4. If the common prefix length is zero, return -1 (cannot make them equal).
  5. Otherwise, the total deletions needed is the sum of (length of each string - common prefix length).

This works because we can only remove from the right, so the strings must match from the left up to the common prefix.

Perl Solution

ch-1.pl

#!/usr/bin/env perl use strict; use warnings; use v5.10; sub equal_strings_ops { my ($s1, $s2, $s3) = @_; my $min_len = length($s1); $min_len = length($s2) if length($s2) < $min_len; $min_len = length($s3) if length($s3) < $min_len; my $i = 0; while ($i < $min_len) { my $ch = substr($s1, $i, 1); last if $ch ne substr($s2, $i, 1) || $ch ne substr($s3, $i, 1); ++$i; } return -1 if $i == 0; return (length($s1) - $i) + (length($s2) - $i) + (length($s3) - $i); } # Test cases from the blog my @tests = ( ['abc', 'abb', 'ab', 2], ['ayz', 'cyz', 'xyz', -1], ['yza', 'yzb', 'yzc', 3], ); for my $test (@tests) { my $result = equal_strings_ops($test->[0], $test->[1], $test->[2]); my $expected = $test->[3]; say $result == $expected ? 'ok' : "not ok: got $result, expected $expected"; }

Python Solution

ch-1.py

#!/usr/bin/env python3 """Solution for Perl Weekly Challenge 314 Task 1: Equal Strings""" def equal_strings_ops(s1, s2, s3): """Return the minimum number of rightmost deletions required to make the three strings equal, or -1 when no non-empty common prefix exists.""" min_len = min(len(s1), len(s2), len(s3)) i = 0 while i < min_len: if s1[i] != s2[i] or s1[i] != s3[i]: break i += 1 if i == 0: return -1 return (len(s1) - i) + (len(s2) - i) + (len(s3) - i) # Test cases from the blog if __name__ == "__main__": test_cases = [ ("abc", "abb", "ab", 2), ("ayz", "cyz", "xyz", -1), ("yza", "yzb", "yzc", 3), ] for s1, s2, s3, expected in test_cases: result = equal_strings_ops(s1, s2, s3) status = "OK" if result == expected else f"FAILED: got {result}, expected {expected}" print(f"equal_strings_ops('{s1}', '{s2}', '{s3}') = {result} [{status}]")

Task 2: Sort Column

You are given a list of strings of same length.

Write a script to make each column sorted lexicographically by deleting any non sorted columns.

Return the total columns deleted.

Logic

To delete columns so that each remaining column is sorted lexicographically (top to bottom):

  1. If the list is empty, return 0.
  2. Determine the number of columns from the length of the first string.
  3. For each column index, check if the characters in that column are in non-decreasing order from top to bottom.
  4. If a column is not sorted (i.e., any character is greater than the one below it), increment the delete count.
  5. Return the total delete count.

This approach checks each column independently and counts those that violate the sorted order.

Perl Solution

ch-2.pl

#!/usr/bin/env perl use strict; use warnings; use v5.10; sub delete_columns { my ($list_ref) = @_; my @list = @$list_ref; return 0 unless @list; my $cols = length($list[0]); my $delete_count = 0; for my $col (0 .. $cols-1) { my $sorted = 1; for my $row (1 .. $#list) { if (substr($list[$row-1], $col, 1) gt substr($list[$row], $col, 1)) { $sorted = 0; last; } } $delete_count++ unless $sorted; } return $delete_count; } # Test cases from the blog my @tests = ( [ ["swpc", "tyad", "azbe"], 2 ], [ ["cba", "daf", "ghi"], 1 ], [ ["a", "b", "c"], 0 ], ); for my $test (@tests) { my $result = delete_columns($test->[0]); my $expected = $test->[1]; say $result == $expected ? 'ok' : "not ok: got $result, expected $expected"; }

Python Solution

ch-2.py

#!/usr/bin/env python3 """Solution for Perl Weekly Challenge 314 Task 2: Sort Column""" def delete_columns(str_list): """Return the number of columns to delete so that each column is sorted lexicographically.""" if not str_list: return 0 n_cols = len(str_list[0]) delete_count = 0 for col in range(n_cols): # Check if column is sorted for row in range(1, len(str_list)): if str_list[row-1][col] > str_list[row][col]: delete_count += 1 break return delete_count # Test cases from the blog if __name__ == "__main__": test_cases = [ (["swpc", "tyad", "azbe"], 2), (["cba", "daf", "ghi"], 1), (["a", "b", "c"], 0), ] for str_list, expected in test_cases: result = delete_columns(str_list) status = "OK" if result == expected else f"FAILED: got {result}, expected {expected}" print(f"delete_columns({str_list}) = {result} [{status}]")