at the moment I have the following code:
for(int i = 0; i < 4; i++){
cout << rowNo[i] << endl;
}
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
cout << rowNo[i] << '.';
cout << rowNo[j] << endl;
}
}
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
for(int k = 0; k < 4; k++){
cout << rowNo[i] << '.';
cout << rowNo[j] << '.';
cout << rowNo[k] << endl;
}
}
}
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
for(int k = 0; k < 4; k++){
for(int l = 0; l < 4; l++){
cout << rowNo[i] << '.';
cout << rowNo[j] << '.';
cout << rowNo[k] << '.';
cout << rowNo[l] << endl;
}
}
}
}
Where rowNo[] is an array {1,2,3,4}
And I was wondering two things:
Can this be simplified, so maybe put into some sort of recursive loop?
Following that, can this then be made for an array of size N?
Your looking for Cartesian_product
With
bool increment(std::vector<std::size_t>& v, std::size_t maxSize)
{
for (auto it = v.rbegin(); it != v.rend(); ++it) {
++*it;
if (*it != maxSize) {
return true;
}
*it = 0;
}
return false;
}
then you can do:
void print_cartesian_product(const std::vector<int>&v, int n)
{
std::vector<std::size_t> indexes(n);
do {
print(v, indexes);
} while (increment(indexes, v.size()));
}
Demo
You are actually trying to print a number encoded in base4 with digit {1, 2, 3, 4}. To achieve it, You only need to define a function to increment by one. I propose a generic solution in the term of amount of number to print and base.
Like others, I use a number to mean "empty digit", and I use zero which is quite convenient.
Complete source code :
#include <iostream>
#include <vector>
bool increment_basep(std::vector<int>& number, int p)
{
int i = 0;
while(i < number.size() && number[i] == p)
{
number[i] = 1;
++i;
}
if(i >= number.size())
return false;
++number[i];
return true;
}
void print_vect(std::vector<int>& number)
{
for(int i = number.size() -1 ; i >= 0; --i)
{
if(number[i] != 0)
std::cout << number[i];
}
std::cout << std::endl;
}
int main() {
int n = 4;
int p = 4;
std::vector<int> num4(n);
std::fill(num4.begin(), num4.end(), 0);
while(increment_basep(num4, p))
{
print_vect(num4);
}
return 0;
}
The increment return whether or not the computation has overflown. When we overflow we know we need to stop.
First solution it comes my mind is that on every loop to put in a buffer and finally to print all the buffers.
I think there are some other ingenious methods
for(int i = 0; i < 4; i++){
put in buffer1 rowNo[i]
for(int j = 0; j < 4; j++){
put in buffer2 rowNo[i],rowNo[j]
for(int k = 0; k < 4; k++){
put in buffer3 rowNo[i],rowNo[j],rowNo[k]
for(int l = 0; l < 4; l++){
put in buffer4 rowNo[i],rowNo[j],rowNo[k],rowNo[l],endl.
}
}
}
}
print(buffer1);
print(buffer2);
print(buffer3);
print(buffer4);
The following is the simplest code I came up with. There has to be a more direct way of doing this though...
It basically introduces a "ghost" index -1, corresponding to an empty place in a number. The ternary operators in the loops conditions are there to avoid duplicates.
int main()
{
int N = 4;
int rowNo[4] = {1, 2, 3, 4};
for (int i = -1; i < N; i++)
for (int j = (i > -1 ? 0 : -1); j < N; j++)
for (int k = (j > -1 ? 0 : -1); k < N; k++)
for (int l = (k > -1 ? 0 : -1); l < N; l++)
{
if (i > -1) std::cout << rowNo[i] << '.';
if (j > -1) std::cout << rowNo[j] << '.';
if (k > -1) std::cout << rowNo[k] << '.';
if (l > -1) std::cout << rowNo[l];
std::cout << std::endl;
}
}
It can of course be generalized to an array of arbitraty size, possibly with some code generation script.
Related
So I have array A and B, two of them contain random numbers and I need to write in the C array initially even numbers of A and B and then odd. I have made this wtih vector but I wonder if there is other way to do it like in Javascript there are methods like .unshift(), .push() etc
#include<iostream>
#include<vector>
using namespace std;
int main() {
const int n = 4;
int A[n];
int B[n];
vector<int>C;
for (int i = 0; i < n; i++)
{
A[i] = rand() % 10;
cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; i++)
{
B[i] = rand() % 30;
cout << B[i] << " ";
}
for (int i = 0; i < n; i += 1)
{
if (A[i] % 2 == 0)
{
C.push_back(A[i]);
}
if (B[i] % 2 == 0)
{
C.push_back(B[i]);
}
}
for (int i = 0; i < n; i++)
{
if (A[i] % 2 != 0)
{
C.push_back(A[i]);
}
if (B[i] % 2 != 0)
{
C.push_back(B[i]);
}
}
cout << endl;
for (int i = 0; i < C.size(); i++)
cout << C[i] << " ";
}
I would suggest interleaving A and B initially:
for (int i = 0; i < n; i += 1)
{
C.push_back(A[i]);
C.push_back(B[i]);
}
And then partitioning C into even and odd elements:
std::stable_partition(C.begin(), C.end(), [](int i) { return i % 2 == 0; });
vector::push_back is the simplest way to have a collection that grows as you add things to the end.
Since you have fixed size for A and B, you could make them primitive arrays instead, which is what you have done. But for C you don't know how long it will be, so a collection that has a changeable size is appropriate.
You can use std::array, if you know the size you need in compile time. You can then add using an iterator.
#include<vector>
using namespace std;
int main() {
const int n = 4;
int A[n];
int B[n];
std::array<int, n+n>C; // <-- here
auto C_it = C.begin(); // <-- here
for (int i = 0; i < n; i++)
{
A[i] = rand() % 10;
cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; i++)
{
B[i] = rand() % 30;
cout << B[i] << " ";
}
for (int i = 0; i < n; i += 1)
{
if (A[i] % 2 == 0)
{
*C_it++ = A[i]; // <-- here
}
if (B[i] % 2 == 0)
{
*C_it++ = B[i];
}
}
for (int i = 0; i < n; i++)
{
if (A[i] % 2 != 0)
{
*C_it++ = A[i];
}
if (B[i] % 2 != 0)
{
*C_it++ = B[i];
}
}
cout << endl;
for (int i = 0; i < C.size(); i++)
cout << C[i] << " ";
}
Alternatively if you want to be more safe you can hold the next unwritten index and access elements with C.at(last++) = A[i], which checks for out-of-bounds and throws an exception instead of UB.
well you don't to change much.
first of declare C array as int C[n+n]; and declare a variable for incrementing through c array as int j=0;
and in if statements of loops do this C[j]=A[i]; j++; for first if and C[j]=B[i]; j++; for the second if statements
int main() {
const int n = 4;
int A[n];
int B[n];
int C[n+n];
int j=0;
for (int i = 0; i < n; i++)
{
A[i] = rand() % 10;
cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; i++)
{
B[i] = rand() % 30;
cout << B[i] << " ";
}
for (int i = 0; i < n; i += 1)
{
if (A[i] % 2 == 0)
{
C[j]=A[i];
j++;
}
if(B[i]%2==0){
C[j]=B[i];
j++;
}
}
for (int i = 0; i < n; i++)
{
if (A[i] % 2 != 0)
{
C[j]=A[i];
j++;
}
if (B[i] % 2 != 0)
{
C[j]=B[i];
j++;
}
}
j=0;
cout << endl;
for (int i = 0; i < C[].lenght(); i++)
cout << C[i] << " ";
}
Can't use libraries and other methods.
As you can see my program finds the repeated numbers and print it but I need to print the numbers just once.
As example if entered:
7 1 1 2 1 2 2 9
It should print
1 2
In case there is no any repeated number:
7 1 2 3 4 5 6 7
There should not be any output!
Also note, that the first number is the length of array:
#include <iostream>
int main()
{
unsigned size;
std::cin >> size;
int* myArray = new int[size];
for (int i = 0; i < size; i++) {
std::cin >> myArray[i];
}
for (int i = 0; i < size; i++) {
bool found = false;
for (int j = 0; j < i && !found; j++) {
found = (myArray[i] == myArray[j]);
}
if (!found) {
std::cout << myArray[i] << " ";
}
}
delete []myArray;
}
The easiest approach would probably be to use a set, but I'm not sure if that's allowed under the "can't use other libraries" rule.
Using just arrays, for each item you could iterate over all the items before it, and only print it if it wasn't found there:
for (int i = 0; i < size; i++) {
bool found = false;
for (int j = 0; j < i && !found; j++) {
found = (myArray[i] == myArray[j]);
}
if (!found) {
cout << myArray[i] << " ";
}
}
The first occurrence of a repeated number has no occurrences before it and at least one after it.
This is reasonably easy to detect:
for (int i = 0; i < size; i++) {
bool before = false;
for (int j = 0; j < i && !before; j++) {
before = myArray[i] == myArray[j];
}
if (!before) {
bool after = false;
for (int j = i + 1; j < size && !after; j++) {
after = myArray[i] == myArray[j];
}
if (after)
{
cout << myArray[i] << " ";
}
}
}
Instead of two bools as the other user suggested I would use the counter basically doing the same thing but with one variable. The trick is to check if you have already had the number you are checking right now before so that you wouldn't print it again.
And then to check the rest of the list for duplicates.
#include <iostream>
int main()
{
unsigned size;
std::cin >> size;
int* myArray = new int[size];
for (int i = 0; i < size; i++) {
std::cin >> myArray[i];
}
for (int i = 0; i < size; i++) {
int count = 0;
//check if the number has already been found earlier
for (int j = 0; j < i && !count; j++) {
if(myArray[i] == myArray[j]) count++;
}
//check the rest of the array for the repeated number
if (!count) {
for (int j = i; j < size; j++) {
if(myArray[i] == myArray[j]) count++;
}
}
//print if repeated
if (count > 1) {
std::cout << myArray[i] << " ";
}
}
delete []myArray;
}
I did the same question a while ago, but It got closed. I'll try to express myself better this time.
I want to make an algorithm that can solve a sudoku puzzle, looks like It is working, but in the backtracking part(where I need to go back to a previous recursion to test a different value), It doesn't, showing a "segment fault" error.
Also, I use "0" as a blank space, so that's why "if (!board[i][j]) //do something"
// Solves the game
vector<vector<int>> sudokuSolver(vector<vector<int>> board) {
if (isFull(board)) {
return board;
}
bool found = false;
int line = 0;
int col = 0;
for (int i = 0; i <= 8; i++) {
for (int j = 0; j <= 8; j++) {
if (!board[i][j]) {
line = i;
col = j;
found = true;
break;
}
}
if (found) break;
}
vector<int> possibleNumbers = possibilities(board, line, col);
cout << '\n';
printBoard(board);
cout << '\n';
cout << line << ' ' << col << '\n';
cout << '\n';
printVector(possibleNumbers);
int size = possibleNumbers.size();
for (int k = 0; k < size; k++) {
board[line][col] = possibleNumbers[k];
cout << k << '\n';
sudokuSolver(board);
// the code doesn't pass to the next cout. Why?
cout << "it doesn't reach here :/" << '\n';
}
cout << "backtracking!!" << '\n';
board[line][col] = 0;
cout << "agora:" << '\n';
printBoard(board);
}
I put some "couts" to help me visualize the problem. The "backtracking!!" cout is working properly, but the "it doesn't reach here" cout is not. I thought that, after the code realize It doesn't have possible solutions, It would simply go back to the last recursion, but It's not, giving "segmento fault" error. I don't understand
for (int k = 0; k < size; k++) {
board[line][col] = possibleNumbers[k];
cout << k << '\n';
sudokuSolver(board);
// the code doesn't pass to the next cout. Why?
cout << "it doesn't reach here :/" << '\n';
}
Am I not getting something?
Also, if It's not clear, "isFull" checks if the board is full (base case, game is complete), and possibilities checks the number possibilities of a single cell
Thanks in advance. I guess the details are way better this time, hope I did It right
Edit: The extra couts are ways of showing me where the code is. They are not important for the algorithm itself
Final edit: I did it! Thanks you all. For anyone who wants the full code, here it is:
#include <bits/stdc++.h>
using namespace std;
bool gameRunning = true;
void printBoard(vector<vector<int>> board) {
for (int i = 0; i <= 8; i++) {
for (int j = 0; j <= 8; j++) {
cout << board[i][j] << ' ';
}
cout << '\n';
}
cout << '\n';
}
void printVector(vector<int> v) {
for (auto x : v) {
cout << x << ' ';
}
cout << '\n';
cout << '\n';
}
// Checks if the board is full, deciding if the game is already won
bool isFull(vector<vector<int>> board) {
for (int i = 0; i <= 8; i++) {
for (int j = 0; j <= 8; j++) {
if (!board[i][j]) return false;
}
}
return true;
}
// Generates all number possibilites for a given cell on the board
vector<int> possibilities(vector<vector<int>> board, int i, int j) {
bitset<9> p;
for (int i = 1; i <= 9; i++) {
p[i] = 1;
}
//horizontal check
for (int col = 0; col <= 8; col++) {
if (board[i][col]) {
p[board[i][col]] = 0;
}
}
//vertical check
for (int line = 0; line <= 8; line++) {
if (board[line][j]) {
p[board[line][j]] = 0;
}
}
//mini-square check
int linesquare = (i / 3) * 3;
int colsquare = (j / 3) * 3;
for (int l = linesquare; l <= linesquare + 2; l++) {
for (int c = colsquare; c <= colsquare + 2; c++) {
if (board[l][c]) {
p[board[l][c]] = 0;
}
}
}
vector<int> numberPossibilities;
for (int k = 1; k <= 9; k++) {
if (p[k]) numberPossibilities.push_back(k);
}
return numberPossibilities;
}
// Solves the game
void sudokuSolver(vector<vector<int>> board) {
if (isFull(board)) {
printBoard(board);
gameRunning = false;
}
if (gameRunning) {
bool found = false;
int line = 0;
int col = 0;
for (int i = 0; i <= 8; i++) {
for (int j = 0; j <= 8; j++) {
if (!board[i][j]) {
line = i;
col = j;
found = true;
break;
}
}
if (found) break;
}
vector<int> possibleNumbers = possibilities(board, line, col);
int size = possibleNumbers.size();
for (int k = 0; k < size; k++) {
board[line][col] = possibleNumbers[k];
sudokuSolver(board);
}
board[line][col] = 0;
}
}
int main() {
/*
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
*/
vector<vector<int>> v;
for (int i = 0; i < 9; i++) {
vector<int> hold;
for (int j = 0; j < 9; j++) {
int a;
cin >> a;
hold.push_back(a);
}
v.push_back(hold);
}
cout << '\n';
sudokuSolver(v);
return 0;
}
Bye, have a great day
So I'm working on a code to find the Union, Intersection and Difference between two arrays. I'm done with the Union and Intersection but i just can't figure out the difference(A - B) ,For example A={1,3,6,9,7,9} , B={2,3,-2,9} i want to get A - B = { 1,6,7,0} .
I don't want to use any other library except iostream.
This is my code so far.
/* Prints union of A[] and B[]
SizeA is the number of elements in A[]
SizeB is the number of elements in B[] */
cout << "\nUnion of A and B = "; //
i = 0; j = 0;
while (i < SizeA && j < SizeB)
{
if (A[i] < B[j])
cout << A[i++] << " ";
else if (B[j] < A[i])
cout << B[j++] << " ";
else
{
cout << B[j++] << " ";
i++;
}
}
/* Print remaining elements of the larger array */
while (i < SizeA)
cout << A[i++] << " ";
while (j < SizeB)
cout << B[j++] << " ";
cout << "\nIntersection of A and B = ";
for (i = 0; i < SizeA; i++) //for loop to calculate the intersection of A and B.
{
for (j = 0; j < SizeB; j++)
{
if (A[i] == B[j])
{
cout << A[i] << " ";
}
}
}
This is very bad practice because it's not general, not using a clean function and using plain old arrays but I assumed that you are beginner and have to do it in this way
#include <iostream>
int main()
{
int A [] ={1,3,6,9,7}, Asz = 5, B [] ={2,3,-2,9}, Bsz = 4;
std::cout << "\nThe difference is {";
for( int i = 0; i < Asz; ++i){
int temp = A[i];
bool notFound = true;
for(int j = 0; j < Bsz; ++j){
if(temp == B[j]) notFound = false;
}
if(notFound)
{
if(i < Asz - 1) std::cout << temp << ", ";
else std::cout << temp ;
}
}
std::cout << "}";
}
The way I prefer
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> A = {1,3,6,9,7, 0} , B={2,3,-2,9}, C;
std::sort(A.begin(), A.end());
std::sort(B.begin(), B.end());
std::set_difference(A.cbegin(), A.cend(), B.cbegin(), B.cend(), std::back_inserter(C), std::less<int>{});
for(auto const & el : C)
std::cout << el << ", ";
}
If you could save the intersection, you could then just check each element of A and B against the elements of the intersection. Otherwise, you need two for-loops:
cout << "\nDifference of A and B = ";
for (i = 0; i < SizeA; i++) //for loop to calculate the intersection of A and B.
{
bool found = false
for (j = 0; j < SizeB; j++)
{
if (A[i] == B[j])
{
found = true;
}
}
if (!found) {
cout<<A[i]<<" ";
}
}
for (i = 0; i < SizeB; i++)
{
bool found = false
for (j = 0; j < SizeA; j++)
{
if (B[i] == A[j])
{
found = true;
}
}
if (!found) {
cout<<B[i]<<" ";
}
}
Edit: Never mind, i got the definition of difference wrong (thought it was (A-B) + (B-A)), so only the first for-loop is needed, and there's no point saving the intersection.
I have an array in c++ with unknown entries (minimum 6) i need a for loop (probably includes a few for loop) which makes 3 groups of 2. I don't care about order of groups or in the group. And tricky part is that double counting is not allowed. I tried something like this but it is obviously triple counts...
for(int i = 0; i < nArray - 1; i++)
{
for(int j = i+1; j < nArray; j++)
{
for(int k = 0; k < nArray - 1; k++)
{
for(int l = k+1; l < nArray; l++)
{
for(int m = 0; m < nArray - 1; m++)
{
for(int n = m+1; n < nArray; n++)
{
if(k!=i && k!=j && l!=i && l!=j && m!=i && m!=j && n!=i && n!=j && m!=k && m!=l && n!=k && n!=l)
{
std::cout << array[i] << "-" << array[j] << std::endl << array[k] << "-" << array[l] << std::endl << array[m] << "-" << array[n] << std::endl << std::endl;
}
}
}
}
}
}
}
Edit: for example let our array is {1,2,3,4,5,6} which has 6 entries. Output should look like:
12-34-56
12-35-46
12-36-45
13-24-56
13-25-46
13-26-45
14-23-56
14-25-36
14-26-35
15-23-46
15-24-36
15-26-34
16-23-45
16-24-35
16-25-34
But there should not be 12-43-56 or 34-12-56 since there is 12-34-56.
And for the array {1,2,3,4,5,6,7}
12-34-56
12-34-57
12-34-67
12-35-46
12-35-47
12-35-67
...
and so on.
Make it recursively. Choose two elements from the array to form a pair, remove them from the array and call the same function on reduced array. That way you'll have only two nested loops and you'll cover the whole array.
Alternatively, use additional array with information, which elements were already used instead of removing them from original array.
void GeneratePairs(std::vector<int> & values, std::vector<bool> & used, std::vector<std::pair<int, int>> & results)
{
int i = 0;
while (i < values.size() && used[i])
i++;
if (i != values.size())
{
used[i] = true;
for (int j = i + 1; j < values.size(); j++)
{
if (!used[j])
{
used[j] = true;
std::pair<int, int> tmp(values[i], values[j]);
results.push_back(tmp);
GeneratePairs(values, used, results);
results.pop_back();
used[j] = false;
}
}
used[i] = false;
}
else
{
for (int i = 0; i < results.size(); i++)
{
printf("%d,%d", results[i].first, results[i].second);
if (i < results.size() - 1)
printf("-");
}
printf("\n");
}
}
// (...)
int main(int argc, char * argv)
{
std::vector<int> input;
input.push_back(1);
input.push_back(2);
input.push_back(3);
input.push_back(4);
input.push_back(5);
input.push_back(6);
std::vector<bool> used;
for (int i = 0; i < input.size(); i++)
used.push_back(false);
std::vector<std::pair<int, int>> results;
GeneratePairs(input, used, results);
getchar();
}
I just want to mention I have figured out the simple detail which solves this problem:
for(int i=0;i<input.size();i++)
{
for(int j=i+1;j<input.size();j++)
{
for(int k=i+1;k<input.size();k++)
{
for(int l=k+1;l<input.size();l++)
{
if( j==k || j==l) continue;
for(int m=k+1;m<input.size();m++)
{
for(int n=m+1;n<input.size();n++)
{
if( m==j || m==l || n==j || n==l) continue;
std::cout << input[i] << input[j] << "-" << input[k] << input[l] << "-" << input[m] << input[n] << std::endl;
}
}
}
}
}
}