-
-
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) |
one liner... not much to do lately...
def find_deviation(arr, d)
arr.each_cons(d).inject(0) { |max_dev, slice| [max_dev, slice.minmax.reverse.reduce(:-)].max }
end
trying to make stuff fast instead of fancy..
The idea is to avoid calling min and max (iterating twice to find them) and using .minmax that would find both with only one iteration
the improvement is really insignificant for small d
I kept your logic this time
def find_deviation(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
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)}
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)}
This is the challenge question as posed:
Given an array of integer elements and an integer d please consider all the sequences of d consecutive elements in the array. For each sequence we compute the difference between the maximum and the minimum value of the elements in that sequence and name it the deviation.
Your task is to
Note that your function will receive the following arguments:
Data constraints
Efficiency constraints
Example
Input Output
v: 6, 9, 4, 7, 4, 1
d: 3
6
Explanation
The sequences of length 3 are: