I am writing a chess engine using an array (single dimension) in C?
#define ROW(sq) (sq >> 3)
#define COL(sq) (sq & 7)
int board[64] = {
0,1,2,3,4,5,6,7,
8,9,10,11,12,13,,14,15,
.......................
.......................
56,57,48,59,60,61,62,63
}
Now:
To get the row and col of number 11 I use this:
int r = ROW(11);
int c = COL(11);
It gives:
r = 1
c = 3
Please help me to write a function so that it takes the parameter as r and c and gives the correct square like:
sq = fnc(r,c);
sq = fnc(1,3);
sq = 11;
You just have to calculate row * MAX_COL + col where MAX_COL = 8. With row * MAX_COL you will go into the next row, like the following figure shows:
1 * 8 --- 2 * 8 ---
| |
| row = 0 | v row = 1 | v row = 2
| 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15 | 16 ...
If you want a macro which uses the global variable board:
#define FIELD(row,col) board[(row) * 8 + (col)]
or as function which also uses the global defined board variable:
inline int FIELD (int row, int col)
{
return board[row * 8 + col]
}
if you want to pass the board as array to the function you can do the following, where int boardArr[] decays to a pointer:
inline int FIELD (int boardArr[], int row, int col)
{
return boardArr[row * 8 + col]
}
Also you should change your macro definitions, because they are unsafe if the parameter that is passed is a value that is used in a calculation. You can read it here on SO. So you should use braces around the parameters sq:
#define ROW(sq) ((sq) >> 3)
#define COL(sq) ((sq) & 7)
It would be even better to use inline functions as it is also said in the SO answer.
If your board is always 8x8, you can see that each r starts at 0, 8, 16... and each c is just the offset from those initial points, so given an r and c, you can calculate the array index by board[(r * 8) + c] to get the corresponding piece.
This is best approached using a two-dimensional array because that way you can simply access board[r][c].
If you (or your professor) insist on a one-dimensional array, this macro will do what you want:
#define GET_PIECE(r, c) (board[((c) + (8) * (r))])
Notice how everything is wrapped in parentheses. This is very important with macros!
A better solution would be to use an inline function.
Related
I have a column vector X of size N-by-1 with two values: 10 and 25. I want to switch those values, i.e. every element with value 10 should become 25 and vice versa.
Pseudo-code:
A = [ 10; 25; 25; 10; 25; 25; 10]
NewNew = find(A == 10)
NewNew2 = find(A == 25)
NewNew3 = [ ];
for NewNew3
if NewNew
NewNew=25
else NewNew2
NewNew2=10
end
I tried this now still no success:
for B = 1:size(A)
if A == 10
A = 25
elseif A == 25
A = 10
end
end
How can I switch values?
If you only have two values, why not subtracting from their addition:
A = 35 - A;
N=10;
X = randi([1 2],N,1);
A = zeros(size(X)); % create output vector
A(X==2)=1; % whenever X==2, set A=1
A(X==1) = 2; % whenever X==1, set A=2
[X A]
ans =
1 2
2 1
2 1
1 2
2 1
1 2
1 2
2 1
2 1
2 1
You can do this with logical indexing. Just make sure to get a separate output vector, as setting X(X==1)=2 will make your whole vector 2, and then calling X(X==2)=1 sets the whole vector to 1. If necessary, use X=A at the end.
Final advice: your for loop needs indexing, which is about as basic as MATLAB goes. You can solve this problem with a for loop, although I'd recommend using logical indexing as per the above. I strongly suggest you to either take a basic course in MATLAB, or read the MathWork's own tutorial on MATLAB.
There are some other options you can consider.
1.) (Irrelevant option. Use ibancg's option, cleaner and faster.)
If you have just those two values, a simpler and faster solution would be to initialize to one of these two numbers and flip just a subset of the numbers:
A = [ 10; 25; 25; 10; 25; 25; 10];
X = ones(size(A)) * 10; % initialize X with 10.
X(A == 10) = 25; % Set values where A is 10 to 25.
2.) (irrelevant, too slow): Another possibility if you know that some numbers will never appear is to use temporary third number and avoid creating a new matrix - operate kind of similar to the typical "swap two numbers" recipe.
A(A == 10) = 1; % Temp value
A(A == 25) = 10;
A(A == 1) = 25;
3.) Finally, the third option would be to save logical matrix and then overwrite A.
Ais10 = A==10;
Ais25 = A==25;
A(Ais10) = 25;
A(Ais25) = 10;
Now, for the benchmarks: I used very simple script, varying N and M.
tic
for i = 1 : M
X1 = randi([1 2],N,1);
... % depends on test cases. Result can be in X or A.
toc
Therefore, it also times randi, but as it is a part of every code it should only mask the relative speed differences, keeping absolute ones the same. Computer is i7 4770k, 32GB RAM.
Row vector has 1000 elements, 1M runs; 100M elements, 10 runs; 1B elements, 1 run; 3B elements, 1 run
Codes that rely on having just 2 values:
1I): 18.3 s; 20.7 s; 20.3 s; 63.6 s
1Z): 33.0 s; 38.2 s; 38.0 s; NA (out of memory)
Code relies on lacking one value that can be used for swap:
2Z): 54.0 s; 60.5 s; 60.0 s; 659 s
Code handles arbitrary data, swapping 2 values.
3A): 45.2 s; 50.5 s; 49.0 s; NA (out of memory)
3Z): 41.0 s; 46.1 s; 45.8 s; NA (out of memory)
So, to summarize, Ibancg's option is much faster and simpler than the rest and should be used if possible (= just those 2 different values in the vector). My 2nd option is far too slow to be relevant. Rather do step by step swap on the vector using any of the general methods. Either general option is fine.
I have been learning memory allocation and pointers lately, and I made this program which will ask the user to input the dimensions of a matrix and enter it's elements, after which it displays the elements in a matrix format. Here's the code that I've typed.
#include"stdio.h"
#include"stdlib.h"
int *minput();
int *minput(int x,int y)
{
int *M;
M=(int*)malloc(x*y*sizeof(int));
for(int i=0;i<=(x-1);i++)
{
for(int j=0;j<=(y-1);j++)
{
printf("A(%d,%d)=",i+1,j+1);
scanf("%d",(M+i+j));
}
}
return M;
}
int main()
{
int *A,a,b;
printf("Matrix is (m*n)\n\n");
printf("m=");
scanf("%d",&a);
printf("n=");
scanf("%d",&b);
A=minput(a,b);
printf("\n");
for(int k=0;k<=(a-1);k++)
{
for(int l=0;l<=(b-1);l++)
{
printf("%d ",*(A+k+l));
}
printf("\n");
}
free(A);
return 0;
}
However when I gave my inputs, I got this:
Matrix is (m*n)
m=3
n=3
A(1,1)=1
A(1,2)=2
A(1,3)=3
A(2,1)=4
A(2,2)=5
A(2,3)=6
A(3,1)=7
A(3,2)=8
A(3,3)=9
1 4 7
4 7 8
7 8 9
What's wrong? Amn't I supposed to get
1 2 3
4 5 6
7 8 9
Is there anything I had made wrong in my code?
You get incorrect output because *(A+k+l) is not the right way of accessing matrix element at matrix[k][l].
For addressing a matrix stored as a "flat" array you need to multiply the value of one of the indexes by the size of the opposite dimension. Depending on which index you multiply you get either a row-major order or a column-major order.
You need to apply the same fix to (M+i+j) inside minput function.
// Input
scanf("%d",(M+y*i+j));
...
// Output
printf("%d ",*(A+b*k+l));
The idea behind multiplying k by b is to make k "count faster". For each increment of k by 1 you need to skip an entire row of b elements. In your three-column matrix example, if you would like to access elements at A[k][0] (the initial column) of your matrix for each row, your index would count by three: 0, 3, 6. This is accomplished by multiplying k by b. The rest is the same as the usual pointer arithmetic: *(A+b*k+l) is equivalent to A[b*k+l].
Demo.
Lets take a close look at one of your loops (I use the input loop, but the error is in the output loop as well):
for(int i=0;i<=(x-1);i++)
{
for(int j=0;j<=(y-1);j++)
{
printf("A(%d,%d)=",i+1,j+1);
scanf("%d",(M+i+j));
}
}
The first iteration of the outer loop, i is zero. Then the inner loop runs, and we read into (in turn) M+0+0, M+0+1 and M+0+2.
Then we run the second iteration of the outer loop, where the inner loop will read into M+1+0, M+1+1 and M+1+2.
In these two iterations of the outer loop you will read into M+1 and M+2 twice. That's because M+0+1 and M+1+0 are the same element.
To fix this, lets take a look at your "matrix" as it is in memory
+---+---+---+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
The numbers inside are the indexes. Now, 0, 1 and 2 is the first row. 3, 4 and 5 is the second. And 6, 7 and 8 is the last.
From this we can see that to get to the next line, we have to add the number of columns.
From this we get the formula line * number_of_columns + column to get the index.
Putting it in place, your input loop could look like
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
printf("A(%d,%d)=",i+1,j+1);
scanf("%d",M+i*y+j);
}
}
To choose the address in which to write a value, you use:
M+i+j
Let's try that for a few values of (i,j):
0,0 -> M + 0
0,1 -> M + 1
0,2 -> M + 2 // So far so good.
1,0 -> M + 1 // not right
1,1 -> M + 2 // not right
... etc.
You want M + (i * x) + j. For x == 3:
0,0 -> M + 0
0,1 -> M + 1
0,2 -> M + 2
1,0 -> M + 3
1,1 -> M + 4
... etc.
The same goes for the pointer arithmetic when reading from the same memory.
Furthermore, since the pointer just goes up by one each time, you could get the same behaviour with:
int *m = M;
for(int i=0;i<x;i++)
{
for(int j=0;j<=(y-1);j++)
{
printf("A(%d,%d)=",i+1,j+1);
scanf("%d",m);
m++;
}
}
Or even:
for(int i=0; i<x*y; i++) {
printf("A(%d,%d)=", i/3, i%3);
scanf("%d", M + i);
}
Other points:
In one method you use variables x,y,i,j, and in another you use a,b,k,l. I assume you've done this because you don't want to overwrite one with the other. But because of scope, that's not a factor. x is local to the function minput() -- you can have another x in main() and they will be completely independent of one another. Use x,y,i,j in both places, because they are the "sensible" names for dimensions and loop counters.
for(i=0; i<x; i++) is the conventional way of looping x times. Your i<=(x-1) is equivalent but messy and confusing.
Casting the result of malloc() is discouraged nowadays. Do I cast the result of malloc?
int *M = malloc(x*y*sizeof(int));
I wrote this code that check suduko answers and for some reason my the array which I sum the squares of the suduko into is all zeros in the functions I zero it in, but when I use it in my check function it isn't all zeros
if i move the exact same code of my array zeroing function to my other function and run it it works.
(i am using c99, dont know if it matters)
Any ideas?
int squareSum[5][5];
//set array elements to zero
setArrayToZero(squareSize, squareSize, squareSum);
/*for(int i = 0; i<squareSize; i++){
for(int j = 0; j<squareSize; j++)
squareSum[i][j] = 0;
}*/
printf("%d, %d\n%d, %d\n\n", squareSum[0][0], squareSum[0][1], squareSum[1][0], squareSum[1][1]);
this is the array is case squareSize is two
if i add the for in the comments in, the array isall zeros, and as you can see below its the exact same as the function i call.
void setArrayToZero(int rows, int columns, int array[][columns]){
for(int i = 0; i<rows; i++)
for(int j = 0; j<columns; j++)
array[i][j] = 0;\\if i print the array in function its all zeros.
p.s
i know i am using only part of the array, its an assignment from the university and we are not allowed to use malloc so i am creating the array at thier max size - 25.
thank you in advance.
full c file:
https://drive.google.com/open?id=1L00L3lvMYNcaz2SswEBnmi9KO-79oaHg
all the print functions, are part of the demand for the course (for auto checking)
A reference to an object of type array-of-T which appears in an
expression decays (with three exceptions) into a pointer to its first
element; the type of the resultant pointer is pointer-to-T.
So that means in this case also (this is not one of those 3 exceptions) your passed array will decay into pointers and now you change to the array by accessing the address, that's why it will be retained in the callee function.
You are doing it the right way. The problem is not with passing or anything. Maybe you are accessing it wrong or maybe you didn't initialize it properly. But there is nothing wrong with the zeroing out.
And for further information everything is pass by value in C. There is nothing called pass by reference in C. The pointer workings makes us think that there is something called pass by reference in C but that's not the case, here also pointer variables are copied into some local variable in the called function. but as we have those addresses in the called function and we access them and make changes - they retain in callee function.
After OP posted the sample code
Apaprt from the overly complicated sudoku checking logic there is much more going wrong.
I will just mention the printing part.
In C elements of 2d-arrays are stored sequentially. When we pass the 2d array to the function we need to specify the column size so that we can determine the correct element.
Suppose you want to access a[4][7] in 10x13 array. The element would be at the address &a[0][0]+4*13+7. That's why the column part is passed as an argument.
Now what you did :
int squareSum[5][5], rowColSum[25][2];
//set arrays elements to zero
setArrayToZero(size, 2, rowColSum);
setArrayToZero(squareSize, squareSize, squareSum);
The first one is alright. As there are 2 columns. But what about the second one?
here you are telling the function that you are passing an array with column size = 2 but that is not the case. It is still the 2d array with 5 columns.
That's where you had the problem. Suppose you initialize the array with 10,21,34,14
Suppose grid is 5x5 array (in your case it's 25x25)
grid[5][5] array
And you do this
for(int i = 0; i<squareSize; i++)
for(int j = 0; j<squareSize; j++)
scanf("%d",&grid[i][j]);
/*
Input is 13 17 19 23
*/
+-----+-----+-----+------+-----+-----+-----+----+----+----+--...\
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+-----+-----+-----+------+-----+-----+-----+----+----+----+--...\
/ \ \ / \ \
13 17 19 23
Now you access it like this
You pass it to the function with this call print2dArray(int row, int col, int g[][col])
You call like this `print2dArray(2,2,grid);``
...
for(int i = 0; i<row; i++)
for(int j = 0; j<col; j++)
printf("%d",&grid[i][j]);
Now you will print these elements (i) : denotes the order
+-----+-----+-----+------+-----+-----+-----+----+----+----+--...\
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+-----+-----+-----+------+-----+-----+-----+----+----+----+--...\
/ \ \ ^ ^ / \ \
13 17 | | 19 23
(1) (2) (3) (4)
Similarly, those were uninitialized in your case. That's why you got those weird results. You were initializing some elements of the 2d array to 0 but when you are reading the array then you were accessing some different elements. That's why the wrong result.
Solution for this:
Call int correctSum = inputGrid(squareSize, 25, grid); Note that it should be squareSize. Accordingly change the storage of digitsCounter in inputGrid.
The function signature for inputGrid would be inputGrid(size, col, grid[][col]);
Same when calling the
setArrayToZero(size, 2, rowColSum); and
setArrayToZero(squareSize, 5, squareSum);
I simply didn't check the logic. The answer deals with explaining the printing behavior of the 2d array.
Code:
#include <stdio.h>
int main(void)
{
int arr[2][3] = {{1,2,3},{4,5,6}};
int i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("%d ", *((*arr+(i*3))+j));
}
printf("\n");
}
return 0;
}
I'm surprised how the above code gives the output:
1 2 3
4 5 6
I know that *(arr+i) == arr[i] and also that I should be using arr[i][j] instead of making everything more complicated, but I don't understand how *((*arr+(i*3))+j) works.
In my understanding, *((*arr+(i*3))+j) can be simplified to *((*arr)+(i*3)+j) since the *(indirection operator) has the most precedence here.
So, when i is zero and j iterates through, 0 to 2, the expression is the same as arr[0][j] which prints the integers of the first subarray.
My confusion builds up when i becomes 1. The next three expressions will be *((*arr)+(1*3)+0), *((*arr)+(1*3)+1) and *((*arr)+(1*3)+2) which can be simplified to arr[0][3], arr[0][4] and arr[0][5].
How does this print the last three values?
int arr[2][3] = {{1,2,3},{4,5,6}};
In memory :
1 | 2 | 3 | 4 | 5 | 6
each number on an adjacent memory "cell" the size of an int, in this order
Second line :
i = 1
j = 0
*((*arr+(i*3))+j)) means *((*arr + 3) + 0)-> *({1, 2, 3} + 3) -> *({4, 5, 6}) = 4
Keep in mind that x[n] is equivalent to *(x + n), whatever x or n. (This also means arr[1] is equivalent to *(arr + 1), *(1 + arr) and so 1[arr] which I find funny)
Here arr[1][0] : x is arr[1] and n is 0 so first equivalence: *(arr[1] + 0)
Second x is arr and n is 1 so *(*(arr + 1) + 0).
Finally arr + 1 means the adress at arr + sizeof(*arr), which means:
(arr + 1) is equivalent to (*arr + 3) because *arr is arr[0] which is of type int[3]
The C language stores multidimensional arrays in what is called row-major order,
so when you declare int arr[2][3] the memory is actually laid out with the entries of the array occurring adjacent to each other in
memory in this sequence:
arr[0][0] arr[0][1] arr[0][2] arr[1][0] arr[1][1] arr[1][2]
This has a couple of consequences that are useful to know:
arr[1] acts like a pointer to a one-dimensional array. just as it does when you declare int **arr;.
The initializers in your initialization list are copied into memory locations in exactly the order you list them.
The array is stored in your memory like :
_____ _____ _____ _____ _____ _____
| 1 | | 2 | | 3 | | 4 | | 5 | | 6 |
----- ----- ----- ----- ----- -----
So even though it is stored in a two dimensional array it is contagiously allocated memory during compilation. When you write a[1][1] the compiler accesses the (1*(no of columns) + 1 ) position from front i.e. the 4 position from start.
See http://www.fredosaurus.com/notes-cpp/arrayptr/23two-dim-array-memory-layout.html
I came across this question in an interview.
Any number with 3 in its units position has at least one multiple containing all ones. For instance, a multiple of 3 is 111, a multiple of 13 is 111111. Given a number ending in 3, I was asked the best method to find its multiple containing all 1's.
Now a straightforward approach is possible, where you do not consider space issues but as the number grows, and sometimes even if it doesn't, an int (or a long int at that!) in C cannot hold that multiple.
What is the optimal way to implement such an algorithm in C?
UPDATE: Incorporating Ante's observations and making the answer community wiki.
As usual in this type of problems, coding any working brute-force algorithm is relatively easy, but the more math. you do with pencil and paper, the better (faster) algorithm you can get.
Let's use a shorthand notation: let M(i) mean 1111...1 (i ones).
Given a number n (let's say n = 23), you want to find a number m such that M(m) is divisible by n. A straightforward approach is to check 1, 11, 111, 1111, ... until we find a number divisible by n. Note: there might exist a closed-form solution for finding m given n, so this approach is not necessarily optimal.
When iterating over M(1), M(2), M(3), ..., the interesting part is, obviously, how to check whether a given number is divisible by n. You could implement long division, but arbitrary-precision arithmetic is slow. Instead, consider the following:
Assume that you already know, from previous iterations, the value of M(i) mod n. If M(i) mod n = 0, then you're done (M(i) is the answer), so let's assume it's not. You want to find M(i+1) mod n. Since M(i+1) = 10 * M(i) + 1, you can easily calculate M(i+1) mod n, as it's (10 * (M(i) mod n) + 1) mod n. This can be calculated using fixed-precision arithmetic even for large values of n.
Here's a function which calculates the smallest number of ones which are divisible by n (translated to C from Ante's Python answer):
int ones(int n) {
int i, m = 1;
/* Loop invariant: m = M(i) mod n, assuming n > 1 */
for (i = 1; i <= n; i++) {
if (m == 0)
return i; /* Solution found */
m = (10*m + 1) % n;
}
return -1; /* No solution */
}
You don't have to consider this question in the 'big number' way. Just take a paper, do the multiplication by hand, and soon you'll find the best answer:)
First, let's consider the units' digit of the result of 3x
x 0 1 2 3 4 5 6 7 8 9
3x 0 3 6 9 2 5 8 1 4 7
Thus, the relationship is:
what we want 0 1 2 3 4 5 6 7 8 9
multiplier 0 7 4 1 8 5 2 9 6 3
Second, do the multiplication, and don't save unnecessary numbers. Take 13 for example, to generate a '1', we have to choose the multiplier 7, so
13 * 7 = 91
well, save '9', now what we faces is 9. We have to choose multiplier[(11-9)%10]:
13 * 4 = 52, 52 + 9 = 61
Go on! Save '6'. Choose multiplier[(11-6)%10]
13 * 5 = 65, 65 + 6 = 71
Save '7'. Choose multiplier[(11-7)%10]
13 * 8 = 104, 104 + 7 = 111
Save '11'. Choose multiplier[(11-11)%10]
13 * 0 = 0, 0 + 11 = 11
Save '1'. Choose multiplier[(11-1)%10]
13 * 0 = 0, 0 + 1 = 1
Save '0'. WOW~! When you see '0', the algorithm ends!
Finally, if you print a '1' for one step above, here you will get a '1' string answer.
Like Bolo's solution with simpler equality M(i+1) = 10*M(i) + 1. Here is python version:
def ones( n ):
i = m = 1
while i <= n:
if m == 0:
return i
m = ( ( 10 * m ) + 1 ) % n
i += 1
return None
The multiple of 23 is 1111111111111111111111
#include <stdio.h>
int
main () {
unsigned int ones = 1;
double result, by = 23, dividend = 1;
while (dividend) {
result = dividend / by;
if (result < 1) {
dividend = dividend * 10 + 1;
++ones;
} else {
dividend -= by * (int)result;
}
}
while (ones--) {
printf("1");
}
printf("\n");
return 0;
}
In case, someone is looking for a solution in Java:
public static void main(String[] args) {
int input = 55333;
int minAllOnesNum = 1;
int nextAllOnesNum= minAllOnesNum;
int numberof1s=1;
int count = 0;
while(true)
{
count++;
if(nextAllOnesNum%input == 0 )
{
break;
}
nextAllOnesNum = nextAllOnesNum*10 + 1;
if(nextAllOnesNum>=input) {
nextAllOnesNum%=input;
}
numberof1s++;
}
System.out.println("count : " + count);
for(int i=1; i<=numberof1s; i++) {
System.out.print("1");
}
}