Multiple formatted by 0/1 [duplicate] - numbers

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Find multiple of a number that can be written with 1s and 0s
Given the number n (2 <= n <= 1000), find the lowest nonzero multiple of which is written in base 10 with digits 0 and 1 only. Examples: 2 -> 10, 3 -> 111, 4 -> 100, 7 -> 1001, 11 -> 11, 9 -> 111 111 111.
I think, follow the remaining division of numbers consist of numbers n which is formatted 0/1.Thanks for your help!
{10/3= 3 remaining 1 -> and the finaly is 111 !!!
10/4= 4 ramining 2 -> and the finaly is 100 !!!
10/6= 1 ramainin 4 -> and the finaly is 1110 !!!
I don't understand is the logic}

The question is basically saying: Find the first non-zero multiple of n that consists of only 1s and 0s. And we're not talking binary (base 2) or remainders or anything fancy here. Here are some examples, in the format:
n => The first multiple of n with only 1s and 0s is x (n * y = x)
--------------------------------------------------------------------------
2 => (2 x 5 = 10)
3 => (3 x 37 = 111)
4 => (4 x 25 = 100)
7 => (7 x 143 = 1001)
11 => (11 x 1 = 11)
9 => (9 x 12,345,679 = 111,111,111)
You need to figure out an algorithm to make it work! You could use brute force:
for each n between 2 and 1000
y = 1
x = 0
do
x = n * y++
while (x is not 0 and string(x) is not all 0s and 1s)
print n => x
next n
I implemented this in C# to test it and it gave me the following output for n between 2 and 10:
2 => 10
3 => 111
4 => 100
5 => 10
6 => 1110
7 => 1001
8 => 1000
9 => 111111111
10 => 10
There are probably faster implementations, but this should give you an idea of where to start.

If you're asking for help interpreting the (homework) question, here's what I think it means: "For a given number, find out lowest multiple of it that contains only digits 1 or 0"
So, for example, if the number is 2:
Multiples of 2 = {2, 4, 6, 8, 10, 12, 14, .... }
|
|
this is your answer!
The non-bruteforce way to do this would be to iterate throught numbers that contain only 0 and 1 then figure out if the number is a multiple of the number in question. This approach will be substantially more efficient than iterating through the multiples of n and determining if it contains only 0 and 1.
An easy way to get a list of numbers that contain only 0 and 1 would be iterate throught the integers and for each value, interpret its binary representation as a decimal number.
Here's an online demo to get you started: http://jsfiddle.net/6j5De/4/
Since it's likely to be homework, I'll leave it up to you to translate that to your subject language.

Related

How do I evaluate a function into a matrix in KDB?

Let's say I've got a function that defines a matrix in terms of it's i and j coordinates:
f: {y+2*x}
I'm trying to create a square matrix that evaluates this function at all locations.
I know it needs to be something like f ' (til 5) /:\: til 5, but I'm struggling with rest.
Rephrasing your question a bit, you want to create a matrix A = [aij] where aij = f(i, j), i, j = 0..N-1.
In other words you want to evaluate f for all possible combinations of i and j. So:
q)N:5;
q)i:til[N] cross til N; / all combinations of i and j
q)a:f .' i; / evaluate f for all pairs (i;j)
q)A:(N;N)#a; / create a matrix using #: https://code.kx.com/q/ref/take/
0 1 2 3 4
2 3 4 5 6
4 5 6 7 8
6 7 8 9 10
8 9 10 11 12
P.S. No, (til 5) /:\: til 5 is not exactly what you'd need but close. You are generating a list of all pairs i.e. you are pairing or joining the first element of til 5 with every element of (another) til 5 one by one, then the second , etc. So you need the join operator (https://code.kx.com/q/ref/join/):
(til 5),/:\: til 5
You were close. But there is no need to generate all the coordinate pairs and then iterate over them. Each Right Each Left /:\: manages all that for you and returns the matrix you want.
q)(til 5)f/:\:til 5
0 1 2 3 4
2 3 4 5 6
4 5 6 7 8
6 7 8 9 10
8 9 10 11 12

kdb q - create 2d buckets for positive integers

I am trying create 2d buckets in q
Given a 2d grid
5 o---o---o
| | |
3 o---o---o
| | |
0 o---o---o
0 3 5
each node on the grid defines the boundary of 2d buckets for positive integers. For example the center node would contain tuples (x;y) where 3<=x<5 and 3<=y<5. The nine buckets are indexed from 0,...,8.
The way I tried to implemented this in q is
bucketidx:{((0 3 5i) cross (0 3 5i)) bin "i"$(first x;last x)}
To traverse through the buckets:
bucketidx each ((0 3 5i) cross (0 3 5i))
/0j, 1j, 2j, 3j, 4j, 5j, 6j, 7j, 8j
However I get a strange behavior on bucketidx 6 0. I expect this to be in the upper left node
(5<=y) and (x=0)
but it returns index 8 which would be the upper right node. I hope it is clear what I am trying to do.
Thanks for the help
Thats because of the bin behavior.
Binary search returns the index of the last item in x which is <=y
https://code.kx.com/q/ref/search/#bin-binr
Your list is :
q) a:(0 3 5i) cross (0 3 5i)
q) a / (0 0; 0 3;0 5;3 0; 3 3; 3 5;5 0;5 3; 5 5)
You are searching (6 0) in this list using bin function and last item in that list which is <=(6;0) is (5;5) and index of that item is 8.
q) a bin 6 0 / 8
thats the reason you are getting 8.
I think 'tuple with bin' approach is not the right way to go for this problem.
You could use something similar to below idea. First argument to function is X coordinate and second is Y coordinate.
q) node:{b:0 3 5;(b bin x)+3*b bin y}
q) node[0;6] / 6
Another approach is to use a dictionary with sorted attribute, which makes it a step function.
q)d:`s#0 3 5!0 1 2
q)3 sv' d#(0 3 5i) cross (0 3 5i)
0 1 2 3 4 5 6 7 8
q)3 sv' d#enlist 6 0
,6

Finding where a set of values lie within a matrix

I have two values (k and j) which I know are within an nx3 matrix (M). I know that they're and on the same row and that j is always to the right of k, so if k is in M(2,1), then j will be in M(2,2). I tested for this earlier in the function, but now I want to know which row that is for a given k and j. I need the row number of their location to proceed. There are no duplicate combinations of k and j in the matrix.
So if I have the matrix
M=
1 4 5
1 5 7
k j 5
4 5 6
2 3 1
Then I want to know that they're in row 3. None of the columns are ordered.
What I have tried:
I used the code below
[row,~] = find(M==k);
I'm not sure how to look for a combination of them. I want to avoid using the find function. I hope to potentially use logical indexing.
How do I go about doing this? I hope this question makes sense.
You can use bsxfun -
find(all(bsxfun(#eq,A(:,1:2),[k,j]),2) | all(bsxfun(#eq,A(:,2:3),[k,j]),2))
Being a relational operation with bsxfun, according to this post on benchmarked results, this should be pretty efficient.
Sample runs
Case #1 :
A =
1 4 5
1 5 7
6 7 1
4 5 6
2 3 1
k =
6
j =
7
>> find(all(bsxfun(#eq,A(:,1:2),[k,j]),2) | all(bsxfun(#eq,A(:,2:3),[k,j]),2))
ans =
3
Case #2 :
A =
1 4 5
1 5 7
1 6 7
4 5 6
2 3 1
k =
6
j =
7
>> find(all(bsxfun(#eq,A(:,1:2),[k,j]),2) | all(bsxfun(#eq,A(:,2:3),[k,j]),2))
ans =
3
Slightly different version on bsxfun. This one doesn't limit the matrix to three columns.
find(sum(((bsxfun(#eq,M,j) + bsxfun(#eq,M,k)) .* M).' ) == j+k >0)
Case 1:
M = [
1 4 5
1 5 7
6 7 1
4 5 6
2 3 1]
k=6;j=7;
ans = 3
Case 2:
M=[
1 4 5
1 5 7
1 6 7
4 5 6
2 3 1
];
k=6;j=7;
ans = 3
Use this:
row = find(((M(:,1) == k ) & ( M(:,2) == j)) | ((M(:,1) == k ) & ( M(:,3) == j)) | ((M(:,2) == k ) & ( M(:,3) == j)) )
Also, logical indexing can only give you a matrix with zeros at all other positions and one at your required position. But to get the index of that position, you will have to use find.

i use factor(n) in matlab but it don't work for numbers like ((10^11-1)/11),for same number what can i do?

I use factor(n) in matlab but it don't work for numbers like ((10^11-1)/11) - what can I do? My source is here.
m=input('Enter your number: ');
i=0;
while (i<m)
if(isprime(i))
% sum=factor((10^(i-1)-1));
sum=factor((10^(i-1)-1)/i);
disp(sum);
end
i =i+1;
end
but for large n it returns errors!!
>> FactorGen
Enter your number: 45
3 3
3 3 11
3 3 11 101
3 3 3 7 11 13 37
3 3 11 41 271 9091
3 3 3 7 11 13 37 101 9901
Error using factor (line 26) When n is single or double, its maximum
allowed value is FLINTMAX.
Error in FactorGen (line 7) sum=factor((10^(i-1)-1));
I want the function factor((10^(i-1)-1)) to work for same number. How can I solve my problem?
I think this can be partially alleviated by converting your large number into uint64 format. For R2014b maximum integer that can be handled is:
n = intmax('uint64')
n = 1.8447e+19
While the maximum double that can be handled is:
n = flintmax('double')
n = 9.0072e+15
This can be verified by simple example. Let's use factor on the number larger than flintmax. First, try double:
factor(10^16)
Error using factor (line 26)
When n is single or double, its maximum allowed value is FLINTMAX.
Now, we try uint64:
factor(uint64(10^16))
ans = 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
So, using factor(uint64(x)) increases your limit by several orders. Indeed, there's no sense in using double format for factor function.
By the way, since using factor on large numbers may freeze your system, I suggest using this function:
function f = Factorize(n)
i = 0;
while mod(n,2) == 0
i = i + 1;
n = n/2;
f(i) = 2;
disp([2,n])
end
q = round(sqrt(double(n)));
q = q + 1 - mod(q,2);
for j = 3:2:q
while mod(n,j) == 0
i = i + 1;
f(i) = j;
n = n/j;
end
end
if n > 2;
i = i + 1;
f(i) = n;
end
It is much faster for large numbers and does not overload the system at large n
Hope that helps

Efficiently generating unique pairs of integers

In MATLAB, I would like to generate n pairs of random integers in the range [1, m], where each pair is unique. For uniqueness, I consider the order of the numbers in the pair to be irrelevant such that [3, 10] is equal to [10, 3].
Also, each pair should consist of two distinct integers; i.e. [3, 4] is ok but [3, 3] would be rejected.
EDIT: Each possible pair should be chosen with equal likelihood.
(Obviously a constraint on the parameters is that n <= m(m-1)/2.)
I have been able to successfully do this when m is small, like so:
m = 500; n = 10; % setting parameters
A = ((1:m)'*ones(1, m)); % each column has the numbers 1 -> m
idxs1 = squareform(tril(A', -1))';
idxs2 = squareform(tril(A, -1))';
all_pairs = [idxs1, idxs2]; % this contains all possible pairs
idx_to_use = randperm( size(all_pairs, 1), n ); % choosing random n pairs
pairs = all_pairs(idx_to_use, :)
pairs =
254 414
247 334
111 146
207 297
45 390
229 411
9 16
75 395
12 338
25 442
However, the matrix A is of size m x m, meaning when m becomes large (e.g. upwards of 10,000), MATLAB runs out of memory.
I considered generating a load of random numbers randi(m, [n, 2]), and repeatedly rejecting the rows which repeated, but I was concerned about getting stuck in a loop when n was close to m(m-1)/2.
Is there an easier, cleaner way of generating unique pairs of distinct integers?
Easy, peasy, when viewed in the proper way.
You wish to generate n pairs of integers, [p,q], such that p and q lie in the interval [1,m], and p
How many possible pairs are there? The total number of pairs is just m*(m-1)/2. (I.e., the sum of the numbers from 1 to m-1.)
So we could generate n random integers in the range [1,m*(m-1)/2]. Randperm does this nicely. (Older matlab releases do not allow the second argument to randperm.)
k = randperm(m/2*(m-1),n);
(Note that I've written this expression with m in a funny way, dividing by 2 in perhaps a strange place. This avoids precision problems for some values of m near the upper limits.)
Now, if we associate each possible pair [p,q] with one of the integers in k, we can work backwards, from the integers generated in k, to a pair [p,q]. Thus the first few pairs in that list are:
{[1,2], [1,3], [2,3], [1,4], [2,4], [3,4], ..., [m-1,m]}
We can think of them as the elements in a strictly upper triangular array of size m by m, thus those elements above the main diagonal.
q = floor(sqrt(8*(k-1) + 1)/2 + 1/2);
p = k - q.*(q-1)/2;
See that these formulas recover p and q from the unrolled elements in k. We can convince ourselves that this does indeed work, but perhaps a simple way here is just this test:
k = 1:21;
q = floor(sqrt(8*(k-1) + 1)/2 + 3/2);
p = k - (q-1).*(q-2)/2;
[k;p;q]'
ans =
1 1 2
2 1 3
3 2 3
4 1 4
5 2 4
6 3 4
7 1 5
8 2 5
9 3 5
10 4 5
11 1 6
12 2 6
13 3 6
14 4 6
15 5 6
16 1 7
17 2 7
18 3 7
19 4 7
20 5 7
21 6 7
Another way of testing it is to show that all pairs get generated for a small case.
m = 5;
n = 10;
k = randperm(m/2*(m-1),n);
q = floor(sqrt(8*(k-1) + 1)/2 + 3/2);
p = k - (q-1).*(q-2)/2;
sortrows([p;q]',[2 1])
ans =
1 2
1 3
2 3
1 4
2 4
3 4
1 5
2 5
3 5
4 5
Yup, it looks like everything works perfectly. Now try it for some large numbers for m and n to test the time used.
tic
m = 1e6;
n = 100000;
k = randperm(m/2*(m-1),n);
q = floor(sqrt(8*(k-1) + 1)/2 + 3/2);
p = k - (q-1).*(q-2)/2;
toc
Elapsed time is 0.014689 seconds.
This scheme will work for m as large as roughly 1e8, before it fails due to precision errors in double precision. The exact limit should be m no larger than 134217728 before m/2*(m-1) exceeds 2^53. A nice feature is that no rejection for repeat pairs need be done.
This is more of a general approach rather then a matlab solution.
How about you do the following first you fill a vector like the following.
x[n] = rand()
x[n + 1] = x[n] + rand() %% where rand can be equal to 0.
Then you do the following again
x[n][y] = x[n][y] + rand() + 1
And if
x[n] == x[n+1]
You would make sure that the same pair is not already selected.
After you are done you can run a permutation algorithm on the matrix if you want them to be randomly spaced.
This approach will give you all the possibility or 2 integer pairs, and it runs in O(n) where n is the height of the matrix.
The following code does what you need:
n = 10000;
m = 500;
my_list = unique(sort(round(rand(n,2)*m),2),'rows');
my_list = my_list(find((my_list(:,1)==my_list(:,2))==0),:);
%temp = my_list; %In case you want to check what you initially generated.
while(size(my_list,1)~=n)
%my_list = unique([my_list;sort(round(rand(1,2)*m),2)],'rows');
%Changed as per #jucestain's suggestion.
my_list = unique([my_list;sort(round(rand((n-size(my_list,1)),2)*m),2)],'rows');
my_list = my_list(find((my_list(:,1)==my_list(:,2))==0),:);
end