finding divisors from sequence of triangle [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Project Euler Problem 12 - C++
The sequence of triangle numbers is generated by adding the natural numbers. Hence, the 7th
triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28.
The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors. What is the value of the
first triangle number to have over one hundred divisors?

You've only copied the problem description! What's your problem with the problem? You have to state that.
The question is posed "what is the 1st triangle number to have over one hundred divisors?" Simply iterate over the triangle numbers, finding out how many factors each one has. When you find one with >100 factors, you're done.
for each whole number 'n' from 1 -> +INF
let tn = triangleNumber(n);
let nf = numFactors(tn);
if (nf > 100)
print tn " has " nf " factors.\n";
return;

Firstly try do it by yourself. If you are not able to get your answer then understand this code.Try to understand the problem and then try to impliment it by yourself. Firstly you have to check untill your divisor is over 100 so there would be one while loop.Inside that while you have to create that sequence of triangle i.e sum of consecutive numbers (1+2+3+4+5+6+7). And then use counter and increment it to find out the number of divisor of the sum.
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(){
int div=0,sum=0,num,i=1,chk=0,a;
cout<<"enter the number of divisors"<<endl;
cin>>a;
while(div<=a)
{div=0;
sum=sum+i;
for(int j=1;j<=sum;j++)
{if(sum%j==0)
div++;
}
chk++;
i++;
}
cout<<"Value of first triangle number value is "<<sum<<endl;
cout<<"Value of triangle number is "<<chk<<endl;
system("PAUSE");
return 0;
}

Related

Code Chef DSA Learning Series : Multiple of 3 Multhree

My algorithm is different from question previously uploaded so please don't close it by seeing the same topic of the question
Consider a very long K-digit number N with digits d0, d1, ..., dK-1 (in decimal notation; d0 is the most significant and dK-1 the least significant digit). This number is so large that we can't give it to you on the input explicitly; instead, you are only given its starting digits and a way to construct the remainder of the number.
Specifically, you are given d0 and d1; for each i ≥ 2, di is the sum of all preceding (more significant) digits, modulo 10 — more formally, the following formula must hold:
Determine if N is a multiple of 3.
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first and only line of each test case contains three space-separated integers K, d0 and d1.
Output
For each test case, print a single line containing the string "YES" (without quotes) if the number N is a multiple of 3 or "NO" (without quotes) otherwise.
Example
Input:
3
5 3 4
13 8 1
760399384224 5 1
Output:
NO
YES
YES
Explanation
Example case 1: The whole number N is 34748, which is not divisible by 3, so the answer is NO.
Example case 2: The whole number N is 8198624862486, which is divisible by 3, so the answer is YES.
question link
I am not able to understand whats wrong with this code,
it doesn't work with this test case:
input : 1 760399384224 5 1
#include <iostream>
using namespace std;
int main() {
// your code goes here
int t;
std::cin >> t;
for(int i=0;i<t;i++)
{
long long k,d0,d1,sum=0,x;
std::cin >> k>>d0>>d1;
sum=d0+d1;
for(;k>2;k--)
{
x=sum;
int z=x%10;
if(z==0)
break;
sum=sum+z;
}
cout<<sum<<endl;
/*if(sum>10)
{
long long a=sum/10;
long long b=sum%10;
sum=a+b;
}*/
if(sum%3==0)
sum=0;
if(sum%3==0)
{
std::cout << "YES" << std::endl;
}
else
std::cout << "NO" << std::endl;
}
return 0;
}

find the minimum lucky number that has the sum of digits equal to N

The lucky numbers are the positive integers whose decimal representations contain only the digits 4 or 7 .enter code here`
For example, numbers 47 , 474 , 4 are lucky and 3 , 13 , 567 are not
if there is no such no then output should -1.
input is sum of digits.
i have written this code:
int main(){
long long int s,no=0,minimum=999999999999999999999;
cin>>s;
for(int i=0; i<=s; i++){
for(int j=0; j<=s; j++){
if(i*4+j*7==s){no=0;
for(int k=0; k<i; k++){
no=no*10+4;
}
for(int l=0; l<j; l++){
no=no*10+7;
}if(no<minimum){
minimum=no;}
}
}
}if(minimum==999999999999999999999){cout<<-1;}
else {cout<<minimum;}
}
it is working fine smaller sum values but input is large then no formed is large due to which i am not able to compare them, the constraints for sum is 1<=n<=10^6
This answer shows a process, one of refinement to develop an efficient solution. The most efficient answer can be found in the paragraphs at the bottom, starting with the text "Of course, you can be even more clever ...".
I've left the entire process in so you can understand the sort of thinking that goes into algorithm development. So, let's begin.
First, I wouldn't, in this case, try to compare large numbers, it's totally unnecessary and limits the sort of ranges you want to handle. Instead, you simply have some number of fours and some number of sevens, which you can easily turn into a sum with:
sum = numFours * 4 + numSevens * 7
In addition, realising that the smallest number is, first and foremost, the one with the least number of digits, you want the absolute minimum number of fours and maximum number of sevens. So start with no fours and as many sevens as needed until you're at or just beyond the required sum.
Then, as long as you're not at the sum, perform the following mutually exclusive steps:
If you're over the desired sum, take away a seven if possible. If there are no sevens to take away, you're done, and there's no solution. Log that fact and exit.
Otherwise (i.e., if you're under the sum), add a four.
At this point, you will have a solution (no solution possible means that you would have already performed an exit in the first bullet point above).
Hence you now have a count of the fours and sevens that sum to the desired number, so the lowest number will be the one with all the fours at the left (for example 447 is less than any of {474, 744}). Output that, and you're done.
By doing it this way, the limitation (say, for example, an unsigned 32-bit int) is no longer the number you use (about four billion, so nine digits), instead it is whatever number of fours you can hold in four billion (about a billion digits).
That's an increase of about 11 billion percent, hopefully enough of an improvement for you, well beyond the 106 maximum sum specified.
In reality, you won't get that many fours since any group of seven fours can always be replaced with four sevens, giving a smaller number (a7777b will always be less than a4444444b, where a is zero or more fours and b is zero or more sevens, same counts in both numbers), so the maximum count of fours will always be six.
Here's some pseudo-code (Python code, actually) to show it in action. I've chosen Python, even though you stated C++, for the following reasons:
This is almost certainly an educational question (there's very little call for this sort of program in the real world). That means you're better off doing the heavy lifting of writing the code yourself, to ensure you understand and also to ensure you don't fail for just copying code off the net.
Python is the most awesome pseudo-code language ever. It can easily read like normal English pseudo-code but has the added benefit that a computer can actually run it for testing and validation purposes :-)
The Python code is:
import sys
# Get desired sum from command line, with default.
try:
desiredSum = int(sys.argv[1])
except:
desiredSum = 22
# Init sevens to get at or beyond sum, fours to zero, and the sum.
(numSevens, numFours) = ((desiredSum + 6) // 7, 0)
thisSum = numSevens * 7 + numFours * 4
# Continue until a solution is found.
while thisSum != desiredSum:
if thisSum > desiredSum:
# Too high, remove a seven. If that's not possible, exit.
if numSevens == 0:
print(f"{desiredSum}: no solution")
sys.exit(0)
numSevens -= 1
thisSum -= 7
else:
# Too low, add a four.
numFours += 1
thisSum += 4
# Only get here if solution found, so print lowest
# possible number that matches four/seven count.
print(f"{desiredSum}: answer is {'4' * numFours}{'7' * numSevens}")
And here's a transcript of it in action for a small sample range:
pax:~> for i in {11..20} ; do ./test47.py ${i} ; done
11: answer is 47
12: answer is 444
13: no solution
14: answer is 77
15: answer is 447
16: answer is 4444
17: no solution
18: answer is 477
19: answer is 4447
20: answer is 44444
And here's the (rough) digit count for a desired sum of four billion, well over half a billion digits:
pax:~> export LC_NUMERIC=en_US.UTF8
pax:~> printf "%'.f\n" $(./test47.py 4000000000 | wc -c)
571,428,597
If you really need a C++ solution, see below. I wouldn't advise using this if this is course-work, instead suggesting you convert the algorithm shown above into your own code (for reasons previously mentioned). This is provided just to show the similar approach in C++:
#include <iostream>
int main(int argc, char *argv[]) {
// Get desired sum from command line, defaulting to 22.
int desiredSum = 22;
if (argc >= 2) desiredSum = atoi(argv[1]);
// Init sevens to get at or beyond desired sum, fours to zero,
// and the sum based on that.
int numSevens = (desiredSum + 6) / 7, numFours = 0;
int thisSum = numSevens * 7 + numFours * 4;
// Continue until a solution is found.
while (thisSum != desiredSum) {
if (thisSum > desiredSum) {
// Too high, remove a seven if possible, exit if not.
if (numSevens == 0) {
std::cout << desiredSum << ": no solution\n";
return 0;
}
--numSevens; thisSum -= 7;
} else {
// Too low, add a four.
++numFours; thisSum += 4;
}
}
// Only get here if solution found, so print lowest
// possible number that matches four / seven count.
std::cout << desiredSum << ": answer is ";
while (numFours-- > 0) std::cout << 4;
while (numSevens-- > 0) std::cout << 7;
std::cout << '\n';
}
Of course, you can be even more clever when you realise that the maximum number of fours will be six, and that you can add one to the sum-of-digits by removing one seven and adding two fours.
So simply:
work out the number of sevens required to get at or just below the desired sum;
add a single four if that will still keep you at or below the desired sum;
then adjust by enough actions of "remove one seven and add two fours" until you get to that desired sum (keeping in mind you may already be there). This will be done exactly once for each unit the shortfall in your current sum (how far it is below the desired sum) so, if the shortfall was two, you would remove two sevens and add four fours (- 14 + 16 = 2). That means you can use a simple mathematical formula rather than a loop.
if that formula results in a negative count of sevens, there was no solution, otherwise use the counts as previously mentioned to form the lowest number (fours followed by sevens).
Just Python for this solution, given how easy it is:
import sys
# Get desired number.
desiredNum = int(sys.argv[1])
# Work out seven and four counts as per description in text.
numSevens = int(desiredNum / 7) # Now within six of desired sum.
shortFall = desiredNum - (numSevens * 7)
numFours = int(shortFall / 4) # Now within three of desired sum.
shortFall = shortFall - numFours * 4
# Do enough '+7-4-4's to reach desired sum (none if already there).
numSevens = numSevens - shortFall
numFours = numFours + shortFall * 2
# Done, output solution, if any.
if numSevens < 0:
print(f"{desiredNum}: No solution")
else:
print(f"{desiredNum}: {'4' * numFours}{'7' * numSevens}")
That way, no loop is required at all. It's all mathematical reasoning.
If I understand the question correctly, you are searching for the smallest number x which contains only the numbers 4 and 7 and the sum of its digits N. The smallest number is for sure written as:
4...47...7
and consists of m times 4 and n times 7. So we know that N = n · 4 + m · 7.
Here are a couple of rules that apply:
(n + m) · 7 ≥ N :: This is evident, just replace all 4's by 7's.
(n + m) · 4 ≤ N :: This is evident, just replace all 7's by 4's.
(n + m) · 7 − N = m · (7 − 4) :: in other words (m+n) · 7 − N needs to be divisible by 7 − 4
So with these two conditions, we can now write the pseudo-code very quickly:
# always assume integer division
j = N/7 # j resembles n+m (total digits)
if (N*7 < N) j++ # ensure rule 1
while ( (j*4 <= N) AND ((j*7 - N)%(7-4) != 0) ) j++ # ensure rule 2 and rule 3
m = (j*7 - N)/(7-4) # integer division
n = j-m
if (m>=0 AND n>=0 AND N==m*4 + n*7) result found
Here is a quick bash-awk implementation:
$ for N in {1..30}; do
awk -v N=$N '
BEGIN{ j=int(N/7) + (N%7>0);
while( j*4<=N && (j*7-N)%3) j++;
m=int((j*7-N)/3); n=j-m;
s="no solution";
if (m>=0 && n>=0 && m*4+n*7==N) {
s=""; for(i=1;i<=j;++i) s=s sprintf("%d",(i<=m?4:7))
}
print N,s
}'
done
1 no solution
2 no solution
3 no solution
4 4
5 no solution
6 no solution
7 7
8 44
9 no solution
10 no solution
11 47
12 444
13 no solution
14 77
15 447
16 4444
17 no solution
18 477
19 4447
20 44444
21 777
22 4477
23 44447
24 444444
25 4777
26 44477
27 444447
28 7777
29 44777
30 444477
The constraints for sum are 1 ≤ n ≤ 106
It means that you might have to find and print numbers with more than 105 digits (106 / 7 ≅ 142,857). You can't store those in a fixed-sized integral type like long long, it's better to directly generate them as std::strings composed by only 4 and 7 characters.
Some mathematical properties may help in finding a suitable algorithm.
We know that n = i * 4 + j * 7.
Of all the possible numbers generated by each combination of i digits four and j digits seven, the minimum is the one with all the fours at left of all the sevens. E.g. 44777 < 47477 < 47747 < ... < 77744.
The minimal lucky number has at max six 4 digits, because, even if the sum of their digits is equal, 4444444 > 7777.
Now, let's introduce s = n / 7 (integer division) and r = n % 7 (the remainder).
If n is divisible by 7 (or when r == 0), the lucky number is composed only by exactly s digits (all 7).
If the remainder is not zero, we need to introduce some 4. Note that
If r == 4, we can just put a single 4 at the left of s sevens
Every time we substitute (if we can) a single 7 with two 4s, the sum of the digits increases by 1.
We can calculate exactly how many 4 digits we need (6 at max) without a loop.
This is enough to write an algorithm.
#include <string>
struct lucky_t
{
long fours, sevens;
};
// Find the minimum lucky number (composed by only 4 and 7 digits)
// that has the sum of digits equal to n.
// Returns it as a string, if exists, otherwise return "-1".
std::string minimum_lucky(long n)
{
auto const digits = [multiples = n / 7L, remainder = n % 7L] {
return remainder > 3
? lucky_t{remainder * 2 - 7, multiples - remainder + 4}
: lucky_t{remainder * 2, multiples - remainder};
} ();
if ( digits.fours < 0 || digits.sevens < 0 )
{
return "-1";
}
else
{
std::string result(digits.fours, '4');
result.append(digits.sevens, '7');
return result;
}
}
Tested here.

Cross sum calculation, Can anyone explain the code please?

i'm going to learn C++ at the very beginning and struggling with some challenges from university.
The task was to calculate the cross sum and to use modulo and divided operators only.
I have the solution below, but do not understand the mechanism..
Maybe anyone could provide some advice, or help to understand, whats going on.
I tried to figure out how the modulo operator works, and go through the code step by step, but still dont understand why theres need of the while statement.
#include <iostream>
using namespace std;
int main()
{
int input;
int crossSum = 0;
cout << "Number please: " << endl;
cin >> input;
while (input != 0)
{
crossSum = crossSum + input % 10;
input = input / 10;
}
cout << crossSum << endl;
system ("pause");
return 0;
}
Lets say my input number is 27. cross sum is 9
frist step: crossSum = crossSum + (input'27' % 10 ) // 0 + (modulo10 of 27 = 7) = 7
next step: input = input '27' / 10 // (27 / 10) = 2.7; Integer=2 ?
how to bring them together, and what does the while loop do? Thanks for help.
Just in case you're not sure:
The modulo operator, or %, divides the number to its left by the number to its right (its operands), and gives the remainder. As an example, 49 % 5 = 4.
Anyway,
The while loop takes a conditional statement, and will do the code in the following brackets over and over until that statement becomes false. In your code, while the input is not equal to zero, do some stuff.
To bring all of this together, every loop, you modulo your input by 10 - this will always return the last digit of a given Base-10 number. You add this onto a running sum (crossSum), and then divide the number by 10, basically moving the digits over by one space. The while loop makes sure that you do this until the number is done - for example, if the input is 104323959134, it has to loop 12 times until it's got all of the digits.
It seems that you are adding the digits present in the input number. Let's go through it with the help of an example, let input = 154.
Iteration1
crossSum= 0 + 154%10 = 4
Input = 154/10= 15
Iteration2
crossSum = 4 + 15%10 = 9
Input = 15/10 = 1
Iteration3
crossSum = 9 + 1%10 = 10
Input = 1/10 = 0
Now the while loop will not be executed since input = 0. Keep a habit of dry running through your code.
#include <iostream>
using namespace std;
int main()
{
int input;
int crossSum = 0;
cout << "Number please: " << endl;
cin >> input;
while (input != 0) // while your input is not 0
{
// means that when you have 123 and want to have the crosssum
// you first add 3 then 2 then 1
// mod 10 just gives you the most right digit
// example: 123 % 10 => 3
// 541 % 10 => 1 etc.
// crosssum means: crosssum(123) = 1 + 2 + 3
// so you need a mechanism to extract each digit
crossSum = crossSum + input % 10; // you add the LAST digit to your crosssum
// to make the number smaller (or move all digits one to the right)
// you divide it by 10 at some point the number will be 0 and the iteration
// will stop then.
input = input / 10;
}
cout << crossSum << endl;
system ("pause");
return 0;
}
but still dont understand why theres need of the while statement
Actually, there isn't need (in literal sense) for, number of digits being representable is limited.
Lets consider signed char instead of int: maximum number gets 127 then (8-bit char provided). So you could do:
crossSum = number % 10 + number / 10 % 10 + number / 100;
Same for int, but as that number is larger, you'd need 10 summands (32-bit int provided)... And: You'd always calculate the 10 summands, even for number 1, where actually all nine upper summands are equal to 0 anyway.
The while loop simplifies the matter: As long as there are yet digits left, the number is unequal to 0, so you continue, and as soon as no digits are left (number == 0), you stop iteration:
123 -> 12 -> 1 -> 0 // iteration stops, even if data type is able
^ ^ ^ // to store more digits
Marked digits form the summands for the cross sum.
Be aware that integer division always drops the decimal places, wheras modulo operation delivers the remainder, just as in your very first math lessons in school:
7 / 3 = 2, remainder 1
So % 10 will give you exactly the last (base 10) digit (the least significant one), and / 10 will drop this digit afterwards, to go on with next digit in next iteration.
You even could calculate the cross sum according to different bases (e. g. 16; base 2 would give you the number of 1-bits in binary representation).
Loop is used when we want to repeat some statements until a condition is true.
In your program, the following statements are repeated till the input becomes 0.
Retrieve the last digit of the input. (int digit = input % 10;)
Add the above retrieved digit to crosssum. (crosssum = crosssum + digit;)
Remove the last digit from the input. (input = input / 10;)
The above statements are repeated till the input becomes zero by repeatedly dividing it by 10. And all the digits in input are added to crosssum.
Hence, the variable crosssum is the sum of the digits of the variable input.

Number guessing game with illogical bug

#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
srand(time(NULL));
int main(){
int botguess;
int playerinput;
int mi=1, ma=100;
int turns = 0;
cout<<" what do you want guessed:";
cin>> playerinput;
cout<< "time for me to start guessing\n";
for(int i = 0;i < 50;i++) {
botguess = rand() % ma + mi;
if(playerinput > botguess){ //<--the problem
mi = botguess;
}
if(playerinput < botguess) {
ma = botguess;
}
cout<<"Max:"<<ma<<"\n"<<botguess<<"\n";
Sleep(1000);
if(botguess == playerinput)
{
cout<<"you win";
}
}
cin.get();
return 0;
}
So I've been tearing my hair out about why logically this doesn't work. This is a program that is supposed to guess the players number quickly but not instantly. The program doesn't perform like it looks.
The line that I noted causes a bug where the max number possible is being ignored. im getting number that are 100+ but under 200 and i don't know why. When I remove the lines concerning the mi variable nested in the statement in the for loop. The program doesn't go over 100 but I don't get the other end of the program solving the player number.
Also if you figure it out can you please explain it to me I don't just want a answer.
botguess = rand() % (ma - mi + 1) + mi
You don't want ma different numbers, you want much less of them. Look at an example: (5..10) contains 6 different numbers: [5, 6, 7, 8, 9, 10]; but if you do rand() % 10 + 5, you're getting numbers from 5 (5 + 0) to 14 (5 + 9). What you need is rand() % 6 + 5, where 6 is 10 - 5 + 1.
The problem you are having is caused by the fact that mi is set to botguess, which can easily be greater than zero, then on the next cycle if ma is still 100 (or anywhere near it), you're going to sometimes get numbers greater than 100 set into botguess.
Edit added: the % operator in C++ is mod division (ie. gives the remainder of integer division) So for example, 98 % 100 + 15 will be 98 + 15, i.e. 113
This link may help you:
http://www.cplusplus.com/reference/cstdlib/rand/

How does the modulus operator work?

Let's say that I need to format the output of an array to display a fixed number of elements per line. How do I go about doing that using modulus operation?
Using C++, the code below works for displaying 6 elements per line but I have no idea how and why it works?
for ( count = 0 ; count < size ; count++)
{
cout << somearray[count];
if( count % 6 == 5) cout << endl;
}
What if I want to display 5 elements per line? How do i find the exact expression needed?
in C++ expression a % b returns remainder of division of a by b (if they are positive. For negative numbers sign of result is implementation defined). For example:
5 % 2 = 1
13 % 5 = 3
With this knowledge we can try to understand your code. Condition count % 6 == 5 means that newline will be written when remainder of division count by 6 is five. How often does that happen? Exactly 6 lines apart (excercise : write numbers 1..30 and underline the ones that satisfy this condition), starting at 6-th line (count = 5).
To get desired behaviour from your code, you should change condition to count % 5 == 4, what will give you newline every 5 lines, starting at 5-th line (count = 4).
Basically modulus Operator gives you remainder
simple Example in maths what's left over/remainder of 11 divided by 3? answer is 2
for same thing C++ has modulus operator ('%')
Basic code for explanation
#include <iostream>
using namespace std;
int main()
{
int num = 11;
cout << "remainder is " << (num % 3) << endl;
return 0;
}
Which will display
remainder is 2
It gives you the remainder of a division.
int c=11, d=5;
cout << (c/d) * d + c % d; // gives you the value of c
This JSFiddle project could help you to understand how modulus work:
http://jsfiddle.net/elazar170/7hhnagrj
The modulus function works something like this:
function modulus(x,y){
var m = Math.floor(x / y);
var r = m * y;
return x - r;
}
You can think of the modulus operator as giving you a remainder. count % 6 divides 6 out of count as many times as it can and gives you a remainder from 0 to 5 (These are all the possible remainders because you already divided out 6 as many times as you can). The elements of the array are all printed in the for loop, but every time the remainder is 5 (every 6th element), it outputs a newline character. This gives you 6 elements per line. For 5 elements per line, use
if (count % 5 == 4)