My goal here is pretty simple, I want to turn a number like 12435987234 into an array of integers in reverse order. So that would look like:


I want to do this without changing the number to a string and back. Really, I don't want to convert it at all but I'm open to hearing ideas around this.

I've found one way to do in ruby via #divmod but suspect there is a more perfomant way.

# turns 1234 into
# [4,3,2,1]
def reversed_digits(val)
  quot = val
  results = []
  while quot > 0 do
    quot, remainder = quot.divmod(10)
    results << remainder

puts reversed_digits(1234)
=> [4,3,2,1]
  • 1
    \$\begingroup\$ I benchmarked doing it with a string, and it's about 3x faster than this method. Are you trying to do it without conversion just for the intellectual challenge? \$\endgroup\$
    – Jonah
    Jan 21, 2016 at 1:15
  • \$\begingroup\$ Thanks @Jonah - I saw some similar benchmark results on my end and was hoping to tighten the above up and do a few other comparisons as well. So yes, intellectual challenge you could say. \$\endgroup\$
    – Anthony
    Jan 21, 2016 at 1:21
  • \$\begingroup\$ What is the reverse of 0? \$\endgroup\$
    – greybeard
    Jan 21, 2016 at 1:26
  • \$\begingroup\$ @greybeard fair question. This method today takes integers roughly the size of a credit card number (16-24) digits so the scenario smaller isn't a concern and I would likely guard against it. \$\endgroup\$
    – Anthony
    Jan 21, 2016 at 1:29
  • 1
    \$\begingroup\$ If you mention data like card numbers; be aware such data may have leading zeros, so they might be stored as strings rather than numbers, and conversion to string would not be necessary at all. However, if they are numeric variables, possibly your conversion routine should take additional parameter to describe the output size (number of items to pad to with zeros)? If implemented, that would cover the zero input value case, too, with desired_output_length=1. \$\endgroup\$
    – CiaPan
    Jan 21, 2016 at 10:41

1 Answer 1


I don't think your algorithm can be improved in speed. I'd propose a different implementation, though, a more shorter recursive function:

def reversed_digits(num, base: 10)
  quotient, remainder = num.divmod(base)
  [remainder] + (quotient == 0 ? [] : reversed_digits(quotient, base: base))
  • \$\begingroup\$ I don't think keyword parameters should be used here. Also your code is not tail-recursive unlike OP's one. \$\endgroup\$
    – Nakilon
    Jan 21, 2016 at 13:18
  • \$\begingroup\$ why is it not? reversed_digits is the final call in the function, when it recurses \$\endgroup\$
    – Jonah
    Jan 21, 2016 at 18:31
  • \$\begingroup\$ @Jonah: It's not tail-recursive, the recursive call is inside another expression. We would just need to add an accumulator. \$\endgroup\$
    – tokland
    Jan 21, 2016 at 18:39
  • \$\begingroup\$ ah, i see it now. \$\endgroup\$
    – Jonah
    Jan 21, 2016 at 18:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.