Find the sum of the difference of maximum and minimum element of all subarrays - stack

sample input: 3 1 4 2
output: 1) Subarrays of size 1 : (3),(1),(4),(2) , sum = 0 + 0 + 0 + 0 = 0.
2) Subarrays of size 2: [3, 1], [1, 4], [4, 2], sum = 2 + 3 + 2 = 7.
3) Subarrays of size 3:- [3, 1, 4], [1, 4, 2], sum = 3 + 3 = 6.
4) Subarrays of size 4:- [3, 1, 4, 2], sum = 3
Total sum = 16

Here the problem can solve in many ways, hope this might help you to get your ideas.
arr = [3, 1, 4, 2]
lists = []
res = 0
for i in range(len(arr) + 1):
for j in range(i):
if len(arr[j: i]) > 1:
res += np.max(arr[j:i]) - np.min(arr[j:i])
lists.append(arr[j:i])
print(res)

Related

Swift: convert an array into x arrays with n elements each?

I have an array in Swift:
[1, 2, 3, 4, 5, 6, 7, 8]
I need to have X number of arrays each has n elements, say n = 3:
[1, 2, 3], [4, 5, 6], [7, 8]
So that if elements in the end are less than n the last sub-array will have whatever remaining.
I thought about using stride:
let array = [1, 2, 3, 4, 5, 6, 7, 8]
let n = 3
var subarrays = [[Int]]()
for i in stride(from: 0, to: array.count, by: n) {
let slice = array[i..<min(i+n, array.count)]
subarrays.append(Array(slice))
}
I wonder if there's a better way of doing this?
Thanks!

How to improve memory usage when generating a contiguous permutation

I have code that needs to generate a contiguous permutation:
(1..n).flat_map {|x| array.map {|y| (x..y) unless x > y } }.compact
Which outputs:
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [2], [2, 3], [2, 3, 4], [2, 3, 4, 5],
[3], [3, 4], [3, 4, 5], [4], [4, 5], [5]]
It works really well with low sizes of n, but when I have n = 100000 I run out of memory. Is there a way to improve this but keeping them contiguous?
I need to perform a reject! iterating over poisonous and allergic arrays:
array = (1..n)
permutations = array.flat_map {|x| array.map {|y| (x..y) unless x > y } }.compact
poisonous.each_with_index do |x, i|
permutations.reject! { |y| y.include?(x) && y.include?(allergic[i]) }
end
The problem:
poisonous = [3,4,6]
allergic = [5,6,7]
These numbers can't be together:
3 -> 4
4 -> 6
6 -> 7
combinations = [[1], [3,4], [4,5]]
So, [3,4] is not a valid combination.
I was able to solve the memory issue by using less variables as possible and doing calculations directly while generating the permutation, although processing time has increased a bit, it is using a lot less memory (dropped from 800mb to 32mb approximately). I'm open for suggestions to improve it even more.
counter = 0
(1..n).each {|x|
(1..n).each {|y|
counter += 1 if !(x > y) && !poisonous.each_with_index.select {|poison, i| (x..y).include?(poison) && (x..y).include?(allergic[i])}.any?
}
}
The following computes the number of "clean combinations". As no large arrays are produced it has modest memory requirements.
require 'set'
def clean_combos(n, poisonous, allergic)
arr = (1..n).to_a
bad_allergies = poisonous.zip(allergic).to_h
arr.sum do |m|
arr.combination(m).sum do |combo|
combo_set = combo.to_set
bad_allergies.any? do |poison, allergy|
combo_set.include?(poison) && combo_set.include?(allergy)
end ? 0 : 1
end
end
end
n = 10
poisonous = [3,4,6]
allergic = [5,6,7]
clean_combos(n, poisonous, allergic)
#=> 479
bad_allergies is found to equal {3=>5, 4=>6, 6=>7}.
This concludes that, for the array [1, 2,..., 10], there are 479 combinations of elements of size between 1 and 10 such that, for each combination, 3 and 5 are not both included, and neither are 4 and 5, and 6 and 7.
See Array#zip, Array#to_h, Array#sum, Array#combination, Hash#any? and Set#include?. Array#to_set is added when include 'set' is executed.
I've converted each combo to a set to speed lookups.
Some tweaks might improve efficiency, so experimentation may be called for. This may depend on the size of the array poisonous (and of allergic) relative to n.

Calculate sum of every 5 elements in array of Integer in Swift iOS

In Swift 3, how can we calculate sum of every 5 elements in array of Int.
For example, we have an array [1,2,3,4,5,6,7,8,9,0,12,23]
1+2+3+4+5 = 15
6+7+8+9+0 = 30
12+23+0+0+0 = 35
The result something like this [15,30,35]
Here is my solution in playgroud:
//: Playground - noun: a place where people can play
import UIKit
var arr = [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3]
let chunkSize = 5
let chunks = stride(from: 0, to: arr.count, by: chunkSize).map {
Array(arr[$0..<min($0 + chunkSize, arr.count)])
}
print(chunks)
var summ = chunks.map { $0.reduce(0, {$0 + $1}) }
print(summ)
OUTPUT:
[[1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3]]
[5, 10, 15]
Take a look at:
Finding sum of elements in Swift array

How to optimize the solution for Two_sum code in ruby

I am woking on the solution for the following question.
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
This is the solution submitted in ruby after referring the C++ code http://leetcodeunlock.com/2016/05/20/leetcode-1-two-sum-easy/ .
def two_sum(nums, target)
hash = {}
arr = []
nums.each_with_index do |value,index|
y = target - value
if(hash.find{|key,val| key == value})
arr << hash[value]
arr << index
return arr
else
hash[y] = index
end
end
end
My submission failed with the message : Time limit exceeded. Can anyone point out the mistake and help me optimise the code?
nums = [2, 7, 11, 15]
target = 9
# this will find all combinations of 2 elements that add up to 9
results = (0...nums.size).to_a.combination(2).select { |first, last| nums[first] + nums[last] == target }
results.first #=> [0, 1]
Explanation of some parts of the code:
# Get indexes of all elements of nums array
(0...nums.size).to_a #=> [0, 1, 2, 3]
# Generate all combinations of indexes of each 2 elements
(0...nums.size).to_a.combination(2).to_a #=> [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
I have modified the line
if(hash.find{|key,val| key == value})
to
if(hash.key?(value))
to find if a specific key is present in the hash and this solved the issue.
Code
def sum_to_num(arr, num)
return [num/2, num/2] if num.even? && arr.count(num/2) > 1
a = arr.uniq.
group_by { |n| (2*n-num).abs }.
find { |_,a| a.size > 1 }
a.nil? ? nil : a.last
end
This method requires three or four passes through the array, if num is even, one to count the instances of num/2, one to remove duplicate values, one to group_by and one to find the pair of numbers that sum to the desired total. It therefore should be much faster than methods that evaluate every pair of the array's elements, particularly as the size of the array is increased.
Examples
sum_to_num [2, 11, 7, 15], 9
#=> [2, 7]
sum_to_num [2, 5, 2, 6, 1, -5, 4], 10
#=> [6, 4]
sum_to_num [2, 7, 11, -7, 15], 0
#=> [7, -7]
sum_to_num [2, 7, 11, 7, 15], 14 #???
sum_to_num [2, -7, 11, -7, 15], -14 #???
sum_to_num [2, 7, 11, 15], 17
#=> [2, 15]
sum_to_num [2, -11, 8, 15], 4
#=> [-11, 15]
sum_to_num [2, -11, 8, 15], -3
#=> [-11, 8]
sum_to_num [2, -11, 8, 15], 100
#=> nil
Explanation
Assume x and y sum to num. Then
2*x-num + 2*y-num = 2*(x+y) - 2*num
= 2*num - 2*num
= 0
meaning that 2*x-num and 2*y-num are either both zero or they have the opposite signs and the same absolute value. Similarly, if 2*x-num and 2*y-num sum to zero, then
2*x-num + 2*y-num = 0
2*(x+y) - 2*num = 0
meaning that n+m = num (which is hardly surprising considering that 2*x+num is a linear transformation.
Suppose
arr = [2, 5, 2, 6, 1, -5, 4]
num = 10
then
if num.even? && arr.count(num/2) > 1
#=> if 10.even? && arr.count(5) > 1
#=> if true && false
#=> false
Therefore, do not return [5,5].
b = arr.uniq
#=> [2, 5, 6, 1, -5, 4]
c = b.group_by { |n| (2*n-num).abs }
#=> {6=>[2], 0=>[5], 2=>[6, 4], 8=>[1], 20=>[-5]}
a = c.find { |_,a| a.size > 1 }
#=> [2, [6, 4]]
return nil if a.nil?
# do not return
a.last
#=> [6, 4]
I was doing this challenge for fun and wrote a cleaned up ruby solution.
def two_sum(nums, target)
hash = {}
nums.each_with_index { |number, index| hash[number] = index }
nums.each_with_index do |number, index|
difference = target - number
if hash[difference] && hash[difference] != index
return [index, hash[difference]]
end
end
end
# #param {Integer[]} nums
# #param {Integer} target
# #return {Integer[]}
def two_sum(nums, target)
length = nums.length
for i in 0..length
j = i+1
for a in j..length
if j < length
if nums[i] + nums[a] == target
return [i, a]
end
end
j+=1
end
end
[]
end
Well this is my way of solving this
def two_sum(nums, target)
nums.each_with_index do |value, index|
match_index = nums.find_index(target - value)
return [index, match_index] if match_index
end
nil
end
The above has the advantage that it stops execution when a match is found and so hopefully won't time out. :)

How to Line Chart this data?

I would like to create line chart for following data. I would also like to have the ability to hover over each data point to look at the x and y value at that data point. I have the following data structure:
x[0] = [23 4 2 2 4 4 5 3 334 2]
y[0] = [6 24 1 2 2 5 1 3 8 0]
x[1] = [5 6 8 6 3 4 6 3 3]
y[1] = [9 7 8 6 3 4 1 9 2]
x[2] = [6 9 9 6 2 5 8 3]
y[2] = [1 0 2 5 6 2 1 5]
... so that I will have 3 lines on the same chart.
I played with "Seer" without much success. Can anyone provide any recommendations / examples / references for plotting similar data using Seer or anything else?
Thanks.
Give the lazy_high_charts gem a try.
#app/views/layouts/appliction.*
= javascript_include_tag 'highcharts.js'
#Gemfile
gem 'lazy_high_charts'
# my_controller#my_action
x_0 = [23, 4, 2, 2, 4, 4, 5, 3, 334, 2]
y_0= [6, 24, 1, 2, 2, 5, 1, 3, 8, 0]
x_1 = [5, 6, 8, 6, 3, 4, 6, 3, 3]
y_1 = [9, 7, 8, 6, 3, 4, 1, 9, 2]
x_2 = [6, 9, 9, 6, 2, 5, 8, 3]
y_2 = [1, 0, 2, 5, 6, 2, 1, 5]
data_0 = x_0.zip(y_0)
data_1 = x_1.zip(y_1)
data_2 = x_2.zip(y_2)
#h = LazyHighCharts::HighChart.new('graph') do |f|
f.series(:name => "xy0", :data => data_0)
f.series(:name => "xy1", :data => data_1)
f.series(:name => "xy3", :data => data_2)
f.chart({:defaultSeriesType=>"line" })
f.yAxis(:title => { :text => "y axis values" } )
f.xAxis(:title => { :text => "x axis values"} )
f.title(:text => "XY Graph")
f.plotOptions({}) # override the default values that lazy_high_charts puts there
f.legend({}) # override the default values
end
#app/views/my_controller/my_action
= high_chart("chart", #h)
Caveat:
HighCharts is only free for non-commercial use. That may or may not be a dealbreaker for you.
I've really liked jQuery flot for this kind of thing:
http://code.google.com/p/flot/
Check out the example here:
http://flot.googlecode.com/svn/trunk/README.txt
In your controller or view, you can use Ruby's zip to zip together arrays of x and y values if you need to:
> a = [1,2,3]
=> [1, 2, 3]
> b = [5,6,7]
=> [5, 6, 7]
> a.zip(b)
=> [[1, 5], [2, 6], [3, 7]]

Resources