solving project euler #4 with c++ - c++

Q.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.
this is my code .it worked for 2 digit problem and gave 9009 as answer but it is not working for 3 digit number part.
#include <iostream>
using namespace std ;
bool ispallin(int n)
{
int reverse = 0, temp;
temp = n;
while (temp != 0)
{
reverse = reverse * 10;
reverse = reverse + temp%10;
temp = temp/10;
}
if (n == reverse)
return true;
else
return false;
}
int main() {
int a[999*999]={0},i,j,no;//0 implies no. at i th position is pallindrome
for(i=100;i<1000;i++)
{
for(j=100;j<1000;j++)
{
if(a[i*j]==0)//no. is pallin
{
if(ispallin(i*j))
no=i*j;
else a[i*j]=1;//no. at this pos is not pallindrome
}
}
}
cout<<no;
return 0;
}

your code is very nice, i would add a little bit more comments or maybe meaningful names to the functions but it is good code, the answer isn't what you were looking for because you never made sure that the result is the highest there is.
maybe 700*700 would be a palindrome but then 701*600 would also be a palindrome, i your case once 'i' is bigger it will overwrite the result, even if the polindrom is a bigger one.

Related

why for loop is not work correctly for a simple multiplication numbers 1 to 50?

code:
#include <iostream>
using namespace std;
int main() {
int answer = 1;
int i = 1;
for (; i <= 50; i++){
answer = answer * i;
}
cout << answer << endl;
return 0;
}
resault :
0
...Program finished with exit code 0
Press ENTER to exit console.
when i run this code in an online c++ compiler, it shows me zero(0) in console. why?
I will answer specifically the asked question "Why?" and not the one added in the comments "How?".
You get the result 0 because one of the intermediate values of answer is 0 and multiplying anything with it will stay 0.
Here are the intermediate values (I found them by moving your output into the loop.):
1
2
6
24
120
720
5040
40320
362880
3628800
39916800
479001600
1932053504
1278945280
2004310016
2004189184
-288522240
-898433024
109641728
-2102132736
-1195114496
-522715136
862453760
-775946240
2076180480
-1853882368
1484783616
-1375731712
-1241513984
1409286144
738197504
-2147483648
-2147483648
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
E.g. here https://www.tutorialspoint.com/compile_cpp_online.php
Now to explain why one of them is 0 to begin with:
Because of the values, the sequence of faculties, quickly leaves the value range representable in the chosen data type (note that the number decimal digits does not increase at some point; though the binary digits are the relevant ones).
After that, the values are not really related to the correct values anymore, see them even jumping below zero and back...
... and one of them happens to be 0.
For the "How?" please see the comments (and maybe other, valuable answers).
Short Answer:
Your code is not working correctly because it performs 50 factorial, that the answer is 3.04*10^64. This number is greater than the int size, that is 2^31 - 1.
Long answer
You can check the problem logging the intermediate answers. This can help you to have some insights about the code situation. Here you can see that the number rotate from positive to negative, that's show the maximum possible multiplication with this code strategy.
https://onlinegdb.com/ycnNADKmX
The answer
30414093201713378043612608166064768844377641568960512000000000000
To archive the correct answer to any case of factorial, you need to have some strategy to operate to large numbers.
In fact, if you're working a large company, you probably have some library to work with large numbers. In this situation, is very important use this library to keep the code consistent.
In other hand, supposing that's an academic homework, you can choose any strategy in the Internet. In this situation I used the strategy that uses string to represent large numbers. You can see the solution here https://www.geeksforgeeks.org/multiply-large-numbers-represented-as-strings
The final program that compute the 50! in the proper manner using the string strategy to represent large numbers you can find here https://onlinegdb.com/XRL9akYKb
PS: I'll put the complete answer here to archive the code for future references.
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
//#see https://www.geeksforgeeks.org/multiply-large-numbers-represented-as-strings/
// Multiplies str1 and str2, and prints result.
string multiply(string num1, string num2)
{
int len1 = num1.size();
int len2 = num2.size();
if (len1 == 0 || len2 == 0)
return "0";
// will keep the result number in vector
// in reverse order
vector<int> result(len1 + len2, 0);
// Below two indexes are used to find positions
// in result.
int i_n1 = 0;
int i_n2 = 0;
// Go from right to left in num1
for (int i=len1-1; i>=0; i--)
{
int carry = 0;
int n1 = num1[i] - '0';
// To shift position to left after every
// multiplication of a digit in num2
i_n2 = 0;
// Go from right to left in num2
for (int j=len2-1; j>=0; j--)
{
// Take current digit of second number
int n2 = num2[j] - '0';
// Multiply with current digit of first number
// and add result to previously stored result
// at current position.
int sum = n1*n2 + result[i_n1 + i_n2] + carry;
// Carry for next iteration
carry = sum/10;
// Store result
result[i_n1 + i_n2] = sum % 10;
i_n2++;
}
// store carry in next cell
if (carry > 0)
result[i_n1 + i_n2] += carry;
// To shift position to left after every
// multiplication of a digit in num1.
i_n1++;
}
// ignore '0's from the right
int i = result.size() - 1;
while (i>=0 && result[i] == 0)
i--;
// If all were '0's - means either both or
// one of num1 or num2 were '0'
if (i == -1)
return "0";
// generate the result string
string s = "";
while (i >= 0)
s += std::to_string(result[i--]);
return s;
}
// Calculates the factorial of an inputed number
string fact(int in) {
string answer = "1";
for (int i = 2 ; i <= in; i++) {
string tmp = std::to_string(i);
answer = multiply(answer, tmp);
}
return answer;
}
int main()
{
string answer = fact(50);
cout << answer << endl;
return 0;
}

Trying out a problem but code I had written is not giving output for large numbers. why?

I was trying this question.
The prime factors of 13195 are 5, 7, 13 and 29.What is the largest prime factor of the number 600851475143 ?
And I had written the following code:
#include<iostream>
#define num 600851475143
using namespace std;
int isprime(unsigned long long int n)
{
unsigned long long int c=0;
for(unsigned long long int i=2;i<n;i++)
{
if(n%i==0)
{
c++;
break;
}
}
if(c==0)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
unsigned long long int a,i,n=num;
while(n-- && n>1)
{
if(isprime(n)==1 && num%n==0)
{
cout<<n;
break;
}
}
return 0;
}
The problem occurring with the code is it is working for 13195 and other small values. But not getting any output for 600851475143. Can anyone explain why it is not working for large value and also tell the changes that should be made in these to get the correct output.
The below code snippets are from c (but should run quite nice with c++ as well):
#include <stdio.h>
#define uIntPrime unsigned long long int
#define uIntPrimeFormat "llu"
uIntPrime findSmallestPrimeFactor(uIntPrime num)
{
uIntPrime limit = num / 2 + 1;
for(uIntPrime i=2; i<limit; i++)
{
if((num % i) == 0)
{
return i;
}
}
return num;
}
uIntPrime findLargestPrimeFactor(uIntPrime num)
{
uIntPrime largestPrimeFactor = 1; // start with the smallest possible value
while (num > 1) {
uIntPrime primeFactor = findSmallestPrimeFactor(num);
if (primeFactor > largestPrimeFactor) largestPrimeFactor = primeFactor;
num = num / primeFactor;
}
return largestPrimeFactor;
}
How can this work?
(first function:) Counting the numbers up from 2 means you are starting with prime factors on the lower end. (Numbers that are non-prime when counting are just not working out as fraction-less divisors and at the same time their prime number factor components were already probed because they are lower.)
(second function:) If a valid factor is found then the factor is pulled out from the number in question. Thus the search for the now smallest prime in the pulled-out number can repeat. (The conditional might probably be superfluous due to lower numbers are found first anyway - but it might resemble a search pattern you are familiar with - like in a minimum/maximum/other-criteria search. I am now leaving it up to you to proof it right or wrong with testing with your own main routine.)
The stop condition is about having the last factor extracted means dividing the value by itself and getting a value of 1 for num.
(There is for sure still much space for speeding this up!)

How to solve Permutation of a phone number problem

The Problem:
A company is distributing phone numbers to its employees to make things easier. the next digit cannot be equal to the last is the only rule for example 0223 is not allowed while 2023 is allowed. At least three digits will be excluded every time. Write a function that takes in a length of the phone number and the digits that will be excluded. The function should print all possible phone numbers.
I got this question in an interview and I have seen one like it before at my university. It is a permutation problem. My question is what is the best way or decent way to solve this without a million for loops.
I do understand that this is technically how it works
length of phone number = 3;
[0-9], [0-9] excluding the last digit, [0-9] excluding the last digit
but I am unsure on how the best way to turn this into code. Any language is accepted!
thank you:
Also I might be asking this in the wrong place. please let me know if I am.
A simple way to solve this problem could be using Recursion. Here's my commented C++ code:
void solve(int depth, int size, vector <int> &curr_seq){
// If the recursion depth is equal to size, that means we've decided size
// numbers, which means that curr_seq.size() == size. In other words, we've
// decided enough numbers at this point to create a complete phone number, so
// we print it and return.
if(depth == size){
for(int item : curr_seq){
cout << item;
}
cout << "\n";
return;
}
// Try appending every possible digit to the current phone number
for(int i = 0; i <= 9; ++i){
// Make sure to only append the digit i if it is not equal to the last digit
// of the phone number. We can also append it, however, if curr_seq
// is empty (because that means that we haven't decided the 1st digit yet).
if(curr_seq.empty() || curr[curr.size() - 1] != i){
curr_seq.push_back(i);
solve(depth + 1, size, curr);
curr_seq.pop_back();
}
}
}
I think I like the recursive solution, but you can also just generate all permutations up to the limit (iterate), filter out any with repeating digits, and print the successful candidates:
#include <iomanip>
#include <iostream>
#include <sstream>
using namespace std;
// Because C/C++ still has no integer power function.
int ipow(int base, int exp) {
int result = 1;
for (;;) {
if (exp & 1)
result *= base;
exp >>= 1;
if (!exp)
return result;
base *= base;
}
}
void noconsec(const int len) {
int lim = ipow(10, len);
// For e.g. len 4 (lim 10000),
// obviously 00xx won't work, so skip anything smaller than lim / 100.
int start = (len <= 2) ? 0 : (lim / 100);
for (int num = start;num < lim;num++) {
// Convert to string.
std::stringstream ss;
ss << std::setw(len) << std::setfill('0') << num;
std::string num_s = ss.str();
// Skip any consecutive digits.
bool is_okay = true;
auto prev_digit = num_s[0];
for (int digit_idx = 1;digit_idx < num_s.length();digit_idx++) {
auto digit = num_s[digit_idx];
if (prev_digit == digit) {
is_okay = false;
}
prev_digit = digit;
}
// Output result.
if (is_okay) {
cout << num_s << "\n";
}
}
}
int main(const int argc, const char * const argv[]) {
noconsec(4);
}
Differences to note, this needs an integer power function to compute the limit. Converting an int to a string and then checking the string is more complex than constructing the string directly. I guess it could be useful if you have a list of integers already, but mostly I did it for fun.

How to check each element in an array if its prime or not

I'm trying to make program that prints out values form an array and that if they are or are not prime numbers. So far I have been able to make program which can take one value and print out if it's prime or not, however I haven't been able to implement this over to arrays. Here are my codes for printing out single numbers.
int isElementPrime(int value) {
if (0 == value % 2 || value < 2)
{
printf_s("Number %d is not prime\n", value);
}
else
{
printf_s("Number %d is prime\n", value);
}
return 0;
int main() {
int value = 4;
isElementPrime(value);
Output:
Number 4 is not prime
So the question is, how can this same thing be implemented to work with arrays?
EDIT As someone referred below, code is intended to only work up to number 8.
you want something as this?
int isElementPrime(int value) {
if (0 == value % 2 || value < 2)
{
printf_s("Number %d is not prime\n", value);
}
else
{
printf_s("Number %d is prime\n", value);
}
return 0;
}
int main() {
int values[4] = {1,2,3,4};
for(int i = 0; i < values.size();i++)
isElementPrime(values[i]);
a simple although inefficient way way to check if a number is prime is to loop through all of the whole integers from 2 up until the square root of the number in question and check if the loop counter (which will be between 2 and value exclusive) divides evenly into the tested value (with no remainder). This is a good place to start, you can then think about how to avoid unnecessary loop iterations.

Find number of palindromes that are anagrams in C++

I am taking part in an online programming contest for fun on http://www.hackerrank.com. One of the problems that I am working on is to find number of anagrams of a string that are palindrome as well. I have solve the problem but when I try to upload it it fails on a number of test cases. As the actual test cases are hidden from me I do not know for sure why its failing but I assume it could be a scalability issue. Now I do not want someone to give me a ready made solution because that would not be fair but I am just curious on what people think about my approach.
Here is the problem description from the website:
Now that the king knows how to find out whether a given word has an anagram which is a palindrome or not, he is faced with another challenge. He realizes that there can be more than one anagram which are palindromes for a given word. Can you help him find out how many anagrams are possible for a given word which are palindromes?
The king has many words. For each given word, the king needs to find out the number of anagrams of the string which are palindromes. As the number of anagrams can be large, the king needs number of anagrams % (109+ 7).
Input format :
A single line which will contain the input string
Output format :
A single line containing the number of anagram strings which are palindrome % (109 + 7).
Constraints :
1<=length of string <= 105
Each character of the string is a lowercase alphabet.
Each testcase has atleast 1 anagram which is a palindrome.
Sample Input 01 :
aaabbbb
Sample Output 01 :
3
Explanation :
Three permutation of given string which are palindrome can be given as abbabba , bbaaabb and bababab.
Sample Input 02 :
cdcdcdcdeeeef
Sample Output 02 :
90
As specified in the problem description input strings can be as large as 10^5, hence all palindromes for a large string is not possible since I will run into number saturation issues. Also since I only need to give a modulo (10^9 + 7) based answer, I thought of taking log of numbers with base (10^9 + 7) and after all computations take antilog of fraction part with base (10^9 + 7) of the answer since that will be the modulo anyway.
My algorithm is as follows:
Store freq of each char (only need to look half of the string since
second half should be same as first one by def of palindrome)
If there are more than one char appearing with odd number of time no palindrome possible
Else for each char's freq incrementally calculate number of palindromes (Dynamic Programming)
For the DP following is the subproblem:
previous_count = 1
For each additional character added number of palindromes = previous_count * (number_of_char_already_seen + 1)/(number of char same as current char)
Here is my code:
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <fstream>
using namespace std;
#define MAX_SIZE 100001
void factorial2 (unsigned int num, unsigned int *fact) {
fact[num]++;
return;
}
double mylog(double x) {
double normalizer = 1000000007.0;
return log10(x)/log10(normalizer);
}
int main() {
string in;
cin >> in;
if (in.size() == 1) {
cout << 1 << endl;
return 0;
}
map<char, int> freq;
for(int i=0; i<in.size(); ++i) {
if (freq.find(in.at(i)) == freq.end()) {
freq[in.at(i)] = 1;
} else {
freq[in.at(i)]++;
}
}
map<char, int> ::iterator itr = freq.begin();
unsigned long long int count = 1;
bool first = true;
unsigned long long int normalizer = 1000000007;
unsigned long long int size = 0;
unsigned int fact[MAX_SIZE] = {0};
vector<unsigned int> numerator;
while (itr != freq.end()) {
if (first == true) {
first = false;
} else {
for (size_t i=1; i<=itr->second/2; ++i) {
factorial2(i, fact);
numerator.push_back(size+i);
}
}
size += itr->second/2;
++itr;
}
//This loop is to cancel out common factors in numerator and denominator
for (int i=MAX_SIZE-1; i>1; --i) {
while (fact[i] != 0) {
bool not_div = true;
vector<unsigned int> newNumerator;
for (size_t j=0; j<numerator.size(); ++j) {
if (fact[i] && numerator[j]%i == 0) {
if (numerator[j]/i > 1)
newNumerator.push_back(numerator[j]/i);
fact[i]--; //Do as many cancellations as possible
not_div = false;
} else {
newNumerator.push_back(numerator[j]);
}
}
numerator = newNumerator;
if (not_div) {
break;
}
}
}
double countD = 0.0;
for (size_t i=0; i<numerator.size(); ++i) {
countD += mylog(double(numerator[i]));
}
for (size_t i=2; i <MAX_SIZE; ++i) {
if (fact[i]) {
countD -= mylog((pow(double(i), double(fact[i]))));
fact[i] = 0;
}
}
//Get the fraction part of countD
countD = countD - floor(countD);
countD = pow(double(normalizer), countD);
if (floor(countD + 0.5) > floor(countD)) {
countD = ceil(countD);
} else {
countD = floor(countD);
}
count = countD;
cout << count;
return 0;
}
Now I have spent a lot of time on this problem and I just wonder if there is something wrong in my approach or am I missing something here. Any ideas?
Note that anagrams are reflexive (they look the same read from the back as from the front), so half the occurrences of each character will be on one side and we just need to calculate the number of permutations of these. The other side will be an exact reversal of this side, so it doesn't add to the number of possibilities. The odd occurrence of a character (if one exists) must always be in the middle, so it can be ignored when calculating the number of permutations.
So:
Calculate the frequencies of the characters
Check that there's only 1 odd frequency
Divide the frequency of each character (rounding down - removes any odd occurrence).
Calculate the permutation of these characters using this formula:
(as per Wikipedia - multiset permutation)
Since the above terms can get quite big, we might want to split the formula up into prime factors so we can cancel out terms so we're left with only multiplication, then I believe we can % 109 + 7 after each multiplication, which should fit into a long long (since (109+7)*105 < 9223372036854775807).
Thanks to IVlad for pointing out a more efficient method of avoiding overflow than above:
Notice that p = 109 + 7 is a prime number, so we can use Fermat's little theorem to compute the multiplicative inverses of the mi mod p, and multiply by these and take the mod at each step instead of dividing. mi-1 = mi(10^9 + 5) (mod p). Using exponentiation by squaring, this will be very fast.
I also found this question (which also has some useful duplicates).
Examples:
Input: aaabbbb
Frequency:
a b
3 4
Div 2:
a b
1 2
Solution:
3!/2!1! = 3
Input: cdcdcdcdeeeef
Frequency:
c d e f
4 4 4 1
Div 2:
c d e f
2 2 2 0
Solution:
6!/2!2!2!0! = 90
The basic formula is:
p!/(a!*b!...*z!)
where p is floor of length/2 of the word and a,b,c..,z denotes the floor of half of frequency of occurrences a,b,c..,z in the word receptively.
The only problem now you are left is how to calculate this. For that, check this out.