Coming with a procedure to generate an array with special properties - algorithm

I have an array of size n. Each element can hold any integer as long as the following properties holds:
1) All elements are non-negative
2) sum(array[0,i+1])<i for 0<=i<n
3) sum(array)=n-1
Let's call such an array a bucket.
I need to come up with a procedure that will generate the next bucket.
We can assume the first bucket is {0,0,0...n-1}
Example: For n=5, some possible combinations are
[0 0 0 0 4]
[0 0 0 1 3]
[0 0 0 2 2]
[0 0 0 3 1]
[0 0 1 2 1]
[0 0 2 1 1]
[0 1 1 1 1]
[0 1 0 0 3]
[0 1 1 0 2]
I'm having trouble coming up with a procedure that hits all the possible combinations. Any hints/tips? (Note I want to generate the next bucket. I'm not looking to print out all possible buckets at once)

You can use a simple backtracking procedure. The idea is to keep track of the current sum and the current index i. This would allow you to express the required constrains.
n = 5
a = [0] * n
def backtrack(i, sum):
if i > 0 and sum > i-1:
return
if i == n:
if sum == n-1:
print(a)
return
for e in range(n-sum):
a[i] = e
backtrack(i + 1, sum+e)
backtrack(0, 0)
test run

Related

Slice appending not working as intended when generating a binary sequence

I have this piece of code that generate all binary sequences of length n.
so:
allBitsSeqs(2) gives a 1-by-n int slice [[1 1][0 0] [1 0] [0 1]]
Here's the code:
func allBitSeqs(n int) [][]int {
seq := [][]int{{1}, {0}}
for floor := 1; floor < n; floor++ {
remember := [][]int{}
for i := 0; i < len(seq); i++ {
one := append(seq[i], 1)
remember = append(remember, one)
zero := append(seq[i], 0)
remember = append(remember, zero)
}
seq = remember
}
return seq
}
playground link: https://play.golang.org/p/s40RS7qEKfL
problem is, when n = 4 or more, I get:
[[1 1 1 0] [1 1 1 0] [1 1 0 0] [1 1 0 0] [1 0 1 0] [1 0 1 0] [1 0 0 0] [1 0 0 0] [0 1 1 0] [0 1 1 0] [0 1 0 0] [0 1 0 0] [0 0 1 0] [0 0 1 0] [0 0 0 0] [0 0 0 0]]
Notice how they are repeating in pairs.
I have tried some debugging and I think it has something to do with how Go copy its slices when it needs to allocate more space.
A slice is a view of an underlying array. If you have multiple slices working with the same underlying array, you may get unexpected results if you don't know how slices work.
one := append(seq[i], 1)
Say, one is a slice pointing to an array that has the capacity to hold the added element. Something like the following:
[ 1 1 . . . ]
The array capacity is 5, with first two elements set to 1 (slice len=2). When you add another 1, it becomes:
[ 1 1 1 . .]
Then you do the following:
remember = append(remember, one)
With this, you added a slice pointing to the above array, with len=3 and capacity=5.
Then:
zero := append(seq[i], 0)
Remember that seq[i] is still pointing to the same array. Further, seq[i] has len=2. So the array becomes:
[ 1 1 0 . . ]
That is your zero. However, when you add that 0, you also changed the slice one. You end up with both zero and one pointing to [1 1 0 . .].
Long story short: when you assign a slice to a variable, you assign the view to an array. If you modify the contents of the underlying array, the contents of the view also change.
To fix: create a new slice, copy data, and store that copy.

Find maximum covered elements without block by obstacles in path

Given MXN matrix where matrix elements are either "." or "*". Where . is representing road and * is representing block or wall. Person can move adjacent forward, down and diagonally, we need to find maximum "." covered by person without blocked by wall. Example(in image)
Can you please suggest me efficient algorithm to approach this problem?
You have to do this: https://en.wikipedia.org/wiki/Flood_fill
Take the biggest flood you can do.
You go through your matrix and find a '.'
Do a flood from that point. The amount of elements you flood the area you always compare it with the maximum you already found. To make this easy you can flood with a letter or a number or whatever you want but not with '.'. What you add instead of '.' consider it as a wall or a '*' so you don't try to flood that area again and again.
Continue to go through the matrix and try to find the next '.'. All the previous '.' where flooded so you won't consider the same area twice.
Redo 2 until you can't find any more '.'. The maximum will contain your answer.
When you have the answer you can go back in the Matrix and you already know the letter or number you flooded the area with the maximum result so you can print the biggest area.
Are you looking for the exact path or only the number of cases?
Edit: here a smallp Python script which creates a random matrix and count the number of cases in each zone defined by your "walls".
import numpy as np
matrix = np.random.randint(2, size=(10, 10))
print(matrix)
M, N = matrix.shape
walked = []
zonesCount = []
def pathCount(x, y):
if x < 0 or y < 0 or x >= M or y >= N:
return 0
if matrix[x, y] == 1: # I replaced * by 1 and . by 0 for easier generation
return 0
if (x, y) in walked:
return 0
walked.append((x, y))
count = 1
for i in [x - 1, x, x + 1]:
for j in [y - 1, y, y + 1]:
if (i, j) != (x, y):
count += pathCount(i, j)
return count
for x in range(M):
for y in range(N):
if not (x, y) in walked:
zonesCount.append(pathCount(x, y))
print('Max zone count :', max(zonesCount))
And here is the result:
[[0 0 1 0 0 0 1 0 1 0]
[1 0 1 0 0 0 1 0 1 1]
[0 1 0 0 1 0 0 1 1 1]
[0 0 1 0 0 0 1 1 0 1]
[1 0 1 1 1 1 0 1 1 0]
[1 0 1 1 1 1 0 1 1 0]
[0 0 0 1 1 1 0 0 0 0]
[1 0 0 1 1 0 0 1 1 0]
[0 1 0 1 0 0 1 0 1 1]
[0 1 1 0 0 0 1 0 1 0]]
Max zone count : 50

Octave model matrix

Is there a simple (non for loop) way to create a model matrix in Octave. In R i use model.matrix() to do this.
I have this array:
array = [1;2;3;2]
and i need (for regression reasons)
*(model = [1 0 0 0; 0 1 0 1; 0 0 1 0])* EDIT on my side
result is this model (colum 1 is for 1, column 2 for the two's etc.:
model = [1 0 0 ; 0 1 0 ; 0 0 1 ; 0 1 0]
I can do this with a for loop:
model = zeros(4,3);
for i=1:4
model(i,array(i)) = 1;
end
but it would be nice to do this in one step something like:
model = model.matrix(array)
i can than include it in a formula straight away
You need to turn your values into linear indices like so:
octave:1> array = [1 2 3 2];
octave:2> model = zeros ([numel(array) max(array)]);
octave:3> model(sub2ind (size (model), 1:numel(array), array)) = 1
model =
1 0 0
0 1 0
0 0 1
0 1 0
Because your matrix will be very sparse, a possible optimization is to create a sparse matrix instead.
octave:4> sp = sparse (1:numel(array), array, 1, numel (array), max (array))
sp =
Compressed Column Sparse (rows = 4, cols = 3, nnz = 4 [33%])
(1, 1) -> 1
(2, 2) -> 1
(4, 2) -> 1
(3, 3) -> 1
octave:5> full (sp)
ans =
1 0 0
0 1 0
0 0 1
0 1 0
This will take a lot less memory but many functions will be unable to handle them and convert them to a full matrix anyway. So whether this is worth is dependent on what you want to do next.

Counting subrows in each row of a matrix in Matlab?

I need an algorithm in Matlab which counts how many adjacent and non-overlapping (1,1) I have in each row of a matrix A mx(n*2) without using loops. E.g.
A=[1 1 1 0 1 1 0 0 0 1; 1 0 1 1 1 1 0 0 1 1] %m=2, n=5
Then I want
B=[2;3] %mx1
Specific case
Assuming A to have ones and zeros only, this could be one way -
B = sum(reshape(sum(reshape(A',2,[]))==2,size(A,2)/2,[]))
General case
If you are looking for a general approach that must work for all integers and a case where you can specify the pattern of numbers, you may use this -
patt = [0 1] %%// pattern to be found out
B = sum(reshape(ismember(reshape(A',2,[])',patt,'rows'),[],2))
Output
With patt = [1 1], B = [2 3]
With patt = [0 1], B = [1 0]
you can use transpose then reshape so each consecutive values will now be in a row, then compare the top and bottom row (boolean compare or compare the sum of each row to 2), then sum the result of the comparison and reshape the result to your liking.
in code, it would look like:
A=[1 1 1 0 1 1 0 0 0 1; 1 0 1 1 1 1 0 0 1 1] ;
m = size(A,1) ;
n = size(A,2)/2 ;
Atemp = reshape(A.' , 2 , [] , m ) ;
B = squeeze(sum(sum(Atemp)==2))
You could pack everything in one line of code if you want, but several lines is usually easier for comprehension. For clarity, the Atemp matrix looks like that:
Atemp(:,:,1) =
1 1 1 0 0
1 0 1 0 1
Atemp(:,:,2) =
1 1 1 0 1
0 1 1 0 1
You'll notice that each row of the original A matrix has been broken down in 2 rows element-wise. The second line will simply compare the sum of each row with 2, then sum the valid result of the comparisons.
The squeeze command is only to remove the singleton dimensions not necessary anymore.
you can use imresize , for example
imresize(A,[size(A,1),size(A,2)/2])>0.8
ans =
1 0 1 0 0
0 1 1 0 1
this places 1 where you have [1 1] pairs... then you can just use sum
For any pair type [x y] you can :
x=0; y=1;
R(size(A,1),size(A,2)/2)=0; % prealocarting memory
for n=1:size(A,1)
b=[A(n,1:2:end)' A(n,2:2:end)']
try
R(n,find(b(:,1)==x & b(:,2)==y))=1;
end
end
R =
0 0 0 0 1
0 0 0 0 0
With diff (to detect start and end of each run of ones) and accumarray (to group runs of the same row; each run contributes half its length rounded down):
B = diff([zeros(1,size(A,1)); A.'; zeros(1,size(A,1))]); %'// columnwise is easier
[is js] = find(B==1); %// rows and columns of starts of runs of ones
[ie je] = find(B==-1); %// rows and columns of ends of runs of ones
result = accumarray(js, floor((ie-is)/2)); %// sum values for each row of A

Auto complete an array according a vector

I have an array of 16 squares and I would like to auto complete it with integers values depending of the position in the array and the vector TOP_RIGHT.
TOP_RIGHT = 3
# Build the array...
#top_right = Array.new(16, 0)
#top_right.each_index do |square|
#top_right[square] = square / TOP_RIGHT if (0...16).include?(square - TOP_RIGHT)
end
# Print the array...
i = 0
#top_right.each do |square|
puts if i % 4 == 0
print "#{square} "
i += 1
end
My code seems to be okay, but after testing the result is:
0 0 0 1
1 1 2 2
2 3 3 3
4 4 4 5
I would like to get this array:
0 0 0 0
1 1 1 0
2 2 1 0
3 2 1 0
Do you think it is possible, using array and simple Ruby methods?
Thanks, and happy end year!
Edit:
In the previous example, TOP_RIGHT is a vector like and its value is the number of cases that we can add or sub in order to go from the source square to the destination square (which is on top-right).
For example if I get this other vector: TOP, its value is 4 and the generated array can be:
# print_array(4)
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
...and if the vector is RIGHT, its value is -1 and the array can be:
# print_array(-1)
3 2 1 0
3 2 1 0
3 2 1 0
3 2 1 0
Isn't it a little beat tricky? :)
I don't see how to process for designing a constructor which can build such arrays, by passing a value of a vector.
If you use an array to hold an array, and don't try to do it in a vector, it's not too bad:
#!/usr/bin/ruby1.8
top_right = 3
array_size = 4
a = (0...array_size).collect do |i|
(0...array_size).collect do |j|
[i, j].collect do |e|
top_right - e
end.min
end
end.reverse
a.each do |e|
p e
end
=> [0, 0, 0, 0]
=> [1, 1, 1, 0]
=> [2, 2, 1, 0]
=> [3, 2, 1, 0]
And if you really need the array squished into a vector, then:
v = a.flatten

Resources