c++ function which gives four digit numbers all odd - c++

Hello everyone and thank you for taking your time to answer this very stupid but for me tough question. I have spent so much time trying to figure out how to do this, yet some may find this very simple. The exercise goes like this: "Write the program, that contains a function "numbers", which
will print all four-digit numbers which: all digits are odd and
do not contain a digit 0."
My code is below but if anyone knows how to write a better code than to just correct mine, please share it in the comments.
#include <iostream>
using namespace std;
/* s is the remain when dividing i by 10 */
void numbers ()
{
for (int i = 9999; i >= 1000; i/=10)
{
int s = i % 10;
if (s % 2 == 1 && s != 0)
{
cout << i << endl;
}
i/=10;
}
}
int main()
{
numbers();
return 0;
}

We can approach the problem by analyzing the requirements.
So, we need odd digits. There are only 5 odd digits: 1,3,5,7,9. Any number that we create can consist only of those 5 digits.
The second observation is that there are 5^(NumberOfDigits) different numbers. That is easy to understand. Example: For the first digit, we have 5 possibilities. And then, for each of this 5 digits we have again 5 possible second digits. So, now already 5*5=25 numbers. And for each of the 5 second digits we have again 5 third digits, so, 125 numbers. And for a 4 digit number, we have 5*5*5*5=5^4=625 different numbers.
Good, how to find them? It is obvious, that the delta between two odd digits is 2. Or with other words, if we have an odd digit, we can simply add 2 to get the next odd digit. After the 9, we will have an overflow and need to continue again with 1.
There are many potential designs for the solution.
I will show here an example, were I do not use a complete number, but an array of digits. Then I will add 2 to one digit and if there is an overflow, I will also add 2 to the next digit and so on and so on. Somehow simple.
We do this, until the most significant digit will flip to one, and then all digits are 1 again.
#include <iostream>
#include <array>
#include <algorithm>
#include <iterator>
#include <iomanip>
// Number of digits in a number
constexpr size_t NumberOfDigits = 4u;
// Representation of the number as an array of digits
using Digits = std::array<int, NumberOfDigits>;
// Get the next number/digits
constexpr void nextDigits(Digits& digits) noexcept {
// Starting at the least significant digit
for (int i{ NumberOfDigits-1 }; i >= 0; --i) {
// Get the next odd number
digits[i] += 2;
// Check for overflow, then reset to 1, else stop
if (digits[i] > 9) digits[i] = 1;
else break;
}
}
int main() {
// Define our array with digits and fill it with all one
Digits d{};
std::fill(d.begin(), d.end(), 1);
// Some counter, Just for display purposes
unsigned long long i = 1;
do {
// Some debug output
std::cout << std::right << std::setw(30) << i++ << " --> ";
std::copy(d.begin(), d.end(), std::ostream_iterator<int>(std::cout));
std::cout << '\n';
// And, get the next number/digits
nextDigits(d);
// Do this, until we have found all numbers
} while (not std::all_of(d.begin(), d.end(), [](const int i) {return i == 1; }));
}
Again, this is one of many potential solutions

Related

How can you get a "x" element from rand()?

I have a rand number generator.
Now my question is how do I get for instance the first/second/third/fourth digit of the generated random number.
Implementing this so the user can use a hint when guessing the number.
example: result(rand): 9876
print hint 1: second number 8
print hint 2: fourth number 6
Whats the best way to tackle this? I've been thinking to convert the string to an char array in order to print out the certain locations where the values are being kept but that won't work I guess.
Correct me if my way of asking this questions is very bold.
int nummer = 4;
std :: string result = "";
for (int i = 0; i < nummer; i++)
{
result.push_back(rand()%10 + '0');
}
You have two options for solving this problem:
Create one random number between 0 and 9999 and then calculate the individual digits.
Create four random numbers between 0 and 9 which represent the individual digits and then, if necessary, calculate the whole number from the individual digits.
Normally, doing option #1 would be more straightforward. You seem to be going for option #2. Both ways are possible and which one is better probably depends on whether your program works more with the number as a whole or with individual digits.
If you decide to do option #2, then the question arises whether you want to work with ASCII character codes between '0' and '9' (i.e. codes between 48 and 57) or with actual numbers between 0 and 9. Normally, it is a bit easier to work with the actual numbers instead of ASCII character codes, but both ways are feasible.
Personally, I would solve it the following way:
#include <iostream>
#include <cstdlib>
#include <ctime>
int main()
{
//seed random number generator
std::srand( std::time(nullptr) );
//note that NUM_DIGITS should not be set so high
//that MAX_NUMBER is not representable as an `int`
constexpr int NUM_DIGITS = 4;
//set this to the highest possible number that
//corresponds to NUM_DIGITS
constexpr int MAX_NUMBER = 9999;
//this variable holds the entire number
int random;
//this array holds the individual digits
int digits[NUM_DIGITS];
///generate the random number
random = std::rand()%(MAX_NUMBER+1);
//calculate the individual digits of the random number
int remaining = random;
int divisor = (MAX_NUMBER+1) / 10;
for ( int i = 0; i < NUM_DIGITS; i++ )
{
digits[i] = remaining / divisor;
remaining = remaining % divisor;
divisor/= 10;
}
//print the whole random number
std::cout << "Whole random number:\n" << random << "\n\n";
//print the individual digits
std::cout << "Individual digits:\n";
for ( int i = 0; i < NUM_DIGITS; i++ )
{
std::cout << digits[i] << "\n";
}
}
Sample output (actual output depends on random number seed):
Whole random number:
8695
Individual digits:
8
6
9
5
I've been thinking to convert the string to an char array but that won't work I guess.
I see no reason to do this. In your posted code, you can simply write
result[0]
result[1]
result[2]
result[3]
to access the individual digits of the number.
In that respect, converting a std::string to a C-style character array has no advantages.
The code you've written is fine.
Whether you store the characters in an array or a string, you can access the elements using result[i] where i starts at 0.
I've been thinking to convert the string to an char array but that won't work I guess.
Using std::string is usually a better idea - still possible but a little harder to screw them up, and they're more powerful generally, but you could use a char array if you wanted:
char result[] = "0000"; // will have null terminator
for (int i = 0; i < 4; ++i)
result[i] = rand() % 10 + '0';
Letting result be a 5-character array - with a null terminator - means you can still print all four digits easily with std::cout << result.
Alternatively, you could pick a random 4-digit number and convert it to a string of a particular width, using '0's to pad:
#include <iostream>
#include <iomanip>
int main() {
std::ostringstream oss;
oss << std::setw(4) << std::setfill('0') << rand() % 10000;
std::cout << '[' << oss.str() << "]\n";
}

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.

Program Last Digit of a Large Fibonacci Number for n-th Fibonacci number. C++

I'm trying to solve Fibonacci using C++, but my code shows negative numbers when the output digit limit crosses with big numbers.
#include<stdio.h>
#include<iostream>
using namespace std;
int64_t get_fibonacci_last_digit_naive(int n)
{
int64_t a = 0, c, i;
int64_t b = 1;
if (n == 0)
return (a);
for (i = 2; i <= n; i++)
{
c = a + b;
a = b;
b = c;
}
return (b);
}
int main()
{
int n;
cin >> n;
cout << get_fibonacci_last_digit_naive(n) << '\n';
return 0;
}
so when my input is 239, my out put shows
239
-1716907696316940191
Process returned 0 (0x0) execution time : 12.395 s
Press any key to continue.
Now how i can store digits with no upper limits in C++?. i am very noob and exlpain me thinking that i dont know anythg. so huw can i print digits more than 30 in c++?
The built-in integer data types in C++ can only store values in a given range. For int64 that would be -263 to 263-1 (NOTE: prior to C++20 the standard allows for different signed integer representations so in theory the limits listed may differ by +/- 1). If a calculation results in values outside of this range you will get integer over flow and your value will continue from the other end of the range. This is the reason you see negative values - the 239-th Fibonacci number is actually very big(it has 50 digits in its decimal notation) and can not be stored in any built-in data type.
On the other hand to compute only the last digit of the 239-th Fibonacci number you do not need to actually compute the whole value. In fact for any number in decimal notation its last digit is the remainder of the number when divided by 10 (i.e. the last digit of X is X%10). This also applies for arithmetic operations for instance the last digit of A + B is (A % 10 + B % 10) % 10. I hope this tip helps you solve the problem on your own.
For starters pay attention to that this header
#include<stdio.h>
is redundant. Neither declaration from the header is used in your program.
And in C++ you should at least specify
#include <cstdio>
if a declaration from the header is required.
To get such a big fibonacci number as the 239-th fibonacci number you need to use a special library that provides services for processing big numbers or you have to write such services yourself by using for example the standard class std::string.
However to get the last digit of a fibonacci number there is no need to calculate the whole fibonacci number. It is enough to track only last digits.
Here is my naive approach.:)
#include <iostream>
#include <functional>
unsigned int get_fibonacci_last_digit_my_naive( unsigned int n )
{
const unsigned int Base = 10;
unsigned int a[] = { 0, 1 };
while (n--)
{
a[1] += std::exchange( a[0], a[1] );
a[1] %= Base;
}
return a[0];
}
int main()
{
unsigned int n = 0;
std::cin >> n;
std::cout << "The last digit of the " << n << "-th fibonacci number is "
<< get_fibonacci_last_digit_my_naive( n ) << '\n';
return 0;
}
The program output is
The last digit of the 239-th fibonacci number is 1
Or if to change the function main the following way
int main()
{
unsigned int n = 0;
std::cin >> n;
for ( unsigned int i = n; i < n + 10; i++ )
{
std::cout << "The last digit of the " << i << "-th fibonacci number is "
<< get_fibonacci_last_digit_my_naive( i ) << '\n';
}
return 0;
}
and to enter the number 230 then the program output will be
The last digit of the 230-th fibonacci number is 5
The last digit of the 231-th fibonacci number is 4
The last digit of the 232-th fibonacci number is 9
The last digit of the 233-th fibonacci number is 3
The last digit of the 234-th fibonacci number is 2
The last digit of the 235-th fibonacci number is 5
The last digit of the 236-th fibonacci number is 7
The last digit of the 237-th fibonacci number is 2
The last digit of the 238-th fibonacci number is 9
The last digit of the 239-th fibonacci number is 1

putting ints into an array c++

this is a super simple problem but it's late and I cant figure out for the life of me why this function doesnt work. I want it to print 1234, but instead it prints 123121. can someone explain what's going on and how to fix it? thanks
#include <iostream>
const int size = 20;
void set_int( int num )
{
int digits[size];
for ( int i = size - 1; i >= 0; i-- )
{
digits[i] = num % 10;
num /= 10;
if ( num != 0 )
std::cout << num;
}
}
int main()
{
set_int( 1234 );
return 0;
}
Well you are outputting the number instead of the digit.
Try changing like,
cout << digits[i]
Further clarification :
On the first run of the loop your num will be 1234 / 10 = 123
Next run your number will be 123 / 10 = 12
Next is going to be 1
You are outputing num, so you get 123121 .
There are several things wrong with that code.
Firstly, the definition
int digits[size];
is a variable length array, which is valid C (since the 1999 C standard) but is not valid C++. Unfortunately, some C++ compilers support such things as an extension.
Second, even if we assume that definition is valid, your code is essentially stating that you need an array with 1234 elements to hold integral values corresponding to four digits (1,2,3, and 4).
As MichaelCMS has described, your code is outputting something other than the digits too. A value of 1234 has 4 digits, so you would need to loop a total of 4 times to find all digits (if doing it right). You would not need to loop 1234 times.
MichaelCMS explained correctly, why you have such output. There are mistakes in your function. I wrote another one.
You can use next code, which helps to find digits of number.
#include <iostream>
int FindNumberOfDigits(int number);
void SplitNumberIntoDigits(int number);
// Splits number into digits.
// Works with not big numbers.
void SplitNumberIntoDigits(int number)
{
int size = FindNumberOfDigits(number);
int * digits = new int[size];
int divider = 0;
int degree = 0;
for(int digit = size; digit > 0; digit --)
{
// Find degree of divider
degree = digit;
// Find divider for each digit of number.
// For 1234 it will be 1000. For 234 it will be 100.
divider = pow(10, degree - 1);
// We use "abs" to get digits without "-".
// For example, when -1234 / 1000, you get -1.
digits[digit] = abs(number / divider);
// Cut number to find remaining digits.
number %= divider;
std::cout << digits[digit];
}
std::cout << std::endl;
}
// If number = 0, number of digits will be 1.
// Else returns number of digits.
int FindNumberOfDigits(int number)
{
int digitsNumber = 0;
if (number)
{
// calculates number of digits
while (number / 10)
{
number /= 10;
digitsNumber ++;
}
}
digitsNumber += 1;
return digitsNumber;
}
int _tmain(int argc, _TCHAR* argv[])
{
SplitNumberIntoDigits(1234);
SplitNumberIntoDigits(0);
SplitNumberIntoDigits(1);
SplitNumberIntoDigits(-1234);
SplitNumberIntoDigits(1234567890);
return 0;
}
As a result this code can help you to find digits of not big numbers. It works with positive, negative numbers and zero.

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.