Math-NumSeq

 view release on metacpan or  search on metacpan

lib/Math/NumSeq/ReverseAddSteps.pm  view on Meta::CPAN

# Copyright 2010, 2011, 2012, 2013, 2014, 2016, 2019, 2020 Kevin Ryde

# This file is part of Math-NumSeq.
#
# Math-NumSeq is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any later
# version.
#
# Math-NumSeq is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License along
# with Math-NumSeq.  If not, see <http://www.gnu.org/licenses/>.

package Math::NumSeq::ReverseAddSteps;
use 5.004;
use strict;

use vars '$VERSION','@ISA';
$VERSION = 75;

use Math::NumSeq;
use Math::NumSeq::Base::IterateIth;
@ISA = ('Math::NumSeq::Base::IterateIth',
        'Math::NumSeq');
*_is_infinite = \&Math::NumSeq::_is_infinite;

# uncomment this to run the ### lines
#use Devel::Comments;


# use constant name => Math::NumSeq::__('Reverse-Add Steps');
use constant description => Math::NumSeq::__('How many steps of reverse and add until a palindrome is reached (sometimes called the 196-algorithm).');
use constant i_start => 1;
use constant values_min => -1;
use constant characteristic_count => 1;
use constant characteristic_smaller => 1;
use constant characteristic_increasing => 0;

use Math::NumSeq::Base::Digits
  'parameter_info_array';   # radix parameter

#------------------------------------------------------------------------------

# http://oeis.org/index/Res#RAA     reverse-adds
#
# cf A015976 - numbers needing 1 iteration to reach palindrome
#    A065206 - 1 iteration to reach palindrome, excluding palindromes
#    A015977 - 2 iterations to reach palindrome
#    A015979 - 3 iterations to reach palindrome
#    A033865 - the palindrome at which each n stops
#
#    A023109 - first number requiring n iterations to palindrome
#                suggesting where to make the hard limit ...
#
#    A030547 - num steps, minimum 0, so palindromes value 1
#    
# ~/OEIS/a058042.txt  on reaching binary palindromes

my @oeis_anum;
$oeis_anum[10] = 'A016016';  # steps to palindrome, or -1 if infinite
# OEIS-Catalogue: A016016

sub oeis_anum {
  my ($self) = @_;
  return $oeis_anum[$self->{'radix'}];
}


#------------------------------------------------------------------------------

use constant 1.02;  # for leading underscore
use constant _LIMIT => 100;

sub new {
  my $self = shift->SUPER::new(@_);

  my $radix = $self->{'radix'};
  my $limit = ~0;
  my $uv_limit = 1;
  while ($limit) {
    $limit = int($limit/$radix);
    $uv_limit *= $radix;
  }
  $self->{'uv_limit'} = $uv_limit;
  ### $uv_limit

  return $self;
}

sub ith {
  my ($self, $k) = @_;
  ### ReverseAddSteps ith(): $k

  if (_is_infinite($k) || $k < 0) {
    return $k;
  }

  my $radix = $self->{'radix'};
  my $uv_limit = $self->{'uv_limit'};

  my $count = 0;
 OUTER: for ( ; $count < _LIMIT; $count++) {
    my @digits;
    ### $count
    ### k: "$k"

    if ($k >= $uv_limit && ! ref $k) {
      $k = Math::NumSeq::_to_bigint($k);
    }

    if (ref $k) {
      ### big ...



( run in 1.825 second using v1.01-cache-2.11-cpan-71847e10f99 )