next_palindrome.pl 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #!/usr/bin/perl
  2. # A nice algorithm, due to David A. Corneth (Jun 06 2014), for generating the next palindrome from a given palindrome.
  3. # See also:
  4. # https://oeis.org/A002113
  5. # https://en.wikipedia.org/wiki/Palindromic_number
  6. use 5.020;
  7. use strict;
  8. use warnings;
  9. use experimental qw(signatures);
  10. sub next_palindrome ($n) {
  11. my @d = split(//, $n);
  12. my $l = $#d;
  13. my $i = ((scalar(@d) + 1) >> 1) - 1;
  14. while ($i >= 0 and $d[$i] == 9) {
  15. $d[$i] = 0;
  16. $d[$l - $i] = 0;
  17. $i--;
  18. }
  19. if ($i >= 0) {
  20. $d[$i]++;
  21. $d[$l - $i] = $d[$i];
  22. }
  23. else {
  24. @d = (0) x (scalar(@d) + 1);
  25. $d[0] = 1;
  26. $d[-1] = 1;
  27. }
  28. join('', @d);
  29. }
  30. my $n = 1;
  31. for (1 .. 100) { # first 100 palindromes
  32. print("$n, ");
  33. $n = next_palindrome($n);
  34. }
  35. say "\n";
  36. say next_palindrome(99977999); #=> 99988999
  37. say next_palindrome(99988999); #=> 99999999
  38. say next_palindrome(99999999); #=> 100000001
  39. say '';
  40. say next_palindrome("51818186768181815"); #=> 51818186868181815
  41. say next_palindrome("51818186868181815"); #=> 51818186968181815
  42. say next_palindrome("51818186968181815"); #=> 51818187078181815