power = 7830457
puts power == 105817 * 37 * 2 - 1

def show_last_10_digits(n)
  return (puts n) if Float === n and n.infinite? # n == Float::INFINITY or n.infinite? hangs if n is a (big I suppose) Bignum
  puts 10.times.map { |i|
    n, rest = n.divmod(10)
    rest
  }.reverse.join # => 8739992577
end

n = 2**power
show_last_10_digits(n)

n = (((2 ** 105817) ** 37) ** 2) / 2
show_last_10_digits(n)

require "prime"
class Integer
  def pow(power)
    add = 0
    until (primes_divisors = Prime.prime_division(power)).size > 1 or prime_division.any? { |prime, pow| pow > 1 }
      power += 1
      add += 1
    end
    primes_divisors = primes_divisors.reverse.inject([]) { |pd, (prime, p_pow)| pd + [prime]*p_pow }
    n = primes_divisors.inject(self) { |n, prime| n ** prime }
    n /= 2**add
    n
  end
end

n = 2.pow(power)
show_last_10_digits(n)

require "test/unit"
class TestPow < Test::Unit::TestCase
  def test_pow
    assert_equal 8, 2.pow(3)
    assert_equal 16, 2.pow(4)
    assert_equal 16, 4.pow(2)
    assert_equal 1024**2, 1024.pow(2)
    assert_equal 2**1024, 2.pow(1024)
    b, p = rand(1000), rand(1000)
    p([b,p])
    assert_equal b**p, b.pow(p) # sometimes failing, I suppose my Integer#pow is not correct (by example 617**617)
  end
end
