Project Euler / programming problems

Perhaps it’s a cheat to use the information of how many numbers there are.

It does make the solution unscalable, but we weren’t asked to make it scalable, so eh. And if I did want to make it work for any parameter, all I’d have to do is put the numbers into a list and cite the list’s length, which isn’t much work.

To quote shuna, with my “solution on paper” “the coding was straight forward enough”.

Python
def problem_2():
    a, b, c = 1, 2, 3;
    sumN = 0;

    for i in range(11):
        sumN += b;
        
        a = b + c;
        b = a + c;
        c = a + b;
        
    return sumN;
Ruby
def problem_2
	a, b, c = 1, 2, 3;
    sumN = 0;
    
    11.times {
    	sumN += b;
        
        a = b + c;
        b = a + c;
        c = a + b;
    }
    
    sumN;
end

(I removed return for Feijoa, but I like my semicolons.)

Perl
sub problem_2 {
	my $a = 1;
	my $b = 2;
	my $c = 3;
	
	my $sumN = 0;
	
	for (1..11) {
		$sumN += $b;
		
		$a = $b + $c;
		$b = $a + $c;
		$c = $a + $b;
	}
	
	return $sumN;
}
Common Lisp
(defun problem-2 ()
	(let ((a 1) (b 2) (c 3) (sum-n 0))
		(loop for i from 1 to 11
			do
				(incf sum-n b)
				
				(setq
					a (+ b c)
					b (+ a c)
					c (+ a b)))
	
	sum-n))
3 Likes

(About problem 1.)

Your Ruby code is practical, but it’s kind of complicated and not very Ruby-like. Well, you can write Ruby however you want, but most code I see is written more simply, without semicolons or return.

Summing things yourself and writing for is also usually not necessary; it’s more pleasant and maybe efficient to make use of the methods in the Enumerable module when you can.

Also, since this is Ruby, why not dynamically modify a core class to allow it to be more expressive?

Summary
def problem1
  Numeric.class_eval do
    def divisible_by_3_or_5
      self % 3 == 0 or self % 5 == 0
    end
  end

  (0...1000)
    .select(&:divisible_by_3_or_5)
    .sum
end

(Thanks @shinuito for the ... tip!)

3 Likes

Because I’ve barely coded in this decade :D

I’m trying to brush up, but you’ve got to let me play a bit in the toddler pool until I can cope with the sharks in the deep end.

Right now, if my code runs and comes up with the right answer, I’m already pretty happy.

I’m watching and learning, though.

3 Likes

Hmm, is return good style in Python?

I think I learnt that it was, but if it isn’t in Ruby then idk.

I believe return is required in Python if you want to get anything back!

2 Likes

If you use a while loop, you could test that b < 4 million instead

1 Like

Less cheating, more commas, and a practical use for semicolon:

ruby
def problem_2
  a, b = 1, 2

  (1..)
    .lazy
    .map { a, b = b, a + b; a }
    .select(&:even?)
    .take_while { |x| x <= 4_000_000 }
    .sum
end

(Is there something better to use than (1..)?)

I’m fully committed to writing the worst solutions out of the entire thread with the help of my old friend javas scriptum

Problem 2, functional via js
const getEvenFibbSumUpTo = (limit, last=1, current=1, sum=0) => current < limit ? getEvenFibbSumUpTo(limit, current, current + last, sum + (current * (1 - (current%2)))) : sum;

getEvenFibbSumUpTo(4000000); 
4 Likes

I mean the fun part about the javascript ones is being able to run it in browser :slight_smile:

2 Likes

One would think that I’d get myself some nice node environment with a file watcher and an auto compilation-and-run on save, but I’ve actually made all of these so far in the developer’s console in the browser.

2 Likes

here’s my code, any ideas on improving efficiency?

Summary
def sumEvenFib(a):
    i = 1
    j = 1
    k = 0
    evenSum = 0
    while (i+j) < a:
        k = i + j
        evenSum = evenSum + k
        j = i + k
        i = j + k
    return  evenSum

print(sumEvenFib(4000000))

Surely not the worst solution of the thread, but certainly the most painstaking function naming ^^

One would be to use a do… while loop if python has them to remove the add operation on every condition check by reusing a variable. But it depends on how far you want to go with the “efficiency”. The most efficient solution would have a predetermined hardcoded array of all the even fibb numbers and then just reducing it to a sum.

How come? It’s descriptive of its exact functionality in a java style.

1 Like
Problem 2, Python
a = s = 0
b = 2
while (b < 4e6):
    s += b
    [a, b] = [b, a + 4*b]
print(s)
6 Likes

That’s a question of preference I would say, it certainly has the advantage of minimal ambiguity

Yeah that is a fair point, I was mainly wondering about general runtime class. But afaik there is no closed expression to get Fibbonacci numbers. It does converge towards Φ^x eventually, but I don’t think it’s possible to use this to get a precise result fast.

Anton’s solution does shave off considerably though, that is quite elegant ^^

1 Like

Yeah I honestly don’t know much about optimising scripting languages aside from the algorithmic complexity. I think if you want an optimal solution to begin with you should use a compiled language, preferably one that is compiled directly to ASM, and then go from there. For instance c++ has templates so I think you can pre-generate a fibb array up to N during compile time, then do a manual malloc and traverse it by direct pointers to the memory with the compiler optimisations disabled so as to bypass CPU caching. That or simply switching over to ASM in the first place.
Or actually a bit of a hacky way to save time is to compile C into ASM with optimisations disabled and then manually edit the generated ASM code to optimise it.

Actually, F_n converges towards phi^n / sqrt(5) very fast, so we can calculate the answer as a geometric sum:

Math
from math import log, ceil, sqrt
N = 4e6
phi = (1 + sqrt(5))/2
x = phi**3
n = ceil(log(sqrt(5)*N, x))
print(round((1-x**n)/(1-x)/sqrt(5)))

This makes use of the well-known property round(a + b) = round(a) + round(b) :wink:

And of course this needs a lot of decimal precision, probably less efficient than iterating.

3 Likes

Depends on what you mean by closed. There is a formula in terms of powers of the golden ratio.

It’s on Wikipedia,

Just depends on whether you want to deal with powers of floating point numbers or instead maybe symbolically/algebraically with the properties of phi. You can always reduces powers of it into linear terms since it satisfies a quadratic polynomial. Seems to be similar with psi=1-phi.

You can calculate the Fibonacci numbers with matrices and look for some tricks with fast exponential of matrices. I don’t know if any of it is better or worse though. Lots of ideas either way.

There’s also identities like

image

also on the Wikipedia.

2 Likes