Four-way equivalence - c++

How do I check the equality between four variables? This is for a 3D tic-tac-toe game.
if (b[0][0] == b[1][0] == b[2][0] == p) { line += 1; }
This doesn't work as equivalent is left-to-right. I don't want to do either of the below:
if (b[0][0] == p && b[1][0] == p && b[2][0] == p) { line += 1; }
if ((b[0][0] == b[1][0]) && (b[1][0] == b[2][0]) && (b[2][0] == p)) { line += 1; }
All variables are integers, as I know with bools I can just use &&. Is there a better way? I considered:
if ((b[0][0] + b[1][0] + b[2][0]) == (3 * p)) { line += 1; }
Since p will be one of three values (0 for neither X or O, 1 for X, 2 for O), it would need only changing the value of O to 4 or something impossible to achieve with three 1s, 0s, or combinations thereof. But it lacks finesse.

Since 3 out of 4 variables in the question belong to one object, you can create a method to wrap it all. Something like bool isValid(int *A, int val) {...} and then use it in your statement like if (isValid(b, p)) {...}. The name is arbitrary since the wider context is not given.

Now that you've mentioned tic-tac-toe, things change a bit. Ultimately you'll be checking each column for the same value and each row for the same value. That doesn't require a long if ... else if... ladder. Instead, write a function to check a row:
bool row_matches(board b, int row, int value) {
for (int col = 0; col < 3; ++col)
if (b[row][col] != value)
return false;
return true;
}
and write a similar function for columns. Diagonals are even simpler.

Related

Equality test function

Below is a function which aims to perform an equality test between adjacent numbers in a one dimensional vector.
This 1D vector will have values which will represent an nxn grid. [ v is the vector]
When they are equal it returns false.
For example consider this 3x3 grid:
i\j| 0 | 1 | 2
0 | 1 | 2 | 3
1 | 4 | 5 | 6
2 | 7 | 8 | 9
The issue with the code I wrote is that not all of the numbers in the grid will have 4 other adjacent numbers and testing for indexes which don't exist e.g when trying to compare the number above the top left number in the grid (1 in the example) might lead to some inaccurate outcomes.
In addition to this what I wrote seems not to be the most efficient way to go about it. Surely there could be a simpler way to do this than having to list 5 new variables?
for( int i= 0; i < n ; i++ ){
for( int j = 0; j < n; j++){
int x = v[convert(i, j, n)];
int c = v[convert(i-1, j, n)];
int s = v[convert(i+1, j, n)];
int b = v[convert(i, j+1, n)];
int n = v[convert(i, j-1, n)];
if (x == c || x == s || x == b || x == n ) {
return false;
}
}
}
//another function used to convert 2d into 1D index
int convert(int row, int col, int rowlen){
return row*rowlen+col;
}
I would appreciate any help.
If you want an efficient way to do this, you should consider the cache locality of your values, how much index conversion you do, how many bounds tests you do, and how many comparisons are needed.
First thing to note is that you do not need to compare to the left and above when you're already comparing to the right and below. This is because the left/up test will happen when testing to the right/down on the next iteration. So immediately, that halves the amount of testing.
A first optimization would be to split the operation into row tests and column tests:
// Test adjacency in rows
for (const int *rowptr = v, *end = v + n * n;
rowptr != end;
rowptr += n)
{
for (int col = 1; col < n; col++) {
if (rowptr[col-1] == rowptr[col]) return false;
}
}
// Test adjacency in columns
for (const int *row0ptr = v, *row1ptr = v + n, *end = v + n * n;
row1ptr != end;
row0ptr = row1ptr, row1ptr += n)
{
for (int col = 0; col < n; col++) {
if (row0ptr[col] == row1ptr[col]) return false;
}
}
To avoid making two passes through the entire array, you'd need to combine these, but it starts getting a bit messy. Notice how the two separate passes currently have different bounds (the row-tests loop from column 1 to n, whereas the column tests loop from row 0 to n-1).
Combining the loops would only make sense if n is quite large and if it's absolutely critical that this piece of code is fast. The idea is to perform a single pass through the entire array, avoiding any issues with stuff like L1 cache misses on the second pass.
It would look something like this:
const int *row0ptr = v, *row1ptr = v + n, *end = v + n * n
for ( ; row1ptr != end; row0ptr = row1ptr, row1ptr += n)
{
// Test first column
if (row0ptr[0] == row1ptr[0]) return false;
// Test row0 and remaining columns
for (int col = 1; col < n; col++) {
if (row0ptr[col-1] == row0ptr[col]) return false;
if (row0ptr[col] == row1ptr[col]) return false;
}
}
// Test last row
for (int col = 1; col < n; col++) {
if (row0ptr[col-1] == row0ptr[col]) return false;
}
First I'd recommend breaking up the logic because it's getting quite convoluted. But something like this works, it avoids going outside the grid by adding extra checks on i and j and it may avoid unnecessary calls to convert since if one of the earlier tests is true the later tests aren't performed.
int x = v[convert(i, j, n)];
if (i > 0 && x == v[convert(i-1, j, n)])
return false;
if (i < n - 1 && x == v[convert(i+1, j, n)])
return false;
if (j > 0 && x == v[convert(i, j-1, n)])
return false;
if (j < n - 1 && x == v[convert(i, j+1, n)])
return false;

How to get the remaining axis of a 3d vector knowing the other two?

I need to get the remaining value of a 3d vector "v[3]"
I have a function that returns the remaining axis having the other two as parameters:
static get_remain_axis(const short a, const short b) {
if (a == 0) {
if (b == 1)
return 2;
else
return 1;
}
else if (a == 1) {
if (b == 0)
return 2;
else
return 0;
}
else {
if (b == 0)
return 1;
else
return 0;
}
}
So I could do so:
v[get_remain_axis(a, b)]
But I need efficiency in this operation, and if possible, it would be nice if it were atomic.
How to do this function more efficiently?
At least as I read things, you have axes 0, 1 and 2. The inputs are two of those, and you want to return the third one.
Assuming that's the case, the three numbers need to add up to 3, so you can just do: return 3 - (a + b);

bug in c++ program count no of 1's in vector

A question was asked to me during an online interview.
They provided a piece of code and we have to find out a possible bug in the code.
The code is provided below as it is.
The function is provided with a non empty zero indexed vector of integers (which contains only 1 and 0).
The function will return the start position of longest sequence of 1's.
for example if the input values {0,0,0,1,1,1,1,1,0,0,1,1,1,0,1,1} it will return 3 because the longest sequence of 1's is from position 3 to 7 total five consecutive 1's.
if the input values are {0,0,1} then it will return 2 because there is only one 1 and length of longest sequence of 1 is one.
If there are no 1's then it will return -1.
The input vector can be changed so we can't change the signature of the vector to const.
I tested this function with variable no of inputs and I found out that it is working fine.
I am not able to find out any bug in the code. But the instruction says that there is a bug in the code and we can change maximum 2 lines of code to solve the bug.
int solution(vector<int>& A) {
int n = A.size();
int i = n - 1;
int result = -1;
int k = 0;
int maximal = 0;
while (i > 0) {
if (A[i] == 1) {
k = k + 1;
if (k >= maximal) {
maximal = k;
result = i;
}
} else {
k = 0;
}
i = i - 1;
}
if (A[i] == 1 && k + 1 > maximal)
result = 0;
return result;
}
To fix UB for empty case, I add check for !A.empty(),
and I profit of that to replace i by 0 (at that point i == 0)
and to replace the check with maximal value to have a coherent result for tie:
if (!A.empty() && A[0] == 1 && k + 1 >= maximal)
And as I may change an other line, I would fix the prototype as A is not modified.
int solution(const std::vector<int>& A) {
problem specifications are that
1.vector is immutable and
2.Input vector is not empty
I tried same problem in Java but different approach to see what is missing because i cant find any bug in above code.
package javaapplication7;
/**
*
* #author Owner
*/
public class JavaApplication7 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] A={0,1,0,1,1,1,1};
System.out.println(solution(A));
}
static int solution(int A[]){
int i=0,count=0,max=0,pos=-1;
while(i<=A.length-1)
{
if(A[i]==1)
{
count++;
i=i+1;
}
else
{
i=i+1;
count=0;
}
if(count>max)
{
pos=i-count;
max=count;
}
}
if(count==0)
return pos;
else
return pos;
}
}
the given code will favor a sequence closer to the left side if two sequences are of equal length. that doesn't happen for the checking of index 0
if (A[i] == 1 && k + 1 > maximal)
should be
if (A[i] == 1 && k + 1 >= maximal)

sudoku,recursive function solves half the puzzle

I'm working on a Sudoku solver, and my program is having trouble recursing backwards when it has exhausted its outputs.
I have four functions that do the check:
scolumn, srow, sbox. Each one will return false if the number already exists in the column row or box respectively.
bool sudoku::solve(int row, int column)
{
if(column == 9)
{
column = 0;
row +=1;
}
if(puzzle[row][column] != 0)
{
solve(row, column + 1);
return false;
}
else
{
for(int n = 0; n < 10; n ++)
{
if(srow(column, n) && scolumn(row,n) && sbox(row, column, n)
{
puzzle[row][column] = n;
if(!solve(row, column + 1);
table[row][column] = 0;
}
}
puzzle[row][column] = 0;// if not commented out then infinite loop
}
return false
}
the problem with it is that if its at 9 and there is no next choice, it will not backtrack correctly.
There are a number of problems with your code, as people have observed in the comments.
This answer summarises some of them:
1) As #n.m. said, you should not be trying '0' as a valid choice in a cell. That will be the cause of some infinite looping, no doubt.
2) As you have observed, you don't know how the recursion finishes. The answer is that when you get to the last cell, and you find a value that works in it, you are supposed to return true. This is what is supposed to break the for(n) loop: that loop is saying "try each number until the call of solve to the right of this cell succeeds'. Success is measured by your routine returning true.
Since you try every number (n) in the current cell, no matter whether or not the call to the solve on its right works ... it's not going to work.
You'll know that you're more on the right track when:
You can see the place in your code where you return true when you discover that you can put a number in the last cell (9,9)
You can see how it is that you stop trying numbers (n=0..9) when the call to the right succeeds.
Given int puzzle[9][9], and your srow, scol, and sbox functions:
bool sudoku::solve(int row, int column) //to solve entire puzzle, call with parameters 0 and 0
{
int cell;
//ignore all nonzero cells (zero = empty)
while (row < 9 && puzzle[row][column] != 0)
{
column++;
if (column == 9)
{
row++;
column = 0;
}
}
if (row == 9) return true; //puzzle is already solved
//try values 1-9 inclusive. If successful, then return true
for (cell = 1; cell <= 9; cell++)
{
puzzle[row][column] = cell;
if (srow(row) &&
scol(column) &&
sbox(row-row%3, column-column%3) &&
solve(row, column)) //recursion!!
{
return true;
}
}
//if no value works, reset the cell and return false.
puzzle[row][column] = 0;
return false;
}

In Place rotation C++ Practice

I have a working rotating function going for my "items" int array. The code below gets it done, except that im transferring values out unnecessarily. Im trying to acheive the "inplace" rotation. What I mean by that is where the ptrs would increment or decrement instead of grabbing values out of the array..By which I need to "up" the efficiency level in that way for this method..Any Suggestions?
void quack::rotate(int nRotations)
{
if ( count <= 1 ) return;
else // make sure our ptrs are where we want them.
{
intFrontPtr = &items[0].myInt;
intBackPtr = &items[count-1].myInt;
}
for (int temp = 0; nRotations != 0;)
{
if ( nRotations > 0 )
{
temp = *intFrontPtr;
*intFrontPtr = *intBackPtr;
*intBackPtr = temp; // Connect temps for the rotation
--intBackPtr; // Move left [...<-] into the array
}
else if ( nRotations < 0 )
{
temp = *intBackPtr;
*intBackPtr = *intFrontPtr;
*intFrontPtr = temp; // Connect temps for the rotation
++intFrontPtr; // Move right [->...] into the array
}
if ( intBackPtr == &items[0].myInt ||
intFrontPtr == &items[count-1].myInt )
{
intFrontPtr = &items[0].myInt;
intBackPtr = &items[count-1].myInt; // need to re-set
if ( nRotations > 0 ) nRotations--; // Which ways did we rotate?
else nRotations++;
}
}
}
Oh yes, Im trying to practice c++ and know their are many functions floating around that are programmed to do this already...Im trying to "build my own". I think i've got it down syntactically, but the efficiency is always where i struggle. As, a novice, I would greatly appreciate critisim towards this aspect..
There is an old trick for rotating elements in an array (I first saw it in Programming Pearls)
Say you want to rotate an array to the left by three elements.
First reverse the first three elements, next reverse the remaining elements, and then reverse the entire array.
Starting Array:
1 2 3 4 5 6 7
After reversing the first three elements
3 2 1 4 5 6 7
After reversing the remaining elements
3 2 1 7 6 5 4
Finally reverse the entire array to get the final rotated array
4 5 6 7 1 2 3
Reversing portions of the array can be done in place so you don't need any extra memory.
You can leave the data in place, and have a "base index" member to indicate where the array should start. You then need to use this to adjust the index when accessing the array. The array itself should be private, and only accessed through accessor functions that do the adjustment. Something like this:
class quack
{
public:
explicit quack(int size) : items(new Item[size]), size(size), base(0) {}
~quack() {delete [] items;}
void rotate(int n) {base = (base + n) % size;}
Item &operator[](int i) {return items[(base + i) % size];}
private:
quack(quack const&) = delete; // or implement these if you want
void operator=(quack const&) = delete; // the container to be copyable
Item *items;
int size;
int base;
};
although I'd call it something like RotatableArray, rather than quack.
As usual, if you really have to physically rotate the elements, the correct answer for C++ would be to use std::rotate, which does exactly what you want to do.
If you have to implement it manually (as a practice assignment), take a look at these slides for algorithms from John Bentley's "Programming Pearls".
doing the rotations one by one is really not the way to go. If you are doing anything more than 2 or 3 rotations it gets really slow really quick.
edit:
as a final thought... putting the elements in a (double) linked 'looped' list (so the final element points to the first), would require for a rotate to only move the head pointer a few elements. (The head pointer being a pointer to indicate which element in the looped list is the beginning).
this is by far the quickest (and easiest) way to do a rotate on a list of elements
Really the way to do it is to use indexes instead of pointers.
int to = 0;
int from = (to + nRotations) % count;
if (to == from)
return;
for (int i=0; i < count; i++) {
swap(from, to);
from = advance(from);
to = advance(to);
}
// ...
static inline int advance(int n, int count) { return (n + 1) % count; }
I may have an alternate solution to rotating the array inline. Rather than the old trick of reversing sets of elements, as proposed earlier, this approach works as follows:
Initialization:
(Note q = amount to shift left, n = length of array)
Determine the first source element, which is located at x1=q%n
The destination element is at x2=0
char, ch1, is the ar[x1] element
char, ch2, is the ar[x2] element
Loop on i=0 to n-1, where n = length of array
Overwrite the destination element, ar[x2] with ch1
Set ch1 = ch2
Set x1 = x2
Set x2 = x2 - q
If x2 is negative due to the above subtraction, add n to it
ch2 = ar[x2]
The following may help explain how this works.
Example, rotate to the left by 2 characters:
a b c d e f g
c d e f g a b
x1 ch1 x2 ch2
2 c 0 a
0 a 5 f
5 f 3 d
3 d 1 b
1 b 6 g
6 g 4 e
4 e 2 c
As you can see, this requires no more than n iterations, so it is linear time algorithm that also rotates inline (requires no additional storage other than the few temporary variables).
Here is a function that implements the above algorithm so you can try it out:
void rotate(char *ar, int q)
{
if (strlen(ar) < 2)
{
return;
}
if (q <= 0)
{
return;
}
char ch1;
char ch2;
int x1;
int x2;
int i;
int n;
n = strlen(ar);
q %= n;
if (q == 0)
{
return;
}
x1 = q;
ch1 = ar[x1];
x2 = 0;
ch2 = ar[x2];
for (i=0;i<n;i++)
{
ar[x2] = ch1;
ch1 = ch2;
x1 = x2;
x2 -= q;
if (x2 < 0)
{
x2 += n;
}
ch2 = ar[x2];
}
}
Here's one that I got by modifying the code here:
template<class It>
It rotate(It begin, It const middle, It end)
{
typename std::iterator_traits<It>::difference_type i = 0, j;
if (begin != middle && middle != end)
{
while ((i = std::distance(begin, middle)) !=
(j = std::distance(middle, end)))
{
It k = middle;
std::advance(
k,
std::max(typename std::iterator_traits<It>::difference_type(),
j - i));
std::swap_ranges(k, end, begin);
if (i > j) { std::advance(begin, j); }
else { std::advance(end, -i); }
}
}
return std::swap_ranges(middle - i, middle, middle);
}
Here is code for sdtom solution
void rotateArray(int arr[], int low, int high)
{
while (low<high) {
int temp = arr[low];
arr[low]=arr[high];
arr[high]=temp;
low++;
high--;
}
}
void rotate (int arr[], int k,int uperLimit)
{
rotateArray(arr,0,k);
rotateArray(arr,k+1,uperLimit-1);
rotateArray(arr,0,uperLimit-1);
}
https://stackoverflow.com/q/17119000/2383578 : This is somewhat similar to what is discussed here. Rotating the array by a particular amount.
There are many ways to do array rotation by d places.
Block swap algorithm.
Juggling Algorithm.
Reversal Algorithm.
The link below is from Programming Pearls pdf. Check this out. Explained very clearly with code.
http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf