Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use Test::More;
- use Test::Exception;
- use Data::Dumper;
- use strict;
- use warnings;
- use constant {
- SOLVE => 0
- };
- SOLVE
- ? solve()
- : run_tests();
- sub solve {
- my $sherlock_string_checker = HackerRank::SherlockString->new();
- $sherlock_string_checker->set_string_to_check('abc');
- $sherlock_string_checker->is_string_valid();
- }
- sub run_tests {
- subtest 'set_string_to_check' => sub {
- my $sherlock_string_checker = HackerRank::SherlockString->new();
- $sherlock_string_checker->set_string_to_check('a');
- is($sherlock_string_checker->{string_to_check}, 'a');
- $sherlock_string_checker->set_string_to_check('ab');
- is($sherlock_string_checker->{string_to_check}, 'ab');
- $sherlock_string_checker->set_string_to_check('abc');
- is($sherlock_string_checker->{string_to_check}, 'abc');
- $sherlock_string_checker->set_string_to_check('a' x 10000);
- is($sherlock_string_checker->{string_to_check}, 'a' x 10000);
- dies_ok { $sherlock_string_checker->set_string_to_check('') } 'String must have at least one char';
- dies_ok { $sherlock_string_checker->set_string_to_check('1') } 'String cannot contain non lower case letters';
- dies_ok { $sherlock_string_checker->set_string_to_check('a1') } 'String cannot contain non lower case letters';
- dies_ok { $sherlock_string_checker->set_string_to_check('$') } 'String cannot contain non lower case letters';
- dies_ok { $sherlock_string_checker->set_string_to_check('a1b&') } 'String cannot contain non lower case letters';
- dies_ok { $sherlock_string_checker->set_string_to_check('a' x 10001) } 'String cannot exceed size of 10000';
- };
- subtest 'is_string_valid' => sub {
- my $sherlock_string_checker = HackerRank::SherlockString->new();
- $sherlock_string_checker->set_string_to_check('a');
- is($sherlock_string_checker->is_string_valid(), 1);
- $sherlock_string_checker->set_string_to_check('ab');
- is($sherlock_string_checker->is_string_valid(), 1);
- $sherlock_string_checker->set_string_to_check('aa');
- is($sherlock_string_checker->is_string_valid(), 1);
- $sherlock_string_checker->set_string_to_check('aab');
- is($sherlock_string_checker->is_string_valid(), 1);
- $sherlock_string_checker->set_string_to_check('abc');
- is($sherlock_string_checker->is_string_valid(), 1);
- $sherlock_string_checker->set_string_to_check('aabc');
- is($sherlock_string_checker->is_string_valid(), 1);
- $sherlock_string_checker->set_string_to_check('aaab');
- is($sherlock_string_checker->is_string_valid(), 1);
- $sherlock_string_checker->set_string_to_check('aabc');
- is($sherlock_string_checker->is_string_valid(), 1);
- $sherlock_string_checker->set_string_to_check('aaacb');
- is($sherlock_string_checker->is_string_valid(), 0);
- $sherlock_string_checker->set_string_to_check('aaaccb');
- is($sherlock_string_checker->is_string_valid(), 0);
- };
- done_testing();
- }
- package HackerRank::SherlockString;
- use Data::Dumper;
- use strict;
- use warnings;
- sub new {
- my $class = shift;
- my $self = {
- string_to_check => '',
- };
- return bless $self, $class;
- }
- sub set_string_to_check {
- my $self = shift;
- $self->{string_to_check} = shift;
- die 'Invalid string' if (!$self->validate_string_to_check());
- }
- sub validate_string_to_check {
- my $self = shift;
- my $string_to_check_has_non_lc_alpha_chars = $self->{string_to_check} =~ m/[^a-z]+/;
- return (
- !$string_to_check_has_non_lc_alpha_chars
- && length($self->{string_to_check}) >= 1
- && length($self->{string_to_check}) <= 10000
- );
- }
- sub is_string_valid {
- my $self = shift;
- my @sorted_frequencies = sort { $a <=> $b } values % { $self->get_letter_frequencies() };
- if (frequency_start_and_end_are_same(\@sorted_frequencies) || check_if_removing_single_frequency_validates_string(\@sorted_frequencies)) {
- return 1;
- }
- my $current_frequency = $sorted_frequencies[0];
- my $performed_delete = 0;
- for (my $index = 1; $index < scalar(@sorted_frequencies); $index++) {
- if ($current_frequency != $sorted_frequencies[$index]) {
- if ($performed_delete || $current_frequency < $sorted_frequencies[$index] - 1) {
- return 0;
- }
- else {
- $performed_delete = 1;
- }
- }
- $current_frequency = $sorted_frequencies[$index];
- }
- return 1;
- }
- sub get_letter_frequencies {
- my $self = shift;
- my $letter_frequencies = {};
- foreach my $letter (split(//, $self->{string_to_check})) {
- $letter_frequencies->{$letter} = ++$letter_frequencies->{$letter} || 1;
- }
- return $letter_frequencies;
- }
- sub frequency_start_and_end_are_same {
- my $frequencies = shift;
- return $frequencies->[0] == $frequencies->[-1];
- }
- sub check_if_removing_single_frequency_validates_string {
- my $frequencies = shift;
- if ($frequencies->[0] == 1 && $frequencies->[1] != 1) {
- my $removed_first = splice(@$frequencies, 1, -1);
- return frequency_start_and_end_are_same($removed_first);
- }
- }
Add Comment
Please, Sign In to add comment