Class: Collatz::HailstoneSequence

Inherits:
Object
  • Object
show all
Defined in:
lib/collatz/hailstone_sequence.rb

Overview

Contains the results of computing a hailstone sequence via hailstone_sequence(~).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_value, p, a, b, max_total_stopping_time, total_stopping_time) ⇒ Object

Initialise and compute a new Hailstone Sequence.

(number of iterations to obtain 1) rather than the regular stopping time (number of iterations to reach a value less than the initial value).

Parameters:

  • +Integer+

    initial_value The value to begin the hailstone sequence from.

  • +Integer+

    p: Modulus used to devide n, iff n is equivalent to (0 mod p).

  • +Integer+

    a: Factor by which to multiply n.

  • +Integer+

    b: Value to add to the scaled value of n.

  • +Integer+

    max_total_stopping_time: Maximum amount of times to iterate the function, if 1 is not reached.

  • +Boolean+

    total_stopping_time: Whether or not to execute until the “total” stopping time

Raises:

  • FailedSaneParameterCheck If p or a are 0.



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/collatz/hailstone_sequence.rb', line 43

def initialize(initial_value, p, a, b, max_total_stopping_time, total_stopping_time)
  terminate = stopping_time_terminus(initial_value, total_stopping_time)
  if initial_value.zero?
    # 0 is always an immediate stop.
    @values = [0]
    @terminal_condition = SequenceState::ZERO_STOP
    @terminal_status = 0
  elsif initial_value == 1
    # 1 is always an immediate stop, with 0 stopping time.
    @values = [1]
    @terminal_condition = SequenceState::TOTAL_STOPPING_TIME
    @terminal_status = 0
  else
    # Otherwise, hail!
    min_max_total_stopping_time = [max_total_stopping_time, 1].max
    pre_values = Array.new(min_max_total_stopping_time+1)
    pre_values[0] = initial_value
    for k in 1..min_max_total_stopping_time do
      next_value = Collatz.function(pre_values[k-1], p: p, a: a, b: b)
      # Check if the next_value hailstone is either the stopping time, total
      # stopping time, the same as the initial value, or stuck at zero.
      if terminate.call(next_value)
        pre_values[k] = next_value
        if next_value == 1
          @terminal_condition = SequenceState::TOTAL_STOPPING_TIME
        else
          @terminal_condition = SequenceState::STOPPING_TIME
        end
        @terminal_status = k
        @values = pre_values.slice(0, k+1)
        return
      end
      if pre_values.include? next_value
        pre_values[k] = next_value
        cycle_init = 1
        for j in 1..k do
          if pre_values[k-j] == next_value
            cycle_init = j
            break
          end
        end
        @terminal_condition = SequenceState::CYCLE_LENGTH
        @terminal_status = cycle_init
        @values = pre_values.slice(0, k+1)
        return
      end
      if next_value.zero?
        pre_values[k] = 0
        @terminal_condition = SequenceState::ZERO_STOP
        @terminal_status = -k
        @values = pre_values.slice(0, k+1)
        return
      end
      pre_values[k] = next_value
    end
    @terminal_condition = SequenceState::MAX_STOP_OUT_OF_BOUNDS
    @terminal_status = min_max_total_stopping_time
    @values = pre_values
  end
end

Instance Attribute Details

#terminal_conditionObject (readonly)

A terminal condition that reflects the final state of the hailstone sequencing, whether than be that it succeeded at determining the stopping time, the total stopping time, found a cycle, or got stuck on zero (or surpassed the max total).



15
16
17
# File 'lib/collatz/hailstone_sequence.rb', line 15

def terminal_condition
  @terminal_condition
end

#terminal_statusObject (readonly)

A status value that has different meanings depending on what the terminal condition was. If the sequence completed either via reaching the stopping or total stopping time, or getting stuck on zero, then this value is the stopping/terminal time. If the sequence got stuck on a cycle, then this value is the cycle length. If the sequencing passes the maximum stopping time then this is the value that was provided as that maximum.



22
23
24
# File 'lib/collatz/hailstone_sequence.rb', line 22

def terminal_status
  @terminal_status
end

#valuesObject (readonly)

The set of values that comprise the hailstone sequence.



10
11
12
# File 'lib/collatz/hailstone_sequence.rb', line 10

def values
  @values
end