Skip to content

Instantly share code, notes, and snippets.

@thomasgwatson
Created April 4, 2014 22:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomasgwatson/9983924 to your computer and use it in GitHub Desktop.
Save thomasgwatson/9983924 to your computer and use it in GitHub Desktop.
def find_deviation(v, d)
max_dev = 0
iterations = v.length - d + 1
index = 0
iterations.times do
sub = v[index...index+d]
sub_max_dev = sub.max - sub.min
max_dev = sub_max_dev if sub_max_dev > max_dev
index +=1
end
p max_dev
end
v = [6,9,4,7,4,1]
d = 3
find_deviation(v,d)
@hzla
Copy link

hzla commented Apr 5, 2014

I decided to tackle this since I haven't had much to do lately either, here's a comparison of the solutions proposed so far. My solution is similar to Thomas's.

However, I added an if statement to the loop that would check the last digit of each sub_array and only run the code inside the loop if the digit was greater than the last sub_max or less than the last sub_min.

I also tested it against an array of 100,000 random digits in range 1..231 and with d being a random integer in range 1..5000. The if statement seems to help the method loop through a lot faster once the array increases in size.

def find_deviation_thomas(v, d)
    max_dev = 0
    iterations = v.length - d + 1
    index = 0
    iterations.times do
      sub = v[index...index+d]
      sub_max_dev = sub.max - sub.min
      max_dev = sub_max_dev if sub_max_dev > max_dev
      index +=1
    end
    p max_dev
end


def find_deviation_bruno(v, d)
  max_dev = 0
  iterations = v.length - d + 1
  index = 0
  iterations.times do
    slice_minmax = v[index...index+d].minmax
    dev = slice_minmax[1] - slice_minmax[0]
    max_dev = max_dev < dev ? dev : max_dev

    index +=1
  end
  max_dev
end

def find_deviation_andy(v,d)
  max_dev = 0
  max = 0
  min = 0
  v.each_with_index do |n, i|
    last_num = v[i + d -1]
    if i == 0 || last_num == nil || last_num > max || last_num < min
      sub = v[i..i + d - 1]
      max = sub.max
      min = sub.min
      sub_max_dev = max - min
      max_dev = sub_max_dev if sub_max_dev > max_dev
    end
  end
  p max_dev
end

v = [6,9,4,7,4,1]
d = 3

test = []
100_000.times { test << rand(231) }
test_d = rand(5000)

require 'benchmark'

puts Benchmark.measure {find_deviation_thomas(v,3)}
puts Benchmark.measure {find_deviation_bruno(v,3)}
puts Benchmark.measure {find_deviation_andy(v,3)}


# puts Benchmark.measure {find_deviation_thomas(test, test_d)}
# puts Benchmark.measure {find_deviation_bruno(test, test_d)}
puts Benchmark.measure {find_deviation_andy(test, test_d)}

@ltrainpr
Copy link

ltrainpr commented Apr 5, 2014

Andy's solution is by far the fastest. If you wanted to get even faster use a for loop vs an each (2x-4x faster).

def find_deviation_lionel(array, sequence_number)
  largest_difference = 0
  max = 0
  min = 0
  for i in 0..(array.length-sequence_number)
    last_num = array[i+(sequence_number-1)]
    if last_num == nil || i == 0 || last_num > max || last_num < min
      sub_array = array[i..(i+(sequence_number-1))]
      max = sub_array.max
      min = sub_array.min
      max_min_difference = max - min
      largest_difference = max_min_difference if max_min_difference > largest_difference
    end
  end
  p largest_difference
end

def find_deviation_andy(v,d)
  max_dev = 0
  max = 0
  min = 0
  v.each_with_index do |n, i|
    last_num = v[i + d -1]
    if i == 0 || last_num == nil || last_num > max || last_num < min
      sub = v[i..i + d - 1]
      max = sub.max
      min = sub.min
      sub_max_dev = max - min
      max_dev = sub_max_dev if sub_max_dev > max_dev
    end
  end
  p max_dev
end

test = []
100_000.times { test << rand(231) }
test_d = rand(5000)

require 'benchmark'

puts Benchmark.measure {find_deviation_andy(test, test_d)}
puts Benchmark.measure {find_deviation_lionel(test, test_d)}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment