Guest User

Untitled

a guest
Dec 11th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.14 KB | None | 0 0
  1. use Test::More;
  2. use Test::Exception;
  3. use Data::Dumper;
  4. use strict;
  5. use warnings;
  6.  
  7. use constant {
  8. SOLVE => 0
  9. };
  10.  
  11. SOLVE
  12. ? solve()
  13. : run_tests();
  14.  
  15. sub solve {
  16. my $sherlock_string_checker = HackerRank::SherlockString->new();
  17. $sherlock_string_checker->set_string_to_check('abc');
  18. $sherlock_string_checker->is_string_valid();
  19. }
  20.  
  21. sub run_tests {
  22. subtest 'set_string_to_check' => sub {
  23. my $sherlock_string_checker = HackerRank::SherlockString->new();
  24.  
  25. $sherlock_string_checker->set_string_to_check('a');
  26. is($sherlock_string_checker->{string_to_check}, 'a');
  27.  
  28. $sherlock_string_checker->set_string_to_check('ab');
  29. is($sherlock_string_checker->{string_to_check}, 'ab');
  30.  
  31. $sherlock_string_checker->set_string_to_check('abc');
  32. is($sherlock_string_checker->{string_to_check}, 'abc');
  33.  
  34. $sherlock_string_checker->set_string_to_check('a' x 10000);
  35. is($sherlock_string_checker->{string_to_check}, 'a' x 10000);
  36.  
  37. dies_ok { $sherlock_string_checker->set_string_to_check('') } 'String must have at least one char';
  38.  
  39. dies_ok { $sherlock_string_checker->set_string_to_check('1') } 'String cannot contain non lower case letters';
  40. dies_ok { $sherlock_string_checker->set_string_to_check('a1') } 'String cannot contain non lower case letters';
  41. dies_ok { $sherlock_string_checker->set_string_to_check('$') } 'String cannot contain non lower case letters';
  42. dies_ok { $sherlock_string_checker->set_string_to_check('a1b&') } 'String cannot contain non lower case letters';
  43. dies_ok { $sherlock_string_checker->set_string_to_check('a' x 10001) } 'String cannot exceed size of 10000';
  44. };
  45.  
  46. subtest 'is_string_valid' => sub {
  47. my $sherlock_string_checker = HackerRank::SherlockString->new();
  48. $sherlock_string_checker->set_string_to_check('a');
  49. is($sherlock_string_checker->is_string_valid(), 1);
  50.  
  51. $sherlock_string_checker->set_string_to_check('ab');
  52. is($sherlock_string_checker->is_string_valid(), 1);
  53.  
  54. $sherlock_string_checker->set_string_to_check('aa');
  55. is($sherlock_string_checker->is_string_valid(), 1);
  56.  
  57. $sherlock_string_checker->set_string_to_check('aab');
  58. is($sherlock_string_checker->is_string_valid(), 1);
  59.  
  60. $sherlock_string_checker->set_string_to_check('abc');
  61. is($sherlock_string_checker->is_string_valid(), 1);
  62.  
  63. $sherlock_string_checker->set_string_to_check('aabc');
  64. is($sherlock_string_checker->is_string_valid(), 1);
  65.  
  66. $sherlock_string_checker->set_string_to_check('aaab');
  67. is($sherlock_string_checker->is_string_valid(), 1);
  68.  
  69. $sherlock_string_checker->set_string_to_check('aabc');
  70. is($sherlock_string_checker->is_string_valid(), 1);
  71.  
  72. $sherlock_string_checker->set_string_to_check('aaacb');
  73. is($sherlock_string_checker->is_string_valid(), 0);
  74.  
  75. $sherlock_string_checker->set_string_to_check('aaaccb');
  76. is($sherlock_string_checker->is_string_valid(), 0);
  77. };
  78.  
  79. done_testing();
  80. }
  81.  
  82. package HackerRank::SherlockString;
  83. use Data::Dumper;
  84. use strict;
  85. use warnings;
  86.  
  87. sub new {
  88. my $class = shift;
  89. my $self = {
  90. string_to_check => '',
  91. };
  92.  
  93. return bless $self, $class;
  94. }
  95.  
  96. sub set_string_to_check {
  97. my $self = shift;
  98.  
  99. $self->{string_to_check} = shift;
  100. die 'Invalid string' if (!$self->validate_string_to_check());
  101. }
  102.  
  103. sub validate_string_to_check {
  104. my $self = shift;
  105.  
  106. my $string_to_check_has_non_lc_alpha_chars = $self->{string_to_check} =~ m/[^a-z]+/;
  107.  
  108. return (
  109. !$string_to_check_has_non_lc_alpha_chars
  110. && length($self->{string_to_check}) >= 1
  111. && length($self->{string_to_check}) <= 10000
  112. );
  113. }
  114.  
  115. sub is_string_valid {
  116. my $self = shift;
  117. my @sorted_frequencies = sort { $a <=> $b } values % { $self->get_letter_frequencies() };
  118.  
  119. if (frequency_start_and_end_are_same(\@sorted_frequencies) || check_if_removing_single_frequency_validates_string(\@sorted_frequencies)) {
  120. return 1;
  121. }
  122.  
  123. my $current_frequency = $sorted_frequencies[0];
  124. my $performed_delete = 0;
  125. for (my $index = 1; $index < scalar(@sorted_frequencies); $index++) {
  126. if ($current_frequency != $sorted_frequencies[$index]) {
  127. if ($performed_delete || $current_frequency < $sorted_frequencies[$index] - 1) {
  128. return 0;
  129. }
  130. else {
  131. $performed_delete = 1;
  132. }
  133. }
  134.  
  135. $current_frequency = $sorted_frequencies[$index];
  136. }
  137.  
  138. return 1;
  139. }
  140.  
  141. sub get_letter_frequencies {
  142. my $self = shift;
  143.  
  144. my $letter_frequencies = {};
  145.  
  146. foreach my $letter (split(//, $self->{string_to_check})) {
  147. $letter_frequencies->{$letter} = ++$letter_frequencies->{$letter} || 1;
  148. }
  149.  
  150. return $letter_frequencies;
  151. }
  152.  
  153. sub frequency_start_and_end_are_same {
  154. my $frequencies = shift;
  155.  
  156. return $frequencies->[0] == $frequencies->[-1];
  157. }
  158.  
  159. sub check_if_removing_single_frequency_validates_string {
  160. my $frequencies = shift;
  161.  
  162. if ($frequencies->[0] == 1 && $frequencies->[1] != 1) {
  163. my $removed_first = splice(@$frequencies, 1, -1);
  164. return frequency_start_and_end_are_same($removed_first);
  165. }
  166. }
Add Comment
Please, Sign In to add comment