Herhangi bir çözüm doğru çözüm mü?

8 Cevap php

Ben her zaman "Yeterince iyi şu işleri", bir süre ile bağlı olan bir programlama meydan okuma çözümü sonra kendi kendime düşünüyorum.

Benim görüşüme göre, bu gerçekten doğru zihniyet olduğunu düşünmüyorum ve ben her zaman büyük performansı ile kod çalışıyor gerektiğini düşünüyorum.

Bu dedi ile Neyse, ben sadece bir ProjectEuler soru çalıştı. Özellikle 2. soru.

Bunu nasıl çözüm geliştirilmiş olabilir. Ben onun really ayrıntılı gibi hissediyorum. Sanki özyinelemede önceki sayıyı geçiyorum.

<?php
  /* Each new term in the Fibonacci sequence is generated by adding the previous two
     terms. By starting with 1 and 2, the first 10 terms will be:

     1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

     Find the sum of all the even-valued terms in the sequence which do not exceed
     four million.
   */
   function fibonacci ( $number, $previous = 1 ) {
     global $answer;
     $fibonacci = $number + $previous;
     if($fibonacci > 4000000) return;
     if($fibonacci % 2 == 0) {
       $answer = is_numeric($answer) ? $answer + $fibonacci : $fibonacci;
     }
     return fibonacci($fibonacci, $number);
   }
   fibonacci(1);
   echo $answer;
?>

Note this isn't homework. I left school hundreds of years ago. I am just feeling bored and going through the Project Euler questions

8 Cevap

I always think to myself after solving a programming challenge that I have been tied up with for some time, "It works, thats good enough".

I don't think this is really the correct mindset, in my opinion and I think I should always be trying to code with the greatest performance.

Sunulan klasik şeylerden biri Code Complete programcılar, bir hedef verilmiş, birçok ölçüt birini kullanarak "optimum" bilgisayar programı oluşturabilir, ama bu imkansız all in için optimize etmek olduğunu kerede parametreleri. Gibi parametreler

  • Kod readabilty
  • Kod Çıktı anlaşılabilirliği
  • Kod uzunluğu (satır)
  • Kod Yürütme Hız (performans)
  • Kod yazma hızı

Aynı anda hepsi için optimize hayal kırıklığı içinde bir egzersiz olabilir, ya da bir overdesigned sisteme neden olabilir ki bu parametrelerden herhangi biri için optimize etmek için çekinmeyin, ama akılda tutmak.

Siz kendinize sormalısınız: hedefleriniz nelerdir? Bu durumda ne "yeterince iyi" nedir? Sadece öğrenme ve işler daha adil kusursuz bir program oluşturmak için sonsuz zaman alır farkında olmak, bunun için gitmek elbette, optimize edilmiş, ve zaman kendi içinde ve değerlidir yapmak istiyor iseniz.

You can avoid the mod 2 section by doing the operation three times (every third element is even), so that it reads: $fibonacci = 3*$number + 2*$previous; and the new input to fibonacci is ($fibonnacci,2*$number+$previous) I'm not familiar with php, so this is just general algorithm advice, I don't know if it's the right syntax. It's practically the same operation, it just substitutes a few multiplications for moduluses and additions.

Ayrıca, hatta $ sayı ve sırayla ondan önce garip biri olarak önceki $ (Eğer 1 $ olarak önceki 2, $ olarak numarası ile başlar, ve toplam da 2 başlamak olabilir) ile başlar emin olun .

Fibonacci (Problem 2) unut, ben Euler sadece peşin söylüyorlar. Her soru için uygun kodu bulmak için zaman kaybetmeyin.

Cevabınız One minute rule hasıl olursa, o zaman bir sonraki denemek için iyi. Birkaç sorunlardan sonra, sert şeyler alacak ve bu hedefe ulaşmak için yazmak yaparken kodunu optimize olacaktır

Burada diğerleri de bunu söyledi, "Bu gerçek business sorunları vs örnek sorular ile sorunun bir parçasıdır"

Bu sorunun cevabı nedenlerle bir dizi için cevap vermek çok zordur:

  • Dil büyük bir rol oynar. Eğer "beliğ daha az" kendi çözüm bulacağız bir uyumsuzluğu ile karşı karşıya iseniz, bazı dillerin çok daha uygun bazı sorunlar ve so
  • Bu sorunu çözmek için daha fazla zaman daha büyük olasılıkla size (tersi de çok zaman yapar bazen doğru olsa üzerinde düşünmek) sizin gibi bir çözüm gelecek, sen sorunu çözmek için ne kadar zaman bağlıdır
  • Bu genel memnuniyet düzeyine bağlıdır. Ben parçaları büyük düşündüm çeşitli projeler üzerinde çalıştı ve güzel kodlanmış ve diğer parçaları nerede mutlak çöp, ama onlar dışında ben adrese zaman vardı ne uğradılar.

Ben onun iyi bir çözüm düşünüyorsanız alt çizgi ve müşteri / alıcı / takım / etc süre sonra onun iyi bir çözüm katılıyorum sanırım. Sen ileride fikrinizi değiştirebilir ama şimdi onun iyi bir çözüm için olabilir.

Sorunu çözmek için kod çalıştırmak için yaklaşık bir dakika fazla sürmemesi gerektiğini kılavuz kullanın. Yani IMO, Euler sorunları için en önemli şey.

Bunun ötesinde, sadece okunabilir olduğundan emin olun - kolayca kod nasıl çalıştığını görebilirsiniz emin olun. Zaten bunu çözmek gerektiğini biliyorum çünkü - bu şekilde, daha kolay Hiç sırayla daha hızlı bir şekilde bu sorunu çözmek sağlar giderildiğini Euler sorunlardan biri gibi bir sorun olsun şeylerin nasıl çalıştığını görebilirsiniz.

Kendiniz için diğer kriterleri de ayarlayabilirsiniz, ama ben yukarıda ve Euler sorunların niyeti ötesine gidiyor düşünmek - benim için, sorunların bağlamı içinde başka bir şey daha verimlilik ve okunabilirlik odaklanarak için çok daha uygun görünüyor

Ben aslında bu test etmedi ... ama ben şahsen "halletmek" çağırmadan önce bu çözüm içinde çözmeye çalıştı bir şey vardı.

Globals bir miktar argümanı ile özyinelemeye uygulanması ile mümkün olduğunca kaçınmak

EDIT: Güncelleştirme nnythm algoritması önerisine göre (serin!)

function fibonacci ( $number, $previous, $sum ) {
    if($fibonacci > 4000000) { return $sum; }
    else {
        $fibonacci = 3*$number + 2*$previous;
        return fibonacci($fibonnacci,2*$number+$previous,$sum+$fibonacci); 
    }
}
echo fibonacci(2,1,2);

[Silkme]

Çözeltisi şartları ile değerlendirilmelidir. Tüm gereksinimleri memnun iseniz, o zaman her şey moxy olduğunu. Tüm gereksinimlerin karşılandığı, ve bizzat çözümü ile memnun iseniz, o zaman belki gereksinimleri yeniden değerlendirilmesi gerekir. S: Biz proje yönetimi ve iş gibi şeyleri içine başlar çünkü, yaklaşık kadarıyla bu meta-fizik soru alabilir olarak bulunuyor

Ahem, senin Euler-Proje soru, sadece benim iki pence ile ilgili:

  1. Özyinelemeli karşıt olarak, tekrarlı için üstlenmeden dikkate
  2. Serinin her üçüncü dönem bile fark nedir? Eğer başlangıç ​​dönem verilmiştir kez modulo gerek yok

Örneğin

public const ulong TermLimit = 4000000;

public static ulong CalculateSumOfEvenTermsTo (ulong termLimit)
{
    // sum!
    ulong sum = 0;

    // initial conditions
    ulong prevTerm = 1;
    ulong currTerm = 1;
    ulong swapTerm = 0;

    // unroll first even term, [odd + odd = even]
    swapTerm = currTerm + prevTerm;
    prevTerm = currTerm;
    currTerm = swapTerm;

    // begin iterative sum,
    for (; currTerm < termLimit;)
    {
        // we have ensured currTerm is even,
        // and loop condition ensures it is 
        // less than limit
        sum += currTerm;

        // next odd term, [odd + even = odd]
        swapTerm = currTerm + prevTerm;
        prevTerm = currTerm;
        currTerm = swapTerm;

        // next odd term, [even + odd = odd]
        swapTerm = currTerm + prevTerm;
        prevTerm = currTerm;
        currTerm = swapTerm;

        // next even term, [odd + odd = even]
        swapTerm = currTerm + prevTerm;
        prevTerm = currTerm;
        currTerm = swapTerm;
    }
    return sum;
}

Yani, [pratikte] daha hızlı olması için belki de daha kod satırları, ama garantili. Tekrarlanan bir yaklaşım "zarif" olarak değil, ama özyinelemeli yöntem çağrıları kaydeder ve yığın alanı kazandırır. İkincisi, [açıkça bir döngü genişleyen olduğunu] terimi nesil unrolling Eğer modülü işlemi ve test yapmak zorunda kalacaktı sayısını azaltır şartlı "bile" dedi. Genişleyen da son koşullu [cari dönem sınırından daha az ise] değerlendirilir sayısını azaltır.

Bu "daha iyi", hayır, bu sadece "bir" çözüm edilir.

Php ile tanıdık, ama oldukça iyi tercüme olabilir emin değilim C # için özür dilemek.

:) Umarım bu yardımcı olur

Şerefe

Bu bir çözüm ya da daha da geliştirmek isteyip istemediğinizi mutlu olup olmadığını, tamamen sizin tercihinizdir. Bir kaba kuvvet çözüm çok uzun sürer, ve bir akıllı algoritma aramak zorunda olduğu birçok proje Euler sorun vardır.

Problem 2 doesn't require any optimisation. Your solution is already more than fast enough. Still let me explain what kind of optimisation is possible. Often it helps to do some research on the subject. E.g. the wiki page on Fibonacci numbers contains this formula

fib (n) = (phi ^ n - (1-phi) ^ n) / sqrt (5)

phi altın oran olduğu. Yani

phi = (sqrt (5) +1) / 2.

O yalan (n) kullanırsanız yaklaşık phi ^ n / sqrt (5) daha sonra by M daha küçük büyük Fibonacci sayısı indeksi bulabilirsiniz

n = kat ((M * sqrt (5)) / log (phi) log).

Örneğin M = 4000000, biz bu nedenle daha küçük 4000000 en Fibonacci numarası (33) fib, n = 33 alır. Öyle ki yalan (n) gözlenebilir, n, 3 katları. da Fibonacci bir nedenle toplamıdır bile sayılar

fib (0) + fib (3) + fib (6) + ... + fib (3k)

To find a closed form we use the formula above from the wikipedia page and notice that the sum is essentially just two geometric series. The math isn't completely trivial, but using these ideas it can be shown that

fib (0) + fib (3) + fib (6) + ... + fib (3k) = (fib(3k + 2) - 1) /2 .

Since fib(n) has size O(n), the straight forward solution has a complexity of O(n^2). Using the closed formula above together with a fast method to evaluate Fibonacci numbers has a complexity of O(n log(n)^(1+epsilon)). For small numbers either solution is of course fine.