0

我正在尝试编写一些代码来测试一个数字是否是 Kaprekar 数字。我环顾四周,看看是否有人已经提出了这个问题,但我没有找到足够的信息,所以我把我的烦恼带给你。

什么是 Kaprekar 数:

对于具有 n 位的 Kaprekar 数 k,如果将其平方并将右侧的 n 位添加到左侧的 n 或 n-1 位,则结果和为 k。9 就是一个例子,因为 9^2=81,并且 8+1=9。

这是我现在整理的:

def kaprekar?(k)

  if k**2.to_s.length % 2 == 0
    split_k_array = k**2.to_s.split(//)
    half_k_array_length = split_k_array.length / 2
    i = half_k_array_length
    x1 = 0

    while i > 0
      x1 = x1 + (10**i * split_k_array[i-1])
      i = i - 1
    end

    x2 = 0
    i = split_k_array.length

    while i > half_k_array_length
      x2 = x2 + (10**(i-half_k_array_length))
      i = i - 1
    end

    if k == x1 + x2
      return true
    else
      return false
    end

  else

    puts "Let's figure out what wrong with the other code first :("
    return "Meh"

  end

end

if kaprekar(500500)
  puts "500500 is True :)"
else
  puts "500500 is False :("
end

if kaprekar(9)
  puts "9 is True :)"
else
  puts "9 is False :("
end

if kaprekar(22) puts "22 is True" else puts "22 is False" end

此代码没有返回任何错误,但只要 k 的平方是偶数位长,无论提供的数字是否为 Kaprekar 数,该方法都会返回值 True。事实上,即使我将测试部分更改为:

if x1 + x2 = k
  return false
else
  return false
end

...我仍然得到 True 返回给我!这怎么可能?

任何帮助,将不胜感激!

编辑1:我将真值赋值改为“==”而不是“=”,并将“^”指数更改为“**”。但是,在上述两种情况下,我仍然得到“真实”返回给我。:(

编辑 2:似乎我错过了 2 个“^”!解决它!

编辑 3:每次运行代码时添加一些代码来测试 Kaprekar 方法。修复了在线错误(好像我试图分割字符串的长度,而不是字符串本身。天哪!)。无论如何,现在我收到错误消息:“kaprekarTest.rb:37: undefined method `kaprekar' for main:Object (NoMethodError)” 现在,我刚刚定义了 kaprekar 方法。为什么我会收到一个错误说没有这种方法?

4

5 回答 5

3

找到 kaprekar 数的最佳和简单的解决方案:

def kaprekar?(k)
  ks = k**2
  lenf = (ks.to_s.length)-1
  lenh = (ks.to_s.length / 2) - 1
  a = ks.to_s[0..lenh].to_i
  b = ks.to_s[lenh+1..lenf].to_i
  k == (a+b)
end
于 2015-07-11T11:59:35.000 回答
2

^ 在 Ruby 中不是 pow 。** 是。

> 3^2
=> 1
> 3**2
=> 9
于 2013-10-14T23:28:29.977 回答
1
if x1 + x2 = k

那是一个赋值语句,而不是一个条件语句,因此它总是“真实的”。

正如菲利普所说,“指数运算符”是**而不是^

更新:您正在调用(正如我之前提到的)一个在您调用时不存在的方法,if kaprekar(500500)因为您定义了keprekar?方法。

在您的方法中,您可能需要k**2用括号括起来,以便.to_s调用不仅作用于数字 2。

在这些修复之后,希望您能修复引发的其余错误,所以至少我们可以明白我们可以“首先找出其他代码有什么问题”。

此代码将为您提供答案。未验证这些数字的实际正确性,但至少没有出现语法或运行时错误。

def kaprekar(k)

  if k**2.to_s.length % 2 == 0
    split_k_array = (k**2).to_s.split(//)
    half_k_array_length = split_k_array.length / 2
    i = half_k_array_length
    x1 = 0

    while i > 0
      x1 = x1 + ((10**i) * split_k_array[i-1].to_f)
      i = i - 1
    end

    x2 = 0
    i = split_k_array.length

    while i > half_k_array_length
      x2 = x2 + (10**(i-half_k_array_length))
      i = i - 1
    end

    if k == x1 + x2
      return true
    else
      return false
    end

  else

  end

end

if kaprekar(500500)
  puts "500500 is True :)"
else
  puts "500500 is False :("
end

if kaprekar(9)
  puts "9 is True :)"
else
  puts "9 is False :("
end
于 2013-10-14T23:42:57.240 回答
0

卡普雷卡

def convert_array(number)
  arr = []
  div = 10**(number.to_s.length - 1)

  while div >= 10 do
    arr << (number/div)
    number = (number%div)
    div = (div / 10)
  end

  arr << number
  arr
end

def kaprekar?(number)
  c = convert_array(number**2)
  i = 0
  flag = false

  while i < c.length do
    if number == (c.first(i).join().to_i + c.last(c.length - i).join().to_i)
      flag = true
      break
    end

    i = i+1
  end

  flag
end

尝试这个。

于 2015-07-16T13:22:47.860 回答
-1

如果你想让它更简洁:

def kaprekar?(k)
  k_squared = (k*k).to_s
  idx = k_squared.length / 2
  return k_squared[0..idx-1].to_i + k_squared[idx..-1].to_i == k
end

作为旁注:我很想看看是否有人提出了更快的ruby​​ 实现?

require 'benchmark'
puts Benchmark.measure{ (1..10000000).select{|k| kaprekar?(k)} }

产量

ruby kaprekar.rb
11.240000   0.010000  11.250000 ( 11.249131)

在我的机器上。

编辑:发布了较短版本的解决方案

于 2013-12-22T14:46:07.367 回答