1

Say we have the following code:

def run(input)
  start = 0
  lap = 0

  while true
    opcode = input[start]
    input1 = input[start + 1]
    input2 = input[start + 2]
    output = input[start + 3]

    if opcode == 1
      input[output] = input[input1] + input[input2]
    elsif opcode == 2
      input[output] = input[input1] * input[input2]
    elsif opcode == 99
      puts "breaking"
      break
    else
      puts "CANT RECOGNIZE THAT OPCODE"
    end
    start += 4
    lap += 1
  end
  puts input
  puts "finished after #{lap} loops"
end

input = [1,9,10,3,2,3,11,0,99,30,40,50]
run(input)

I understand why printing input1 I get the number stored in that possition in the array (9), but I don't get why printing input[input1] (input[input[start + 1]]) accesses the value the number in that position (9) points to (30).

The code works for the exercise but I don't understand why.

BobRodes
  • 5,990
  • 2
  • 24
  • 26
pinkfloyd90
  • 588
  • 3
  • 17
  • Tip: Learn about `case` which can help make your code a lot easier to follow as well as more efficient. – tadman Jul 06 '20 at 20:16
  • Also consider looping with `input.each_slice(4) do |opcode, input1, input2, output|` to break out in chunks of 4. – tadman Jul 06 '20 at 20:18
  • Thanks. I actually saved your response from yesterday, but I got it working in a primitive way like this and was thinking of refactoring it later. I still don't understand this though. – pinkfloyd90 Jul 06 '20 at 20:22
  • Almost everything in Ruby is an expression that resolves to some value. `input[9] == 30`, so anything that *resolves* to an index of `9` will also return `30`, because that's the value stored in the input array as the ninth element. – Todd A. Jacobs Jul 06 '20 at 21:05

1 Answers1

3

Each time you call Array#[] you're doing a look-up, and if you nest these then you get an index-based "pointer" to another value. This is common in some data structures as it can store one copy of a value that's used in multiple places, among other things. One example in common use is DNS, as per RFC1035.

In your example it's easier to understand when you consider the order of operations. Ruby, like many languages, evaluates from the inside out, or in other words:

a = [ 1, 2, 3 ]

a[a[1]]
# => 3

Where that's evaluated as if it were expressed as:

x = a[1]
# => 2
a[x]
# => 3

There's no limit on the number of times you can nest an index resolution like this provided none of the indexes exceed the array bounds, as a[1234] returns nil, and a[nil] is an error. You can theoretically do this indefinitely, though in practice you'd rarely do it more than a handful of times.

Community
  • 1
  • 1
tadman
  • 208,517
  • 23
  • 234
  • 262