File Coverage

lib/CellBIS/Random.pm
Criterion Covered Total %
statement 177 248 71.3
branch 52 104 50.0
condition 12 58 20.6
subroutine 20 22 90.9
pod 4 7 57.1
total 265 439 60.3


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