Method: AChain.sequence

Defined in:
lib/numb/achain.rb

.sequence(*terms) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/numb/achain.rb', line 3

def self.sequence(*terms)
  chain, perms = ([1] + terms), {}
  possible =->(term) do
    return true if perms.values.include?(term)
    options = chain.uniq.select{|perm| perm < term}
    (options * 2).permutation(2).to_a.uniq.any? do |perm|
      (perms[perm] ||= perm.reduce(:+)) == term
    end
  end
  loop do
    catch(:restart) do
      (chain = chain.sort.reverse).each_with_index do |term, i|
        return chain.sort.uniq if term == 1
        next if possible[term]
        chain << if term >= (chain[i.succ] * 3)
          term.even? ? term / 2 : term - 1
        else
          term - chain[i.succ]
        end
        throw :restart
      end
    end
  end
end