2

到目前为止我有这个代码:

def longest_awtz(n)
  upto = n
  series = []

  for x in 2..upto
    series << x
  end

  series.each do |num|
    print num.to_s + " - " 
    while num != 1
      if num % 2 == 0
        num = num / 2
        print num.to_s + " - "
      else
        num = (3 * num) + 1
        print num.to_s + " - "
      end
    end
    puts " "
  end
end

longest_awtz(6)

该代码的输出是:

---------------------------------------------
你好世界                                   
2 - 1 -                                      
3 - 10 - 5 - 16 - 8 - 4 - 2 - 1 -  
4 - 2 - 1 -  
5 - 16 - 8 - 4 - 2 - 1 -  
6 - 3 - 10 - 5 - 16 - 8 - 4 - 2 - 1 -  
---------------------------------------------

现在,我想确定哪个起始数字产生最长的链,所以我必须将每个链放入一个数组中并对其进行计数,以确定哪个链是最长的。我的最终输出必须如下所示:

---------------------------------------------
你好世界                                   
2 - 1 -                                      
3 - 10 - 5 - 16 - 8 - 4 - 2 - 1 -  
4 - 2 - 1 -  
5 - 16 - 8 - 4 - 2 - 1 -  
6 - 3 - 10 - 5 - 16 - 8 - 4 - 2 - 1 -  

[2,1] # 有 2
[3,10,5,16,8,4,2,1] #有8个
[4,2,1] # 有 3
[5,16,8,4,2,1] #有6个
[6,3,10,5,16,8,4,2,1] #有9个
# 识别并打印创建最长链的起始编号。
6 是创建最长链的起始数字。
---------------------------------------------

到目前为止,我有上面的第一个输出,我一直在思考如何将每个输出放入一个数组中。你能帮我解决我的问题吗?

4

3 回答 3

2

如果您使用具有适当抽象的函数式方法,则欧拉项目问题(以及与此相关的所有数学问题)会更加简洁和声明性:

collatz = proc { |n| n.even? ? n/2 : (3*n + 1) }
collatz_length = proc { |n| n > 1 ? 1 + collatz_length.(collatz.(n)) : 0 }
(1...1000).max_by(&collatz_length)
#=> 871
于 2013-05-27T09:54:25.933 回答
1

我会首先将序列的生成提取到它自己的方法中:

def generate_sequence(num)
  result = [num]
  while num != 1
    if num%2 == 0
      num = num/2
    else
      num = (3*num)+1
    end
    result << num
  end
  result
end

这将返回一个包含序列的数组。然后,您可以编写一个方法,生成由输入产生的所有系列1..n

def generate_sequences_upto(n)
  1.upto(n).map do |num|
    generate_sequence(num)
  end
end

另一个选择最长的序列:

def longest_sequence(n)
  generate_sequences_upto(n).max_by(&:length)
end

例如,您可以像这样使用它:

longest = longest_sequence(6)
puts "The longest sequence with length #{longest.length} is\n#{longest.inspect}"

它会输出

The longest sequence with length 9 is
[6, 3, 10, 5, 16, 8, 4, 2, 1]

当你想用" - "我推荐使用分隔数字时Array#join

longest.join(' - ')
#=> "6 - 3 - 10 - 5 - 16 - 8 - 4 - 2 - 1"
于 2013-05-27T09:03:28.293 回答
0

你可能想要map,如

array = series.map do |num|

但要正确使用它,您将需要调整您的块,以便它返回您想要的数组的值,而不仅仅是打印出来(puts返回nil,您不想要这里)。

要将每个单独的数字收集到主数组内的子数组中,而不是puts, 您想要subarray.push( num )或类似的 - 有一些等效的语法。然后取而代之(或之后)puts " ",最后只有subarray变量(或您所称的任何内容),这将使其成为块的返回值,并将其添加到您的主数组中。你最终会得到一个数组数组。

如果您想探索 Ruby 对象的可能性,我强烈建议您启动irb并使用methods命令查看您可以使用它做的所有事情:

irb
1.9.3-p327 :001 > a = [1,2,3,4]
 => [1, 2, 3, 4]
1.9.3-p327 :002 > a.methods.sort
 => [:!, :!=, :!~, :&, :*, :+, :-, :<<, :<=>, :==, :===, :=~, :[], :[]=, :__id__, :__send__, :all?, :any?, :assoc, :at, :chunk, :class, :clear, :clone, :collect, :collect!, :collect_concat, :combination, :compact, :compact!, :concat, :count, :cycle, :define_singleton_method, :delete, :delete_at, :delete_if, :detect, :display, :drop, :drop_while, :dup, :each, :each_cons, :each_entry, :each_index, :each_slice, :each_with_index, :each_with_object, :empty?, :entries, :enum_for, :eql?, :equal?, :extend, :fetch, :fill, :find, :find_all, :find_index, :first, :flat_map, :flatten, :flatten!, :freeze, :frozen?, :grep, :group_by, :hash, :include?, :index, :initialize_clone, :initialize_dup, :inject, :insert, :inspect, :instance_eval, :instance_exec, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :join, :keep_if, :kind_of?, :last, :length, :map, :map!, :max, :max_by, :member?, :method, :methods, :min, :min_by, :minmax, :minmax_by, :nil?, :none?, :object_id, :one?, :pack, :partition, :permutation, :pop, :private_methods, :product, :protected_methods, :public_method, :public_methods, :public_send, :push, :rassoc, :reduce, :reject, :reject!, :repeated_combination, :repeated_permutation, :replace, :respond_to?, :respond_to_missing?, :reverse, :reverse!, :reverse_each, :rindex, :rotate, :rotate!, :sample, :select, :select!, :send, :shift, :shuffle, :shuffle!, :singleton_class, :singleton_methods, :size, :slice, :slice!, :slice_before, :sort, :sort!, :sort_by, :sort_by!, :taint, :tainted?, :take, :take_while, :tap, :to_a, :to_ary, :to_enum, :to_s, :transpose, :trust, :uniq, :uniq!, :unshift, :untaint, :untrust, :untrusted?, :values_at, :zip, :|]

这是大量的学习方法!但是,如果您Ruby Array map在 Google 中输入 eg,您通常会在第一个答案中获得有用的参考。

许多 Ruby 习语都是基于您可以通过将数组方法与块组合来完成的事情,值得花时间进行探索。

于 2013-05-27T08:07:40.997 回答