2010-11-22 18 views
1

Ich entschied mich heute, Projekt Euler Problem 17 zu versuchen, und ich schrieb schnell einen ziemlich schnellen Code in C++, um es zu lösen. Aus irgendeinem Grund ist das Ergebnis jedoch falsch. Die Frage ist:Projekt Euler Problem 17 - Was ist los?

Wenn die Zahlen 1 bis 5 in Worten ausgeschrieben werden: eins, zwei, drei, vier, fünf, dann werden insgesamt 3 + 3 + 5 + 4 + 4 = 19 Buchstaben verwendet.

Wenn alle Zahlen von 1 bis einschließlich 1000 (eintausend) in Worten geschrieben wären, wie viele Buchstaben würden verwendet?

HINWEIS: Leerzeichen oder Bindestriche nicht zählen. Zum Beispiel enthält 342 (dreihundertzweiundvierzig) 23 Buchstaben und 115 (einhundertfünfzehn) enthält 20 Buchstaben. Die Verwendung von "und" beim Schreiben von Nummern entspricht der britischen Verwendung.

Ich weiß wirklich nicht warum, denn ich habe jeden Teil meines Programms gründlich überprüft und ich kann nichts falsch finden. Die einzige Sache, die ich finden könnte, ist, wenn ich auf 1000 überprüfe, prüft meine while-Schleife nicht richtig. Ich habe das behoben, indem ich das Limit meiner while-Schleife auf < 1000 statt < 1001 gesenkt und einfach 11 (onethousand = 11) manuell zur Summe addiert habe. Und trotzdem funktioniert es nicht. Ich würde es wirklich schätzen, wenn Sie mir sagen könnten, was los ist. Ich bin mir sicher, dass mein Code ziemlich schlecht ist, aber es ist in ein paar Minuten erledigt. Also hier ist es:

int getDigit (int x, int y) 
{ 
return (x/(int)pow(10.0, y)) % 10; 
} 

int main() 
{ 
string dictionary[10] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; 
string dictionary2[18] = { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" }; 
string dictionary3[10] = { "onehundred", "twohundred", "threehundred", "fourhundred", "fivehundred", "sixhundred", "sevenhundred", "eighthundred", "ninehundred", "onethousand" }; 

int i = 1; 
int last; 
int first; 
int middle; 

_int64 sumofletters = 0; 

while (i < 10)  //OK 
{ 
    sumofletters += dictionary[i].length(); 

    i++; 
} 

cout << sumofletters << endl; 

while (i < 20)  //OK 
{ 
    last = i % 10; 

    sumofletters += dictionary2[last].length(); 

    i++; 
} 

while (i < 100)  //OK 
{ 
    first = (i/10) + 8; 
    last = i % 10; 

    if (last != 0) 
    { 
    sumofletters += dictionary2[first].length() + dictionary[last].length(); 
    } 

    else 
    sumofletters += dictionary2[first].length(); 

    i++; 
} 

cout << sumofletters << endl; 

while (i < 1000)  //OK 
{ 
    last = i % 10; 
    first = (i/100) - 1; 
    middle = (getDigit(i, 1)) + 8; 

    if (middle != 0 && last != 0) //OK 
    { 
    if (middle == 1) 
    sumofletters += dictionary3[first].length() + dictionary2[last].length() + 3; 
    else 
    sumofletters += dictionary3[first].length() + dictionary2[middle].length() + dictionary[last].length() + 3; 
    } 

    else if (last == 0 && middle != 0) //OK 
    { 
    if (middle == 1) 
    sumofletters += dictionary3[first].length() + 6; 
    else 
    sumofletters += dictionary3[first].length() + dictionary2[middle].length() + 3; 
    } 

    else if (middle == 0 && last != 0) //OK 
    sumofletters += dictionary3[first].length() + dictionary[last].length() + 3; 

    else 
    sumofletters += dictionary3[first].length(); 

    i++; 
} 

sumofletters += 11; 

cout << sumofletters << endl; 

return 0; 
} 
+1

Für diejenigen, die nicht mit Project Euler Problem 17 vertraut sind, könnten Sie erklären, was es ist oder zumindest einen Link geben. Sie können nicht erwarten, dass die Leute Ihnen sagen, wo das Problem liegt, wenn sie nicht wissen, was das Programm tun soll. – ereOn

+0

Oh ja .. vergaß das.Bearbeitet: P – Lockhead

+2

Ich schlage vor, Sie lösen Ihr Rechenpuzzle in einer Computer-Mode: Holen Sie sich die Ausgabe in einer Form, die leicht verifiziert werden kann - drucken Sie die textliche Beschreibung jeder Zahl, zusammen mit Ihrer Berechnung der Anzahl der Buchstaben, dann haben a durchschauen und vor allem in den eher ungewöhnlichen Fällen eine Plausibilitätsprüfung durchführen. –

Antwort

1

Das Problem scheint mit dieser Linie zu sein:

middle = (getDigit(i, 1)) + 8; 

Sie fügen 8 auf diese Nummer - vermutlich als ein in Ihr dictionary2 versetzt zu agieren - aber im folgenden if-Anweisungen, Sie Fälle, wo es braucht um 0 zu sein. Diese können niemals zufrieden sein, es sei denn, getDigit würde -8 zurückgeben.

Anstatt Ihren Offset dort hinzuzufügen, fügen Sie ihn hinzu, wenn Sie ihn brauchen - oder noch besser, speichern Sie diese Dinge nicht im selben Wörterbuch.

Noch besser wäre eine völlig andere Struktur: schreibe eine Funktion, die den String für eine Zahl generiert, und nimm dann die Länge dieses Strings für deine Zählung. Dies wird es auch viel einfacher machen, Probleme wie diese zu debuggen, weil Sie die tatsächliche Länge der Kette sehen können.

+0

Danke! Es funktioniert jetzt. : D – Lockhead

2

vierzig ist falsch und sollte vierzig sein.

Überprüfen Sie Ihre Vergleiche Mitte == 0/Mitte! = 0/Mitte = 0. Gehen Sie zurück, wo Sie Mitte berechnen. Das ist falsch.

Das Beheben beider von denen erhält die richtige Antwort.

+0

Das Ergebnis ist immer noch falsch = [ – Lockhead

+0

+1. Aber so unfair für jemanden, dessen Englisch nicht fließend ist! ;) – ereOn

+0

Zweites Update hinzugefügt und es bekommt jetzt die richtige Antwort. – marcog

4

Anstatt tun Ihre Arbeit für Sie:

es aufgeteilt in kleinere Funktionen. Dann können Sie jede Funktion unabhängig testen.

Schreiben Sie einige Komponententests dann, wenn Sie benötigen, oder verwenden Sie einfach einen Debugger und Schritt und machen Sie es auch auf ein wenig Papier und sehen Sie, wo Sie und Ihr Code divergieren.

+0

+1 Das Aufteilen und Testen von Teilen fängt diese Art von Fehlern in fast allen Fällen ein. – daramarak