Fork me on GitHub

Project Notes

#355 Array Accumulation Problem

Using ruby to solve the array accumulation problem; cassidoo’s interview question of the week (2025-09-08).

Notes

The interview question of the week (2025-09-08) is an unusual way to sum an array with a moving window. But as in most cases, there’s a naïve way to solve it, and sneakier ways:

For an array of numbers, generate an array where for every element, all neighboring elements are added to itself, and return the sum of that array.

Examples:

[]               -> 0
[1]              -> 1
[1, 4]           -> 10 // (1+4 + 4+1)
[1, 4, 7]        -> 28
[1, 4, 7, 10]    -> 55
[-1, -2, -3]     -> -14
[0.1, 0.2, 0.3]  -> 1.4
[1,-20,300,-4000,50000,-600000,7000000] -> 12338842

Initial Approach

A naïve implementation literally scans the array and adds the values as requested:

result = 0
input.each_with_index do |value, index|
  result += value
  result += input[index - 1] if index > 0
  result += input[index + 1] if index < input.length - 1
end
result

That works, of course, but there’s a lot of array indexing going on.

Running some examples:

$ ./examples.rb "1, 4, 7"
Using algorithm: default
Input: [1, 4, 7]
Result: 28
$ ./examples.rb "0.1, 0.2, 0.3"
Using algorithm: default
Input: [0.1, 0.2, 0.3]
Result: 1.4

Improving the Solution

Perhaps a smarter approach is to recognise that for arrays with more than one element:

  • the first and last elements have 2x their value added
  • all others have 3x their value added

A 1 element array just has its value added.

Let’s try that:

result = 0
last_index = input.length - 1
input.each_with_index do |value, index|
  multiplier = if last_index.zero?
    1
  elsif index.zero? || index == last_index
    2
  else
    3
  end
  result += value * multiplier
end
result

Also works. A few more lines, but more direct code.

Running some examples:

$ ./examples.rb "1, 4, 7" improved
Using algorithm: improved
Input: [1, 4, 7]
Result: 28
$ ./examples.rb "0.1, 0.2, 0.3" improved
Using algorithm: improved
Input: [0.1, 0.2, 0.3]
Result: 1.4

Tests

I’ve setup some validation in test_examples.rb:

$ ./test_examples.rb
Run options: --seed 47624

# Running:

................

Finished in 0.000330s, 48484.8484 runs/s, 48484.8484 assertions/s.

16 runs, 16 assertions, 0 failures, 0 errors, 0 skips

Example Code

Final code is in examples.rb:

#!/usr/bin/env ruby

class ArrayAccumulationProblem
  attr_reader :input

  def initialize(input)
    @input = input
  end

  def default
    result = 0
    input.each_with_index do |value, index|
      result += value
      result += input[index - 1] if index > 0
      result += input[index + 1] if index < input.length - 1
    end
    result
  end

  def improved
    result = 0
    last_index = input.length - 1
    input.each_with_index do |value, index|
      multiplier = if last_index.zero?
        1
      elsif index.zero? || index == last_index
        2
      else
        3
      end
      result += value * multiplier
    end
    result
  end
end


if __FILE__==$PROGRAM_NAME
  (puts "Usage: ruby #{$0} (string) (algorithm)"; exit) unless ARGV.length > 0
  input = ARGV[0].split(',').map do |item|
    item.include?('.') ? item.to_f : item.to_i
  end
  algorithm = ARGV[1] || 'default'
  puts "Using algorithm: #{algorithm}"
  calculator = ArrayAccumulationProblem.new(input)
  puts "Input: #{calculator.input}"
  puts "Result: #{calculator.send(algorithm)}"
end

Credits and References

About LCK#355 rubycassidoo

This page is a web-friendly rendering of my project notes shared in the LittleCodingKata GitHub repository.

Project Source on GitHub Return to the LittleCodingKata Catalog
About LittleCodingKata

LittleCodingKata is my collection of programming exercises, research and code toys broadly spanning things that relate to programming and software development (languages, frameworks and tools).

These range from the trivial to the complex and serious. Many are inspired by existing work and I'll note credits and references where applicable. The focus is quite scattered, as I variously work on things new and important in the moment, or go back to revisit things from the past.

This is primarily a personal collection for my own edification and learning, but anyone who stumbles by is welcome to borrow, steal or reference the work here. And if you spot errors or issues I'd really appreciate some feedback - create an issue, send me an email or even send a pull-request.

Follow the Blog follow projects and notes as they are published in your favourite feed reader