aboutsummaryrefslogtreecommitdiff
path: root/challenge-081/bob-lied/perl/lib/CommonBaseString.pm
blob: 4c6f98901c8042c5d67058c386457f42de1ad69d (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
# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
#=============================================================================
# CommonBaseString.pm
#=============================================================================
# Copyright (c) 2020, Bob Lied
#=============================================================================
# Description:
#=============================================================================

package CommonBaseString;

use strict;
use warnings;
use v5.30;

use feature qw/ signatures /;
no warnings qw/ experimental::signatures /;

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw();
our @EXPORT_OK = qw(commonPrefix);

sub new($class, $a, $b)
{
    $class = ref($class) || $class;
    my $self = {
        _a => $a,
        _b => $b,
    };
    bless $self, $class;
    return $self;
}

# 
sub commonPrefix($s, $t)
{
    my @s1 = split("", $s);
    my @s2 = split("", $t);
    my $prefix = "";
    my @possiblePrefixes = ();

    while ( @s1 && @s2 && ($s = shift @s1) eq ($t = shift @s2) )
    {
        $prefix .= $s;
        push @possiblePrefixes, $prefix;
    }
    return \@possiblePrefixes;
}

sub run($self)
{
    my ($A, $B) = @{$self}{qw(_a _b)};
    my ($lenA, $lenB) = ( length($A), length($B) );
    my @thisWorks = ();

    my $prefixes = commonPrefix($A, $B);

    for my $prefix ( @$prefixes )
    {
        my $lenP = length($prefix);
        # Only prefixes that can be repeated to the length of both strings
        # are candidates.
        next unless $lenA % $lenP == 0;
        next unless $lenB % $lenP == 0;

        # Number of repetitions required for each string.
        my $repA = $lenA / $lenP;
        my $repB = $lenB / $lenP;

        my $buildsA = ( ($prefix x $repA) eq $A );
        my $buildsB = ( ($prefix x $repB) eq $B );
        push @thisWorks, $prefix if ( $buildsA && $buildsB );
    }

    return \@thisWorks;
}

1;