Tuesday, September 21, 2010

Kaprekar Numbers

I saw this one over on Programming Praxis and thought that it would be a good ruby problem and probably something that I might use as an interview question for a programmer. Once again, like our post on Happy Numbers, it has both math and string work plus it can be done relatively quickly. Here's the introduction from Programming Praxis ...

Wolfram’s MathWorld describes Kaprekar numbers like this:

Consider an n-digit number k. Square it and add the right n digits to the left n or n-1 digits. If the resultant sum is k, then k is called a Kaprekar number. For example, 9 is a Kaprekar number since 92 = 81 and 8 + 1 = 9 and 297 is a Kaprekar number since 2972 = 88209 and 88 + 209 = 297.

Your task is to write a function that identifies Kaprekar numbers and to determine the Kaprekar numbers less than a thousand. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.


And here's the ruby code for this ...

# Wolfram’s MathWorld describes Kaprekar numbers like this:
#
# Consider an n-digit number k. Square it and add the right n digits to the
# left n or n-1 digits. If the resultant sum is k, then k is called a
# Kaprekar number. For example, 9 is a Kaprekar number since 92 = 81 and 8
# + 1 = 9 and 297 is a Kaprekar number since 2972 = 88209 and 88 + 209 =
# 297.
#
# Your task is to write a function that identifies Kaprekar numbers and to
# determine the Kaprekar numbers less than a thousand. When you are finished,
# you are welcome to read or run a suggested solution, or to post your own
# solution or discuss the exercise in the comments below.

def kaprekar?(k)
# Get the number of digits in k.
n = k.to_s.length

# Get the number squared and convert it to a string.
k_sqr_str = (k**2).to_s

# Get the right side of n digits. Here we use the ruby array function that
# starts from the end of the array and counts back n digits and then grabs
# n digits.
right = k_sqr_str[-n, n]

# Grab the remaining n or n-1 digits.
left = k_sqr_str[0, k_sqr_str.length-right.length]

# Sum the left and right sides.
sum = left.to_i + right.to_i

# Check if the sum that we just computed is the same
# as k that we passed in. If so return true for a kaprekar
# number otherwise false.
sum == k ? true : false
end

# Find the kaprekar numbers up to 1000 and print
# the ones we find.
1.upto(1000) do |k|
puts "#{k} is a kaprekar number" if kaprekar?(k)
end


This is a relatively "naive" implementation and you can see that the implementations given on the Praxis site are a bit more interesting. This though is something like what I'd expect someone to come up with as part of an interview. Also, I managed to misspell Kaprekar when I did this over at Praxis and this contains the correct spelling.

Let me know if you have questions or comments.

No comments:

Post a Comment