File Coverage

lib/CellBIS/Random.pm
Criterion Covered Total %
statement 179 250 71.6
branch 52 108 48.1
condition 10 54 18.5
subroutine 20 22 90.9
pod 4 7 57.1
total 265 441 60.0


line stmt bran cond sub pod time code
1             package CellBIS::Random;
2 4     4   277653 use strict;
  4         48  
  4         115  
3 4     4   23 use warnings;
  4         8  
  4         116  
4 4     4   2100 use utf8;
  4         51  
  4         19  
5              
6 4     4   107 use Carp ();
  4         8  
  4         79  
7 4     4   18 use Scalar::Util qw(blessed weaken);
  4         6  
  4         190  
8 4     4   1858 use List::SomeUtils qw(part);
  4         47805  
  4         8326  
9              
10             # ABSTRACT: Tool for Randomize characters in strings.
11             our $VERSION = '0.1';
12              
13             # Constructor :
14             # ------------------------------------------------------------------------
15             sub new {
16 2     2 0 124 my $class = shift;
17 2         9 my $self = {
18             string => shift,
19             result => 'null'
20             };
21 2         4 bless $self, $class;
22 2         5 return $self;
23             }
24              
25             sub set_string {
26 3     3 1 17 my ($self, $string) = @_;
27 3         10 $self->{string} = $string;
28             }
29              
30             sub get_result {
31 0     0 1 0 my $self = shift;
32 0         0 return $self->{result};
33             }
34              
35             sub random {
36 4     4 1 165 my $self = shift;
37 4         10 my $arg_len = scalar @_;
38 4         8 my $string = '';
39 4         7 my $count_odd = 0;
40 4         9 my $count_even = 0;
41 4         5 my $nested = 0;
42 4 50 66     27 Carp::croak(q{Arguments is less than 2 or 3})
43             unless $arg_len == 2 or $arg_len >= 3;
44            
45 4 100       20 if (blessed($self)) {
46 2         4 $string = $self->{string};
47 2 50       6 ($count_odd, $count_even) = @_ if ($arg_len >= 2);
48 2 50       6 ($count_odd, $count_even, $nested) = @_ if ($arg_len >= 3);
49 2 50       23 ($string, $count_odd, $count_even, $nested) = @_ if ($arg_len >= 4);
50             } else {
51 2 50       11 ($string, $count_odd, $count_even) = @_ if ($arg_len >= 3);
52 2 50       7 ($string, $count_odd, $count_even, $nested) = @_ if ($arg_len >= 4);
53             }
54            
55 4         9 my $result = $string;
56 4         5 my $i = 0;
57            
58             # For Nested loop == 1 :
59 4 50       21 if ($nested == 1) {
    50          
60 0 0 0     0 if ($count_odd != 0 and $count_even != 0) {
61 0         0 $i = 0;
62 0         0 while ($i < $count_odd) {
63 0         0 $result = $self->_union_odd_even($string);
64 0         0 $i++;
65             }
66             }
67 0 0 0     0 if ($count_odd != 0 and $count_even == 0) {
68 0         0 $i = 0;
69 0         0 while ($i < $count_even) {
70 0         0 $result = $self->_union_even_odd($string);
71 0         0 $i++;
72             }
73             }
74             }
75            
76             # For Nested loop == 2 :
77             elsif ($nested == 2) {
78 0 0 0     0 if ($count_odd != 0 and $count_even != 0) {
79 0         0 for ($i = 0; $i < $count_odd; $i++) {
80 0         0 $result = $self->_union_odd_even($string);
81 0         0 $result = $self->loop_union_for_odd_even($count_even, $result, 'even_odd');
82             }
83             }
84 0 0 0     0 if ($count_odd != 0 and $count_even == 0) {
85 0         0 $i = 0;
86 0         0 while ($i < $count_odd) {
87 0         0 $result = $self->_union_odd_even($string);
88 0         0 $i++;
89             }
90             }
91 0 0 0     0 if ($count_odd == 0 and $count_even != 0) {
92 0         0 $i = 0;
93 0         0 while ($i < $count_odd) {
94 0         0 $result = $self->_union_even_odd($string);
95 0         0 $i++;
96             }
97             }
98             }
99            
100             # For Nested loop == 0 :
101             else {
102 4 50 33     25 if ($count_odd != 0 and $count_even != 0) {
103 4         6 $i = 0;
104 4         18 my $result1 = $self->loop_union_for_odd_even($count_odd, $result, 'odd_even');
105 4         11 $result = $self->loop_union_for_odd_even($count_even, $result1, 'even_odd');
106             }
107 4 50 33     31 if ($count_odd != 0 and $count_even == 0) {
108 0         0 $i = 0;
109 0         0 $result = $self->loop_union_for_odd_even($count_odd, $result, 'odd_even');
110             }
111 4 50 33     14 if ($count_odd == 0 and $count_even != 0) {
112 0         0 $i = 0;
113 0         0 $result = $self->loop_union_for_odd_even($count_even, $result, 'even_odd');
114             }
115             }
116 4 100       18 $self->{'result'} = $result if blessed($self);
117 4         12 return $result;
118             }
119              
120             sub unrandom {
121 2     2 1 10 my $self = shift;
122 2         13 my $arg_len = scalar @_;
123 2         3 my $string = '';
124 2         3 my $count_odd = 0;
125 2         3 my $count_even = 0;
126 2         4 my $nested = 0;
127 2 50 66     8 Carp::croak(q{Arguments is less than 2 or 2})
128             unless $arg_len == 2 or $arg_len >= 3;
129            
130 2 100       7 if (blessed($self)) {
131 1         2 $string = $self->{string};
132 1 50       4 ($count_odd, $count_even) = @_ if ($arg_len >= 2);
133 1 50       2 ($count_odd, $count_even, $nested) = @_ if ($arg_len >= 3);
134 1 50       10 ($string, $count_odd, $count_even, $nested) = @_ if ($arg_len >= 4);
135             } else {
136 1 50       3 ($string, $count_odd, $count_even) = @_ if ($arg_len >= 3);
137 1 50       3 ($string, $count_odd, $count_even, $nested) = @_ if ($arg_len >= 4);
138             }
139            
140 2         4 my $result = $string;
141 2         4 my $i = 0;
142            
143             # For Nested loop == 1 :
144 2 50       9 if ($nested == 1) {
    50          
145 0 0 0     0 if ($count_odd != 0 and $count_even != 0) {
146 0         0 $i = 0;
147 0         0 while ($i < $count_odd) {
148 0         0 $result = $self->_reverse_union_odd_even($string);
149 0         0 $i++;
150             }
151             }
152 0 0 0     0 if ($count_odd != 0 and $count_even == 0) {
153 0         0 $i = 0;
154 0         0 while ($i < $count_even) {
155 0         0 $result = $self->_reverse_union_even_odd($string);
156 0         0 $i++;
157             }
158             }
159             }
160            
161             # For Nested loop == 2 :
162             elsif ($nested == 2) {
163 0 0 0     0 if ($count_odd != 0 and $count_even != 0) {
164             # $i = 0;
165 0         0 for ($i = 0; $i < $count_odd; $i++) {
166 0         0 $result = $self->reverse_loop_union_for_odd_even($count_even, $string, 'even_odd');
167 0         0 $result = $self->_reverse_union_odd_even($result);
168             }
169             }
170 0 0 0     0 if ($count_odd != 0 and $count_even == 0) {
171 0         0 $i = 0;
172 0         0 while ($i < $count_odd) {
173 0         0 $result = $self->_reverse_union_odd_even($string);
174 0         0 $i++;
175             }
176             }
177 0 0 0     0 if ($count_odd == 0 and $count_even != 0) {
178 0         0 $i = 0;
179 0         0 while ($i < $count_odd) {
180 0         0 $result = $self->_reverse_union_even_odd($string);
181 0         0 $i++;
182             }
183             }
184             }
185            
186             # For Nested loop == 0 :
187             else {
188 2 50 33     27 if ($count_odd != 0 and $count_even != 0) {
189 2         8 my $result1 = $self->reverse_loop_union_for_odd_even($count_even, $result, 'even_odd');
190 2         17 $result = $self->reverse_loop_union_for_odd_even($count_odd, $result1, 'odd_even');
191             }
192 2 50 33     10 if ($count_odd != 0 and $count_even == 0) {
193 0         0 $i = 0;
194 0         0 $result = $self->reverse_loop_union_for_odd_even($count_odd, $string, 'odd_even');
195             }
196 2 50 33     7 if ($count_odd == 0 and $count_even != 0) {
197 0         0 $i = 0;
198 0         0 $result = $self->reverse_loop_union_for_odd_even($count_even, $string, 'even_odd');
199             }
200             }
201 2 100       31 $self->{'result'} = $result if blessed($self);
202 2         7 return $result;
203             }
204              
205             #############################################################################################
206             # UTILITIES :
207             #############################################################################################
208              
209             sub loop_union_for_odd_even {
210 8     8 0 23 my ($self, $count_loop, $string, $type) = @_;
211 8         36 my $result = $string;
212 8         13 my $i = 0;
213            
214 8 100       20 if ($type eq 'odd_even') {
215 4         12 while ($i < $count_loop) {
216 8         28 $result = $self->_union_odd_even($result);
217 8         25 $i++;
218             }
219             }
220 8 100       17 if ($type eq 'even_odd') {
221 4         13 while ($i < $count_loop) {
222 12         25 $result = $self->_union_even_odd($result);
223 12         25 $i++;
224             }
225             }
226            
227 8         17 return $result;
228             }
229              
230             sub reverse_loop_union_for_odd_even {
231 4     4 0 11 my ($self, $count_loop, $string, $type) = @_;
232            
233 4         6 my $result = $string;
234 4         5 my $i = 0;
235            
236 4 100       8 if ($type eq 'odd_even') {
237 2         6 while ($i < $count_loop) {
238 4         22 $result = $self->_reverse_union_odd_even($result);
239 4         8 $i++;
240             }
241             }
242 4 100       7 if ($type eq 'even_odd') {
243 2         5 while ($i < $count_loop) {
244 6         11 $result = $self->_reverse_union_even_odd($result);
245 6         12 $i++;
246             }
247             }
248            
249 4         9 return $result;
250             }
251              
252             sub _reverse_union_odd_even {
253 4     4   6 my ($self, $string) = @_;
254            
255 4         42 my @arr_str = $self->_split_blen($string, 1);
256 4         6 my $i = 0;
257 4     84   18 my ($even, $odd) = part {$i++ % 2} @arr_str;
  84         104  
258 4         9 my $str_odd = join '', @{$odd};
  4         8  
259 4         5 my $str_even = join '', @{$even};
  4         8  
260 4         4 my $len_odd = length $str_odd;
261 4         5 my $len_even = length $str_even;
262 4         6 my $for_odd = substr $string, 0, $len_odd;
263 4         5 my $for_even = substr $string, $len_odd, $len_even;
264 4         8 my @arr_even = $self->_split_blen($for_even, 1);
265 4         6 my @arr_odd = $self->_split_blen($for_odd, 1);
266 4         6 my $result = '';
267            
268 4 50       9 if ($len_even > $len_odd) {
269 4         29 $i = 0;
270 4         20 while ($i < $len_even) {
271 44 50       54 $result .= $arr_even[$i] if exists $arr_even[$i];
272 44 100       53 $result .= $arr_odd[$i] if exists $arr_odd[$i];
273 44         47 $i++;
274             }
275             }
276 4 50       24 if ($len_even == $len_odd) {
277 0         0 $i = 0;
278 0         0 while ($i < $len_odd) {
279 0 0       0 $result .= $arr_even[$i] if exists $arr_even[$i];
280 0 0       0 $result .= $arr_odd[$i] if exists $arr_odd[$i];
281 0         0 $i++;
282             }
283             }
284 4         16 return $result;
285             }
286              
287             sub _reverse_union_even_odd {
288 6     6   9 my ($self, $string) = @_;
289            
290 6         11 my @arr_str = $self->_split_blen($string, 1);
291 6         8 my $i = 0;
292 6     126   35 my ($even, $odd) = part {$i++ % 2} @arr_str;
  126         147  
293 6         15 my $str_even = join '', @{$even};
  6         12  
294 6         7 my $str_odd = join '', @{$odd};
  6         9  
295 6         7 my $len_even = length $str_even;
296 6         6 my $len_odd = length $str_odd;
297 6         7 my $for_even = substr $string, 0, $len_even;
298 6         9 my $for_odd = substr $string, $len_even, $len_odd;
299 6         10 my @arr_even = $self->_split_blen($for_even, 1);
300 6         9 my @arr_odd = $self->_split_blen($for_odd, 1);
301 6         7 my $result = '';
302 6 50       15 if ($len_even > $len_odd) {
303 6         8 $i = 0;
304 6         8 while ($i < $len_even) {
305 66 50       87 $result .= $arr_even[$i] if exists $arr_even[$i];
306 66 100       87 $result .= $arr_odd[$i] if exists $arr_odd[$i];
307 66         78 $i++;
308             }
309             }
310 6 50       10 if ($len_even == $len_odd) {
311 0         0 $i = 0;
312 0         0 while ($i < $len_odd) {
313 0 0       0 $result .= $arr_even[$i] if exists $arr_even[$i];
314 0 0       0 $result .= $arr_odd[$i] if exists $arr_odd[$i];
315 0         0 $i++;
316             }
317             }
318 6         28 return $result;
319             }
320              
321             sub _union_odd_even {
322 8     8   19 my ($self, $string) = @_;
323            
324 8         23 my $odd_char = $self->_odd_even_char('odd', $string);
325 8         22 my $even_char = $self->_odd_even_char('even', $string);
326            
327 8         23 return $odd_char . $even_char;
328             }
329              
330             sub _union_even_odd {
331 12     12   20 my ($self, $string) = @_;
332            
333 12         27 my $even_char = $self->_odd_even_char('even', $string);
334 12         25 my $odd_char = $self->_odd_even_char('odd', $string);
335            
336 12         26 return $even_char . $odd_char;
337             }
338              
339             sub _odd_even_char {
340 40     40   68 my ($self, $type, $string) = @_;
341 40         44 my $data = '';
342            
343 40         96 my @arr_str = $self->_split_blen($string, 1);
344            
345 40         68 my @result = ();
346 40         48 my @pre_data = ();
347 40         43 my @pre_data1 = ();
348 40         44 my @data = ();
349 40 100       86 if ($type eq 'odd') {
350 20         34 @result = grep {$_ % 2 == 1} 0 .. $#arr_str;
  420         569  
351 20         47 @pre_data1 = map {$pre_data[$_] => $arr_str[$result[$_]]} 0 .. $#result;
  200         293  
352 20         98 @data = grep (defined, @pre_data1);
353             }
354 40 100       75 if ($type eq 'even') {
355 20         34 @result = grep {$_ % 2 == 0} 0 .. $#arr_str;
  420         563  
356 20         40 @pre_data1 = map {$pre_data[$_] => $arr_str[$result[$_]]} 0 .. $#result;
  220         299  
357 20         95 @data = grep (defined, @pre_data1);
358             }
359 40         79 $data = join '', @data;
360 40         150 return $data;
361             }
362              
363             sub _split_bchar {
364 0     0   0 my ($self, $string, $delimiter) = @_;
365            
366             # Split :
367 0         0 my @split = split /$delimiter/, $string;
368            
369             # Return :
370 0         0 return @split;
371             }
372              
373             sub _split_blen {
374 70     70   97 my ($self, $string, $length) = @_;
375            
376             # Split :
377 70         87 my $len = "." x $length;
378 70         579 my @data = grep {length > 0} split(/($len)/, $string);
  2520         3145  
379            
380             # Return :
381 70         370 return @data;
382             }
383              
384             1;
385              
386             =encoding utf8
387              
388             =head1 NAME
389              
390             CellBIS::Random - Tool for Randomize characters in strings.
391              
392             =head1 SYNOPSIS
393              
394             use CellBIS::Random;
395            
396             my $rand = CellBIS::Random->new();
397            
398             my $string = 'my_string_test_random';
399             $rand->set_string($random);
400            
401             my $random = $rand->random(2, 3);
402             print 'Random : ', $random, "\r"; #-> ynsn_dtgso__tmrtrmaei
403            
404             my $unrandom = $rand->unrandom(2, 3);
405             print 'Unrandom : ', $unrandom, "\r"; #-> my_string_test_random
406              
407             =head1 DESCRIPTION
408              
409             The purpose of this module is to randomize characters in strings.
410             Before a random or unrandom character (extract from random), the string
411             will be converted to an array to get an odd/even number of key array.
412              
413             =head1 METHODS
414              
415             There is four methods C, C, C and C.
416              
417             Specifically for C and C methods, you can use two or three arguments.
418             If using Object Oriented, you can use 2 arguments. But if using Procedural, you can use 3 arguments.
419            
420             # Object Oriented
421             # Arguments : ,
422             $rand->random(2, 3);
423             $rand->unrandom(2, 3);
424            
425             # Procedural
426             # Arguemnts : , ,
427             CellBIS::Random->random('your string to random', 2, 3);
428             CellBIS::Random->unrandom('result of random to extract', 2, 3);
429              
430             =head2 set_string
431              
432             Method to set up string for Random action.
433              
434             =head2 get_result
435              
436             Method to get result of random character and Extract result of random.
437              
438             =head2 random
439              
440             With C :
441              
442             use CellBIS::Random;
443            
444             my $string = 'my string here';
445             $rand->set_string($string);
446            
447             my $result_random = $rand->random(2, 3);
448             print "Random Result : $result_random \n";
449            
450             Without C :
451            
452             my $result_random = $rand->random('my string here', 2, 3);
453             print "Random Result : $result_random \n";
454              
455             =head2 unrandom
456              
457             With C :
458              
459             $rand->set_string($result_random);
460            
461             my $result_unrandom = $rand->unrandom(2, 3);
462             print "Extract Random Result : $result_unrandom \n";
463            
464             Without C :
465            
466             my $result_unrandom = $rand->unrandom($rand->{result}, 2, 3);
467             print "Extract Random Result : $result_unrandom \n";
468            
469             =head1 EXAMPLES
470              
471             Example to using Procedural and Object Oriented
472              
473             =head2 Procedural
474              
475             Case 1
476              
477             use CellBIS::Random;
478            
479             my $result_random = CellBIS::Random->random('my string here', 2, 3);
480             print "Random Result : $result_random \n";
481            
482             my $extract_random = CellBIS::Random->unrandom($result_random, 2, 3);
483             print "Extract Random Result : $extract_random \n";
484            
485             Case 2
486              
487             use CellBIS::Random;
488            
489             my $rand = CellBIS::Random->new();
490             my $result_random = $rand->random('my string here', 2, 3);
491             print "Random Result : $result_random \n";
492            
493             my $extract_random = $rand->unrandom($result_random, 2, 3);
494             print "Extract Random Result : $extract_random \n";
495            
496             =head2 Object Oriented
497              
498             Case 1
499              
500             use CellBIS::Random;
501            
502             my $rand = CellBIS::Random->new();
503            
504             # For Random
505             $rand->set_string('my string here');
506             $rand->random(2, 3);
507             my $result_random = $rand->get_result();
508            
509             print "Random Result : $result_random \n";
510            
511             =====================================================
512            
513             # For Extract Random
514             $rand->set_string($result_random);
515             $rand->unrandom(2, 3);
516             my $extract_random = $rand->get_result();
517            
518             print "Extract Random Result : $extract_random \n";
519            
520             Case 2
521              
522             use CellBIS::Random;
523            
524             my $rand = CellBIS::Random->new();
525            
526             # For Random
527             $rand->set_string('my string here');
528             my $result_random = $rand->random('my string here', 2, 3);
529            
530             print "Random Result : $result_random \n";
531            
532             =====================================================
533            
534             # For Extract Random
535             my $extract_random = $rand->unrandom($result_random, 2, 3);
536            
537             print "Extract Random Result : $extract_random \n";
538            
539            
540             =head1 AUTHOR
541              
542             Achmad Yusri Afandi, Eyusrideb@cpan.orgE
543              
544             =head1 COPYRIGHT AND LICENSE
545              
546             Copyright (C) 2018 by Achmad Yusri Afandi
547              
548             This program is free software, you can redistribute it and/or modify it under the terms of
549             the Artistic License version 2.0.
550              
551             =cut