I am stuck with my solution to problem 4 of Project Euler, I have the following code which should work and it does iterate through the solution to the problem as I have researched and discovered (993*913):
// Michael Clover
// Project Euler
// Problem 4
/* A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.
Find the largest palindrome made from the product of two 3-digit numbers. */
#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
using namespace std;
bool achieved = false; // change to true when the palindrome is found
string string_conversion = "";
string first_half = ""; // first half of string
string second_half = ""; // second half of string
stringstream conversion; // use this to convert integers to strings
int check(string first_half, string second_half) {
if (first_half.compare(second_half) == 0) {
achieved = true;
return 0;
}
else {
return 0;
}
return 0;
}
int convert(int result) {
char temp;
conversion << result;
conversion >> string_conversion;
if (string_conversion.size() == 6) {
temp = string_conversion.at(0);
//cout << "temp = " << temp << endl;
first_half+=(temp);
temp = string_conversion.at(1);
//cout << "temp = " << temp << endl;
first_half+=(temp);
temp = string_conversion.at(2);
//cout << "temp = " << temp << endl;
first_half+=(temp);
temp = string_conversion.at(5);
//cout << "temp = " << temp << endl;
second_half+=(temp);
temp = string_conversion.at(4);
//cout << "temp = " << temp << endl;
second_half+=(temp);
temp = string_conversion.at(3);
//cout << "temp = " << temp << endl;
second_half+=(temp);
//cout << first_half << second_half << endl;
check(first_half, second_half);
}
//if (string_conversion.size() == 5) {
//cout << "The size of the string is 5" << endl;
//exit(1);
//}
string_conversion = "";
cout << first_half << endl;
cout << second_half << endl;
first_half.clear();
second_half.clear();
conversion.clear();
conversion.str("");
//cout << "conversion: " << conversion << endl;
return 0;
}
int iterate(int operator_one, int operator_two) { // takes two numbers and iterates through them, each time it is iterated, the result is passed to the convert function to convert to string
int two = operator_two;
for (int i = operator_one; i > 100; i--) {
int result = i * two;
cout << i << "x" << two << endl;
convert(result);
}
return 0;
}
int main() { // Use the stringstream to convert the numerical values into strings which you can then use to check if they are palindromes
int operator_one = 999;
int operator_two = 999;
while (achieved == false) {
for (int i = operator_two; i > 100; i--) {
iterate(999, i);
}
}
cout << "The largest palindrome made from the product of two 3-digit numbers is: " << string_conversion << endl;
return 0;
}
This program iterates through all of the numbers through 999x999 downwards and then splits the 6-digit numbers into two strings with the second half of the result being arranged from back to front. As shown in the console using cout << during runtime, the program tries 993*913 and both the second_half string and the first_half string contain 906. What I thought the program should then do is perform the check(string first_half, string second_half) function after iterating this and decide that both of the strings match (which should according to various sources return 0) this should then initiate the if statement within check() and set the boolean achieved to true ending the program within the main statement and printing the result before exiting the program. It does not do this however and this is my problem. Thank you for any and all help.
Leaving aside some other issues I see in this code, I think your termination problem is because you only check achieved after the outer loop in main() is finished. So the inner loop (iterate()) will continue until operator_one falls below 100 and then the outer loop will continue until operator_two falls below 100 before you actually check your termination condition.
Related
I've been working on the Euler 29 problem for a few days and am having difficulty getting the mpz_t type to work correctly. The objective is to iterate through a^b for values of 2 <= a,b <= 100 and count the nonrepeat values.
Using vector I was able to store the values using pointers in an array like so:
mpz_t a;
mpz_init(a);
vector<mpz_t*> numbers;
numbers.push_back(&a);
However, when running the full program below you can see that after it inserts the first value 4, it doesn't insert any new values. This is because the temp value being compared to rop is not being set to what is already in the array, and instead is set to the value shared by rop.
#include <iostream>
#include <vector>
#include <chrono>
#include "gmp.h"
using namespace std;
int main()
{
auto start = std::chrono::high_resolution_clock::now();
int solution = 0;
bool found = false;
int r = 10;
mpz_t rop;
mpz_init(rop);
mpz_t temp;
mpz_init(temp);
vector<mpz_t*> numbers;
for(int a = 2; a <= 5; a++)
{
for(int b = 2; b <= 5; b++)
{
mpz_ui_pow_ui(rop, a, b);
for(int i = 0; i < numbers.size(); i++)
{
cout << "i: " << i << endl;
cout << "rop: ";
mpz_out_str(stdout,10,rop);
cout << endl;
mpz_set(temp,*(numbers.at(i)));
cout << " temp: ";
mpz_out_str(stdout,10,temp);
cout << endl;
r = mpz_cmp(rop,temp);
cout << " r: " << r << endl << endl;
if(r == 0)
{
found = true;
break;
}
}
if(found == false)
{
numbers.push_back(&rop);
solution++;
cout << "pushed! " << endl << endl;
}
found = false;
}
}
auto done = std::chrono::high_resolution_clock::now();
cout << "Solution: " << solution << endl << endl;
cout << "Program completed in " << std::chrono::duration_cast<std::chrono::milliseconds>(done - start).count() << " milliseconds." << endl;
}
This line of code should be setting temp equal to 4 at the start of the forloop, but instead sets it equal to rop:
mpz_set(temp,*(numbers.at(i)));
Since the problem clearly has to do with the fact I'm using pointers and passing the actual address in memory to store these mpz_t variables, how can I change the code so that it is able to work properly? I'm under the impression using the function mpz_clear(rop) after each push_back to the numbers vector wouldn't work as it releases the address from memory.
I figured out that due to the way mpz_t variables work the mpz_set function does not work with a pointer to mpz_t type variables as a parameter.
Instead, I was able to get the program to work by assigning the mpz_get_str function to a string and pushing that to a vector of strings to check for repeat values.
mpz_t rop;
mpz_init(rop);
char * num;
vector<string> numbers;
num = mpz_get_str(num,10,rop)
numbers.push_back(num);
If the generated random number to look for does not exist in hashtable array, then programm gets stuck in endless loop in function void hashSearch(),
whereas it should just get out of the loop and output that search item is not found. The exact place in code is where these to outputs are:
cout << "stuck in else loop \n"; and cout << "stuck in while loop end \n";.
I've googled around, but can't find similar examples.
#include <iostream>
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
#include <chrono>
using namespace std;
int arr [1000];
int arr2 [1000];
int randArrayInt, n, randSearchItem, searchInt, address, size2;
void printZeroArr();
void linearSentinelSearch();
void printHashArray();
void hashSearch();
int main ()
{
srand (time(nullptr)); //initialize random seed:
n = rand() % 900 + 100; //random integer number from 100 - 1000, length of the array
//n = rand() % 10; // random number in the range 1-10 for sanity tests, length of the array
//randSearchItem = rand() % 10 + 1;
randSearchItem = rand() % 900 + 100; //this is the number to search for
cout << "Array length is " << n << endl;
cout << "[";
for (int i = 0; i <= n; i++)
{
randArrayInt = rand() % 900 + 100;
//randArrayInt = rand() % 10 + 1; // generate random 1-10 number for for sanity tests
arr[i] = randArrayInt; // insert into array position the generated random number
cout<< " " << arr[i]; // print out array element at current loop position
}
cout << " ]\n" << endl;
printZeroArr();
}
void printZeroArr()
{
size2 = n + 1; //length of hashed array
cout << "This is the random key to search for in array: " << randSearchItem << endl;
cout << "This is the size2 length " << size2 << endl;
cout << "This is the hasharray with zeros" << endl;
cout << "[";
for (int i = 0; i <= size2; i++)
{
arr2[i] = 0; // insert into hasharray number 0
cout<< " " << arr2[i]; // print out hasharray element at current loop position
}
cout << " ]\n" << endl;
linearSentinelSearch();
}
void linearSentinelSearch()
{
auto start = std::chrono::high_resolution_clock::now();
arr[n + 1] = randSearchItem;
//cout << "testing arr[n + 1] is " << arr[n + 1] << endl;
int i = 0;
while (arr[i] != randSearchItem) i++;
if (i == n + 1)
cout << "Sentinel search did not found the searchitem in random array" << "\n" << endl;
else
cout << "Searchitem found in array with linearsearch at position " << i << "\n" << endl;
auto finish = std::chrono::high_resolution_clock::now();
chrono::duration<double> elapsed = finish - start;
cout << "Elapsed time: " << elapsed.count() << " s\n";
printHashArray();
}
void printHashArray()
{
//cout << "printing out 'address' value, or the modulo result: " << endl;
//cout << "[";
for (int i = 0; i <= n; i++)
{
address = arr[i] % size2;
//cout << " " << address;
while (arr2[address] != 0)
{
if (address == size2 - 1)
{
address = 0;
} else
{
address++;
}
}
arr2[address] = arr[i];
}
//cout << " ]\n" << endl;
cout << "This is the hasharray with hashitems" << endl;
cout << "[";
for (int i = 0; i <= size2; i++)
{
cout << " " << arr2[i];
}
cout << " ]\n" << endl; hashSearch();
}
void hashSearch()
{
auto start = std::chrono::high_resolution_clock::now();
int searchInt = randSearchItem % size2;
while ((arr2[searchInt] != 0) && (arr2[searchInt] != randSearchItem))
{
if (searchInt == size2 - 1)
{
searchInt = 0;
cout << "if loop \n";
}
else
{
searchInt++;
cout << " stuck in else loop \n";
}
cout << " stuck in while loop end \n";
}
if (searchInt == 0) {
cout << "Search item not found using hashSearch" << endl;
} else {
cout << "Search item " << randSearchItem << " found using hashSearch at position " << searchInt << " in arr2." << endl;
}
auto finish = std::chrono::high_resolution_clock::now();
chrono::duration<double> elapsed = finish - start;
cout << "Elapsed time: " << elapsed.count() << " s\n";
}
Whereas it should just get out of the loop and output that search item is not found.
Search for cout << " stuck in else loop \n"; and cout << " stuck in while loop end \n";.
You want to stop your loop when you hit the end of the array: To that effect, you set the item to search for to zero:
if (searchInt == size2 - 1)
{
searchInt = 0;
cout << "if loop \n";
}
But in the loop control, you don't test that. You only test the array element at the current index for zero (not found) or the item to search (found):
while ((arr2[searchInt] != 0) && (arr2[searchInt] != randSearchItem)) ...
You need an additional test:
while ((searchInt != 0) && ...) ...
It took me a while to see that you want to code an open-address hastable where a zero marks unused slots. The hash value is just the number itself. Using zero as indicator for an empty slot is not ideal: You cannot store numbers whose hash code modulo the table size is zero.
I'd also code this with a non-void function where the return value is the index or some unambiguous value meaning "not found", perhaps -1. (Alternatively, you can return a pointer to the found item or NULL if the item isn't found -- after all, the index in the hash array is part of the hash table's internals and non concern to the caller.)
Then you can use early returns:
int hashSearch(const int *arr2, int size2, int item)
{
int i = item % size2;
for (; i < size2; i++) {
if (arr2[i] == -1) break; // -1 indicated unused space
if (arr2[i] == item) return i; // return index of item
}
return -1; // not found!
}
But what do you do if there is no room for a further element when you have a hash code close to the array size? You will need to add extra space at the end or you'll need to wrap around. Perhaps that is what you wanted to achieve by setting the index back to zero. In your case, ther array is full, so there are no zeros that could serve as loop-breaking criterion. You will have to find another criterion. You could ensure that there are zeros by making the hash table 30% or so bigger than the number of entries. Or you could try to detect whether the index has come full circle to the original index.
As already pointed out to you in comments: Try to use function arguments and local variables rather than puttin everything into global space. Also, the chaining of function calls, where the last thing in a function is to call the next one is strange. It's probably better to put all sequential calls into main.
For anyone that might be able to help me figure this out. I am creating a method that will compare two strings and detect whether they are an anagram or not. An anagram is two strings that have the same letters, though they may be in a different order. For example "listen" and "iltsen" are anagrams.
I have decided to break the strings up into char arrays. I know that is working correctly because I tested it using cout on each array element. Next is where it goes wrong. I attempt to use the ASCII value of each char and add it to a variable for each array. This would mean that if the values match then they must be an anagram.
However for whatever unknown reason it is not working correctly. I am finding that it is reading index 0 twice for one array and not for the other. I am so confused beyond reason. I have absolutely no idea what this is occurring. I have tried multiple different solutions and had no luck finding out the problem. If anyone has any idea whats going on here I would greatly appreciate the help.
-Thanks!
#include "stdafx.h"
#include <iostream>
#include <string>
#include <math.h>
#include <iomanip>
#include <cctype>
#include <vector>
using namespace std;
bool isAnagram(string s1,string s2)
{
static char firstString[] = { 'c' };
static char secondString[] = { 'c' };
int size = s1.length();
static int count1 = 0;
static int count2 = 0;
cout << s1 << endl;
cout << s2 << endl;
if (s1.length() == s2.length())
{
for (int i = 0; i < size; i++)
{
firstString[i] = s1.at(i);
cout << i;
}
for (int i = 0; i < size; i++)
{
secondString[i] = s2.at(i);
cout << i;
}
cout << endl;
for (int i = 0; i < size; i++)
{
count1 = count1 + (int)firstString[i];
cout << "first" << i << ": " << firstString[i] << " = " << (int)firstString[i] << endl;
count2 = count2 + (int)secondString[i];
cout << "second" << i << ": " << secondString[i] << " = " << (int)secondString[i] << endl;
}
cout << count1 << " and " << count2 << endl;
if (count1 == count2)
return true;
}
else
return false;
count1 = 0;
count2 = 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
static char end;
do
{
string s1;
string s2;
cout << "Please enter the first string: ";
cin >> s1;
cout << endl << "Please enter the second string: ";
cin >> s2;
bool result = isAnagram(s1, s2);
static string resultString;
if (result == true)
resultString = "True";
else
resultString = "False";
cout << endl << "Anagram test result: " << resultString << endl;
cout << endl << "enter E for end or any other key to run again: ";
cin >> end;
cout << "----------------------------------------" << endl;
} while (end != 'e' && end != 'E');
return 0;
}
It's not useful to use static variables in your case, without them you wouldn't need the last 2 lines of isAnagram.
It's also useless to store both strings in char arrays because you can use them directly in your 3rd loop(also you are overflowing your buffer which has a size of 1)
for (int i = 0; i < size; i++)
{
std::cout << count1 << " ";
count1 = count1 + (int)s1.at(i);
cout << "first" << i << ": " << s1.at(i) << " = " << (int)s1.at(i) << endl;
count2 = count2 + (int)s2.at(i);
cout << "second" << i << ": " << s2.at(i) << " = " << (int)s2.at(i) << endl;
}
Also you can't say that 2 strings do contain the same letters by comparing the sum of their ASCII values, thats like saying 3 + 4 is the same as 2 + 5 because both give 7.
You could create an array of 52 ints, each element is a counter for its own letter, then you could loop over both strings with one loop where each letter of the first string is incrementing its element in the array and the second strings letters are decrementing elements.
if (s1.length() != s2.length())
return false;
std::vector<int> counts(52);
for (unsigned int i = 0; i < s1.length(); ++i)
{
++counts[s1[i] - (s1[i] < 91 ? 65 : 71)];
--counts[s2[i] - (s2[i] < 91 ? 65 : 71)];
}
be sure that the array is initialized to 0.
At the end you need to loop over the array, if one of the elements is not 0 it's not an anagram, else return true.
for (unsigned int i = 0; i < 52; ++i)
if (counts[i] != 0)
return false;
return true;
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int value1; // these holds the original numbers inputted by the users
int value2;
int result;
// this holds the answer to be compared against the answer provided by using the algorithm
cout << "Please Enter the first number to be multiplied"<< endl;
cin >> value1;
cout << "Please Enter the second number to be multiplied"<< endl;
cin >> value2;
int tempnumber1 {value1}; //create a temp variable for halving while keeping main numbers stored for later use.
vector <int> halving; // this opens this vector halving which the algorithm uses
cout << "This is the Halving Step" << endl;
do
{
halving.push_back(tempnumber1);
cout <<tempnumber1 << endl;
tempnumber1/=2;
}
while (tempnumber1>0);
cout << " This is the Doubling stage" <<endl;
int tempnumber2 {value2};
for (int i=0; i<halving.size(); i++)
{
cout << tempnumber2 << endl;
tempnumber2*=2;
}
int total{0};
int doubling = value2;
for (int i =0; i < halving.size(); i++)
{
if (halving [i] %2==1)
{
cout << doubling << " Is Added to total" << endl;
total += doubling;
}
doubling *= 2; // this is used to avoid having to use two vectors.
}
//total /= 2;
result = value1*value2; // this provides the check value
cout << "The result is:" << total;
cout << "[Check Value:" << result << "]" << endl;
}
Hi, this was a university assignment from a few months ago which i passed.
The assignment was to use the russian peasant multiplication work in C++
but looking back at it, I realized that it wouldn't work with negative numbers, how would I make this program work with negative numbers?
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main()
{
int value1; // these holds the original numbers inputted by the users
int value2;
int result;
// this holds the answer to be compared against the answer provided by using the algorithm
cout << "Please Enter the first number to be multiplied"<< endl;
cin >> value1;
cout << "Please Enter the second number to be multiplied"<< endl;
cin >> value2;
int tempnumber1 {value1}; //create a temp variable for halving while keeping main numbers stored for later use.
vector <int> halving; // this opens this vector halving which the algorithm uses
cout << "This is the Halving Step" << endl;
do
{
halving.push_back(tempnumber1);
cout <<tempnumber1 << endl;
tempnumber1/=2;
}
while ((tempnumber1>0 && value1>0) ||(tempnumber1<0 && value1<0));
cout << " This is the Doubling stage" <<endl;
int tempnumber2 {value2};
for (int i=0; i<halving.size(); i++)
{
cout << tempnumber2 << endl;
tempnumber2*=2;
}
int total{0};
int doubling = value2;
for (int i =0; i < halving.size(); i++)
{
if (abs(halving [i]) % 2==1)
{
cout << doubling << " Is Added to total" << endl;
total += doubling;
}
doubling *= 2; // this is used to avoid having to use two vectors.
}
//total /= 2;
result = value1*value2; // this provides the check value
cout << "The result is:" << total;
cout << "[Check Value:" << result << "]" << endl;
}
The most elegant I could think of:
cout << "This is the Halving Step" << endl;
do {
halving.push_back(tempnumber1);
cout << tempnumber1 << endl;
tempnumber1 /= 2;
} while (tempnumber1 != 0);
int total{0};
int doubling = value2;
int sign{0};
for (int i = 0; i < halving.size(); i++) {
if ((sign = halving[i] % 2) != 0) {
cout << doubling*sign << " Is Added to total" << endl;
total += doubling*sign;
}
doubling *= 2; // this is used to avoid having to use two vectors.
}
This;
while (tempnumber1>0);
Should be changed to this;
while (tempnumber1>0 || tempnumber1 < 0);
//Or
while (tempnumber1 != 0); //Thanks #besc
And this;
if (halving [i] %2==1)
Should change to this;
if (halving [i] %2==1 || halving [i] %2==-1)
//Or
if(halving[i] % 2 != 0); //Thanks #stefaanv
To accommodate negative numbers
i think you can use this(correct me if i'm wrong);
while (isdigit(tempnumber1)==0);
Ok I have been struggling with this code and I think I have it written out right but here is the rules from my teacher
1 = implies right Number, Right Place.
2 = implies right Number, Wrong Place.
0 = implies Wrong Number.
So the computer decides on 12345; the user guesses 11235; the computer should respond with 10221. Hint: Watch out for a double number like 11 when there is only one.
I have it where it does all of that except I can not get it to show a 0 when it is wrong can you please help me every single part is written except that part here is my code
// Programming 2
// Mastermind
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
struct fields{//the list of variables used in my program
int size = 5;;
int range = 9;
char lowest = '0';
string guess;
string answer;
int number;
int correct;
int position;
bool gameover = false;
};
void gameplay(fields & info);//declaring the function
int main()
{
fields game;
gameplay(game);//calling the function
system("pause");
return 0;
}
void gameplay(fields & info){//calling the structure into the function
srand(time(0));//to randomize number
info.answer = "";//getting the number
for (int i = 0; i < info.size; i++)
{
char ch = info.lowest + rand() % info.range;
info.answer += ch;
}
info.number = 1;
info.correct = 0;
info.position = 0;
while (!info.gameover)//using a while loop to let them go until they guess it
{
cout << "Guess #" << info.number << ": Enter 5 numbers that are '0' through '9': ";//asking them to guess
cout << info.answer;
cout << "\n";
cin >> info.guess;
if (info.guess == info.answer)//if the guess is right this will end the game
{
cout << "Right! It took you " << info.number << " move";
if (info.number != 1) cout << "s";
cout << "." << endl;
info.gameover = true;
}
int correctNumbers = 0;
for (char const &ch : info.guess) //seeing if there are numebrs in the guess that is in the answer
{
if (info.answer.find(ch) != string::npos)
{
++correctNumbers;
}
}
int const digits = 5;
int correctPositions = 0;
int correctPosition[digits];
int test = 0;
for (int i = 0; i < digits; ++i)//telling which numbers is correct and displaying the 2 or 0 for number is correct or number is wrong
{
if (info.answer[i] == info.guess[i])
{
++correctPositions;
}
if (info.answer[i] == info.guess[i]){
correctPosition[i] = 2;
cout << correctPosition[i];
}
if (correctPosition[i] != 2){
correctPosition[i] = 1;
cout << correctPosition[i];
}
if (correctPosition[i] != 2 && correctPosition[i] != 1)){
correctPosition[i] = 0;
cout << correctPosition[i];
}
}
cout << "\nYou have " << correctPositions << " numbers in the correct position " <<endl;
cout << "You have " << correctNumbers <<" correct numbers in the wrong position"<< endl;
}
cout << "GAME OVER\n\n";
}