Project Euler problem 57
This requires in-depth research .... I wrote it violently .. Sorry... Change later...
We are also looking at the continuous score recently .. But it is still too busy ..
The following is a discussion in the Forum .. Sort it out later .. I feel like I have met a great guy ....
I realized that you are really strong !!
. Data?
Sumof dd?
Cword DW?
. Code
Start:
MoV ECx, 1000; loop counter
Finit
Fstcw cword; get control word
Or cword, 0c00h; adjust it for truncating
Fldcw cword; Modify FPU accordingly
Fld1
Fld1; initialize 2 registers
Start1:
FADD St, ST (1)
Fadd st (1), ST; expand the 2 numbers
Fxch; larger one in top register
Fldlg2
Sort ST (2)
Fyl2x; Get log of smaller number
Frndint; keep only the mantissa
Fldlg2
Sort ST (2)
Fyl2x; Get log of larger number
Frndint
Fcomip St, ST (1); compare the 2 mantissas
Fstp St
JZ @ F
INC sumof; increment if not the same
@@:
Dec ECx
Jnz start1
; Final result is in "sumof"
05 Sep 2005 pm
Kermitdfrog (penpencil/paper)
If you examine the function:
Len (numerator)/Len (denominator)
You'll notice a pattern.
1 <= x <2
X, 1, x, X, 1, x...
That is, an X (the value with different Len values. Records T in the first case of 1.) followed by 7 ones, X, then 4
Ones, then X.
So, if we measure the distances between X's, we get 8, and 5, (thats measured x to X. as follows:
X, 1, 1, 1, 1, 1, 1, 1, 1, x, 1, 1, 1, x...
0, 1, 2, 3, 4, 5, 6, 7, 8,
0, 1, 2, 3, 4, 5...
So the first answer you shoshould generate out of this is:
; This is just psuedocode.
Loop while I <= limit [
I + = 8
I + = 5
X + = 2
]
So, this can be easily simplified
Loop while I <= limit [
I + = 13
X + = 2
]
Further, you can break this down
2 * (Limit-1)/13)
That is, x + = 2 becomes 2 *
Limit is the upper limit of the function (1000 in this case)
You subtract one to eliminate the first X (which equals 1, and is therefore an exception to the pattern.) and
Divide by 13, which is the distance between pairs of X' s.
So, the number of non-1 values the Function
Len (N)/Len (d), where the limit value is 1000, is the following.
2 * (1000-1/13)
2 * (999/13)
1998/13
153.692
The function has a minor margin of error, so for relatively small limit-values, you shoshould be accurate enough
Just take the integer part, which I did, and, apparently, became the first person to post a non-bruteforce Method
To solve this problem.
Rockin.
PS, this officially puts me as more than 1/4 done. 13/50's of the way done, to be exact.
; Edit
This is a better formula, eliminates the INT (n) portion. Simple mod trick.
{[2 (Limit-1)-(Limit-1) mod 13)]/13} + 1
They shocould install mathtex or latex on this forum, so I can spew my genius in the appropriate form.
I believe the magic number in there (the + 1) accounts for the first X in the series -- not entirely sure, can't
Prove anything yet ..
Ribbet.
11 Sep 2005 AM
Kermitdfrog (penpencil/paper)
Just a quick update, the cleanest method I came up with uses Mathematica's floor function, it looks something
Like:
(2 * floor [(L-1)/13]) + 1
Although, I'm convinced there is a prettier way of doing this. That doesn't involve that uugly floor function.
~~ Joe
PS, how are you coming with your better way, zron?
Letting n (n) and D (n) represent the nth numerator and denominator, we have the recurrence relations
N (0) = 1, n (1) = 1, n (n) = 2 * n (n-1) + N (n-2) for N> = 2
D (0) = 0, D (1) = 1, D (n) = 2 * D (n-1) + d (n-2) for N> = 2
These are linear, homogeneous recurrence relations, relatively easily solvable by standard methods. (try
Solution of the Form A (n) = R ^ N, you'll get a quadratic equation for R, with roots R1 and R2, and the final
Solution will be a linear combination a (n) = A * R1 ^ N + B * R2 ^ n, where A and B are determined by the initial
Conditions .)
In this case, R1 = 1 + SQRT (2) and R2 = 1-sqrt (2), and
N (n) = (R1 ^ N + R2 ^ N)/(2)
D (n) = (R1 ^ N-R2 ^ N)/(2 * SQRT (2 ))
In fact, I 've actually set it so that when the above formula starts with n = 2, it coincides with the first
Numerator & denominator given in the problem.
Using the formula that the number of digits of X is 1 + floor (log10 (x), we see that
Numer_dig = 1 + floor (log10 (n) = 1 + floor (N * log10 (R1) + log10 (1 + (R2/R1) ^ N) -log10 (2 ))
Denom_dig = 1 + floor (log10 (D (N) = 1 + floor (N * log10 (R1) + log10 (1-(R2/R1) ^ N) -1.5 * log10 (2 ))
[Hide Code]
# Include <stdio. h>
# Include <math. h>
Int main (void)
{
INTN, count;
Doublec1, C2, power, numer_dig, denom_dig;
C1 = log10 (1.0 + SQRT (2.0 ));
C2 = 2.0 * SQRT (2.0)-3.0;
Count = 0;
For (n = 2; n <= 1001; n ++ ){
Power = POW (C2, N );
Numer_dig = 1 + floor (N * C1 + log10 (1 + power)-1.0 * log10 (2.0 ));
Denom_dig = 1 + floor (N * C1 + log10 (1-power)-1.5 * log10 (2.0 ));
If (numer_dig> denom_dig) Count ++;
}
Printf ("Count = % d/N", count );
Return 0;
}
31 Jan 2008 pm
Observ (C/C ++)
Using the recurrences
Nr = 2dr-1 + nr-1 [0]
Dr = dr-1 + nr-1 [1]
=> Nr = DR + dr-1 [2]
I end up
[Hide Code]
# Include <iostream>
# Include <iomanip>
# Include <gmpxx. h>
Int main ()
{
Mpz_class N (1393), D (985), powerten (1000 );
Int Sn = 7, Count = 0;
Do
{
Do
{
If (n> = powerten)
++ Count;
Mpz_class old_d (d );
D = N + D;
N = d + old_d;
} While (++ Sn <1000 & D <powerten );
Powerten * = 10;
} While (Sn <1000 );
STD: cout <"Answer:" <count <STD: Endl;
Return 0;
}
Amitg @ Athena. time./P57
Answer: 153
./P57 0.00 s user 0.00 s system 154% CPU 0.003 total
Incidentally, we can derive a pure recurrence for the denominator (not involving the numerator ):
Nr-1 + dr-1 = Dr [3] (from 1)
Nr-1-DR-1 = dr-2 [4] (from 2)
Subtracting 4 from 3:
2dr-1 = dr-DR-2
=> DR = 2dr-1 + dr-2 [5]
Now, given that n1 = 3 and D1 = 2, we get (from 1 and 2 ):
2n0 + D0 = 3
N0 + D0 = 2
We get N0 = D0 = 1.
This makes 5 the Pell number recurrence (see http://mathworld.wolfram.com/PellNumber.html), with values 1, 2, 5,
12, 29 ,...
Similarly, we can derive a recurrence relation only in N for the numerator:
2dr-1 = nR-nr-1 (from 0)
2dr = 2dr-1 + 2nr-1 (from 1)
=> Nr + 1-Nr = nR-nr-1 + 2nr-1
=> Nr + 1 = 2nr + nr-1
=> Nr = 2nr-1 + nr-2 [6]
This is the same recurrence relation as the denominator, but with different seed values, so it does not generate
Pell numbers.
I found it easier to use the mutually dependent recurrences, however.