Trying to loop over index values - Intend to to get False value for every index number divided by 2 - python-3.7

I have a list such as:
bool_list = [False,False,True,True,True,True]
Now I plan to run a for loop to make sure that every index value divided by 2 gets converted to False. In case, the index value is not divided by 2 then it remains the same.
For example, I want a result in which the bool_list will display =
[False,False,False,True,False,True] as the 2nd and 4th index has been turned to False.
I have tried to write the following for loop using the enumerate function to get the index value but somehow it's giving me an error:
def mark_false(bool_list, p):
for idx,val in enumerate(bool_list):
if idx % p ==0:
bool_list[idx] ==False
else:
bool_list[idx] = bool_list[idx]
return (bool_list)
The function is going to be with p = 2

You can do this without a loop by replacing the slice of every other index with a list of False objects of the same length:
>>> bool_list = [False,False,True,True,True,True]
>>> bool_list[::2] = [False] * len(bool_list[::2])
>>> bool_list
[False, False, False, True, False, True]

I assume this is what your are looking for.
just changes 4th and 6th element of bool_list.
def mark_false(bool_list, p):
for i in range(2 * p, len(bool_list), p):
bool_list[i] = False
return bool_list
print(mark_false(list_true(6), 2))

Related

Check if assigned elements satisfy a condition in OR-Tools

I have say 100 elements that I want to assign to say 10 spots.
# the elements list holds 100 variables that signify the assignment to a spot
elements = [model.NewIntVar(1, 10) for i in range(100)]
Each of my element has a specific size. Now I want to model one (set of) constraint(s) per spot that says: The added sizes of all elements assigned to this spot lies in a fixed range.
So if spot 1 gets elements 1, 16 and 64 assigned, and their sizes are 1521, 1732, 1431 and my range is (3000, 6000) that would be ok. But if too many or too large elements (or too few/small) get assigned to spot 1, that would not be ok.
Something like the following, which does not work:
for spot in range(10):
sum_ = sum([get_size(e) for e in elements if e == spot]) # if think if e == spot is what fails
model.Add(sum_ >= 3000)
model.Add(sum_ <= 6000)
How can I model such a thing? I have looked at channeling constraints but I can't quite wrap my head around it.
I think it is better to model the assignment as a boolean:
from ortools.sat.python import cp_model
model = cp_model.CpModel()
solver = cp_model.CpSolver()
all_spots = range(10)
all_elems = range(100)
elements = {
(elem, spot): model.NewBoolVar(f"{elem} in spot {spot}")
for elem in all_elems
for spot in all_spots
}
# only one spot for element
for elem in all_elems:
model.Add(sum(elements[elem, spot] for spot in all_spots) == 1)
for spot in all_spots:
# taking the element id as its size
sum_ = sum(elements[elem, spot] * elem for elem in all_elems)
model.Add(sum_ >= 0)
model.Add(sum_ <= 500)
solver.Solve(model)
for (elem, spot), boolean in elements.items():
if solver.Value(boolean):
print(boolean)
See:
https://github.com/google/or-tools/blob/stable/ortools/sat/samples/multiple_knapsack_sat.py
https://github.com/google/or-tools/blob/stable/ortools/sat/samples/binpacking_problem_sat.py
https://github.com/google/or-tools/blob/stable/examples/python/balance_group_sat.py#L102

Is there a way to only keep the last two saved values of the recursion in a dictionary and delete the rest?

i am using memoization to save the last calculated values of fibonacci numbers in a dictionary. Since (i suppose) that we don't need all of the values that were previously calculated in our dictionary so, i want to delete them. specifically i only want to keep only the last two calculated fibonacci numbers, is there a way to do it?
import sys
sys.setrecursionlimit(10000)
cache = {}
def fib(n):
if n in cache:
return cache[n]
elif n <= 2:
value = 1
else:
value = fib(n-1) + fib(n-2)
cache[n] = value
return value
print(fib(1000))
ok i found it.
cache = {}
for x in range(1, 1000001):
if x > 4:
cache.pop(x-3, x-4)
if x <= 2:
value = 1
cache[x] = value
else:
value = cache[x - 1] + cache[x - 2]
cache[x] = value
print(value)

Make zeros to certain rows in 2D array [duplicate]

It's actually a very simple question, but after an hour I can not solve my problem.
I need to create a 2d array of Int.
var arr = [[Int]]()
or
var arr : [[Int]] = []
tried to change value :
arr[x][y] = 1
fatal error: Index out of range
Should I use APPEND or I need specify the size of the array?
I'm confused..
It's not simple really. The line:
var arr : [[Int]] = []
Creates a variable of type Array of Array of Int and initially the array is empty. You need to populate this like any other other array in Swift.
Let's step back to a single array:
var row : [Int] = []
You now have an empty array. You can't just do:
row[6] = 10
You first have to add 7 values to the array before you can access the value at index 6 (the 7th value).
With your array of arrays, you need to fill in the outer array with a whole set of inner arrays. And each of those inner arrays need to be filled out with the proper number of values.
Here is one simple way to initialize your array of arrays assuming you want a pre-filled matrix with every value set to 0.
var matrix : [[Int]] = Array(repeating: Array(repeating: 0, count: 10), count: 10)
The outer count represents the number of rows and the inner count represents the number of columns. Adjust each as needed.
Now you can access any cell in the matrix:
matrix[x][y] = 1 // where x and y are from 0 to rows-1/columns-1
Not only you need to initialize both the array and subarrays before being able to assign any values, but also each array length must be greater than the index position you are trying to set.
This is because Swift does neither initialize the subarrays for you, neither increments the array length when assigning to an index.
For instance, the following code will fail:
var a = [Int]()
a[0] = 1
// fatal error: Index out of range
Instead, you can initialize an array with the number of elements you want to hold, filling it with a default value, zero for example:
var a = Array(repeating: 0, count: 100)
a[0] = 1
// a == [1, 0, 0, 0...]
To create an matrix of 100 by 100 initialized to 0 values:
var a = Array(repeating: Array(repeating: 0, count: 100), count: 100)
a[0][0] = 1
If you don't want to specify an initial size for your matrix, you can do it this way:
var a = [[Int]]()
a.append([])
a[0].append(1)

500000x2 array, find rows meeting specific requirements of 1st and 2nd column, MATLAB

I'm facing a dead end here..
I have collected a huge amount of data and I have isolated only the information that I'm interested in, into a 500K x 2 array of pairs.
1st column contains an ID of, let's say, an Access Point.
2nd column contains a string.
There might be multiple occurrences of an ID in the 1st column, and there can be anything written in the 2nd column. Remember, those are pairs in each row.
What I need to find in those 500K pairs:
I want to find all the IDs, or even the rows, that have 'hello' written in the 2nd column, AND as an additional requirement, there must be more than 2 occurrences of this 'pair'.
Even better want to save how many times this happens, if this happens more than 2 times.
so for example:
col1 (IDs): [ 1, 2, 6, 2, 1, 2, 3, 1]
col2 (str): [ 'hello', 'go', 'hello', 'piz', 'hello', 'da', 'mn', 'hello']
so the data that I ask is :
[ 1, 3 ] , which means, ID=1 , 3 occurences of id=1 with str='hello'
I tried to benchmark it to see if it could do 500.000 rows in a reasonable time.
generate some test data (in total about 60MB)
V = 1+round(rand(5E5,1).*1E4);
H = cell(1,length(V));
for ct = 1:length(H)
switch floor(rand(1)*10)
case 0
H{ct} = 'hello';
case 1
H{ct} = 'go';
case 2
H{ct} = 'piz';
case 3
H{ct} = 'da';
case 4
H{ct} = 'mn';
case 5
H{ct} = 'ds';
case 6
H{ct} = 'wf';
case 7
H{ct} = 'sf';
case 8
H{ct} = 'as';
case 9
H{ct} = 'sg';
end
end
The analysis
tic
a=ismember(H,{'hello'});
M = accumarray(V(a),1);
idx = find(M>1);
result = [idx,M(idx)];
toc
Elapsed time is 0.011699 seconds.
Alternative method with a loop
tic
M=zeros(max(V),1);
for ct = 1:length(H)
if strcmp(H{ct},'hello')
M(V(ct))=M(V(ct))+1;
end
end
idx = find(M>1);
result1 = [idx,M(idx)];
toc
Elapsed time is 0.192560 seconds.
Their are many possible solutions. Here is one: use a map structure. The key set of the map contains the ID's (where "hello" appears in the second column), and the value set contains the number of occurrences.
Run over the second column. When you find "hello", check if the corresponding ID is already a key in the map structure. If true, add +1 to the value associated to that key. Else, add a new pair (key,value) = (the ID, 1).
When finished, remove all the pairs from the map whose values are less or equal than 2. The remaining map is what you are looking for.
Matlab map: https://es.mathworks.com/help/matlab/map-containers.html

matlab search a matching element

I have an integer array of length 2000 elements. For ex
x = [2, 4, 5, 6, 5,6,7,5......];
Now in this array i need to find an element which occurs repeatedly. For ex I need to know how many times a number '5' has been occurred. In the above example it is three times.
Is there any way to search an matching element and returns the count in matlab?
Do you know the number in advance?
If so, to work out how many times it appears in x you could do:
sum(x==5)
The x==5 creates a vector of [FALSE FALSE TRUE FALSE TRUE FALSE FALSE TRUE ...], being TRUE whenever x is 5.
The sum then adds up that vector, where FALSE maps to 0 and TRUE to 1.
A quick way get the count is
sum(x == 5)
If you need the indicies of the matching elements:
find(x == 5)
Notice, the count is also length(find(x == 5)).
Standard caveats apply toward the use of == and floating point numbers.