DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'



def negative_base_encode(n, b)
  raise 'base out of range' if (b < -62) || (b > -2)
  return '0' if n == 0
  revdigs = []
  while n!= 0 do
    n, r = n.divmod(b)
    if r < 0
      n += 1
      r -= b
    end
    revdigs << r
  end
  return revdigs.reduce('') { |digstr, digit| DIGITS[digit] + digstr }
end



def negative_base_decode(n, b)
  raise 'base out of range' if (b < -62) || (b > -2)
  value = 0
  n.reverse.each_char.with_index do |ch, inx|
    value += DIGITS.index(ch) * b**inx
  end
  return value
end



[ [10, -2], [146, -3], [15, -10], [0, -31], [-6221826, -62] ].each do |pair|
  decimal, base = pair
  encoded = negative_base_encode(decimal, base)
  decoded = negative_base_decode(encoded, base)
  puts( %
       [decimal, 10, encoded, base, encoded, base, decoded, 10])
end