I want to find the number of numbers between 1 and n that are valid numbers in base two (binary).
1 ≤ n ≤ 10^9
For example, suppose n is equal to 101.
Input: n = 101
In this case, the answer is 5
Output: 1, 10, 11, 100, 101 -> 5
Another example
Input: n = 13
Output: 1, 10, 11 -> 3
Here is my code...
#include <iostream>
using namespace std;
int main()
{
int n, c = 0;
cin >> n;
for (int i = 1; i <= n; ++i)
{
int temp = i;
bool flag = true;
while(temp != 0) {
int rem = temp % 10;
if (rem > 1)
{
flag = false;
break;
}
temp /= 10;
}
if (flag)
{
c++;
}
}
cout << c;
return 0;
}
But I want more speed.
(With only one loop or maybe without any loop)
Thanks in advance!
The highest binary number that will fit in a d-digit number d1 d2 ... dn is
b1 b2 ... bn where
bi = 0 if di = 0, and
bi = 1 otherwise.
A trivial implementation using std::to_string:
int max_binary(int input) {
int res = 0;
auto x = std::to_string(input);
for (char di : x) {
int bi = x == '0' ? 0 : 1;
res = 2 * res + bi;
}
return res;
}
Details:
In each step, if the digit was one, then we add 2 to the power of the number of digits we have.
If the number was greater than 1, then all cases are possible for that number of digits, and we can also count that digit itself and change the answer altogether (-1 is because we do not want to calculate the 0).
#include <iostream>
using namespace std;
int main()
{
long long int n, res = 0, power = 1;
cin >> n;
while(n != 0) {
int rem = n % 10;
if (rem == 1) {
res += power;
} else if (rem > 1) {
res = 2 * power - 1;
}
n /= 10;
power *= 2;
}
cout << res;
return 0;
}
Related
Here is the link to the problem:
http://www.spoj.com/problems/GCD/
Consider the decimal representation of a natural number N.
Find the greatest common divisor (GCD) of all numbers that can be obtained by permuting the digits in the given number. Leading zeroes are allowed.
I worked on the following approach :
https://math.stackexchange.com/a/22453
First, if all the digits are the same, there is only one number and that is the GCD. As was pointed out before, if 3 or 9 is a factor of one permutation it will be a factor of them all. Otherwise, imagine swapping just the ones and tens digit when they are different. The GCD of these two has to divide 100a+10b+c−100a+10c+b=9(b−c) where b and c are single digits. For the GCD of all the numbers to have a factor 2, all the digits must be even. For the GCD to have a factor 4, all the digits must be 0, 4, or 8 and for 8 they must be 0 or 8. Similarly for 5 and 7. Finally, the GCD will be 27 if all the digits are 0,3,6, or 9 and 27 divides one permutation and 81 if all the digits are 0 or 9 and 81 divides one permutation. Can you prove the last assertion?
My solution:
http://ideone.com/VMUb6w
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
int rem(string str, int a){
if (str.empty())
{
return 0;
}
int temp = (str[str.length() - 1] - '0') % a;
int temp2 = 10 % a;
str.erase(str.length() - 1);
int temp3 = (rem(str, a)*temp2) % a;
return (temp3 + temp) % a;
}
int gcdf(int a, int b)
{
return b ? gcdf(b, a%b) : a;
}
int main(){
string str;
while (cin >> str)
{
size_t l = str.length();
vector<int> digit;
int sum = 0;
int frequency[9];
for (int i = 0; i<9; i++)
frequency[i] = 0;
int zero_sum = 0;
for (size_t i = 0; i < l; i++)
{
if (str.at(i) != '0')
{
frequency[str.at(i) - '1']++;
sum += str.at(i) - '0';
}
else
{
zero_sum++;
}
}
for (size_t i = 0; i < 9; i++)
{
if (frequency[i])
{
digit.push_back(i + 1);
}
}
int gcds = 0, gcd = 1;
for (size_t i = 0; i < digit.size(); i++)
{
gcds = gcdf(digit[i], gcds);
}
if (gcdf(3, gcds) == 1)
{
gcd *= gcds;
}
if (gcds == 6)
{
gcd *= 2;
}
if ((rem(str, 81) == 0) && (gcdf(gcds, 3) == 3))
{
gcd *= 81;
}
else
{
if ((rem(str, 27) == 0) && (gcdf(gcds, 3) == 3))
{
gcd *= 27;
}
else
{
if (sum % 9 == 0)
{
gcd *= 9;
}
else
{
if (sum % 3 == 0)
{
gcd *= 3;
}
}
}
}
if((digit.size()==1)&&(zero_sum==0))
cout<<str;
else
cout << gcd << endl;
}
return 0;
}
But it is giving WA.
I cannot seem to find any edge case on where it might be wrong.
Please tell me where am i wrong. Thanks :)
First, if all the digits are the same, there is only one number and that is the GCD.
You don't handle this (first) case
So with your code all of 11, 111, 44 gives wrong answer.
[..] 81 if all the digits are 0 or 9 and 81 divides one permutation.
It seems that your test is wrong for that:
if ((rem(str, 81) == 0) && (gcdf(gcds, 3) == 3))
Did you mean:
if ((rem(str, 81) == 0) && (gcdf(gcds, 9) == 9))
And so
You have for permutation of 3699 inconsistent results:
27 for 3699, 3996, 6939, 6993, 9369, 9693, 9936
81 for 3969, 6399, 9396, 9639, 9963.
My implementation to check (for int number) is:
int my_gcd(std::string str)
{
std::sort(str.begin(), str.end());
std::string first = str;
int gcd = atoi(first.c_str());
while (std::next_permutation(str.begin(), str.end())) {
gcd = gcdf(atoi(str.c_str()), gcd);
}
return gcd;
}
I made up my mind to write a little piece of code that gets two integers, lets say M and N ( M <= N ) and sum the digits of all the integers between them, inclusive. So for example if M = 1 and N = 9, DigitSum will equal to 45. If M = 10 and N = 11 the sum will be (1 + 0 (10) + 1 + 1 (11) = 3).
Here is my code so far (Done the for loop instead of the return):
#include <iostream>
#include <vector>
using namespace std;
// the partial digits sums digitSum[i] = the sum of the digits between 0 and i
int digitSum[] = {0, 1, 3, 6, 10, 15, 21, 28, 36, 45};
int pow_of_ten[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
// the sums of all the digits in the numbers from 1 to (10^(i) - 1) where i is the index in the array
long subsums[] = {0, 45, 20 * 45, 300 * 45, 4000 * 45, 50000 * 45, 600000 * 45, 7000000 * 45, 80000000 * 45,
900000000 * 45};
//Calculates the sum of all digits between 0 and M inclusive
long Digit_Sum(int M) {
if (M < 10) {
return digitSum[M];
}
long result = 0;
int same = M;
int counter = 0;
int lastdigit = 0;
while (same > 0) {
if (same < 10) {
lastdigit = same;
break;
}
same /= 10;
counter ++;
}
for(;counter >= 0; counter --) {
result += (subsums[counter] + M % pow_of_ten[counter] + 1) * lastdigit;
result += digitSum[lastdigit - 1] * pow_of_ten[counter];
if (counter == 0) {
break;
}
lastdigit = (M / pow_of_ten[counter - 1]) % 10;
}
return result;
}
int main() {
int M;
int N;
vector<long> sums;
while (true) {
cin >> M >> N;
if (M == 0 && N == 0) {
break;
}
sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
}
for (vector<long>::iterator it = sums.begin(); it != sums.end(); ++it) {
cout << *it << endl;
}
}
For most cases this works well but an Online judge says it is wrong. I looked at other solutions that work but no one hard-coded the values in arrays the way I did. May this cause a partial problem, any ideas?
You can easily just create a for-loop to greatly simplify this code.
There is no need to go through all that effort.
for (Initialization Action, Boolean Expression, Update_Action)
Re deletion below: sorry, I have a bit influenza and mizread N as M. :(
I think a main error is M-1 in
sums.push_back(Digit_Sum(N) - Digit_Sum(M - 1));
Also noting that <when corrected that formula will only work for single-digit numbers. My comment earlier about using a simple formula was based on misunderstanding your problem description, in view of that formula and your examples. Both indicated single digit numbers only.
However, the complexity of the code appears unreasonably high. Consider this, assuming non-negative integers as input, and assuming m is always less than or equal to n:
#include <iostream>
#include <stdexcept>
using namespace std;
bool throwX() { throw std::runtime_error( "Ouch." ); }
auto main() -> int
{
for( ;; )
{
int m, n;
cin >> m >> n || throwX();
if( m == 0 && n == 0 ) { break; }
int sum = 0;
for( int i = m; i <= n; ++i )
{
for( int v = i; v != 0; v /= 10 )
{
sum += v % 10;
}
}
cout << sum << endl;
}
}
It needs not be more complicated than that.
Tested and working to spec, sans console input:
#include <iostream>
#include <string>
using namespace std;
void sum_a_to_b(const int & a, const int & b)
{
if (a <= b && a >= 0)
{
long long sum = 0;
for (int i = a; i <= b; i++)
{
sum += i;
}
cout << "Sum of digits from " << a << " through " << b << " is " << sum << ".\n";
}
}
int main()
{
sum_a_to_b(5, 6);
sum_a_to_b(1, 9);
}
How to create all possible numbers, starting from a given one, where all digits of the new ones are moved one slot to the right? For example if we have 1234. I want to generate 4123, 3412 and 2341.
What I have come out with so far is this:
int move_digits(int a)
{
int aux = 0;
aux = a % 10;
for(int i=pow(10, (number_digits(a) - 1)); i>0; i=i/10)
aux = aux * 10 + ((a % i) / (i/10));
return aux;
}
But it doesn't work.
The subprogram number_digits looks like this (it just counts how many digits the given number has):
int number_digits(int a)
{
int ct = 0;
while(a != 0)
{
a = a/10;
ct++;
}
return ct;
}
I think there is no need to write separate function number_digits.
I would write function move_digits simpler
#include <iostream>
#include <cmath>
int move_digits( int x )
{
int y = x;
double n = 0.0;
while ( y /= 10 ) ++n;
return ( x / 10 + x % 10 * std::pow( 10.0, n ) );
}
int main()
{
int x = 1234;
std::cout << x << std::endl;
std::cout << move_digits( x ) << std::endl;
}
Retrieving the last digit of n: n % 10.
To "cut off" the last digit, you could use number / 10.
Say you have a three-digit number n, then you can prepend a new digit d using 1000 * d + n
That said, you probably want to compute
aux = pow(10, number_digits - 1) * (aux % 10) + (aux / 10)
Calculatea/(number_digits(a) - 1) and a%(number_digits(a) - 1)
And your answer is (a%(number_digits(a) - 1))*10 + a/(number_digits(a) - 1)
int i =0 ;
int len = number_digits(a);
while(i < len){
cout << (a%(len - 1))*10 + a/(len - 1) <<endl;
a = (a%(len - 1))*10 + a/(len - 1);
}
void move_digits(int a)
{
int digits = 0;
int b = a;
while(b / 10 ){
digits++;
b = b / 10;
}
for (int i = 0; i < digits; ++i)
{
int c = a / 10;
int d = a % 10;
int res = c + pow(10, digits) * d;
printf("%d\n", res);
a = res;
}
printf("\n");
}
int main()
{
move_digits(12345);
}
I'm working on Project Euler #27 in C++:
Euler published the remarkable quadratic formula:
n² + n + 41
It turns out that the formula will produce 40 primes for the
consecutive values n = 0 to 39. However, when n = 40, 40² + 40 + 41 =
40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 41² +
41 + 41 is clearly divisible by 41.
Using computers, the incredible formula n² − 79n + 1601 was
discovered, which produces 80 primes for the consecutive values n = 0
to 79. The product of the coefficients, −79 and 1601, is −126479.
Considering quadratics of the form:
n² + an + b, where |a| < 1000 and |b| < 1000
where |n| is the modulus/absolute value of n
e.g. |11| = 11 and |−4| = 4
Find the product of the coefficients, a and b, for the quadratic
expression that produces the maximum number of primes for consecutive
values of n, starting with n = 0.
I keep getting -60939 when the real answer is -59231. What am I missing?
#include <iostream>
#include "Helper.h"
using namespace std;
int formula(int a, int b, int n) {
return ((n * n) + (a * n) + b);
}
int main() {
int most = 0;
int ansA = 0;
int ansB = 0;
bool end = false;
for(int a = 999; a >= -999; a--) {
for(int b = 999; b >= 2; b--) { //b must be prime
if(Helper::isPrime(b)) {
end = false;
for(int n = 0; !end; n++) {
if(!Helper::isPrime(formula(a, b, n))) {
if(n-1 > most) {
most = n-1;
ansA = a;
ansB = b;
}
end = true;
}
}
}
}
}
cout << ansA << " * " << ansB << " = " << ansA * ansB << " with " << most << " primes." << endl;
return 0;
}
In case it's the problem, here is my isPrime function:
bool Helper::isPrime(int num) {
if(num == 2)
return true;
if(num % 2 == 0 || num == 1 || num == 0)
return false;
int root = (int) sqrt((double)num) + 1;
for(int i = root; i >= 2; i--) {
if (num % i == 0)
return false;
}
return true;
}
You are allowing a to be negative, and your formula returns an int. Does calling Helper::isPrime with a negative number even make sense (in other words, does Helper::isPrime take an unsigned int?)
Here is my java version. Hope it helps:
static int function(int n, int a, int b){
return n*n + a*n + b;
}
static int consequitive_Primes(int a, int b, HashSet<Integer> primes){
int n = 0;
int number = 0;
while(true){
if(!primes.contains(function(n, a, b)))
break;
number++;
n++;
}
return number;
}
static HashSet<Integer> primes (int n){
ArrayList<Integer> primes = new ArrayList<Integer>();
primes.add(3);
for(int i=3; i<n;i+=2){
boolean isPrime = true;
for(Integer k:primes){
if(i%k==0){
isPrime = false;
break;
}
}
if(isPrime) primes.add(i);
}
return new HashSet<Integer>(primes);
}
static long q27(){
HashSet<Integer> primes = primes(1000);
int max = 0;
int max_ab = 0;
for(int a = -999; a<1000;a++){
for(int b = -999; b<1000;b++){
int prime_No = consequitive_Primes(a,b,primes);
if(max<prime_No){
max = prime_No;
max_ab = a*b;
}
}
}
return max_ab;
}
Suppose I am given:
A range of integers iRange (i.e. from 1 up to iRange) and
A desired number of combinations
I want to find the number of all possible combinations and print out all these combinations.
For example:
Given: iRange = 5 and n = 3
Then the number of combinations is iRange! / ((iRange!-n!)*n!) = 5! / (5-3)! * 3! = 10 combinations, and the output is:
123 - 124 - 125 - 134 - 135 - 145 - 234 - 235 - 245 - 345
Another example:
Given: iRange = 4 and n = 2
Then the number of combinations is iRange! / ((iRange!-n!)*n!) = 4! / (4-2)! * 2! = 6 combinations, and the output is:
12 - 13 - 14 - 23 - 24 - 34
My attempt so far is:
#include <iostream>
using namespace std;
int iRange= 0;
int iN=0;
int fact(int n)
{
if ( n<1)
return 1;
else
return fact(n-1)*n;
}
void print_combinations(int n, int iMxM)
{
int iBigSetFact=fact(iMxM);
int iDiffFact=fact(iMxM-n);
int iSmallSetFact=fact(n);
int iNoTotComb = (iBigSetFact/(iDiffFact*iSmallSetFact));
cout<<"The number of possible combinations is: "<<iNoTotComb<<endl;
cout<<" and these combinations are the following: "<<endl;
int i, j, k;
for (i = 0; i < iMxM - 1; i++)
{
for (j = i + 1; j < iMxM ; j++)
{
//for (k = j + 1; k < iMxM; k++)
cout<<i+1<<j+1<<endl;
}
}
}
int main()
{
cout<<"Please give the range (max) within which the combinations are to be found: "<<endl;
cin>>iRange;
cout<<"Please give the desired number of combinations: "<<endl;
cin>>iN;
print_combinations(iN,iRange);
return 0;
}
My problem:
The part of my code related to the printing of the combinations works only for n = 2, iRange = 4 and I can't make it work in general, i.e., for any n and iRange.
Your solution will only ever work for n=2. Think about using an array (combs) with n ints, then the loop will tick up the last item in the array. When that item reaches max update then comb[n-2] item and set the last item to the previous value +1.
Basically working like a clock but you need logic to find what to uptick and what the next minimum value is.
Looks like a good problem for recursion.
Define a function f(prefix, iMin, iMax, n), that prints all combinations of n digits in the range [iMin, iMax] and returns the total number of combinations. For n = 1, it should print every digit from iMin to iMax and return iMax - iMin + 1.
For your iRange = 5 and n = 3 case, you call f("", 1, 5, 3). The output should be 123 - 124 - 125 - 134 - 135 - 145 - 234 - 235 - 245 - 345.
Notice that the first group of outputs are simply 1 prefixed onto the outputs of f("", 2, 5, 2), i.e. f("1", 2, 5, 2), followed by f("2", 3, 5, 2) and f("3", 4, 5, 2). See how you would do that with a loop. Between this, the case for n = 1 above, and traps for bad inputs (best if they print nothing and return 0, it should simplify your loop), you should be able to write f().
I'm stopping short because this looks like a homework assignment. Is this enough to get you started?
EDIT: Just for giggles, I wrote a Python version. Python has an easier time throwing around sets and lists of things and staying legible.
#!/usr/bin/env python
def Combos(items, n):
if n <= 0 or len(items) == 0:
return []
if n == 1:
return [[x] for x in items]
result = []
for k in range(len(items) - n + 1):
for s in Combos(items[k+1:], n - 1):
result.append([items[k]] + s)
return result
comb = Combos([str(x) for x in range(1, 6)], 3)
print len(comb), " - ".join(["".join(c) for c in comb])
Note that Combos() doesn't care about the types of the items in the items list.
Here is your code edited :D :D with a recursive solution:
#include <iostream>
int iRange=0;
int iN=0; //Number of items taken from iRange, for which u want to print out the combinations
int iTotalCombs=0;
int* pTheRange;
int* pTempRange;
int find_factorial(int n)
{
if ( n<1)
return 1;
else
return find_factorial(n-1)*n;
}
//--->Here is another solution:
void print_out_combinations(int *P, int K, int n_i)
{
if (K == 0)
{
for (int j =iN;j>0;j--)
std::cout<<P[j]<<" ";
std::cout<<std::endl;
}
else
for (int i = n_i; i < iRange; i++)
{
P[K] = pTheRange[i];
print_out_combinations(P, K-1, i+1);
}
}
//Here ends the solution...
int main()
{
std::cout<<"Give the set of items -iRange- = ";
std::cin>>iRange;
std::cout<<"Give the items # -iN- of iRange for which the combinations will be created = ";
std::cin>>iN;
pTheRange = new int[iRange];
for (int i = 0;i<iRange;i++)
{
pTheRange[i]=i+1;
}
pTempRange = new int[iN];
iTotalCombs = (find_factorial(iRange)/(find_factorial(iRange-iN)*find_factorial(iN)));
std::cout<<"The number of possible combinations is: "<<iTotalCombs<<std::endl;
std::cout<<"i.e.the combinations of "<<iN<<" elements drawn from a set of size "<<iRange<<" are: "<<std::endl;
print_out_combinations(pTempRange, iN, 0);
return 0;
}
Here's an example of a plain recursive solution. I believe there exists a more optimal implementation if you replace recursion with cycles. It could be your homework :)
#include <stdio.h>
const int iRange = 9;
const int n = 4;
// A more efficient way to calculate binomial coefficient, in my opinion
int Cnm(int n, int m)
{
int i;
int result = 1;
for (i = m + 1; i <= n; ++i)
result *= i;
for (i = n - m; i > 1; --i)
result /= i;
return result;
}
print_digits(int *digits)
{
int i;
for (i = 0; i < n; ++i) {
printf("%d", digits[i]);
}
printf("\n");
}
void plus_one(int *digits, int index)
{
int i;
// Increment current digit
++digits[index];
// If it is the leftmost digit, run to the right, setup all the others
if (index == 0) {
for (i = 1; i < n; ++i)
digits[i] = digits[i-1] + 1;
}
// step back by one digit recursively
else if (digits[index] > iRange) {
plus_one(digits, index - 1);
}
// otherwise run to the right, setting up other digits, and break the recursion once a digit exceeds iRange
else {
for (i = index + 1; i < n; ++i) {
digits[i] = digits[i-1] + 1;
if (digits[i] > iRange) {
plus_one(digits, i - 1);
break;
}
}
}
}
int main()
{
int i;
int digits[n];
for (i = 0; i < n; ++i) {
digits[i] = i + 1;
}
printf("%d\n\n", Cnm(iRange, n));
// *** This loop has been updated ***
while (digits[0] <= iRange - n + 1) {
print_digits(digits);
plus_one(digits, n - 1);
}
return 0;
}
This is my C++ function with different interface (based on sts::set) but performing the same task:
typedef std::set<int> NumbersSet;
typedef std::set<NumbersSet> CombinationsSet;
CombinationsSet MakeCombinations(const NumbersSet& numbers, int count)
{
CombinationsSet result;
if (!count) throw std::exception();
if (count == numbers.size())
{
result.insert(NumbersSet(numbers.begin(), numbers.end()));
return result;
}
// combinations with 1 element
if (!(count - 1) || (numbers.size() <= 1))
{
for (auto number = numbers.begin(); number != numbers.end(); ++number)
{
NumbersSet single_combination;
single_combination.insert(*number);
result.insert(single_combination);
}
return result;
}
// Combinations with (count - 1) without current number
int first_num = *numbers.begin();
NumbersSet truncated_numbers = numbers;
truncated_numbers.erase(first_num);
CombinationsSet subcombinations = MakeCombinations(truncated_numbers, count - 1);
for (auto subcombination = subcombinations.begin(); subcombination != subcombinations.end(); ++subcombination)
{
NumbersSet cmb = *subcombination;
// Add current number
cmb.insert(first_num);
result.insert(cmb);
}
// Combinations with (count) without current number
subcombinations = MakeCombinations(truncated_numbers, count);
result.insert(subcombinations.begin(), subcombinations.end());
return result;
}
I created a next_combination() function similar to next_permutation(), but valid input is required to make it work
//nums should always be in ascending order
vector <int> next_combination(vector<int>nums, int max){
int size = nums.size();
if(nums[size-1]+1<=max){
nums[size-1]++;
return nums;
}else{
if(nums[0] == max - (size -1)){
nums[0] = -1;
return nums;
}
int pos;
int negate = -1;
for(int i = size-2; i>=0; i--){
if(nums[i]+1 <= max + negate){
pos = i;
break;
}
negate --;
}
nums[pos]++;
pos++;
while(pos<size){
nums[pos] = nums[pos-1]+1;
pos++;
}
}
return nums;
}