acending repetitious function without array 1 22 333 4444 55555 [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
F is a function that number x has been repeated in an ascending order f(x).
x : 1 2 3 4 5 6 7 8 9 10
f(x): 1 2 2 3 3 3 4 4 4 4
my function gets 'x' and gives 'f(x)' and it has to do it without array but it goes wrong in high numbers.
int main()
{
int n;
cin>>n;
int i=1,a=1;
if(n==1)
cout<<'1';
else{
while(true){
a++;
i=i+a;
if(i>=n)
break;
}
}
cout<<a;
return 0;
}

TL;DR
f(x) = floor(0.5 + sqrt(1 + 8 * (x - 1)) / 2)
Explanation
Well, since this is a mathematical problem, just solve it with math ;)
One thing to notice is the correlation between the table and the triangular numbers:
h(x) = sum(range(1, x)) = x*(x + 1)/2 //triangular number
x 1 2 3 4 5 6 7 8 9 10
f(x) 1 2 2 3 3 3 4 4 4 4
h(f(x)) 1 3 3 6 6 6 10 10 10 10
So how does that help us? Well, we can write a new equation:
h(f(x)) = x | x = max({n | f(n) = f(x)})
And logically for the inverse the following should apply:
h^-1(x) = f(x)
No we've got two options:
Call it a day and just solve the rest via brute-force:
i = 1
sum = 0
while sum < x:
sum += i
i++
return i - 1
Or build our function h^-1(x):
h(x) = y = (x+1)x/2
h^-1(y) = x with h(x) = y
x ^ 2 + x - 2y = 0
solve for x using the quadratic formula:
x = 0.5 +/- sqrt(1 + 8y) / 2
Now this formula still lacks a few things:
we get two results, one of which is negative. We can just throw the negative result away, so +/- turns into +
this formula is 0-based. To be honest, I'm still trying to figure out why. Solution: simply decrement y by 1 to get the proper result
while this formula returns the correct result for the matching numbers, i.e. y = 3 -> x = 3, it returns floating-point numbers for other input, so we'll have to round down appropriately
Putting it together:
f(x) = floor(0.5 + sqrt(1 + 8 * (x - 1)) / 2)

int f(int x) {
return (x * (x + 1)) / 2;
}
int main() {
int n;
cin >> n;
int left = 1, right = n;
while(left < right) {
int mid = left + (right - left) / 2;
int val = f(mid);
if(val >= n) {
right = mid;
}
else {
left = mid + 1;
}
}
cout << left;
return 0;
}
Use binary search. Right now I am in mobile. I will add the explanation later if needed. Let me know if you don't understand anything.

Related

How modulus operation works in C++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Why do I get this output: 0 1 2 3 0 1 2 3 0 1 after running the code below? Doesn't the modulus operation finds the remainder after division of one number by another?
#include <iostream>
using namespace std;
int main ()
{
for (int i=0; i< 10; ++i)
cout << i % 4 << " ";
}
The answer is correct. '%' mean "reminder". The % operator is remainder operator. The A % B operator actually answer the question “If I divided A by B using integer arithmetic, what would the remainder be?”
dividend = quotient * divisor + remainder
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
.....
etc..
For negative number...
1 % (-4) = 1
(-2) % 4 = -2
(-3) % (-4) = -3
With a remainder operator, the sign of the result is the same as the sign of the dividend
you can read more at What's the difference between “mod” and “remainder”?
Yes, that's how modulus works. The output is correct.
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...
Take the number, remove as many 4's as you can. Whatever is left over is the modulus.
It does.0 / 4 = 0 remainder 01 / 4 = 0 remainder 1and so on.
Modulus operator returns the remainder after dividing the first number with the second one.
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
6 % 4 = 2
7 % 4 = 3
8 % 4 = 0
9 % 4 = 1

Decreasing Loop Interval by 1 in C/C++

Let's say I have 15 elements. I want to group them such a way that:
group1 = 1 - 5
group2 = 6 - 9
group3 = 10 - 12
group4 = 13 - 14
group5 = 15
This way I'll get elements in each group as below:
group1 = 5
group2 = 4
group3 = 3
group4 = 2
group5 = 1
As you can see loop interval is decreasing.
I took 15 just for an example. In actual programme it's user driven parameter which can be anything (hopefully few thousand).
Now what I'm looking for is:
Whatever is in group1 should have variable "loop" value 0, group2 should have 1, group3 should have 2 and so on... "loop" is an int variable which is being used to calculate some other stuff.
Let's put in other words too
I have an int variable called "loop". I want to assign value to it such a way that:
First n frames loop value 0 next (n -1) frames loop value 1 then next (n - 2) frames loop value 2 all the way to loop value (n - 1)
Let's say I have 15 frames on my timeline.
So n will be 5 ====>>>>> (5 + 4 + 3 + 2 + 1 = 15; as interval is decreasing by 1)
then
first 5 frames(1 - 5) loop is 0 then next 4 frames(6 - 9) loop is 1 then next 3 frames(10 - 12) loop is 2 then next 2 frames(13 - 14) loop is 3 and for last frame(15) loop is 4.
frames "loop" value
1 - 5 => 0
6 - 9 => 1
10 - 12 => 2
13 - 14 => 3
15 => 4
I've tried with modulo(%). But the issue is on frame 12 loop is 2 so (12 % (5 - 2)) remainder is 0 so it increments loop value.
The following lines are sample code which is running inside a solver. #loop is by default 0 and #Frame is current processing frame number.
int loopint = 5 - #loop;
if (#Frame % loopint == 0)
#loop += 1;
If I understand this correctly, then
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
for(int i = 1; i <= n; ++i) {
printf("%d: %f\n", i, ceil((sqrt(8 * (n - i + 1) + 1) - 1) / 2));
}
}
is an implementation in C.
The math behind this is as follows: The 1 + 2 + 3 + 4 + 5 you have there is a Gauß sum, which has a closed form S = n * (n + 1) / 2 for n terms. Solving this for n, we get
n = (sqrt(8 * S + 1) - 1) / 2
Rounding this upward would give us the solution if you wanted the short stretches at the beginning, that is to say 1, 2, 2, 3, 3, 3, ...
Since you want the stretches to become progressively shorter, we have to invert the order, so S becomes (n - S + 1). Therefore the formula up there.
EDIT: Note that unless the number of elements in your data set fits the n * (n+1) / 2 pattern precisely, you will have shorter stretches either at the beginning or in the end. This implementation places the irregular stretch at the beginning. If you want them at the end,
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int n2 = (int) ceil((sqrt(8 * n + 1) - 1) / 2);
int upper = n2 * (n2 + 1) / 2;
for(int i = 1; i <= n; ++i) {
printf("%d: %f\n", i, n2 - ceil((sqrt(8 * (upper - i + 1) + 1) - 1) / 2));
}
}
does it. This calculates the next such number beyond your element count, then calculates the numbers you would have if you had that many elements.

How to sum digits from integer in c++? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I want to sum digits of an integer. If I have 123 I want to sum 1+2+3. I found a program that works well but I don't understand how it works. Can you explain how it works?
#include <iostream>
using namespace std;
int main()
{
int n, sum;
cout << "Enter integer\n";
cin >> n;
sum = n/100 + (n/10)%10 + n%10;
cout << "sum = " << sum << endl;
}
How n/100 generates 1 from 123, (n/10)%10 2 from 123 and n%10 3 from 123
sum = n/100 + (n/10)%10 + n%10;
1) n/100
(n=123)
in this statement 123/100 means ans is = 1
2)(n/10)%10
here (123/10) firstly evaluate and ans is = 12, and then 12%10 gets evaluate and ans is = 2
3)n%10 again 123%10 evaluate ans is 3
then statement becomes
sum = 1 + 2 + 3
Note: % symbol gives remainder
These are very simple maths.
Here, n = 123
100 | 123 | 1
100
_________
23
Therefore the quotient is 1.
The same way, for 123/10,
10 | 123 | 12
10
___________
23
20
___________
3
So, 123/10 = 12. Now for (123/10)%10 = 12%10,
10 | 12 | 1
10
______
2
Therefore, (123/10)%10 = 12%10 = 2.
The same way, 123%10 = 3
Therefore, the answer is: 123/100 + (123/10)%10 + 123%10 = 1 + 2 + 3 = 6
(Note: a % b, here b divides a and returns the remainder)

How should I go about solving this recursion without trial and error

int sum_down(int x)
{
if (x >= 0)
{
x = x - 1;
int y = x + sum_down(x);
return y + sum_down(x);
}
else
{
return 1;
}
}
What is this smallest integer value of the parameter x, so that the returned value is greater than 1.000.000 ?
Right now I am just doing it by trial and error and since this question is asked via a paper format. I don't think I will have enough time to do trial and error. Question is, how do you guys visualise this quickly such that it can be solved easily. Thanks guys and I am new to programming so thanks in advance!
The recursion logic:
x = x - 1;
int y = x + sum_down(x);
return y + sum_down(x);
can be simplified to:
x = x - 1;
int y = x + sum_down(x) + sum_down(x);
return y;
which can be simplified to:
int y = (x-1) + sum_down(x-1) + sum_down(x-1);
return y;
which can be simplified to:
return (x-1) + 2*sum_down(x-1);
Put in mathematical form,
f(N) = (N-1) + 2*f(N-1)
with the recursion terminating when N is -1. f(-1) = 1.
Hence,
f(0) = -1 + 2*1 = 1
f(1) = 0 + 2*1 = 2
f(2) = 1 + 2*2 = 5
...
f(18) = 17 + 2*f(17) = 524269
f(19) = 18 + 2*524269 = 1048556
Your program can be written this way (sorry about c#):
public static void Main()
{
int i = 0;
int j = 0;
do
{
i++;
j = sum_down(i);
Console.Out.WriteLine("j:" + j);
} while (j < 1000000);
Console.Out.WriteLine("i:" + i);
}
static int sum_down(int x)
{
if (x >= 0)
{
return x - 1 + 2 * sum_down(x - 1);
}
else
{
return 1;
}
}
So at first iteration you'll get 2, then 5, then 12... So you can neglect the x-1 part since it'll stay little compared to the multiplication.
So we have:
i = 1 => sum_down ~= 4 (real is 2)
i = 2 => sum_down ~= 8 (real is 5)
i = 3 => sum_down ~= 16 (real is 12)
i = 4 => sum_down ~= 32 (real is 27)
i = 5 => sum_down ~= 64 (real is 58)
So we can say that sum_down(x) ~= 2^x+1. Then it's just basic math with 2^x+1 < 1 000 000 which is 19.
A bit late, but it's not that hard to get an exact non-recursive formula.
Write it up mathematically, as explained in other answers already:
f(-1) = 1
f(x) = 2*f(x-1) + x-1
This is the same as
f(-1) = 1
f(x+1) = 2*f(x) + x
(just switched from x and x-1 to x+1 and x, difference 1 in both cases)
The first few x and f(x) are:
x: -1 0 1 2 3 4
f(x): 1 1 2 5 12 27
And while there are many arbitrary complicated ways to transform this into a non-recursive formula, with easy ones it often helps to write up what the difference is between each two elements:
x: -1 0 1 2 3 4
f(x): 1 1 2 5 12 27
0 1 3 7 15
So, for some x
f(x+1) - f(x) = 2^(x+1) - 1
f(x+2) - f(x) = (f(x+2) - f(x+1)) + (f(x+1) - f(x)) = 2^(x+2) + 2^(x+1) - 2
f(x+n) - f(x) = sum[0<=i<n](2^(x+1+i)) - n
With eg. a x=0 inserted, to make f(x+n) to f(n):
f(x+n) - f(x) = sum[0<=i<n](2^(x+1+i)) - n
f(0+n) - f(0) = sum[0<=i<n](2^(0+1+i)) - n
f(n) - 1 = sum[0<=i<n](2^(i+1)) - n
f(n) = sum[0<=i<n](2^(i+1)) - n + 1
f(n) = sum[0<i<=n](2^i) - n + 1
f(n) = (2^(n+1) - 2) - n + 1
f(n) = 2^(n+1) - n - 1
No recursion anymore.
How about this :
int x = 0;
while (sum_down(x) <= 1000000)
{
x++;
}
The loop increments x until the result of sum_down(x) is superior to 1.000.000.
Edit : The result would be 19.
While trying to understand and simplify the recursion logic behind the sum_down() function is enlightening and informative, this snippet tend to be logical and pragmatic in that it does not try and solve the problem in terms of context, but in terms of results.
Two lines of Python code to answer your question:
>>> from itertools import * # no code but needed for dropwhile() and count()
Define the recursive function (See R Sahu's answer)
>>> f = lambda x: 1 if x<0 else (x-1) + 2*f(x-1)
Then use the dropwhile() function to remove elements from the list [0, 1, 2, 3, ....] for which f(x)<=1000000, resulting in a list of integers for which f(x) > 1000000. Note: count() returns an infinite "list" of [0, 1, 2, ....]
The dropwhile() function returns a Python generator so we use next() to get the first value of the list:
>>> next(dropwhile(lambda x: f(x)<=1000000, count()))
19

Is There a Triangle Wave Function? [duplicate]

This question already has answers here:
Is there a one-line function that generates a triangle wave?
(8 answers)
Closed 8 years ago.
in a for-loop with % to get a saw function, for example using a period of 5 printing 2 cycles would look like this:
for(auto i = 0; i < 5 * 2; ++i) cout << i % 5 << endl;
Results in:
0
1
2
3
4
0
1
2
3
4
I want a function returns a triangle wave, so for some function foo:
for(auto i = 0; i < 5 * 2; ++i) cout << foo(i, 5) << endl;
Would result in:
0
1
2
1
0
0
1
2
1
0
Is there such a function, or do I need to come up with my own?
Looks like a very similar question was answered here: Is there a one-line function that generates a triangle wave?
Taken from Noldorin answer:
Triangular Wave
y = abs((x++ % 6) - 3);
This gives a triangular wave of period 6, oscillating between 3 and 0.
Now put that in a function:
int foo(int inputPosition, int period, int amplitude)
{
return abs((inputPosition % period) - amplitude);
}
You'd have to make your own:
// Assumes 0 <= i < n
int foo(int i, int n) {
int ix = i % n;
if ( ix < n/2 )
return ix;
else
return n-1-ix;
}
I thought we should at least post the correct answer here before this question is closed cause it is a duplicate.
Eric Bainvile's answer is the correct one.
int foo(const int position, const int period){return period - abs(position % (2 * period) - period);}
However this gives a triangle wave with a range from [0, period] and a frequency of 2 * period and I want a range from [0, period / 2] and a cycle of period. This can be accomplished by just passing half of the period to foo or by adjusting the function:
int foo(const int position, const int period){return period / 2 - abs(position % period - period / 2);}
With such a simple function inlining seems preferable though so our final result will be:
for(auto position = 0; position < 5 * 2; ++position) cout << 5 / 2 - abs(position % 5 - 5 / 2) << endl;
Yielding the requested:
0
1
2
1
0
0
1
2
1
0