[英]Finding the 2nd longest array in Ruby - Collatz conjecture algorithm
The Collatz conjecture: Collatz猜想:
https://en.wikipedia.org/wiki/Collatz_conjecture https://en.wikipedia.org/wiki/Collatz_conjecture
For any positive integer n we define two rules: if even: divide by two if odd: multiply by three, then add one, and repeat until the result is the number 1. The smallest value of n is 1. 对于任何正整数n,我们定义两个规则:if:偶数:除以2:odd:乘以3,然后加一,然后重复直到结果为数字1。n的最小值为1。
This will generate sequences of numbers like below, converging to 1: 这将生成如下所示的数字序列,收敛为1:
6, 3, 10, 5, 16, 8, 4, 2, 1 6,3,10,5,16,8,4,2,1
For each number n we can now count the number of steps in this sequence until we reach 1. 现在,对于每个数字n,我们都可以计算此序列中的步数,直到达到1。
So the sequence above, starting with 6, has a length of 9 (including the starting point and the final one). 因此,以上从6开始的序列的长度为9(包括起点和终点)。
My problem: 我的问题:
I am trying to find the second-longest sequence of all the integers smaller or equal than 10 million. 我试图找到所有小于或等于1000万的整数的第二长序列。 How would you go about it?
你会怎么做?
So far I came up with a solution for finding the longest sequence, but I am not sure how to find the 2nd. 到目前为止,我想出了找到最长序列的解决方案,但是我不确定如何找到第二个序列。
def collatz_sequence_eval(n)
array_sequence = []
until n == 1
if n%2 != 0
n = 3*n + 1
array_sequence.push(n)
else
n = n/2
array_sequence.push(n)
end
end
return array_sequence
end
def collatz_iterator
counter = 1
current_longest_sequence = []
until counter == 10000000
cur_seq = collatz_sequence_eval(counter)
if cur_seq.length > current_longest_sequence.length
current_longest_sequence = cur_seq
counter+=1
else
counter+=1
end
end
puts "Starting number is #{current_longest_sequence[0]}.
Sequence length is #{current_longest_sequence.length}"
end
def collatz(n)
seq = [n]
until n == 1
n = n.even? ? n/2 : 3*n + 1
seq << n
end
seq
end
(2..10**7).reduce([[],[]]) do |(longest, next_longest), n|
seq = collatz(n)
seq_size = seq.size
if seq_size > longest.size
[seq, longest]
elsif seq_size < longest.size && seq_size > next_longest.size
[longest, seq]
else
[longest, next_longest]
end
end
#=> [[8400511, 25201534, 12600767, 37802302, 18901151, 56703454,
# ...
# 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1
# [8865705, 26597116, 13298558, 6649279, 19947838, 9973919,
# ...
# 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]]
By changing the final end
to end.map(&:size)
, [686, 668]
is returned, meaning the longest sequence(s) had length 686
, the next longest(s), 668
. 通过将最
end
更改为end.map(&:size)
,返回[686, 668]
end.map(&:size)
[686, 668]
,这意味着最长的序列的长度为686
,下一个最长的序列为668
。
The length of the longest sequence appears consistent with results given in the Wiki , which states that for n < 10^7
685
"steps" are required. 最长序列的长度似乎与Wiki中给出的结果一致,该结果指出对于
n < 10^7
685
,需要“步骤”。
226
seconds were required to perform this calculation when using Linux on a Pixelbook with a 1.2GHz 7th generation i5. 在带有1.2GHz第七代i5的Pixelbook上使用Linux时,执行此计算需要
226
秒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.