keep track of a sum in a nested list? - nested-lists

I need to keep track of the value at index 0 for each instance of a list inside a nested list.
E.g. n = [2, [3, [1], [2]], 2]
The largest depth length is 3, so I need to add 2 + 3 + 1. The problem is, the function used to return the depth of the nested list is recursive, and I can't figure out where to add an accumulator.
def depth(lst):
if isinstance(lst, list):
return 1 + max(depth(item) for item in lst)
else:
return 0
where can I accumulate the values along the path leading to the highest depth?

Related

OR-Tools CP-SAT solver: count successive NewBoolVar occurrences

In a simple range I try to get the amount of successive assignments for a variable. The values should be between 6-12 or should be 0. For example in the case a hospital has 24 shifts and an employee should work between 6 and 12 hours or not at all.
# Build shifts
shifts = {}
for n in all_nurses:
for d in all_days:
for s in all_shifts:
shifts[(n, d, s)] = model.NewBoolVar('shift_n%id%is%i' % (n, d, s))
# Count successive occurrences
for e_count in all_nurses:
s_count = 0
while s_count < len(all_shifts):
model.Add(sum(shifts[e_count, s_count] for s in range(e_count, e_count + 6 == 6) #min
model.Add(sum(shifts[e_count, s_count] for s in range(e_count, e_count + 12 <= 12) #min
Unfortunately this doesn't work since it increases the value with only one, what would be the best approach to check if how many hours have been assigned and increase s_count with that value?
If you just want to constrain the sum, you should use this method
model.AddLinearExpressionInDomain(sum(bool_vars), cp_model.Domain.FromIntervals([0, 0], [6, 12]))
If you want to constrain the length of a sequence, you should look at the shift_scheduling example
In particular, the soft sequence constraint.
The idea is the following, for every starting point, you want to forbid 010, 0110, 01110, ..., 0111110 and 01111111111110 (0110 means work[start] is false, work[start + 1] is true, work[start + 2] is true, work[start + 3] is false.
To forbid a sequence, just add a nogood, that is a clause (or AddBoolOr containing the negation of the pattern.
in my example bool_or(work[start], work[start + 1].Not(), work[start + 2].Not(), work[start + 3]).
Loop over all starting points and all patterns. And pay attention to the boundary conditions.

SML Uncaught exception Empty homework1

Question: Write a function number_before_reaching_sum that takes an int called sum, which you can assume
is positive, and an int list, which you can assume contains all positive numbers, and returns an int.
You should return an int n such that the first n elements of the list add to less than sum, but the first
n + 1 elements of the list add to sum or more. Assume the entire list sums to more than the passed in
value; it is okay for an exception to occur if this is not the case.
I am quit new on SML, and coudn't find out anything wrong with this simple exprssion. The error message Please help me to debug the code below
fun number_before_reaching_sum (sum:int, xl: int list) =
if hd xl = sum
then 0
else
(hd xl) + number_before_reaching_sum(sum, (tl xl))
Try a couple of steps of your solution on a short list:
number_before_reaching_sum (6, [2,3,4])
--> if 2 = 6
then 0
else 2 + number_before_reaching_sum(6, [3,4])
--> 2 + if 3 = 6
then 0
else 3 + number_before_reaching_sum(6, [4])
--> ...
and you see pretty clearly that this is wrong - the elements of the list should not be added up, and you can't keep looking for the same sum in every tail.
You should return an int n such that the first n elements of the list add to less than sum, but the first n + 1 elements of the list add to sum or more.
This means that the result is 0 if the head is greater than or equal to the sum,
if hd xl >= sum
then 0
Otherwise, the index is one more, not hd xl more, than the index in the tail.
Also the "tail sum" you're looking for isn't the original sum, but the sum without hd xl.
else 1 + number_before_reaching_sum(sum - hd xl, tl xl)

Extracting kdb list values based on some condition

Say we have a kdb list
L1:(1 2 3 4 5)
Apply condition
L1 < 3
And how can I retrieve result in another list (1 2)
You can use the where keyword for this:
q)l1 where l1<3
1 2
Applying l1<3 will return a list of booleans 11000b. Using where on this list will return the index of every 1b
q)where 11000b
0 1
Then indexing back into the original list will return the result in another list.

How to match a value of a list of numbers to item from a list of names in netlogo?

I am trying something (in netlogo), but it is not working. I want a value of a position from a list of numbers. And I want to use the number that comes out of it to retrieve a name from a list of names.
So if I have a list like [1 2 3 4] en a list with ["chicken" "duck" "monkey" "dog"]
I want my number 2 to correspond with "duck".
So far, my zq is a list of numbers and my usedstrategies is a list of names.
let m precision (max zq) 1
let l position m zq
let p (position l zq) usedstrategies
But when I try this the result will be false, because l is not part of usedstrategies.
Ideas?
You need the item primitive to select from the list after matching on the other list. I am not sure what the precision line is for. However, here is a self contained piece of code that I think demonstrates what you want to do. Note that NetLogo counts positions from 0, not 1. I also used arbitrary numbers in the list so you don't get confused between the number in the list and its position.
to testme
let usedstrategies (list "chicken" "duck" "monkey" "dog")
let zq (list 5 6 7 8)
let strategynum position 7 zq
let thisstrategy item strategynum usedstrategies
type "Selected strategy number " type strategynum
type " which is " print thisstrategy
end
Jen's solution is perfectly fine, but I think this could also be a good use case for the table extension. Here is an example:
extensions [table]
to demo
let usedstrategies ["chicken" "duck" "monkey" "dog"]
let zq [5 6 7 8]
let strategies table:from-list (map list zq usedstrategies)
; get item corresponding with number 7:
print table:get strategies 7
end
A "table", here, is a data structure where a set of keys are associated with values. Here, your numbers are the keys and the strategies are the values.
If you try to get an item for which there is no key in the table (e.g., table:get strategies 9), you'll get the following error:
Extension exception: No value for 9 in table.
Here is a bit more detail about how the code works.
To construct the table, we use the table:from-list reporter, which takes a list of lists as input and gives you back a table where the first item of each sublist is used as a key and the second item is used as a value.
To construct our list of lists, we use the map primitive. This part is a bit more tricky to understand. The map primitive needs two kind of inputs: one or more lists, and a reporter to be applied to elements of these lists. The reporter comes first, and the whole expression needs to be inside parentheses:
(map list zq usedstrategies)
This expression "zips" our two lists together: it takes the first element of zq and the first element of usedstrategies, passes them to the list reporter, which constructs a list with these two elements, and adds that result to a new list. It then takes the second element of zq and the second element of usedstrategies and does the same thing with them, until we have a list that looks like:
[[5 "chicken"] [6 "duck"] [7 "monkey"] [8 "dog"]]
Note that the zipping expression could also have be written:
(map [ [a b] -> list a b ] zq usedstrategies)
...but it's a more roundabout way to do it. The list reporter by itself is already what we want; there is no need to construct a separate anonymous reporter that does the same thing.

How to do sum of list subset in kdb?

If you have a list and another list with indices (limited number) in of the first list in ascending order.
How can you get a sum of elements in the first list between consecutive indices in the second list.
e.g:
list1: til 100;
idx: (1 20 50 70 100);
How can we get a list with sum of elements of list from elements 1:20, 20:50, 50:70, 70:100?
The obvious approach would be to use # and _ on elements of the idx but can we do that iteratively somehow without using first, first 1_idx etc.
Something like this would work:
q)sum each idx cut list1
190 1035 1190 2535 0
cut operates by cutting the second argument at the indices given in the first. Hence why you see the 0 at the end of the result, as it's cutting at the 100th element.