pastebin - collaborative debugging tool
kpaste.net RSS


seq in perl
Posted by Anonymous on Thu 4th Oct 2012 17:25
raw | new post

  1. #!/usr/bin/perl
  2.  
  3. use 5.14.0;
  4. use warnings;
  5. use strict;
  6. use File::Basename qw(basename);
  7. use POSIX qw(ceil);
  8.  
  9. # This is a quick and dirty 'seq' knock-off. It'll give you a sequence
  10. # of numbers or letters (depending on what you put as arguments).
  11. # The delimiter can be any string or character (even newlines).
  12.  
  13. my %alnum;
  14.  
  15. # Populate the %alnum hash with keys that correspond with either letters
  16. # or numbers. This will be used later to translate letters to numbers
  17. # so we can do math with them. Then we'll translate the numbers back to
  18. # letters.
  19. my $n = 0;
  20. foreach my $letter ('a' .. 'z') {
  21.         $alnum{$letter} = ++$n;
  22.         $alnum{$n} = $letter;
  23. }
  24. my $base = $n;
  25.  
  26. if (!$ARGV[0]) {
  27.         usage();
  28. }
  29.  
  30. # If either second or third argument is empty, set it to '0'.
  31. foreach (1 .. 2) {
  32.         if (!$ARGV[$_]) {
  33.                 $ARGV[$_] = 0;
  34.         }
  35. }
  36.  
  37. my $delimiter = $ARGV[0];
  38. my($start, $end) = ($ARGV[1], $ARGV[2]);
  39. my(@start, @end);
  40. my $abc_regex = qr/^[a-z]+$/;
  41. my $n_regex = qr/^[0-9]+$/;
  42.  
  43. sub alfa2num {
  44. # Sort the output so we can easier do calculations with the numbers.
  45.         my @before_start = sort(split("", lc(shift)));
  46.         my @before_end = sort(split("", lc(shift)));
  47.  
  48.         foreach (@before_start) {
  49.                 push(@start, $alnum{$_});
  50.         }
  51.  
  52.         foreach (@before_end) {
  53.                 push(@end, $alnum{$_});
  54.         }
  55. }
  56.  
  57. sub usage {
  58.         say('Usage: ' . basename($0) . " \'[delimiter]\' [start] [end]\n");
  59.  
  60.         say "* [delimiter] can be any string or character you want.\n" .
  61.                 '* [start] and [end] need to be either numeric or alphabetic' .
  62.                 " characters.\n";
  63.  
  64.         exit;
  65. }
  66.  
  67. if ($start eq $end) {
  68.         usage();
  69.  
  70. } elsif ($start =~ /$abc_regex/i && $end =~ /$abc_regex/i) {
  71.  
  72.         alfa2num($start, $end);
  73.  
  74.         my $start_temp = 0;
  75.         my $end_temp = 0;
  76.         foreach (@start) { $start_temp += $_ };
  77.         foreach (@end) { $end_temp += $_ };
  78.  
  79.         if ($start_temp == $end_temp) { usage(); }
  80.  
  81.         elsif ($start_temp > $end_temp) {
  82.  
  83.                 my $diff = ($start_temp - $end_temp);
  84.                 foreach (@start) { print $alnum{$_} }
  85.                 print $delimiter;
  86.  
  87.                 LOOP_MINUS: foreach (0 .. (my $last = (scalar(@start) - 1))) {
  88.                         while ($start[$_] > 0 && $diff) {
  89.  
  90.                                 $start[$_]--;
  91.                                 $diff--;
  92.  
  93.                                 foreach (@start) { print $alnum{$_} if ($_) }
  94.                                 if ($diff) { print $delimiter }
  95.                                 else { print "\n"; }
  96.                         }
  97.                 }
  98.         } else {
  99.  
  100.                 my $diff = ($end_temp - $start_temp);
  101.                 foreach (@start) { print $alnum{$_} }
  102.                 print $delimiter;
  103.  
  104.                 LOOP_PLUS: foreach (0 .. (my $last = (scalar(@start) - 1))) {
  105.                         while ($start[$_] < $base && $diff) {
  106.                                 $start[$_]++;
  107.                                 $diff--;
  108.  
  109.                                 foreach (@start) { print $alnum{$_} }
  110.                                 if ($diff) { print $delimiter }
  111.                                 else { print "\n"; }
  112.                         }
  113.  
  114.                         if ($_ == $last && $diff) {
  115.  
  116.                                 push(@start, 0);
  117.                                 goto(LOOP_PLUS);
  118.                         }
  119.                 }
  120.         }
  121.         exit;
  122.  
  123. } elsif ($start =~ /$n_regex/ && $end =~ /$n_regex/) {
  124.  
  125.         # In case the arguments passed to the script were floating point
  126.         # numbers, round them upwards.
  127.         $start = ceil($start);
  128.         $end = ceil($end);
  129.  
  130.         if ($start > $end) {
  131.                 my $diff = ($start - $end);
  132.                 print $start . $delimiter;
  133.                 until ($start == $end) {
  134.                         $diff--;
  135.                         print --$start;
  136.                         if ($diff) { print $delimiter; }
  137.                         else { print "\n"; }
  138.                 }
  139.  
  140.         } else {
  141.                 my $diff = ($end - $start);
  142.                 print $start . $delimiter;
  143.                 until ($start == $end) {
  144.                         $diff--;
  145.                         print ++$start;
  146.                         if ($diff) { print $delimiter; }
  147.                         else { print "\n"; }
  148.                 }
  149.         }
  150.         exit;
  151. }
  152.  
  153. usage();

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at