I have the following homework assignment in C. I basically need an approach rather than a solution.
We have a 13 x 13 array. In the array, we have a diamond shape that we need to consider. Everything outside this diamond is initialized to -1 (unimportant). Example 5 x 5 array below-
x x 1 x x
x 2 2 2 x
3 3 3 3 3
x 4 4 4 x
x x 5 x x
x=-1
Now in this array, the values we have in the diamond for each entry contains 11 bits. 5 lsb contains one data (hue), and other 6 contains another data (diameter). We need to sort the data row-wise, monotonically for the hue, and then column-wise for the diameter, monotonically.
What would be the most efficient and memory conserving way of doing this? Since we need to conserve this, it's best if the entries are swapped around rather than creating another array. In the end, we will end up with a sorted diamond array (still with the -1s). Thanks a lot in advance guys!
I didn't understand how exactly you want to reorder the elements
row-wise, monotonically for the hue, and then column-wise for the diameter, monotonically
but here are some ideas you might be able to use.
Your array is 13x13 (169 elements); out of that, almost exactly half (84) are empty, so you can use them as temporary storage (for e.g. radix-sort).
Your values have 11 meaningful bits; numbers in real computers have either 16 or 32 bits - so you can use the 5 (or 21, depending on your system) most significant bits as temporary storage.
One possibly good way to use the upper 5 bits is putting a copy of the 5 LSB (hue) there. This will reverse the significance of the two parts when doing normal integer comparison (making hue more significant than diameter)
I see.
I suppose such a diamond shape could be directly represented by an array.
Ignore all the -1 entries.
{ row-0 row-1 row-2 row-3 ... row-13 }
{ 1 2 2 2 3 3 3 3 3 4 4 4 5 }
You can now sort the array as you like.
Sort it twice, once for hue, once for diameter; or figure out how to sort an array by two criteria.
You can also work in-place, if you just write a function for converting an array index to diamond-coordinates. With that done, you can just work on the diamond-structure as if it was an array.
Write a sorting routine with this prototype:
void sort(int startx, int starty, int dx, int dy, int count, int (*compare)(int, int));
or
void sort(int *start, int stride, int count, int (*compare)(int,int));
Write a couple of comparison functions, and call sort in two for loops, one for rows and another for columns.
Related
I have a grid of pixels 64x8. The aim is to to activate the pixels on this grid in a random manner till the whole grid is activated.
Logically I can generate random numbers in 0-63 and 0-7 range and then activate this pixel. Assuming I run this for long enough, the grid should be completely activated.
However, I am wondering if there is any algorithm that can minimize / avoid altogether collision (returning already activated pixel coordinate) and guarantee complete grid activation in a finite amount of time?
Fill an array of length 512 with numbers increasing from from 0 to 511 (64x8 = 512), so the array will contain {0,1,2,3,..., 511}).
Then shuffle that array, for example like explained here: Shuffle array in C.
Then define a function that maps a number to a coordinate, that would be:
y = n / 8
x = n % 8
n being one of the numbers of the array.
If the array is well shuffled this guarantees that all pixels will be activatged in a random order.
You could implement a pseudo random generator (PRG # Wikipedia) with a period of 64 * 8. Use 3 bits for the axis with 8, and the remaining 6 bits for the axis with 64.
I have small vectors. Each of them is made of 10 integers which are between 0 and 15. This means that every element in a vector can be written using 4 bits. Hence I can concatenate my vector elements and store the whole vector in a single long type (in C, C++, java...)
Vector v1 dominates vector v2 if for each i in 0,...,9, v1[i] >= v2[i]
I want to write a method compare(long v1, long v2) that would return 0 if non of the vectors dominates the other, 1 if the first one dominates and -1 if the second one dominates.
Is there any efficient way to implement compare other than getting every i component and doing 10 times the normal integer comparison?
EDIT
if v1 is exactly the same as v2 returning 1 or -1 are both fine
It's possible to do this using bit-manipulation. Space your values out so that each takes up 5 bits, with 4 bits for the value and an empty 0 in the most significant position as a kind of spacing bit.
Placing a spacing bit between each value stops borrows/carries from propagating between adjacent values and means you can do certain SIMD-like arithmetic operations on the vector just by using regular integer addition or subtraction. We can use subtraction to do a vector comparison.
To do the test you can set all the spacing bits to 1 in one of the vectors and then subtract the second one. If the value in the 4 bits below the spacing bit is greater in the second one then it will carry the bit from the spacing bit and set it to zero in the result, if not then it will remain a one (the first value is greater than or equal to the second). If the first vector dominates the second then all the spacing bits will be one after the subtraction.
Simple demonstration using ints:
#define SPACING_BITS ((1<<4)|(1<<9)|(1<<14)|(1<<19))
int createVector(int v0, int v1, int v2, int v3)
{
return v0 | (v1 << 5) | (v2 << 10) | (v3 << 15);
}
int vectorDominates(int vectorA, int vectorB)
{
// returns 1 if vectorA dominates vectorB:
return (((vectorA | SPACING_BITS) - vectorB) & SPACING_BITS) == SPACING_BITS;
}
int compare(int vectorA, int vectorB)
{
if(vectorDominates(vectorA, vectorB))
return 1;
else if(vectorDominates(vectorB, vectorA))
return -1;
return 0;
}
You can extend it to use 64 bit values using 50 bits to store the 10 values. You can also inline the calls to vectorDominates in the compare function.
Demo
Well, in C you can likely leverage vectorization to do this. I don't think it's directly possible to compare on 4-bit operands, so you're going to have to re-pack (either on the fly or just keep your data in a more suitable format) up to 8-bit before doing the comparison. Since 10 * 8 = 80 which is more than 64, you're going to need 128-bit vector instructions.
Not sure if Java VMs support that yet, but this question suggests that JNI is the answer, i.e. call C code from Java.
I am relatively new to C and am just learning about ways that memory is stored during a program. Can someone please explain why the following code:
int main(int argc, char** argv){
float x[3][4];
printf("%p\n%p\n%p\n%p\n", &(x[0][0]), &(x[2][0]), &(x[2][4]), &(x[3][0]));
return 0;
}
outputs this:
0x7fff5386fc40
0x7fff5386fc60
0x7fff5386fc70
0x7fff5386fc70
Why would the first 3 be different places in memory but the last be the same as the third?
Why is there a gap the size of 20 between the first two, but a gap the size of 10 between the second and third? The distance between &(x[2][0]) and &(x[2][4]) doesn't seem like half the distance between &(x[0][0])and &(x[2][0]).
Thanks in advance.
When you declare an array of size n, the indices range from 0 to n - 1. So x[2][4] and x[3][0] are actually stepping outside the bounds of your arrays.
If you weren't already aware, the multidimensional array you declared is actually an array of arrays.
Your compiler is laying out each array one after the other in memory. So, in memory, your elements are laid out in this order: x[0][0], x[0][1], x[0][2], x[0][3], x[1][0], x[1][1], and so on.
It looks like you already understand how pointers work, so I'll gloss over that. The reason the last two elements are the same is because x[2][4] is out of bounds, so it's referring to the next slot in memory after the end of the x[2] array. That would be the first element of the x[3] array, if there was one, which would be x[3][0].
Now, since x[3][0] refers to an address that you don't have a variable mapping to, it's entirely possible that dereferencing it could cause a segmentation fault. In the context of your program, there just happens to be something stored at 0x7fff5386fc70; in other words, you got lucky.
This is due to pointer arithmetic.
Your array is flat, which means that data are stored in a linear way, each one after the other in memory. First [0][0] then [0][1], etc.
The address of [x][y] is calculated as (x*4+y)*float_size+starting_address.
So the gap between the two first [0][0] and [2][0] is 8*float_size. The difference is 20 in hexadecimal, which is 32 in decimal, float_size is then 4.
In between the second and third you have (2*4+4)-(2*4)*float_size which is 16 in decimal, so 10 in hexadecimal. This is exactly half the size of the previous because it is the size of one row (the size of 4 elements in the third row), and the previous is the size of two rows (the size of 8 elements in the first and second rows).
Arrays are linear data structures. Irrespective of their dimension, say 1-dimensional or 2-dimensional or 3-dimensional, they are linearlly arranged.
Your x[3][4] will be stored in memory as consecutive fixed sized cells like :
| (0,0) | (0, 1) | (0,2) | (0,3) | (1,0) | (1,1) | (1,2) | (1,3) | (2,0) | (2,1) | (2,2) | (2,3) |
This x[0][0] notation is matrix notation. On compile time, it is converted to pointer notation. The calculation is like:
x[i][j] = y * i + j where y in your case is 4.
So on calculating by this way the outputs are perfect.
Array elements in C are stored contiguously, in row-major order. So, in your example, &x[row][column] is exactly equal to &x[0][0]+((row*4)+column))*sizeof(float) (when those addresses are converted to number of bytes, which is what you're outputting).
The third address you're printing has the second index out of bounds (valid values 0 to 3), and the fourth has the first index out of bounds (valid values 0 to 2). It just happens that the values you've chosen work out to the same location in memory, because the rows are laid out in memory end-to-end.
There are 8 elements between &(x[0][0]) and &(x[2][0]). The actual difference in memory is multiplied by sizeof(float) which, for your compiler, is 4. 4*8 is 32 which, when printed as hex, is 0x20, is the difference you're seeing.
If you picked a value of row and column where ((row*4)+column)) was 12(=3*4) or more, your code would be computing the address of something outside the array. Attempting to use such a pointer pointer (e.g. setting the value at that address) would give undefined behaviour. You just got lucky that the indices you picked happen to be within the array.
This question already has answers here:
Binary numbers with the same quantity of 0s and 1s
(6 answers)
Closed 8 years ago.
I want to convert all integers below 1048576 to binary and display all numbers which have the same number of bits set as unset. My program works fine when I use a table t of 20 integers, in which case cpt records the correct result.
However, when I use a table t of 40 integers (which means I want the numbers with 20 '1' bits and 20 '0' bits) the counter is set to 1. What is wrong?
int main(){
long int a;
int r,j,i;
long int aux;
int z,u;
long int cpt;
int t[40];
for(int k=0;k<40;k++) t[k]=0;
cpt=0;
for(a=0;a<1048576;a++){
j=0;u=0;z=0;
aux=a;
do{
r=aux%2;
switch(r){
case 0 : t[j]=0;
aux=(aux/2);
j++;
break;
case 1 : t[j]=1;
aux=((aux-1)/2);
j++;
break;
}
}while(aux!=0);
for(i=0;i<40;i++){
if(t[i]==0) z++;
else u++;
}
if(z==u) cpt++;
}
printf("%d",cpt);
getchar();
}
Your loop only goes to 1048576, which is 2^20.
Don't you need to loop until 2^40?
Also, note that int may not be 40 bits wide.
Note:
The naive solution to check all numbers doesn't scale well. Perhaps you should consider a smarter solution?
Because only one number in the range [0, 1048576) has exactly as many bits 1 as 0, when counted in your 40 "bit" array.
The flaw in your logic is that you do not examine all numbers in a given range. For instance, when you want to examine all 40-bit integers, you need to iterate until 2^40 and not 2^20.
Lastly, this brute force solution won't work very well for your problem. Instead, try to consider the pattern that appears when you examine the number of paths from the top-left node and proceeding to the down or right for a small array on a piece of paper. Does one emerge? If you're math-inclined, you will instantly recognise it; otherwise, take a minute to look through the binomial coefficients.
As others have said, the main thing that is wrong is the algorithm you are using (exhaustive search); you would need to loop from 0 to 240-1 to iterate across the entire set of numbers to be tested (rather than to 220-1), which would be an impractical number of iterations, not least as there are faster ways.
Consider the maths of the problem: you want a 40 bit field, with 20 bits set to 1. So, you are choosing 20 things from 40. Think about the nCr (combination operator from permutations and combinations); that will give you the link to the binomial coefficients. Now think how you might write an algorithm to go through every combination.
Your code would also be more comprehensible if it did not have single letter variable names, and had some comments explaining what it was meant to be doing.
If you are having difficulty remembering the bit width of integer types, I suggest you use
#include <stdint.h>
and use types like int64_t which is guaranteed to be 64 bits. See:
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdint.h.html
(Note that OP apparently wanted a list of the numbers with 20 bits set, rather just the count of such numbers, so merely looking at binomial coefficients is insufficient).
try using a long long int:
unsigned long long int a;
to fasten and clear a lot of code try also using popcount, it's a function that returns the number of 1-bits in x: http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html.
//I'm not 100% sure if the popcount will work with long long ints, but you can try.
BTW I have a question about the same euler problem #: Binary numbers with the same quantity of 0s and 1s
There is also a counterpart which is called density array. What does this mean? I have done some search, but didn't get accurate information.
Say you have a structure
struct SomeStruct {
int someField;
int someUselessField;
int anotherUselessField;
};
and an array
struct SomeStruct array[10];
Then if you look at all the someFields in this array, they can be considered an array on their own, but they're not occupying consequent memory cells, so this array is strided. A stride here is sizeof(SomeStruct), i.e. the distance between two consequent elements of the strided array.
A sparse array mentioned here is a more general concept and actually a different one: a strided array doesn't contain zeroes in skipped memory cells, they're just not the part of the array.
Strided array is a generalization of usual (dense) arrays when stride != sizeof(element).
If you want to operate on a subset of a 2D array, you need to know the 'stride' of the array. Suppose you have:
int array[4][5];
and you want to operate on the subset of the elements starting at array[1][1] to array[2,3].
Pictorially, this is the core of the diagram below:
+-----+-----+-----+-----+-----+
| 0,0 | 0,1 | 0,2 | 0,3 | 0,4 |
+-----+=====+=====+=====+-----+
| 1,0 [ 1,1 | 1,2 | 1,3 ] 1,4 |
+-----+=====+=====+=====+-----+
| 2,0 [ 2,1 | 2,2 | 2,3 ] 2,4 |
+-----+=====+=====+=====+-----+
| 3,0 | 3,1 | 3,2 | 3,3 | 3,4 |
+-----+-----+-----+-----+-----+
To access the subset of the array in a function accurately, you need to tell the called function the stride of the array:
int summer(int *array, int rows, int cols, int stride)
{
int sum = 0;
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
sum += array[i * stride + j];
return(sum);
}
and the call:
int sum = summer(&array[1][1], 2, 3, 5);
To stride is to "take long steps"
thefreedictionary.com/stride
For an array this would mean that only some of the elements are present, like just every 10th element. You can then save space by not storing the empty elements in between.
A dense array would be one where many, if not all, elements are present so there is no empty space between the elements.
I'm adding yet another answer here since I didn't find any of the existing ones satisfactory.
Wikipedia explains the concept of stride, and also writes that “stride cannot be smaller than element size (it would mean that elements are overlapping) but can be larger (indicating extra space between elements)”.
However, from the information I've found, strided arrays allow for exactly this: conserve memory by allowing the stride to be zero or negative.
Strided arrays
Compiling APL to JavaScript explains strided arrays as a way to represent multidimensional arrays with both data and stride, unlike the typical "rectangular" representation of arrays that assumes an implicit stride of 1. It allows both positive, negative and zero stride. Why? It allows for many operations to only alter the stride and shape, and not the underlying data, thus allowing efficient manipulation of large arrays.
The advantage of this strided representation becomes apparent when working with large volumes of data. Functions like transpose (⍉⍵), reverse (⌽⍵), or drop (⍺↓⍵) can reuse the data array and only care to give a new shape, stride, and offset to their result. A reshaped scalar, e.g. 1000000⍴0, can only occupy a constant amount of memory, exploiting the fact that strides can be 0.
I haven't worked out exactly how these operations would be implemented as operations on the stride and shape, but it's easy to see that altering only these instead of the underlying data would be much cheaper in terms of computation. However, it's worth keeping in mind that a strided representation might impact cache locality negatively, so depending on the use case it might be better to use regular rectangular arrays instead.
Possibility 1: Stride describes a buffer array to read an optimized array
When you use a method to
store multidimensional arrays in linear storage. The stride describes the size in each dimension of a buffer which will help you read that array. Image taken from Nd4j (More info about Stride)
Possibility 2 (lower level): Stride is the distance between contiguous members of an array
It means that addresses of items with index 0 and 1 won't be continuous in memory unless you use a unit Stride. A bigger value will have the items more distant in memory.
This is useful at low level (word length optimization, overlapping arrays, cache optimization). Refer to wikipedia.
In highly-optimized code, one reasonably coomon technique is to insert padding into arrays. That means that the Nth logical element no longer is at offset N*sizeof(T). The reason why this is can be an optimization is that some caches are associativity-limited. This means that they can't cache both array[i] and array[j] for some pairs i,j. If an algorithm operating on a dense array would use many of such pairs, inserting some padding might reduce this.
A common case where this happens is in image procesing. An image often has a line width of 512 bytes or another "binary round number", and many image manipulation routines use the 3x3 neighborhood of a pixel. As a result, you can get quite a few cache evictions on some cache architectures. By inserting a "weird" number of fake pixels (e.g. 3) at the end of each line, you change the "stride" and there's less cache interference between adjacent lines.
This is very CPU-specific so there's no general advice here.