Type-safe way to remove nulls from Array in Crystal - crystal-lang

Is there a preferred and type-safe way without forced typecast to remove nils from Array?
[1, nil].select{|x| !!x}
// => Array(Int32 | Nil)
Something like special select?
P.S.
The use case when I hit this issue - I want to calculate median and the sort won't work:
[1, nil].select{|x| !!x}.sort
Map with zeros [1, nil].map{|x| x || 0} won't work as unlike let's say sum for some operations the length does matter (median for example).

Array#compact will remove nils from the Array:
[1, nil].compact # => [1] (Array(Int32))

Related

Find sum of number in multiple sets using exactly one number of each set

Background
Hi, I'm trying to solve a programming problem and I'm stuck on the following problem:
Assume you have multiple lists of numbers. All are sorted in decreasing order.
You now have to take exactly one number from each list to make the biggest possible sum.
So far so easy, to solve this you could just take the first number of each list and you're done.
But now, I need the second-largest sum while still using exactly one number from each list.
To achieve this, I would take the first element in each list but for the list which has the least difference between the first and second number the second number will be used.
This is still pretty doable.
The Problem
But I need an Iterator over every possible sum using exactly one number of each list sorted in decreasing order.
For performance reasons, it isn't possible to just compute every sum and then sort it. The algorithm must already provide the sums in decreasing order. If there are multiple combinations for a sum then the sum must be returned multiple times.
Additional Requirements
The Iterator should be lazy (only calculate the next sum when required).
The Lists are already lazy, which means you should require as few values as possible to calculate the fitting sum.
Example
For the Lists:
List 1: [5, 2, 1]
List 2: [10, 2]
List 3: [6, 1]
The Iterator then should return:
[5, 10, 6] = 21
[2, 10, 6] = 18
[1, 10, 6] = 17
[5, 10, 1] = 16
[5, 2, 6] = 13
[2, 10, 1] = 13
[1, 10, 1] = 12
[2, 2, 6] = 10
[1, 2, 6] = 9
[5, 2, 1] = 8
[2, 2, 1] = 5
[1, 2, 1] = 4
Comment
I don't need code as an answer to my question (you're still welcome to provide it if it helps to explain). What I'm looking for are ideas to solve this, or solutions that I can implement myself.
Thanks in advance!
First of all, Thanks to wlui155 for the help.
For Anyone interested, I coded a BFS algorithm that acts as follows:
Definitions:
Entry: Struct containing indices of used numbers and sum
BSet: Ordered set which can only contain unique Entries
Algorithm:
Pop Entry with biggest sum from BSet
Create a clone for each list
Advance in each clone a different index by one
Put new entries in BSet
Print current Entry
Goto 1.
Now you only have to ensure that no entry appears again after you've popped it. This can be ensured with a separate set containing all combinations for the current sum. Once the current sum gets smaller this set can be cleared.
If you have ideas to improve this, you're welcome to tell me.

Prolog How to Declare a List to a Variable

In Prolog, I'm struggling to understand how to bind a list of lists to a variable. For instance, say I have the predicate makeList (which I don't know how to write), then I should be able to type:
makeList([[0, 0], [1, 0]]).
Now I want to refer to [[0, 0], [1, 0]] in another predicate with a variable, ListList, like:
predicateThatDoesSomething(ListList) :- write(ListList).
Expected Output:
[[0, 0], [1, 0]]
Obviously predicateThatDoesSomething() knows about the variable named ListList already. But how do I make the predicate makeList()? I want to be able to type makeList([[ANY, LIST, IN, HERE], [ANOTHER, LIST]]) and have that be ListList for example.
You have to write a predicate that merge the two list, thus this predicate must unify with something like:
makeList(List1, List2, [List1, List2]).
After defined this predicate in you knowled base, you can interrogate the prolog engine asking:
makeList([1,2],[2,4],D).
And you'll get: D = [[1, 2], [2, 4]]
To make the other predicate (defined in your KB)
predicateThatDoesSomething(ListList) :- write(ListList).
know the result (output parameter, the results of unification), you have to logically and the statements. So you have to ask:
makeList([1,2],[2,4],D) , predicateThatDoesSomething(D).

Ember set subtraction with PromiseArrays

I have two PromiseArray objects, from within a controller, e.g. this.get('content.skills') and this.get('allSkills').
I'd like to do what is essentially set subtraction. For example:
[1, 2, 3] - [2, 3] // => [1]
Is there a straightforward to do this? There's an alias for doing intersections. My guess is that it will use rejectBy somehow, but I'm not quite sure how.
You can use http://emberjs.com/api/classes/Ember.MutableArray.html#method_removeObjects with the Promise's content as long as they are fulfilled.
P1.removeObjects(P2.toArray());

How to join 2 lists in redis

Intro
I'm trying to do something that sounds simple, but so far I'm not having luck finding the answer. I have 2 lists in a redis 2.6.4 standalone server(no cluster):
list1 = [4, 5 ,6]
list2 = [1, 2, 3]
The problem
And I need to concatenate the lists to produce something like this:
list3 = list1 + list2
list3 = [4, 5, 6, 1, 2, 3] <- I need to preserve order, list1 and then list 2
list4 = list2 + list1
list4 = [1, 2, 3, 4, 5, 6]
The question
Since redis use linked lists to store this lists I was expecting to have a straightforward way of doing this, does such a way exists? what's the usual way of doing this in redis?
Thanks in advance!
The easiest way to do this safely is to use LUA scripting, this way you have the guarantee that the resulting list is not missing any element (and you can easily preserve the order).
If LUA is not an option then you need to do this client side and use watch those keys for changes (see transaction in redis and WATCH command)
Here is the Redis command using Lua:
eval "for i,l in ipairs(ARGV) do for i,v in ipairs(redis.call('lrange',l,0,-1)) do redis.call('rpush',KEYS[1],v) end end" 1 list3 list1 list2
As an added bonus you can specify any number of lists to append into your master list by simply adding more list keys at the end

Appending Nested Lists in Python

I have the following question for homework
Define a function append lists that
takes a list of lists and returns a
new list containing the sublist
values. For example, append lists([[1,
2], [3, 4], [5]]) should return the
list [1, 2, 3, 4, 5] and append
lists([[1, 2], [3], [[4, 5]]]) should
return the list [1, 2, 3, [4, 5]].
I've tried various ways of creating this function in order to append the list so it gives the desired output to no avail so I came here looking for some help. I've found a few other ways of going about this online, but they use extensive methods that we haven't even dabbled in as of yet in my CPSC 121 class. We're limited to the basics in what we've learned.
Any help would be much appreciated!
By now, it is likely that the assignment is gone, but here is a solution:
def append_lists(lists):
output = []
for l in lists:
for e in l:
output.append(e)
return output
This appends each element of each list to the output of the function, which eliminates exactly one level of nesting in the elements.