Ruby:Project Euler上的#8,解决方案似乎不起作用,但我觉得非常接近

时间:2016-02-20 09:22:48

标签: ruby project

问题是:
1000位数字中具有最大产品的四个相邻数字为9 × 9 × 8 × 9 = 5832

  

73167176531330624919225119674426574742355349194934   96983520312774506326239578318016984801869478851843   85861560789112949495459501737958331952853208805511   12540698747158523863050715693290963295227443043557   66896648950445244523161731856403098711121722383113   62229893423380308135336276614282806444486645238749   30358907296290491560440772390713810515859307960866   70172427121883998797908792274921901699720888093776   65727333001053367881220235421809751254540594752243   52584907711670556013604839586446706324415722155397   53697817977846174064955149290862569321978468622482   83972241375657056057490261407972968652414535100474   82166370484403199890008895243450658541227588666881   16427171479924442928230863465674813919123162824586   17866458359124566529476545682848912883142607690042   24219022671055626321111109370544217506941658960408   07198403850962455444362981230987879927244284909188   84580156166097919133875499200524063689912560717606   05886116467109405077541002256983155200055935729725   71636269561882670428252483600823257530420752963450

查找具有最大产品的1000位数字中的13个相邻数字。 该产品的价值是什么?

sequence = "73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450"

rows = sequence.each_line("\n").to_a # Split string at each new line, convert to array
products = []
num = 1

# Split each array in rows to an array of chars, while deleting the newline element.
(0...rows.length).each do |row|
  rows[row] = rows[row].split("")
  rows[row].delete("\n")
end

# Change every element in rows to an integer.
(0...rows.length).each do |row|
  (0...50).each do |i|
   rows[row][i] = rows[row][i].to_i
  end
end

# This is where the magic happens
n = 0

while n <= 19
  row = rows[n]
 while row.length >= 13
   for i in (0...13)
     num = num * row[i]
   end
   products.push(num)
   num = 1
   row = row.drop(1)
 end
 n += 1
end

print products.max

我们的想法是为每个50位数行创建一个整数数组,并遍历每个数组,将前13位数相乘,将每个产品存储在一个名为products的数组中。在前13位数相乘后,50位数组的第一个索引被删除,只有49位数,重复前13位的过程重复,直到数组只剩下13个或更少的整数,所有产品都被存储在产品中。

之后,打印出产品中的最大数量,这应该是该序列中13个相邻数字的最大乘积,5377010688。但显然,这是错误的。我不知道为什么。请帮忙!

2 个答案:

答案 0 :(得分:4)

我认为你应该尝试在Ruby中使用String方法。请查看this page here

您可以使用更简单的代码获得相同的结果:

sequence = "73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450"

## This will remove all \n
seq = sequence.tr("\n","")

def multiply_arr(a)
  prod = 1
  a.each do |f|
    prod = prod * f.to_i    
  end
  prod
end


def max_product(s,n)
  max = -1
  lim = s.length - n
  (0..lim).each do |pos|
    ns = s.slice(pos,n)
    arr = ns.each_char.to_a
    prod = multiply_arr(arr)
    max = (prod > max) ? prod : max 
  end
  max
end

puts max_product(seq,4)
puts max_product(seq,13)

我在这里运行并得到以下输出

5832
23514624000

正如您所看到的,第一个产品与您相同。 Haven没有验证第二个,但这对你来说很容易。

顺便说一下,这种代码确实更为通用。现在你可以写一些像

这样的东西
puts max_product(seq,5)

并收到

40824

作为答案。然后你解决了一个更普遍的问题而不是计算4&#39;然后计算13&#39;。

顺便说一下!如果您想知道哪个序列生成此最大值,您可以轻松地将代码重写为

def max_product(s,n)
  max = -1
  maxarr = []
  lim = s.length - n
  (0..lim).each do |pos|
    ns = s.slice(pos,n)
    arr = ns.each_char.to_a
    prod = multiply_arr(arr)
    if (prod > max) 
      max = prod
      maxarr = arr
    end
  end
  { "array" => maxarr, "prod" => max }
end

然后你会得到这个

{"array"=>["9", "9", "8", "9"], "prod"=>5832}
{"array"=>["5", "5", "7", "6", "6", "8", "9", "6", "6", "4", "8", "9", "5"], "prod"=>23514624000}

希望它有所帮助!

答案 1 :(得分:3)

你使自己的生活比你需要的更难。 Ruby有一个非常全面的核心库(以及一个更全面的标准库,但实际上对于这个问题,核心库绰绰有余),为什么不使用它呢?

def max_product_subsequence(sequence, subsequence_length)
  sequence.
    gsub(/\s+/, '').                   # remove whitespace
    each_char.                         # split into characters
    map(&:to_i).                       # convert to integers
    each_cons(subsequence_length).     # sliding window of subsequences
    map {|subseq| subseq.reduce(:*) }. # map each subsequence to its product
    max                                # get the maximum
end