Class: Unodos::Infinite

Inherits:
Enumerator
  • Object
show all
Defined in:
lib/unodos/infinite.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(list) ⇒ Infinite

Returns a new instance of Infinite.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/unodos/infinite.rb', line 6

def initialize(list)
  min_cost = list.size + 1
  result = nil
  list.size.times do |level|
    cost, res = Unodos::Solver.solve list, level, min_cost
    if cost && cost < min_cost
      min_cost = cost
      result = res
    end
  end
  @cost = min_cost
  @elements = result.map do |(_, _, base), v|
    v = v.real.to_i if v.real.to_i == v
    [base, v] if v != 0
  end.compact
  @differential_level = @elements.map(&:first).map(&:differential_level).max
  @initial = list.take(@differential_level)
end

Instance Attribute Details

#costObject (readonly)

Returns the value of attribute cost.



5
6
7
# File 'lib/unodos/infinite.rb', line 5

def cost
  @cost
end

#differential_levelObject (readonly)

Returns the value of attribute differential_level.



5
6
7
# File 'lib/unodos/infinite.rb', line 5

def differential_level
  @differential_level
end

#elementsObject (readonly)

Returns the value of attribute elements.



5
6
7
# File 'lib/unodos/infinite.rb', line 5

def elements
  @elements
end

#initialObject (readonly)

Returns the value of attribute initial.



5
6
7
# File 'lib/unodos/infinite.rb', line 5

def initial
  @initial
end

Instance Method Details

#differential?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/unodos/infinite.rb', line 51

def differential?
  differential_level > 0
end

#each(&block) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/unodos/infinite.rb', line 55

def each(&block)
  Enumerator.new do |y|
    differential = [0] * differential_level
    (0..).each do |i|
      v = if i < differential_level
        initial[i]
      else
        elements.sum do |base, v|
          if base.differential_level > 0
            v * differential[(i - base.differential_level) % differential_level]
          else
            v * base.proc.call(i)
          end
        end
      end
      differential[i % differential_level] = v if differential?
      y << v
    end
  end.each(&block)
end

#inspectObject



43
44
45
46
47
48
49
# File 'lib/unodos/infinite.rb', line 43

def inspect
  if differential?
    "[#{[*initial, rule].join(', ')}]"
  else
    rule
  end
end

#ruleObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/unodos/infinite.rb', line 25

def rule
  es = @elements.map.with_index do |(base, v), i|
    sign = i != 0
    name = base.to_s
    s = if name == '1'
      Unodos::Formatter.format v
    elsif v == 1
      name
    elsif v == -1
      '-' + name
    else
      Unodos::Formatter.format(v, wrap: true) + '*' + name
    end
    i == 0 || '-+'.include?(s[0]) ? s : '+' + s
  end
  "a[n]=#{es.join}"
end