I have developed a macro in VBA which combines three triples of football pools representing the 27 different combinations. 27 represents the max possible combinations of betting. I would like to modify the list in a way to develop a system with double, fixed, triple prediction;
For example, now the program only works for:
1st game 1 x 2
2nd game 1 x 2
3rd game 1 x 2
equal to (3 * 3 * 3 = 27 possible combinations)
but if the prediction was the following:
1st game 1 x
2nd game 1
3rd game 1 x 2
equal to (2 * 1 * 3 = 6 possible combinations)
Now : first game 1 x 2 , second 1 x 2 ,third 1 x 2 ,equal to (3 * 3 * 3 = 27 combinations) but if the prediction should be the following: first game 1 x, second 1 , third x 2 , equal to (2 * 1 * 3 = 6 combinations) should be printed only valid columns.
Thank you in advance who can help me to solve the problem.
Sub Combination_Prediction()
Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim Col1Sviluppo As Integer
Dim Row1Sviluppo As Integer
Col1Sviluppo = 10
Row1Sviluppo = 14
For C = 3 To 5
For B = 3 To 5
For A = 3 To 5
Contatore = Contatore + 1
Col1Sviluppo = Col1Sviluppo + 1
Cells(Row1Sviluppo + 1, Col1Sviluppo) = Cells(2, A)
Cells(Row1Sviluppo + 2, Col1Sviluppo) = Cells(3, B)
Cells(Row1Sviluppo + 3, Col1Sviluppo) = Cells(4, C)
Cells(10, 10) = Contatore & " colonne elaborate"
Next A
Next B
Next C
End Sub
Disclaimer: your logic is based on unpredictable assumptions. Please do not relay on it if youre betting real money. It's all more complicated then you think it is. There is only one reliable way of betting and earning (requires a lot of money to get started and proper and good understanding of bookmakers policies) and it's called sure bets. But please, do not get into it.
Now, back to your original question.
You can have a function return the number of combinations based on the input ยป combinations multipliers
Let's assume that
combinations multipliers
1 - 1
2 - 1X
3 - 1X2
1 represents either home or away win, 1 combination
2 stands for home win or draw, away win or draw, 2 combinations
3 is default: win, draw, win
The code:
Sub Combination_Prediction()
' combinations multipliers
' 1 - 1
' 2 - 1X
' 3 - 1X2
Range("A1") = Combination(3, 3, 3) ' 1x2, 1x2, 1x2
Range("B2") = Combination(2, 1, 3) ' 1x, 1, 1x2
End Sub
Function Combination(c1 As Long, c2 As Long, c3 As Long) As Long
Dim i As Long, j As Long, k As Long, combinationMultiplier As Long
combinationMultiplier = 0
For i = 1 To c1
For j = 1 To c2
For k = 1 To c3
combinationMultiplier = combinationMultiplier + 1
Next k
Next j
Next i
Combination = combinationMultiplier
End Function
If you ran this code, you will see in Cell A1 number 27 which is the correct (and simplified) calculation of possible bets.
The Combination() function takes 3 parameters which are the 3 combinations.
In the first example the first input is 3, 3, 3 as from your sample
1st game = 1x2
2nd game = 1x2
3rd game = 1x2
Now look at the combinations multipliers above
1st game = 1x2 = 3
2nd game = 1x2 = 3
3rd game = 1x2 = 3
Therefore, your 3 parameters are: 3, 3, 3
The second sample you provided
1st game = 1x = 2
2nd game = 1 = 1
3rd game = 1x2 = 3
therefore Combination(2, 1, 3) will return 6 (combinations) to Cell A2
Stick any combination of 1, 2, 3 into the combination function to get results. You can either print them to cell or use msgbox or debug.print for testing.
I hope that helps
Related
I am searching through a large number of possible outcomes and, while I may not find the perfect outcome, I would like to score the various outcomes to see how close they come to ideal. (I think I'm talking about some kind of weighted scoring, but don't let that influence your answer in case I'm completely off base.)
For some context, I'm generating a variety of work schedules and would like to have each result scored such that I don't have to look at them individually (it's a brute force approach, and there are literally billions of solutions) to determine if one is better or worse than any other one.
Input-wise, for each generated schedule, I have a 3x14 array that holds the total number of people that are scheduled to work each shift on any given day (i.e. for each day in a two-week period, the number of people working days, swings, and mids on that day).
So far, I have tried:
A) summing the values in each row, then multiplying each sum (row) by a weight (e.g. row 0 sum * 1, row 1 sum * 2, row 2 sum * 3, etc.), and finally adding together the weighted sums
function calcScore(a)
dim iCol, iTotalD, iTotalM, iTotalS
for iCol = 0 to 13
iTotalD = iTotalD + a(0)(iCol)
iTotalS = iTotalS + a(1)(iCol)
iTotalM = iTotalM + a(2)(iCol)
next
calcScore = iTotalD + iTotalS * 2 + iTotalM * 3
end function
And
B) multiplying each value in each row by a weight (e.g. row 0(0) * 1, row 0(1) * 2, row 0(2) * 3, etc.), and then summing the weighted values of each row
function calcScore(a)
dim iCol, iTotalD, iTotalM, iTotalS
for iCol = 0 to 13
iTotalD = iTotalD + a(0)(iCol) * (iCol + 1)
iTotalS = iTotalS + a(1)(iCol) * (iCol + 1)
iTotalM = iTotalM + a(2)(iCol) * (iCol + 1)
next
calcScore = iTotalD + iTotalS + iTotalM
end function
Below are some sample inputs (schedules), both ideal and non-ideal. Note that in my ideal example, each row is the same all the way across (e.g. all 4's, or all 3's), but that will not necessarily be the case in real-world usage. My plan is to score my ideal schedule, and compare the score of other schedules to it.
Ideal:
Su Mo Tu We ...
Day: 4 4 4 4 ...
Swing: 3 3 3 3 ...
Mid: 2 2 2 2 ...
Not Ideal:
Su Mo Tu We ...
Day: 3 4 4 4 [D(0) is not 4]
Swing: 3 3 3 3
Mid: 2 2 2 2
Not Ideal:
Su Mo Tu We ...
Day: 4 4 4 4
Swing: 3 3 4 3 [S(2) is not 3]
Mid: 0 2 2 2 [M(0) is not 2]
Summarizing my comments into an answer.
So you have an optimal/ideal/perfect solution and want to compare other solutions to it. In this case you could for example compute the sum of (squared) errors. If you need a score you can invert the error.
Specifically, you would have to calculate the sum of (squared) differences between a solution and the optimal by looking at each entry of your matrix and calculating the difference. Sum these (squared) differences up and you get the error.
For the examples you gave the sum of errors are as follows:
E(Ideal, Not Ideal 1) = 1
E(Ideal, Not Ideal 2) = 3
The sum of squared errors would yield the following:
SQE(Ideal, Not Ideal 1) = 1
SQE(Ideal, Not Ideal 2) = 5
Usually, the sum of squared errors is used in order to penalize larger errors more than several small errors.
I was asked this question in a test and I need help with regards to how I should approach the solution, not the actual answer. The question is
You have been given a 7 digit number(with each digit being distinct and 0-9). The number has this property
product of first 3 digits = product of last 3 digits = product of central 3 digits
Identify the middle digit.
Now, I can do this on paper by brute force(trial and error), the product is 72 and digits being
8,1,9,2,4,3,6
Now how do I approach the problem in a no brute force way?
Let the number is: a b c d e f g
So as per the rule(1):
axbxc = cxdxe = exfxg
more over we have(2):
axb = dxe and
cxd = fxg
This question can be solved with factorization and little bit of hit/trial.
Out of the digits from 1 to 9, 5 and 7 can rejected straight-away since these are prime numbers and would not fit in the above two equations.
The digits 1 to 9 can be factored as:
1 = 1, 2 = 2, 3 = 3, 4 = 2X2, 6 = 2X3, 8 = 2X2X2, 9 = 3X3
After factorization we are now left with total 7 - 2's, 4 - 3's and the number 1.
As for rule 2 we are left with only 4 possibilities, these 4 equations can be computed by factorization logic since we know we have overall 7 2's and 4 3's with us.
1: 1X8(2x2x2) = 2X4(2x2)
2: 1X6(3x2) = 3X2
3: 4(2x2)X3 = 6(3x2)X2
4: 9(3x3)X2 = 6(3x2)X3
Skipping 5 and 7 we are left with 7 digits.
With above equations we have 4 digits with us and are left with remaining 3 digits which can be tested through hit and trial. For example, if we consider the first case we have:
1X8 = 2X4 and are left with 3,6,9.
we have axbxc = cxdxe we can opt c with these 3 options in that case the products would be 24, 48 and 72.
24 cant be correct since for last three digits we are left with are 6,9,4(=216)
48 cant be correct since for last three digits we are left with 3,9,4(=108)
72 could be a valid option since the last three digits in that case would be 3,6,4 (=72)
This question is good to solve with Relational Programming. I think it very clearly lets the programmer see what's going on and how the problem is solved. While it may not be the most efficient way to solve problems, it can still bring desired clarity and handle problems up to a certain size. Consider this small example from Oz:
fun {FindDigits}
D1 = {Digit}
D2 = {Digit}
D3 = {Digit}
D4 = {Digit}
D5 = {Digit}
D6 = {Digit}
D7 = {Digit}
L = [D1 D2 D3] M = [D3 D4 D5] E= [D5 D6 D7] TotL in
TotL = [D1 D2 D3 D4 D5 D6 D7]
{Unique TotL} = true
{ProductList L} = {ProductList M} = {ProductList E}
TotL
end
(Now this would be possible to parameterize furthermore, but non-optimized to illustrate the point).
Here you first pick 7 digits with a function Digit/0. Then you create three lists, L, M and E consisting of the segments, as well as a total list to return (you could also return the concatenation, but I found this better for illustration).
Then comes the point, you specify relations that have to be intact. First, that the TotL is unique (distinct in your tasks wording). Then the next one, that the segment products have to be equal.
What now happens is that a search is conducted for your answers. This is a depth-first search strategy, but could also be breadth-first, and a solver is called to bring out all solutions. The search strategy is found inside the SolveAll/1 function.
{Browse {SolveAll FindDigits}}
Which in turns returns this list of answers:
[[1 8 9 2 4 3 6] [1 8 9 2 4 6 3] [3 6 4 2 9 1 8]
[3 6 4 2 9 8 1] [6 3 4 2 9 1 8] [6 3 4 2 9 8 1]
[8 1 9 2 4 3 6] [8 1 9 2 4 6 3]]
At least this way forward is not using brute force. Essentially you are searching for answers here. There might be heuristics that let you find the correct answer sooner (some mathematical magic, perhaps), or you can use genetic algorithms to search the space or other well-known strategies.
Prime factor of distinct digit (if possible)
0 = 0
1 = 1
2 = 2
3 = 3
4 = 2 x 2
5 = 5
6 = 2 x 3
7 = 7
8 = 2 x 2 x 2
9 = 3 x 3
In total:
7 2's + 4 3's + 1 5's + 1 7's
With the fact that When A=B=C, composition of prime factor of A must be same as composition of prime factor of B and that of C, 0 , 5 and 7 are excluded since they have unique prime factor that can never match with the fact.
Hence, 7 2's + 4 3's are left and we have 7 digit (1,2,3,4,6,8,9). As there are 7 digits only, the number is formed by these digits only.
Recall the fact, A, B and C must have same composition of prime factors. This implies that A, B and C have same number of 2's and 3's in their composition. So, we should try to achieve (in total for A and B and C):
9 OR 12 2's AND
6 3's
(Must be product of 3, lower bound is total number of prime factor of all digits, upper bound is lower bound * 2)
Consider point 2 (as it has one possibility), A has 2 3's and same for B and C. To have more number of prime factor in total, we need to put digit in connection digit between two product (third or fifth digit). Extract digits with prime factor 3 into two groups {3,6} and {9} and put digit into connection digit. The only possible way is to put 9 in connection digit and 3,6 on unconnected product. That mean xx9xx36 or 36xx9xx (order of 3,6 is not important)
With this result, we get 9 x middle x connection digit = connection digit x 3 x 6. Thus, middle = (3 x 6) / 9 = 2
My answer actually extends #Ansh's answer.
Let abcdefg be the digits of the number. Then
ab=de
cd=fg
From these relations we can exclude 0, 5 and 7 because there are no other multipliers of these numbers between 0 and 9. So we are left with seven numbers and each number is included once in each answer. We are going to examine how we can pair the numbers (ab, de, cd, fg).
What happens with 9? It can't be combined with 3 or 6 since then their product will have three times the factor 3 and we have at total 4 factors of 3. Similarly, 3 and 6 must be combined at least one time together in response to the two factors of 9. This gives a product of 18 and so 9 must be combined at least once with 2.
Now if 9x2 is in a corner then 3x6 must be in the middle. Meaning in the other corner there must be another multiplier of 3. So 9 and 2 are in the middle.
Let's suppose ab=3x6 (The other case is symmetric). Then d must be 9 or 2. But if d is 9 then f or g must be multiplier of 3. So d is 2 and e is 9. We can stop here and answer the middle digit is
2
Now we have 2c = fg and the remaining choices are 1, 4, 8. We see that the only solutions are c = 4, f = 1, g = 8 and c = 4, f = 8, g = 1.
So if is 3x6 is in the left corner we have the following solutions:
3642918, 3642981, 6342918, 6342981
If 3x6 is in the right corner we have the following solutions which are the reverse of the above:
8192463, 1892463, 8192436, 1892436
Here is how you can consider the problem:
Let's note the final solution N1 N2 N3 N4 N5 N6 N7 for the 3 numbers N1N2N3, N3N4N5 and N5N6N7
0, 5 and 7 are to exclude because they are prime and no other ciphers is a multiple of them. So if they had divided one of the 3 numbers, no other number could have divided the others.
So we get the 7 remaining ciphers : 1234689
where the product of the ciphers is 2^7*3^4
(N1*N2*N3) and (N5*N6*N7) are equals so their product is a square number. We can then remove, one of the number (N4) from the product of the previous point to find a square number (i.e. even exponents on both numbers)
N4 can't be 1, 3, 4, 6, 9.
We conclude N4 is 2 or 8
If N4 is 8 and it divides (N3*N4*N5), we can't use the remaining even numbers (2, 4, 6) to divides
both (N1*N2*N3) and (N6*N7*N8) by 8. So N4 is 2 and 8 does not belong to the second group (let's put it in N1).
Now, we have: 1st grp: 8XX, 2nd group: X2X 3rd group: XXX
Note: at this point we know that the product is 72 because it is 2^3*3^2 (the square root of 2^6*3^4) but the result is not really important. We have made the difficult part knowing the 7 numbers and the middle position.
Then, we know that we have to distribute 2^3 on (N1*N2*N3), (N3*N4*N5), (N5*N6*N7) because 2^3*2*2^3=2^7
We already gave 8 to N1, 2 to N4 and we place 6 to N6, and 4 to N5 position, resulting in each of the 3 numbers being a multiple of 8.
Now, we have: 1st grp: 8XX, 2nd group: X24 3rd group: 46X
We have the same way of thinking considering the odd number, we distribute 3^2, on each part knowing that we already have a 6 in the last group.
Last group will then get the 3. And first and second ones the 9.
Now, we have: 1st grp: 8X9, 2nd group: 924 3rd group: 463
And, then 1 at N2, which is the remaining position.
This problem is pretty easy if you look at the number 72 more carefully.
We have our number with this form abcdefg
and abc = cde = efg, with those digits 8,1,9,2,4,3,6
So, first, we can conclude that 8,1,9 must be one of the triple, because, there is no way 1 can go with other two numbers to form 72.
We can also conclude that 1 must be in the start/end of the whole number or middle of the triple.
So now we have 819defg or 918defg ...
Using some calculations with the rest of those digits, we can see that only 819defg is possible, because, we need 72/9 = 8,so only 2,4 is valid, while we cannot create 72/8 = 9 from those 2,4,3,6 digits, so -> 81924fg or 81942fg and 819 must be the triple that start or end our number.
So the rest of the job is easy, we need either 72/4 = 18 or 72/2 = 36, now, we can have our answers: 8192436 or 8192463.
7 digits: 8,1,9,2,4,3,6
say XxYxZ = 72
1) pick any two from above 7 digits. say X,Y
2) divide 72 by X and then Y.. you will get the 3rd number i.e Z.
we found XYZ set of 3-digits which gives result 72.
now repeat 1) and 2) with remaining 4 digits.
this time we found ABC which multiplies to 72.
lets say, 7th digit left out is I.
3) divide 72 by I. result R
4) divide R by one of XYZ. check if result is in ABC.
if No, repeat the step 3)
if yes, found the third pair.(assume you divided R by Y and the result is B)
YIB is the third pair.
so... solution will be.
XZYIBAC
You have your 7 numbers - instead of looking at it in groups of 3 divide up the number as such:
AB | C | D | E | FG
Get the value of AB and use it to get the value of C like so: C = ABC/AB
Next you want to do the same thing with the trailing 2 digits to find E using FG. E = EFG/FG
Now that you have C & E you can solve for D
Since CDE = ABC then D = ABC/CE
Remember your formulas - instead of looking at numbers create a formula aka an algorithm that you know will work every time.
ABC = CDE = EFG However, you have to remember that your = signs have to balance. You can see that D = ABC/CE = EFG/CE Once you know that, you can figure out what you need in order to solve the problem.
Made a quick example in a fiddle of the code:
http://jsfiddle.net/4ykxx9ve/1/
var findMidNum = function() {
var num = [8, 1, 9, 2, 4, 3, 6];
var ab = num[0] * num[1];
var fg = num[5] * num[6];
var abc = num[0] * num[1] * num[2];
var cde = num[2] * num[3] * num[4];
var efg = num[4] * num[5] * num[6];
var c = abc/ab;
var e = efg/fg;
var ce = c * e
var d = abc/ce;
console.log(d); //2
}();
You have been given a 7 digit number(with each digit being distinct and 0-9). The number has this property
product of first 3 digits = product of last 3 digits = product of central 3 digits
Identify the middle digit.
Now, I can do this on paper by brute force(trial and error), the product is 72 and digits being
8,1,9,2,4,3,6
Now how do I approach the problem in a no brute force way?
use linq and substring functions
example var item = array.Skip(3).Take(3) in such a way that you have a loop
for(f =0;f<charlen.length;f++){
var xItemSum = charlen[f].Skip(f).Take(f).Sum(f => f.Value);
}
// untested code
I have a 3D image, divided into contiguous regions where each voxel has the same value. The value assigned to this region is unique to the region and serves as a label. The example image below describes the 2D case:
1 1 1 1 2 2 2
1 1 1 2 2 2 3
Im = 1 4 1 2 2 3 3
4 4 4 4 3 3 3
4 4 4 4 3 3 3
I want to create a graph describing adjaciency between these regions. In the above case, this would be:
0 1 0 1
A = 1 0 1 1
0 1 0 1
1 1 1 0
I'm looking for a speedy solution to do this for large 3D images in MATLAB. I came up with a solution that iterates over all regions, which takes 0.05s per iteration - unfortunately, this will take over half an hour for an image with 32'000 regions. Does anybody now a more elegant way of doing this? I'm posting the current algorithm below:
labels = unique(Im); % assuming labels go continuously from 1 to N
A = zeros(labels);
for ii=labels
% border mask to find neighbourhood
dil = imdilate( Im==ii, ones(3,3,3) );
border = dil - (Im==ii);
neighLabels = unique( Im(border>0) );
A(ii,neighLabels) = 1;
end
imdilate is the bottleneck I would like to avoid.
Thank you for your help!
I came up with a solution which is a combination of Divakar's and teng's answers, as well as my own modifications and I generalised it to the 2D or 3D case.
To make it more efficient, I should probably pre-allocate the r and c, but in the meantime, this is the runtime:
For a 3D image of dimension 117x159x126 and 32000 separate regions: 0.79s
For the above 2D example: 0.004671s with this solution, 0.002136s with Divakar's solution, 0.03995s with teng's solution.
I haven't tried extending the winner (Divakar) to the 3D case, though!
noDims = length(size(Im));
validim = ones(size(Im))>0;
labels = unique(Im);
if noDims == 3
Im = padarray(Im,[1 1 1],'replicate', 'post');
shifts = {[-1 0 0] [0 -1 0] [0 0 -1]};
elseif noDims == 2
Im = padarray(Im,[1 1],'replicate', 'post');
shifts = {[-1 0] [0 -1]};
end
% get value of the neighbors for each pixel
% by shifting the image in each direction
r=[]; c=[];
for i = 1:numel(shifts)
tmp = circshift(Im,shifts{i});
r = [r ; Im(validim)];
c = [c ; tmp(validim)];
end
A = sparse(r,c,ones(size(r)), numel(labels), numel(labels) );
% make symmetric, delete diagonal
A = (A+A')>0;
A(1:size(A,1)+1:end)=0;
Thanks for the help!
Try this out -
Im = padarray(Im,[1 1],'replicate');
labels = unique(Im);
box1 = [-size(Im,1)-1 -size(Im,1) -size(Im,1)+1 -1 1 size(Im,1)-1 size(Im,1) size(Im,1)+1];
mat1 = NaN(numel(labels),numel(labels));
for k2=1:numel(labels)
a1 = find(Im==k2);
for k1=1:numel(labels)
a2 = find(Im==k1);
t1 = bsxfun(#plus,a1,box1);
t2 = bsxfun(#eq,t1,permute(a2,[3 2 1]));
mat1(k2,k1) = any(t2(:));
end
end
mat1(1:size(mat1,1)+1:end)=0;
If it works for you, share with us the runtimes as comparison? Would love to see if the coffee brews any faster than half an hour!
Below is my attempt.
Im = [1 1 1 1 2 2 2;
1 1 1 2 2 2 3;
1 4 1 2 2 3 3;
4 4 4 4 3 3 3;
4 4 4 4 3 3 3];
% mark the borders
validim = zeros(size(Im));
validim(2:end-1,2:end-1) = 1;
% get value of the 4-neighbors for each pixel
% by shifting the images 4 times in each direction
numNeighbors = 4;
adj = zeros([prod(size(Im)),numNeighbors]);
shifts = {[0 1] [0 -1] [1 0] [-1 0]};
for i = 1:numNeighbors
tmp = circshift(Im,shifts{i});
tmp(validim == 0) = nan;
adj(:,i) = tmp(:);
end
% mark neighbors where it does not eq Im
imDuplicates = repmat(Im(:),[1 numNeighbors]);
nonequals = adj ~= imDuplicates;
% neglect the border
nonequals(isnan(adj)) = 0;
% get these neighbor values and the corresponding Im value
compared = [imDuplicates(nonequals == 1) adj(nonequals == 1)];
% construct your 'A' % possibly could be more optimized here.
labels = unique(Im);
A = zeros(numel(labels));
for i = 1:size(compared,1)
A(compared(i,1),compared(i,2)) = 1;
end
#Lisa
Yours reasoning is elegant, though it obviously gives wrong answers for labels on the edges.
Try this simple label matrix:
Im =
1 2 2
3 3 3
3 4 4
The resulting adjacency matrix , according to your code is:
A =
0 1 1 0
1 0 1 1
1 1 0 1
0 1 1 0
which claims an adjacency between labels "2" and "4": obviously wrong. This happens simply because you are reading padded Im labels based on "validim" indices, which now doesn't match the new Im and goes all the way down to the lower borders.
There are two vectors:
a = 1:5;
b = 1:2;
in order to find all combinations of these two vectors, I am using the following piece of code:
[A,B] = meshgrid(a,b);
C = cat(2,A',B');
D = reshape(C,[],2);
the result includes all the combinations:
D =
1 1
2 1
3 1
4 1
5 1
1 2
2 2
3 2
4 2
5 2
now the questions:
1- I want to decrease the number of operations to improve the performance for vectors with bigger size. Is there any single function in MATLAB that is doing this?
2- In the case that the number of vectors is more than 2, the meshgrid function cannot be used and has to be replaced with for loops. What is a better solution?
For greater than 2 dimensions, use ndgrid:
>> a = 1:2; b = 1:3; c = 1:2;
>> [A,B,C] = ndgrid(a,b,c);
>> D = [A(:) B(:) C(:)]
D =
1 1 1
2 1 1
1 2 1
2 2 1
1 3 1
2 3 1
1 1 2
2 1 2
1 2 2
2 2 2
1 3 2
2 3 2
Note that ndgrid expects (rows,cols,...) rather than (x,y).
This can be generalized to N dimensions (see here and here):
params = {a,b,c};
vecs = cell(numel(params),1);
[vecs{:}] = ndgrid(params{:});
D = reshape(cat(numel(vecs)+1,vecs{:}),[],numel(vecs));
Also, as described in Robert P.'s answer and here too, kron can also be useful for replicating values (indexes) in this way.
If you have the neural network toolbox, also have a look at combvec, as demonstrated here.
One way would be to combine repmat and the Kronecker tensor product like this:
[repmat(a,size(b)); kron(b,ones(size(a)))]'
ans =
1 1
2 1
3 1
4 1
5 1
1 2
2 2
3 2
4 2
5 2
This can be scaled to more dimensions this way:
a = 1:3;
b = 1:3;
c = 1:3;
x = [repmat(a,1,numel(b)*numel(c)); ...
repmat(kron(b,ones(1,numel(a))),1,numel(c)); ...
kron(c,ones(1,numel(a)*numel(b)))]'
There is a logic! First: simply repeat the first vector. Secondly: Use the tensor product with the dimension of the first vector and repeat it. Third: Use the tensor product with the dimension of (first x second) and repeat (in this case there is not fourth, so no repeat.
I know that modulus gives the remainder and that this code will give the survivor of the Josephus Problem. I have noticed a pattern that when n mod k = 0, the starting count point begins at the very beginning of the circle and that when n mod k = 1, the person immediately before the beginning of the circle survived that execution round through the circle.
I just don't understand how this recursion uses modulus to find the last man standing and what josephus(n-1,k) is actually referring to. Is it referring to the last person to get executed or the last survivor of a specific round through the circle?
def josephus( n, k):
if n ==1:
return 1
else:
return ((josephus(n-1,k)+k-1) % n)+1
This answer is both a summary of the Josephus Problem and an answer to your questions of:
What is josephus(n-1,k) referring to?
What is the modulus operator being used for?
When calling josephus(n-1,k) that means that you've executed every kth person up to a total of n-1 times. (Changed to match George Tomlinson's comment)
The recursion keeps going until there is 1 person standing, and when the function returns itself to the top, it will return the position that you will have to be in to survive. The modulus operator is being used to help stay within the circle (just as GuyGreer explained in the comments). Here is a picture to help explain:
1 2
6 3
5 4
Let the n = 6 and k = 2 (execute every 2nd person in the circle). First run through the function once and you have executed the 2nd person, the circle becomes:
1 X
6 3
5 4
Continue through the recursion until the last person remains will result in the following sequence:
1 2 1 X 1 X 1 X 1 X X X
6 3 -> 6 3 -> 6 3 -> X 3 -> X X -> X X
5 4 5 4 5 X 5 X 5 X 5 X
When we check the values returned from josephus at n we get the following values:
n = 1 return 1
n = 2 return (1 + 2 - 1) % 2 + 1 = 1
n = 3 return (1 + 2 - 1) % 3 + 1 = 3
n = 4 return (3 + 2 - 1) % 4 + 1 = 1
n = 5 return (1 + 2 - 1) % 5 + 1 = 3
n = 6 return (3 + 2 - 1) % 6 + 1 = 5
Which shows that josephus(n-1,k) refers to the position of the last survivor. (1)
If we removed the modulus operator then you will see that this will return the 11th position but there is only 6 here so the modulus operator helps keep the counting within the bounds of the circle. (2)
Your first question has been answered above in the comments.
To answer your second question, it's referring to the position of the last survivor.
Consider j(4,2).
Using the algorithm gives
j(4,2)=(j(3,2)+1)%4)+1
j(3,2)=(j(2,2)+1)%3)+1
j(2,2)=(j(1,2)+1)%2)+1
j(1,2)=1
and so
j(2,2)=((1+1)%2)+1=1
j(3,2)=((1+1)%3)+1=3
j(4,2)=((3+1)%4)+1=1
Now the table of j(2,2) is
1 2
1 x
so j(2,2) is indeed 1.
For j(3,2) we have
1 2 3
1 x 3
x x 3
so j(3,2) is 3 as required.
Finally, j(4,2) is
1 2 3 4
1 x 3 4
1 x 3 x
1 x x x
which tells us that j(4,2)=1 as required.