PHIL Sawyer
asked on
Array filtering
Hi
I have an array of numbers and want to find the numbers that can add up to the max number in the array if possible.
E.g.
my_array=[2,4,5,7,10,24,50 ]
So, my max number = 50 and the numbers that can add up to 50 are [4,5,7,10,24] … is this possible and how?
Regards
I have an array of numbers and want to find the numbers that can add up to the max number in the array if possible.
E.g.
my_array=[2,4,5,7,10,24,50
So, my max number = 50 and the numbers that can add up to 50 are [4,5,7,10,24] … is this possible and how?
Regards
ASKER
Yes need maximum from array and yes there could be more than one set - for example...
myarray=[25,15,60,50,2,50, 100]
possible answers …
[50,50],[25,15,60] … both arrays add up to maximum in myarray
Regards
myarray=[25,15,60,50,2,50,
possible answers …
[50,50],[25,15,60] … both arrays add up to maximum in myarray
Regards
interesting, sounds you need some sort of a recursive solution, let me think of an algorithm
ASKER
sounds interesting
arr = [25,15,60,50,2,50,100]
arr_max = arr.max()
def find_graph(arr_local, arr_res, mx)
arr_local.each_index do |i|
new_arr_local = arr_local.values_at(i + 1 .. (arr_local.length - 1))
new_arr_res = arr_res + arr_local.values_at(i)
new_mx = mx - arr_local.values_at(i)[0]
if new_mx == 0 then
puts new_arr_res
puts "-"
elsif new_mx > 0 and new_arr_local.length > 0 then
find_graph(new_arr_local, new_arr_res, new_mx)
end
end
end
find_graph(arr, Array.new(), arr_max)
the find_graph is a recursive method that returns all the arrays that comply
you likely need to tweek it so
but the logic works well
tested some edgecases
eg. arr = [1,1,1,1,1,1,1,1,1,1,3] gives quiet a few combinations, no I don't test for unique ones ;-)
you likely need to tweek it so
puts new_arr_res
actually returns an array instead of a stringified onebut the logic works well
tested some edgecases
eg. arr = [1,1,1,1,1,1,1,1,1,1,3] gives quiet a few combinations, no I don't test for unique ones ;-)
ASKER
Hi Gertone
This is very good - I tested it and works great. One other question if I may - say I have 2 arrays as per the following:
ma1=[1,2,3,4,5,6,7]
ma2=[25,15,60,50,2,50,100]
.. your code working on ma2 would not include the number 2 - so, what if I now wanted to show the 2 arrays (ma1 & ma2a) as per the following:
ma1=[1,2,3,4,5,6,7]
ma2a=[null,null,null,null, 2,null,nul l]
.. what I am now trying to achieve are the numbers that do not make up the sum of the max in array ma2.
Hope I am not asking too much.
Regards
This is very good - I tested it and works great. One other question if I may - say I have 2 arrays as per the following:
ma1=[1,2,3,4,5,6,7]
ma2=[25,15,60,50,2,50,100]
.. your code working on ma2 would not include the number 2 - so, what if I now wanted to show the 2 arrays (ma1 & ma2a) as per the following:
ma1=[1,2,3,4,5,6,7]
ma2a=[null,null,null,null,
.. what I am now trying to achieve are the numbers that do not make up the sum of the max in array ma2.
Hope I am not asking too much.
Regards
will look into this later
Two questions
- what happens when ma2=[25,15,60,50,2,50,100] ? Two result sets, what is null?
- why ma1? non null members of ma2a need to be in ma1?
Two questions
- what happens when ma2=[25,15,60,50,2,50,100]
- why ma1? non null members of ma2a need to be in ma1?
ASKER
Hi Gertone
OK - here is what I am trying to achieve. I already have a connection to sql server using the DBI.connect etc.
Eg
##connection string etc
sth = conn.execute("SELECT ID, Values FROM Products")
ma1=[]
ma2=[]
sth.fetch do |row|
ma1<<row[0]
ma2<<row[1]
end
sth.finish
………………...……..etc
In one of the columns there is an ID and the other column are values. Some ID's have 2 or more values and this is where I am trying to identify any value that that does or does not sum up to the max value for any given ID.
Below are the values returned to arrays ma1 & ma2 ….now I need another array that is my identifier (True or False) - let's call it ma3
The True value is a value that can be used as part of the sum that adds up to the max in any given ID (the max in any ID is always True)
ma1 ma2 ma3
ID Value Identifier
1 25 True
1 15 True
1 60 True
1 50 True
1 2 False
1 50 True
1 100 True ## the max for ID 1
2 4 True
2 6 True ## the max for ID 2
2 2 True
2 5 False
2 5 False
Once I have the ma3 array I can then load this back into a table in SQL server database.
Note: the above is a simple data set example as some ID's can have 100s or values
Hopefully this makes more sense
Regards
OK - here is what I am trying to achieve. I already have a connection to sql server using the DBI.connect etc.
Eg
##connection string etc
sth = conn.execute("SELECT ID, Values FROM Products")
ma1=[]
ma2=[]
sth.fetch do |row|
ma1<<row[0]
ma2<<row[1]
end
sth.finish
………………...……..etc
In one of the columns there is an ID and the other column are values. Some ID's have 2 or more values and this is where I am trying to identify any value that that does or does not sum up to the max value for any given ID.
Below are the values returned to arrays ma1 & ma2 ….now I need another array that is my identifier (True or False) - let's call it ma3
The True value is a value that can be used as part of the sum that adds up to the max in any given ID (the max in any ID is always True)
ma1 ma2 ma3
ID Value Identifier
1 25 True
1 15 True
1 60 True
1 50 True
1 2 False
1 50 True
1 100 True ## the max for ID 1
2 4 True
2 6 True ## the max for ID 2
2 2 True
2 5 False
2 5 False
Once I have the ma3 array I can then load this back into a table in SQL server database.
Note: the above is a simple data set example as some ID's can have 100s or values
Hopefully this makes more sense
Regards
Bit vague Phil, do you imply that you basically have two fields of a database table stored each in an array and expect the ruby code to actually align them?
It feels like a better approach would be
- forget about ma1
- make a first query to get a set of unique ids from the database (a condensed version of ma1)
- iterate over this set of unique ids and query for all the value fields for this particular id (a smaller ma2 that would be)
- do the magic of the graph function, altered to create a new false/true array in sync... although that should not be a new array, find_graph() creates all the summation true arrays, you can linearize that into one array and use it as a lookup when writing back to the database
That is I guess the approach I would take if I understand your issue well enough.
All this sync management of long arrays based on indexes is not good
It feels like a better approach would be
- forget about ma1
- make a first query to get a set of unique ids from the database (a condensed version of ma1)
- iterate over this set of unique ids and query for all the value fields for this particular id (a smaller ma2 that would be)
- do the magic of the graph function, altered to create a new false/true array in sync... although that should not be a new array, find_graph() creates all the summation true arrays, you can linearize that into one array and use it as a lookup when writing back to the database
That is I guess the approach I would take if I understand your issue well enough.
All this sync management of long arrays based on indexes is not good
ASKER
Hi Gertone
OK - I sort of get what you are saying but how can I change your magic graph function to return only values that don't get used in the sum of max value.
Eg
arr = [25,15,12,13] … your function returns #
25
-
12
13
-
which is great - but how can I change it to return …. [null,15,null,null].. this way I only get the value/s which are not used in the sum of max.
Regards
Regards
OK - I sort of get what you are saying but how can I change your magic graph function to return only values that don't get used in the sum of max value.
Eg
arr = [25,15,12,13] … your function returns #
25
-
12
13
-
which is great - but how can I change it to return …. [null,15,null,null].. this way I only get the value/s which are not used in the sum of max.
Regards
Regards
pass an array where you pussh all the valid arrays, flatten the result into a single array
after that you can use a map to fill a new array... but better, write directly to the database there
after that you can use a map to fill a new array... but better, write directly to the database there
arr = [25,15,12,13]
arr_max = arr.max()
arr_end = Array.new()
def find_graph(arr_local, arr_res, mx, arr_e)
arr_local.each_index do |i|
new_arr_local = arr_local.values_at(i + 1 .. (arr_local.length - 1))
new_arr_res = arr_res + arr_local.values_at(i)
new_mx = mx - arr_local.values_at(i)[0]
if new_mx == 0 then
arr_e.push(new_arr_res)
elsif new_mx > 0 and new_arr_local.length > 0 then
find_graph(new_arr_local, new_arr_res, new_mx, arr_e)
end
end
end
find_graph(arr, Array.new(), arr_max, arr_end)
arr_end.flatten!()
arr.map! { |x|
if arr_end.find_index(x) != nil then true
else false
end
}
ASKER
Hi
When I use … find_graph(arr, Array.new(), arr_max, arr_end) at the end of your new code I get an error...
true can't be coerced into Integer (TypeError)
Regards
When I use … find_graph(arr, Array.new(), arr_max, arr_end) at the end of your new code I get an error...
true can't be coerced into Integer (TypeError)
Regards
the arr has changed
arr.map! changes the map in place
so after this the array with numbers has gone.
it is just a mockup, you can easily change that code so it writes to a new array
but you should not call the find_graph() again
arr.map! changes the map in place
so after this the array with numbers has gone.
it is just a mockup, you can easily change that code so it writes to a new array
but you should not call the find_graph() again
ASKER
Hi Gertone
Unfortunately my Ruby is basic and I have been trying to get this to work with no success.
Regards
Unfortunately my Ruby is basic and I have been trying to get this to work with no success.
Regards
Hi Phil,
Currently in the middle of something. Will find time this afternoon
Currently in the middle of something. Will find time this afternoon
ASKER
Many thanks but will keep trying to understand
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
so, instead of overwriting the array, this code creates an ma3 like you wanted in the first place
ASKER
Thanks Gertone - great work and much appreciated
welcome
And then you need all the sets that add up to the max number?
Or would there only be one set?