How to solve 8 queens 1D array with brute force? - c++

I was given an assignment to modify an 8 Queens program to use a 1D array and to use brute force (already did backtracking). I've come up with the following code:
#include <cmath>
#include <iostream>
using namespace std;
bool ok(int board[8]){
for(int j = 0; j <= 7; j++){ //check for repeating digits
cout << "ok loop 1"<<endl;
for (int k = 0; k <= 7; k++)
{
cout << "ok loop 2"<<endl;
if (board[k] = board[j]){ return false; }
}
}
for(int c = 7; c >= 0; c--){ //check if position is safe
cout << "ok loop 3"<<endl;
//int r = 0;
for(int i = 1; i <= c; i++){
cout << "ok loop 4"<<endl;
if(board[c-i] == c)
return false;
else if ((board[c]-i)>0 && board[c-i]-i == 1)
return false;
else if ((board[c]+i)<=7 && board[c-i]+i == 1)
return false;
} // for loop
} // for loop
return true;
} // ok
void print(int board[8], int c){
cout << "Solution " << c << ": " << endl;
for(int i = 0; i < 8; i++){
{
cout << board[i] <<" ";
}
}
cout << endl;
}
int main ()
{
int b[8]={0}; //initialize the array
int count = 0;
for(b[0]=0; b[0]<8; b[0]++)
for(b[1]=0; b[1]<8; b[1]++)
for(b[2]=0; b[2]<8; b[2]++)
for(b[3]=0 ; b[3]<8; b[3]++)
for(b[4]=0; b[4]<8; b[4]++)
for(b[5]=0; b[5]<8; b[5]++)
for(b[6]=0; b[6]<8; b[6]++)
for(b[7]=0; b[7]<8; b[7]++)
if(ok(b))
{
count++;
print(b, count);
}
system("PAUSE");
return 0;
}
It keeps looping forever and I am not sure why. Would anyone mind helping me?

There's a few things that could be improved:
If you passed a reference to a constant array of eight chars to ok() instead of just a pointer to non-const ints, the compiler could have told you about one of the issues.
How many different positions can a queen have? I'd say 64, though your code suggests eight. I'd start with documenting the actual meaning of variables and constants throughout your code, because you seem to be confused there yourself.
You check if board[x] is board[y], but with x and y being equal, and from that you claim that there are repeating digits.
You make a difference between the different queens. In other words, your program will find all permutations of how the queens could be positioned on the same eight positions. This is not incorrect, but inefficient. If you fix the number of positions, that will make a noticeable difference.

Related

Random numbers in the output

I've been coding in c++ for over a day now and I am currently stuck on this particular problem. I want to enter a integer and produce every prime numbers that are smaller than the given integer but the output always has random numbers that aren't prime. Here's the code:
#include <iostream>
#include <math.h>
using namespace std;
int check(int x){
bool prime = true;
if (x <= 1){
prime = false;
return 0;
}
for (int i = 2; i < x; i++){
if (x % i == 0){
prime = false;
return 0;
}
}
if (prime = true){
return x;
}
}
int main(){
int r;
cout << "Enter range: ";
cin >> r;
int primes[r];
int n = 0;
for (int i = 0; i < r; i++){
if (check(i) != 0){
primes[n] = i;
n++;
}
else{
}
}
for (int i : primes){
cout << i << endl;
}
}
Help me fix this problem. Thanks.
The problem in your code is that you check numbers in the range [0,r] and assume to find r prime numbers in that range. Thats of course not correct. For example when in the range [0,r] there are p prime numbers then your output will print the p prime numbers and then r-p uninitialized values (thats undefined behavior, the output of your code could be anything).
Change the last loop to
for (int i=0; i<n; ++i) {
cout << primes[i] << endl;
}
To see only entries of primes that you actually assigned a value in the loop before.
Also please consider that int primes[r]; is not standard C++. See here: Why aren't variable-length arrays part of the C++ standard?. Use std::vector for dynamically sized arrays. Actually in your code you do not need an array at all. You can simply print the prime numbers in the same loop where you check them:
if (check(i) != 0) { std::cout << i << "\n"; }
Moreover, your check is a little too complicated. You are using a flag that you don't need. The last if is wrong, because prime = true is assignment not comparison. However, that doesnt really matter because at that point prime is always true (if not you already returned), and prime=true does evaluate to true. The function can look like this:
int check(int x){
if (x <= 1){
return 0;
}
for (int i = 2; i < x; i++){
if (x % i == 0){
return 0;
}
}
return x;
}
This will also prevent the compiler from issuuing a warning for not returning from all branches. Note that you only need to check factors <= sqrt(x) because when there is a factor bigger than that there must also be a factor smaller than that.

Trouble Sort Google CodeJam 2018 Qualifiers

I am trying to improve my programming skills by solving couple of Code Jam questions. I have been stuck for a while on the "Trouble Sort" question from the Qualifier Rounds in 2018. My code produces the expected output with the example input in my console, but the online judge return "Wrong Answer".
Apparently Trouble sort is just like bubble sort, except instead of comparing the ith and i+1th elements, it compares the ith and i+2th elements and if the former is greater than the latter then the elements are swapped. The question says that this algorithm is flawed as arrays like 897 after trouble sort will return 798, which isn't sorted either. The task is to check if for a given list of integers, trouble sort is able to successfully sort the array or if it isn't then which is the index value of the first element that is out of place.
My code inputs the number of tests t and the size of integer list. Then I make a copy of it and put one copy through bubble sort and the other through trouble sort. Then I compare them element wise and if an index which has the two elements as different integers is found, it is outputted. I'm not sure what I am doing wrong here.
#include<iostream>
#include<vector>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
void swapVal(int& a, int& b)
{
int t = a;
a = b;
b = t;
}
int main()
{
int t;
cin >> t;
for (int i = 1; i <= t; i++)
{
int n;
cin >> n;
vector<int> bs(n);
vector<int> ts(n);
for (int i = 0; i < n; i++)
{
cin >> bs[i];
ts[i] = bs[i];
}
//bubbleSort(bs, n);
{
bool bsSorted = false;
while (!bsSorted)
{
bsSorted = true;
for (int i = 0; i < n - 1; i++)
{
if (bs[i] > bs[i + 1])
{
swapVal(bs[i], bs[i + 1]);
bsSorted = false;
}
}
}
}
//troubleSort(ts, n);
{
bool tsSorted = false;
while (!tsSorted)
{
tsSorted = true;
for (int i = 0; i < n - 2; i++)
{
if (ts[i] > ts[i + 2])
{
swapVal(ts[i], ts[i + 2]);
tsSorted = false;
}
}
}
}
bool same = true;
int minidx = 0;
for (int i = 0; i < n; i++)
{
if (bs[i] != ts[i])
{
same = false;
minidx = i;
break;
}
}
if (same == true)
{
cout << "Case #" << i << ": OK" << endl;
}
else if (same == false)
{
cout << "Case #" << i << ": " << minidx;
}
}
}
I am expecting the judge to give me a tick of approval, but instead it is repeatedly returning "Wrong Answer". What am I doing wrong here?
The algorithm looks correct to me. I noticed that in the false case you seem to be missing the newline. So two consecutive false statements will be on the same line.
cout << "Case #" << i << ": " << minidx<<'\n';
Might solve your problem.
Few remarks:
if (same == true) is equivalent to if(same) and if (same == false) to if(!same).
There's already std::swap.
Some people might not like nested for loops having equally named variables - the nested variable will hide the outer one.

Ambiguous errors when trying to compile C++ code

When trying to compile the code below I get three errors.
'iterator_category': is not a member of any direct or indirect base class of 'std::iterator_traits<_InIt>'
'_Iter_cat_t' : Failed to specialize alias template
type 'unknown-type' unexpected
I'm quite new to C++ and have gone over the code many times changing snippets but nothing helps. Any help deciphering these error messages is much appreciated.
#include "../../std_lib_facilities.h"
class Puzzle {
public:
vector<char> letters;
Puzzle(int my_size);
void generate(void);
void enter_letters(void);
void feedback(Puzzle puzzle);
private:
int size = 4;
};
Puzzle::Puzzle(int my_size)
{
size = my_size;
}
//Generate size unique letters for the letters array.
void Puzzle::generate(void)
{
for (int i = 0; i < size; ++i) {
char rand = randint(26) - 1 + 'a';
while ((find(letters[0], letters[size], rand) != letters[size])) {
rand = randint(26) - 1 + 'a';
}
letters[i] = rand;
}
}
//Let the user enter size unique letters.
void Puzzle::enter_letters(void)
{
cout << "Enter four different letters seperated by spaces:\n";
for (int i = 0; i < size; ++i) {
char letter;
cin >> letter;
letters[i] = letter;
}
}
//Tell the user how many bulls and cows they got.
void Puzzle::feedback(Puzzle puzzle)
{
int cows = 0, bulls = 0;
for (int i = 0; i < size; i++) { //input
for (int j = 0; j < size; ++j) { //puzzle
if (i == j && letters[i] == puzzle.letters[j]) {
++bulls;
break;
}
else if (letters[i] == puzzle.letters[j]) {
++cows;
break;
}
}
}
cout << "Bulls: " << bulls << "\nCows: " << cows << "\n";
}
//Seed the random function.
void seed(void)
{
int sum = 0;
cout << "Enter a random string of characters:\n";
string str;
cin >> str;
for (char& c : str)
sum += c;
srand(sum);
}
int main()
{
constexpr int GAME_SIZE = 4;
seed();
Puzzle puzzle(GAME_SIZE);
puzzle.generate();
Puzzle input(GAME_SIZE);
input.enter_letters();
while (puzzle.letters != input.letters) {
input.feedback(puzzle);
input.enter_letters();
}
cout << "Congragulations, you did it!\n";
keep_window_open();
return 0;
}
You're using find() wrong.
find(letters[0], letters[size], rand)
Your letters is a std::vector. You're passing the first value in the vector, and the last value in the vector, to std::find.
This is actually undefined behavior, since size is not always the actual size of your letters vector. So, you'll be getting a random crash, as an extra bonus here in addition to your compilation error.
The first two parameters to std::find are iterators of a sequence to search, and not values.
This should be:
find(letters.begin(), letters.end(), rand)
Also, your overall algorithm is broken. Once letters reaches a certain size, your random number generating code will take ... a significant time to find some new letter to add to letters, that's not used already. Once letters manages to acquire all 26 characters of the alphabet, this will turn into an infinite loop. But that would be a different question...

Splitting an array at a given value

Hello I am trying to split an array any time there is a negative value (excluding the negative value) and am a bit stuck at the moment. I tried an approach as seen in my code but I am not getting the desired output.
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
string line;
string filename;
int n,length;
std::vector<int>arr1;
fstream file("t1.txt");
if(file.is_open())
{
while(file >> n)
arr1.push_back(n);
for(int i =0; i < (int)arr1.size(); i++)
cout << arr1.at(i);
}
cout << endl;
int* arr2 = &arr1[0];
int arr3[arr1.size()/2];
int arr4[arr1.size()/2];
for(int i = 0; i < arr1.size(); i++)
{
cout << arr2[i];
}
for (int i =0; i < arr1.size(); i++)
{
if(i == -1)
break;
else
arr3[i] = arr2[i];
}
return 0;
}
The main problem is here:
int arr3[arr1.size()/2];
int arr4[arr1.size()/2];
This doesn't compile, and can be replaced with
std::vector<int> arr3; arr3.reserve(arr1.size() / 2);
std::vector<int> arr4; arr4.reserve(arr1.size() / 2);
I've added the "reserve" function so that the program doesn't have to allocate memory over and over in the loop.
Next, you are checking i in your loop, and your i loops from 0 to arr1.size() (which is unsigned so can't be negative) therefore i will never be negative.
What you really wanna check is what is in the arr1 vector at "i" position, and you can do so with the [] operator like
for (int i =0; i < arr1.size(); i++)
{
if (arr1[i] >= 0) //if the value is positive, we push it inside our arr3 vector
arr3.push_back(arr1[i]);
else
{
i++; //skip negative value
//
while (i < arr1.size())
{
if (arr1[i] > 0)
arr4.push_back(arr1[i]);
i++;
}
//
//or
//insert all the elemenents we haven't processed yet in the arr4 vector
//this code assumes those elements are positive values
//arr4.insert(arr4.begin(), arr1.begin() + i, arr1.end());
//break;
}
}
Of course this could be done in a different way, like instead of creating 2 vectors, you could just use the one you have generated already.
Hope this helps.
There are several problems in your code
you should not access the vector's data this way unless you really need to
you prepare arrays with predefined size without knowing where to expect the negative values
you do not assign anything to your array 4
you check the index for being negative, not the value
according to your text there could be several negative values leading to multiple result-arrays. You seem to be prepared for only two.
Here is some code that actually splits when encountering negative values:
std::vector<vector<int> > splitted;
for (int i = 0; i < arr1.size(); ++i)
{
if (i ==0 or arr1[i] < 0)
splitted.push_back(std::vector<int>());
if (arr1[i] >= 0)
splitted.back().push_back(arr1[i]);
}
Testing it:
for (int i = 0; i < splitted.size(); ++i)
{
for (int k = 0; k < splitted[i].size(); ++k)
{
std::cout << splitted[i][k];
}
if (splitted[i].empty())
std::cout << "(emtpy)";
std::cout << '\n';
}
Using the following test input
1 2 3 -1 1 -1 -1
You get the following output:
123
1
(emtpy)
(emtpy)

C++ Bubble Sort (Ascending) function not returning results

I'm trying to use a bubble sort in a function instead of inline, and I seem to be having an issue with it returning results. As in currently, it's giving me no results at all. Here is my code that I have written up so far...
Basically, the user tells the program how many numbers they want to enter (up to 20 allowed) then it inputs those into an array in the order entered. Then it prints the values entered, sorts, and prints the sorted values. Or at least that's what is supposed to happen.
Thanks for the help in advance!
#include <iostream>
using namespace std;
int vault[20] = {}; // array to store the 20 values
int val = 0; // variable to pass values to the array
int amt = 0; // variable to get the amount of numbers the user is going to enter
int i = 0; // loop counter
// Bubble Sort Function Prototype
void bubble (int (&vault)[20], int val);
// Bubble Sort Function
void bubble (int (&vault)[20], int val)
{
int swap = 1; // flag used to indicate swaps occuring
int temp = 0; // holder variable
int x = 0; // loop counter
int y = 0; // second loop counter
for (x = 0; (x < val) && (swap = 1); x++)
{
swap = 0;
for (y = x+1; y < val; y++)
{
if (vault[x] > vault[y])
{
temp = vault[x];
vault[x] = vault[y];
vault[y] = temp;
swap = 1;
}
}
}
return;
}
int main()
{
cout << "Welcome to the Bubble Sort exe\n\n" << endl;
cout << "Please enter in the amount of numbers you would like to enter: ";
cin >> amt;
cout << "Please enter the values you wish to enter: ";
for(i = 0; i < amt; i++)
{
cin >> vault[i];
}
cout << "The values you entered in order are: ";
for (i = 0; i < amt; i++)
{
cout << vault[i] << ' ';
}
cout << "\n\nLet me just sort that for you!" << endl;
bubble(vault, val);
cout << "\n\nHere are the values in ascending order:\n" << endl;
for (i = 0; i < val; i++)
{
cout << vault[i] << ' ';
}
system("pause");
return 0;
}
What you've written isn't a classic bubble-sort algorithm. Bubble-sort iterates through the entire array each time, swapping elements with their immediate successor, doing this over-and-over until no more swaps occur.
In the traditional implementation, there are no "nested for-loops." There's one for-loop nested in a while or repeat-until structure.
The algorithm is called "bubble" because the lowest value "bubbles up" to the top ... with roughly the speed of a bubble trapped in very viscous oil.
(Compare with, say, the Shell sort, which is a slight-seeming alteration to Bubble that makes a tremendous difference. And to the quintessential and definitive Quicksort.)
Mathias pointed me in the correct direction. I had forgotten to initialize the variable 'val'. When I corrected that, it works perfectly.
As for everybody saying that this is not a classic bubble sort, I have seen this exact form on multiple sites and on slides from my prof., what is wrong with this way of writing it?
I'm trying this now instead, and it's completely failing on me (sigh):
void bubble (int (&vault)[20], int val)
{
bool swap = true; // flag used to indicate swaps occuring
int temp = 0; // holder variable
int x = 0; // loop counter
int y = 0; // second loop counter
while (swap = true)
{
swap = false;
x++;
for (y = 0; y < val - x; y++)
{
if (vault[y] > vault[y+1])
{
temp = vault[y];
vault[y] = vault[y+1];
vault[y+1] = temp;
swap = true;
}
}
}
}