我知道我的代码可以获得4个相邻整数的正确答案。但它与13无关。
我唯一能想到的是它可能是unsigned int的一个问题,但在Ruby中我不认为我会遇到这个问题,因为它会自动更改为Bignum类。
这意味着在我计算的某个地方我错了吗?
请给我一个提示。
# Euler 8
# http://projecteuler.net/index.php?section=problems&id=8
# Find the thirteen adjacent digits in the 1000-digit number
# that have the greatest product.
# What is the value of this product?
number = []
#split the integer as a string into an array
long_digit = "73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450"
long_digit.split("").map { |s| number << s.to_i }
#iterate through the array to find the 13 ajacent digits that have the largest product
largest_product = 0
a = 0
#stay within the bounds of the array
while number[a+12]
current_product = number[a] * number[a+1] * number[a+2] * number[a+3] * number[a+4] * number[a+5] * number[a+6] * number[a+7] * number[a+8] * number[a+9] * number[a+10] * number[a+11] * number[a+12]
if current_product > largest_product
largest_product = current_product
end
a = a + 1
end
puts largest_product
答案 0 :(得分:4)
我认为这个解决方案非常简洁明了:
console.log(/\b\w{1,7}\b/i.test('bc4rg6'))
#!/usr/bin/env ruby
input = "
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450"
.gsub(/\s+/, '')
puts input.chars
.map(&:to_i)
.each_cons(13)
.map { |seq| seq.reduce(:*) }
.max
执行修剪。
gsub
获取角色。
chars
将所有字符映射到整数。
map(&:to_i)
获取连续数字的块(https://ruby-doc.org/core-2.4.1/Enumerable.html#method-i-each_cons)
each_cons(13)
将获取每个连续的块并执行reduce(将每个切片/连续数字块的所有数字相乘)。
map { |seq| seq.reduce(:*) }
获得最大值。
答案 1 :(得分:1)
问题似乎是由于字符串long_digit
中的大量空格字符在数组0
中变为number
,因此会产生错误的结果。
这是经过更正和简化的版本。使用gsub
删除换行符和空格后,我们现在有一个1000位的数字,我们得到了正确答案。
number = long_digit.gsub!(/\s/, '').split("").map{ |s| s.to_i }
n = 13
p number.each_cons(n).map{|a| a.reduce {|a, i| a = a * i }}.max
#=> 23514624000
答案 2 :(得分:1)
首先,让我们修复字符串:
long_digit.gsub!(/\s|\n/,'')
long_digit.size #=> 1000
我们可以通过消除包含零的13个字符的子串来加快速度:
shorter_digit_arr = long_digit.split('0').reject { |s| s.size < 13 }
#=> ["7316717653133",
# "6249192251196744265747423553491949349698352",
# "6326239578318",
# "18694788518438586156",
# "7891129494954595",
# "17379583319528532",
# "698747158523863",
# "435576689664895",
# "4452445231617318564",
# "987111217223831136222989342338",
# "81353362766142828",
# "64444866452387493",
# "1724271218839987979",
# "9377665727333",
# "594752243525849",
# "632441572215539753697817977846174",
# "86256932197846862248283972241375657",
# "79729686524145351",
# "6585412275886668811642717147992444292823",
# "863465674813919123162824586178664583591245665294765456828489128831426",
# "96245544436298123",
# "9878799272442849",
# "979191338754992",
# "559357297257163626956188267"]
现在,对于shorter_digit_arr
的每个元素,找到其数字乘积最大的13个字符的子字符串,然后找到其中最大的(shorter_digit_arr.size #=> 24
)个产品。以这种方式将字符串拆分为子字符串的主要好处是,缺少零允许我们以更有效的方式执行产品计算,而不是简单地为每个子字符串研磨12次乘法:
res = shorter_digit_arr.map do |s|
cand = s[0,13].each_char.reduce(1) { |prod,t| prod * t.o_i }
best = { val: cand, offset: 0 }
(13...s.size).each do |i|
cand = cand*(s[i].to_i)/(s[i-13].to_i)
best = { val: cand, offset: i-12 } if cand > best[:val]
end
[best[:val], s[best[:offset],13]]
end.max_by(&:first)
#=> [23514624000, "5576689664895"]
puts "max_product: %d for: '%s'" % res
#=> max_product: 23514624000 for: '5576689664895'
解决方案是:
的最后13个字符s = shorter_digit_arr[7]
#=> "435576689664895"
这里的关键是:
cand = cand*(s[i].to_i)/(s[i-13].to_i)
通过乘以&#34;之前的&#34;来计算13位数的产品。 13位数的乘积加上数字除以数字下降。
在查找此元素的最大乘积时,计算如下:
s = "435576689664895"
cand = s[0,13].each_char.reduce(1) { |prod,t| prod * t.to_i }
#=> = "4355766896648".each_char.reduce(1) { |prod,t| prod * t.to_i }
# = 6270566400
best_val = { val: 6270566400, offset: 0 }
enum = (13...s.size).each
#=> #<Enumerator: 13...15:each>
此枚举器的元素将由Enumerator#each传递给块。我们可以通过将enum
转换为数组来查看它们是什么:
enum.to_a
#=> [13, 14]
我们可以使用Enumerator#next来模拟enum
元素到块的传递及其对块变量i
的赋值。
将枚举器的第一个元素(13
)传递给块:
i = enum.next
#=> 13
cand = cand*(s[i].to_i)/(s[i-13].to_i)
# = 6270566400*(s[13].to_i)/(s[0].to_i)
# = 6270566400*(9)/(4)
# = 14108774400
cand > best[:val]
#=> 14108774400 > 6270566400 => true
best = { val: cand, offset: i-12 }
#=> { val: 14108774400, offset: 1 }
将第二个元素(14
)传递给块:
i = enum.next
#=> 14
cand = cand*(s[i].to_i)/(s[i-13].to_i)
#=> = 14108774400*(s[14].to_i)/(s[1].to_i)
# = 14108774400*(5)/(3)
# = 23514624000
cand > best[:val]
#=> 23514624000 > 14108774400 => true
best = { val: 23514624000, offset: 2 }
现在,枚举器的所有元素都已传递给块。我们可以确认:
i = enum.next
#=> StopIteration: iteration reached an end
结果(shorter_digit_arr[7]
)是:
[best[:val], s[best[:offset],13]]
#=> [23514624000, "435576689664895"[2,13]]
# [23514624000, "5576689664895"]