aboutsummaryrefslogtreecommitdiff
path: root/challenge-331/fabio-valeri/perl/ch-2.pl
blob: e7d389f33b46bdbd38516bea5cdd6c9002f41618 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';


# Task 2: Buddy Strings
# Submitted by: Mohammad Sajid Anwar
#
# You are given two strings, source and target.
# Write a script to find out if the given strings are Buddy Strings.
# If swapping of a letter in one string make them same as the other then they are `Buddy Strings`.
#
# Example 1
# Input: $source = "fuck"
#        $target = "fcuk"
# Output: true
# The swapping of 'u' with 'c' makes it buddy strings.
#
# Example 2
# Input: $source = "love"
#        $target = "love"
# Output: false
#
# Example 3
# Input: $source = "fodo"
#        $target = "food"
# Output: true
#
# Example 4
# Input: $source = "feed"
#        $target = "feed"
# Output: true


# Function to check if two strings are buddy strings
sub are_buddy_strings {
    my ($source, $target) = @_;

    # Must be same length
    return 0 if length($source) != length($target);

    # Find differences
    my @diff_positions = ();
    for my $i (0 .. length($source) - 1) {
        if (substr($source, $i, 1) ne substr($target, $i, 1)) {
            push @diff_positions, $i;
        }
    }

    # Case 1: No differences - strings are identical
    if (@diff_positions == 0) {
        # Check if source has duplicate characters (can swap identical chars)
        my %char_count = ();
        for my $char (split //, $source) {
            $char_count{$char}++;
            return 1 if $char_count{$char} >= 2;  # Found duplicate
        }
        return 0;  # No duplicates, can't swap
    }

    # Case 2: Exactly 2 differences
    elsif (@diff_positions == 2) {
        my ($pos1, $pos2) = @diff_positions;
        # Check if swapping these positions makes strings equal
        return (substr($source, $pos1, 1) eq substr($target, $pos2, 1) &&
                substr($source, $pos2, 1) eq substr($target, $pos1, 1));
    }

    # Case 3: More than 2 differences - impossible with single swap
    else {
        return 0;
    }
}

# Test cases from the problem
my @test_cases = (
              ["fuck", "fcuk", 1, "Swapping 'u' with 'c'"]
             ,["love", "love", 0, "Identical with no duplicates"]
             ,["fodo", "food", 1, "Swapping 'd' with 'o'"]
             ,["feed", "feed", 1, "Identical with duplicate 'e'"]
             ,["abc" , "def" , 0, "Completely different"]
             ,["abcd", "abc" , 0, "Different lengths"]
             ,["ab"  , "ba"  , 1, "Simple swap"]
             ,["aa"  , "aa"  , 1, "Identical with duplicates"]
             ,["abc" , "acb" , 1, "Swap b and c"]
             ,["abcd", "badc", 0, "Too many differences"]
);

say "Testing Buddy Strings:\n";

foreach my $test (@test_cases) {
    my ($source, $target, $expected, $description) = @$test;
    my $result = are_buddy_strings($source, $target);
    my $status = ($result == $expected) ? "OK" : "ERROR";

    printf "%s Source: %-6s Target: %-6s => %s (Expected: %s)  %s\n"
           , $status, "\"$source\"", "\"$target\""
           , $result ? "true" : "false"
           , $expected ? "true" : "false"
           , $description
           f;
}

# Command line testing
if (@ARGV >= 2) {
    say "\nCommand line test:";
    my $result = are_buddy_strings($ARGV[0], $ARGV[1]);
    say "Source: \"$ARGV[0]\", Target: \"$ARGV[1]\" => " . ($result ? "true" : "false");
}