更像红宝石般的解决方案可以解决这个问题吗? [英] More ruby-like solution to this problem?

查看:89
本文介绍了更像红宝石般的解决方案可以解决这个问题吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习红宝石,并通过解决 Project Euler 中的问题来进行实践.

I am learning ruby and practicing it by solving problems from Project Euler.

这是我针对问题 12 的解决方案.

This is my solution for problem 12.

# Project Euler problem: 12
# What is the value of the first triangle number to have over five hundred divisors?

require 'prime'

triangle_number = ->(num){ (num *(num + 1)) / 2 }

factor_count = ->(num) do
  prime_fac = Prime.prime_division(num)
  exponents = prime_fac.collect { |item| item.last + 1 }
  fac_count = exponents.inject(:*)
end

n = 2
loop do
  tn = triangle_number.(n)
  if factor_count.(tn) >= 500
    puts tn
    break
  end
  n += 1
end

可以对这段代码进行任何改进吗?

Any improvements that can be made to this piece of code?

推荐答案

查看问题的各个部分可能会帮助您更好地了解红宝石,而不是一劳永逸地解决问题.

Rather than solve the problem in one go, looking at the individual parts of the problem might help you understand ruby a bit better.

第一部分是找出三角形的数目.由于此操作使用自然数序列,因此可以使用一定范围的红宝石来表示它.这是一个示例:

The first part is finding out what the triangle number would be. Since this uses sequence of natural numbers, you can represent this using a range in ruby. Here's an example:

(1..10).to_a => [1,2,3,4,5,6,7,8,9,10]

ruby​​中的数组被认为是可枚举的,ruby提供了许多枚举数据的方法.使用此概念,您可以使用each方法在此数组上进行迭代,并传递一个对数字求和的块.

An array in ruby is considered an enumerable, and ruby provides lots of ways to enumerate over data. Using this notion you can iterate over this array using the each method and pass a block that sums the numbers.

sum = 0
(1..10).each do |x|
  sum += x
end

sum => 55

这也可以使用另一个称为inject的可枚举方法完成,该方法会将从前一个元素返回的内容传递给当前元素.使用此功能,您可以在一行中获得总和.在此示例中,我使用1.upto(10),其功能与(1..10)相同.

This can also be done using another enumerable method known as inject that will pass what is returned from the previous element to the current element. Using this, you can get the sum in one line. In this example I use 1.upto(10), which will functionally work the same as (1..10).

1.upto(10).inject(0) {|sum, x| sum + x} => 55

逐步执行此操作,第一次调用它,sum = 0,x = 1,所以(sum + x)=1.然后将其传递到下一个元素,因此sum = 1,x = 2,( sum + x)=3.下一个sum = 3,x = 3,(sum + x)=6.sum= 6,x = 4,(sum + x)= 10,等等.

Stepping through this, the first time this is called, sum = 0, x = 1, so (sum + x) = 1. Then it passes this to the next element and so sum = 1, x = 2, (sum + x) = 3. Next sum = 3, x = 3, (sum + x) = 6. sum = 6, x = 4, (sum + x) = 10. Etc etc.

这只是此问题的第一步.如果您想以这种方式学习语言,则应该着手解决问题的每个部分,并了解适合该部分学习的内容,而不是解决整个问题.

That's just the first step of this problem. If you want to learn the language in this way, you should approach each part of the problem and learn what is appropriate to learn for that part, rather than tackling the entire problem.

解决方案(虽然根本没有效果)

REFACTORED SOLUTION (though not efficient at all)

def factors(n)
  (1..n).select{|x| n % x == 0}
end

def triangle(n)
  (n * (n + 1)) / 2
end

n = 2

until factors(triangle(n)).size >= 500
  puts n
  n += 1
end

puts triangle(n) 

这篇关于更像红宝石般的解决方案可以解决这个问题吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆