<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>muvik-multigrid &#187; Projecteuler</title>
	<atom:link href="http://www.muvik.de/tag/projecteuler/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.muvik.de</link>
	<description>open source - engineering - programming</description>
	<lastBuildDate>Wed, 28 Jul 2010 07:56:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Projecteuler: Lösung zu Problem 10</title>
		<link>http://www.muvik.de/2010/07/27/projecteuler-loesung-zu-problem-10/</link>
		<comments>http://www.muvik.de/2010/07/27/projecteuler-loesung-zu-problem-10/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 07:42:12 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Eratosthenes]]></category>
		<category><![CDATA[Primzahlen]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=1384</guid>
		<description><![CDATA[Primzahlen sind das Thema des Projecteuler-Problems Nummer 10. Nach dem 3. und 7. Problem befasst sich nun auch das 10. Problem mit den beliebten Zahlen, die durch beinahe nichts teilbar sind. In diesem Artikel wird, wie gewohnt, das Problem eingegrenzt und mit Python gelöst. Problemvorstellung Wer die Probleme 3 und 7 bereits gelöst hat, wird [...]]]></description>
			<content:encoded><![CDATA[<img class="cat-img-wide" alt="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" title="Projecteuler: Lösungen mit Python und C++" width="443" height="98" />
<p class="preview">Primzahlen sind das Thema des Projecteuler-Problems Nummer 10. Nach dem 3. und 7. Problem befasst sich nun auch das 10. Problem mit den beliebten Zahlen, die durch beinahe nichts teilbar sind. In diesem Artikel wird, wie gewohnt, das Problem eingegrenzt und mit Python gelöst.</p>
<p><span id="more-1384"></span></p>
<h3>Problemvorstellung</h3>
<p>Wer die Probleme <a href="http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/">3</a> und <a href="http://http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/">7</a> bereits gelöst hat, wird mit dem <a href="http://projecteuler.net/index.php?section=problems&#038;id=10">10. Projecteuler-Problem</a> keine Mühe haben. Wieder geht es um Primzahlen und wieder kann der Sieb des Eratosthenes verwendet werden, um die Lösung zu finden.</p>
<p>Ins Deutsche übersetzt lautet die Aufgabenstellung: </p>
<p><strong>Finde die Summe aller Primzahlen, die kleiner als zwei Millionen sind.</strong></p>
<p>Mit dem Hintergrundwissen aus den bereits gelösten Problemen, bräuchte ich eigentlich keinen zusätzlichen Artikel mehr zu verfassen. Es sind bereits alle Mittel, die hierzu benötigt werden, bereits vorgestellt und mit Erfolg verwendet worden.</p>
<p>Aus diesem Grund lässt es sich nicht wirklich nachvollziehen, warum zum heutigen Zeitpunkt lediglich 47699 der insgesamt 114874 Projecteuler-Teilnehmer eine richtige Lösung zu diesem Problem einreichen konnten. Wahrscheinlich sind sie zeitlich verhindert gewesen <img src='http://www.muvik.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> !</p>
<h3>Problemeingrenzung</h3>
<p>Obwohl alle Tipps und Tricks zur vollständigen und erfolgreichen Lösung des Problems bereits im Rahmen dieser Artikelserie genannt und beschrieben wurden, möchte ich einige Tatsachen dennoch der Vollständigkeit wegen wiederholen.</p>
<p>In erster Linie ist das wichtiges Werkzeug, welches bei bisher allen Problemen mit Primzahlen bei mir zum Einsatz kam und es auch diesmal tut <a href="http://de.wikipedia.org/wiki/Sieb_des_Eratosthenes">das Siebes von Eratosthenes</a>. Hierbei handelt es sich um eine Methode, mit welcher man alle Primzahlen bis zu einer gegebenen Zahl <code>N</code> relativ effizient finden kann.</p>
<h4>Das Sieb des Eratosthenes</h4>
<p>Die Vorgehensweise beim <em>Sieben</em> ist recht simpel und schnell erklärt, dabei geht man am besten grafisch vor: Um alle Zahlen bis <code>N</code> mit dem Sieb zu finden, schreibt man die Zahlen, bildlich gesprochen, alle auf. Dann fängt man mit der ersten bekannten Primzahl, also der 2, an und streicht alle Vielfachen dieser Zahl wieder aus der Liste. Hat man das erledigt, so geht es mit der nächsten <strong>nicht</strong> gestrichenen Zahl weiter, die nun eine Primzahl sein sollte. </p>
<p>Wenn nichts schief gegangen ist, so bleiben am Ende alle Primzahlen bis <code>N</code> übrig.</p>
<p>Um einige Rechenoperationen, Vergleiche und Abfragen zu sparen, kann die Methode etwas verfeinert werden. Zum einen ist es bekannt, dass es keine geraden Primzahlen gibt. Also können diese sofort aus der Betrachtung ausgeschlossen werden. Zum anderen ist während des Siebens ebenfalls bekannt, dass alle Vielfachen der Primzahl 5 bereits gestrichen sind, wenn die Primzahl 11 an der Reihe ist. Das gilt auch für alle Primzahlen zwischen 5 und 11. Somit kann die nächste zu streichende Vielfache frühstens 11*11 sein.</p>
<p>Aus der zuletzt angestellten Betrachtung folgt sogleich, dass die größte zu prüfende Primzahl maximal die Wurzel aus N sein kann.<br />
<code class="bash"> x*x <= N</code></p>
<p>Werden die Verfeinerungen im Code angewendet, erhält man einen relativ effizienten Sieb, der mit den vorgegebenen zwei Millionen mühelos fertig werden sollte.</p>
<h3>Problemlösung</h3>
<p>Wie versprochen, brauchen wir zur Lösung des zehnten Projecteuler-Problem nur den Sieb des Eratosthenes und eine Summe aller gefundenen Primzahlen, das war es schon!<br />
Im folgenden die kompakte Lösung:</p>
<pre class="brush:python">import time as t
import numpy as np

def eratosthenes_vect(N):
    primes = np.arange(3,N+1,2)  # only uneven figures
    primes = np.insert(primes,0,2,0) # ... and two

    nUneven = np.size(primes) - 1.0

    for i in np.arange(3,np.ceil(np.sqrt(N))+2,2):
        primes[(i*i+1)/2-1:nUneven+1.0:i] = 0;

    return np.trim_zeros(np.sort(primes))

def solver(N):
    Primes = eratosthenes_vect(N)

    erg = 0;

    for i in Primes:
        erg = erg + i

    return erg

N = 2000000

t0 = t.clock()
Prim = solver(N)
tn = t.clock() - t0

print("Benoetigte Zeit: %15.6f" %tn)
print("Gefundene Summe: %i" %Prim)</pre>
<p>Die Ausgabe des Codes zeigt die benötigt Zeit und die gesuchte Summe:<br />
<code class="bash">Benoetigte Zeit:        5.940000<br />
Gefundene Summe: 142913828922<br />
</code></p>
<p>Sechs Sekunden Rechenzeit für alle Primzahlen, die kleiner als zwei Millionen sind, und die Summe daraus ist, denke ich, annehmbar.</p>
<h3>Schlusswort</h3>
<p>Nach einer etwas langwierigen Zeit, während der nur wenige Artikel in der Serie "Lösungen zu Projecteuler-Problemen mit Python" erschienen sind, gleich zwei Lösungen nach einander. Das ist schon ein Wort und sollte eigentlich mit einem dritten Artikel zum 11. Problem gefeiert werden. Vielleicht lasse ich mich dazu hinreißen <img src='http://www.muvik.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> !</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/07/27/projecteuler-loesung-zu-problem-10/">Permalink</a> |
<a href="http://www.muvik.de/2010/07/27/projecteuler-loesung-zu-problem-10/#comments">keine Kommentare</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/07/27/projecteuler-loesung-zu-problem-10/&title=Projecteuler: Lösung zu Problem 10">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/07/27/projecteuler-loesung-zu-problem-10/&title=Projecteuler: Lösung zu Problem 10">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/07/27/projecteuler-loesung-zu-problem-10/&title=Projecteuler: Lösung zu Problem 10">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/eratosthenes/" rel="tag">Eratosthenes</a>, <a href="http://www.muvik.de/tag/primzahlen/" rel="tag">Primzahlen</a>, <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/07/27/projecteuler-loesung-zu-problem-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 9</title>
		<link>http://www.muvik.de/2010/07/26/projecteuler-loesung-zu-problem-9/</link>
		<comments>http://www.muvik.de/2010/07/26/projecteuler-loesung-zu-problem-9/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 07:48:30 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Pythagoras]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=1351</guid>
		<description><![CDATA[Jetzt geht es beinahe schon Schlag auf Schlag: nach der Vorstellung der Lösung des achten folgt sofort die Lösung des neunten Problems. Das neunte Projecteuler-Problem beschäftigt sich mit dem Satz von Pythagoras und der Bildung von sogenannten Pythagoras-Tripeln. Wie gewohnt, erfolgt auch diesmal die Lösung mit Python. Problemvorstellung Das neunte Projecteuler-Problem dreht sich um den [...]]]></description>
			<content:encoded><![CDATA[<img class="cat-img-wide" alt="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" title="Projecteuler: Lösungen mit Python und C++" width="443" height="98" />
<p class="preview">Jetzt geht es beinahe schon Schlag auf Schlag: nach der Vorstellung der Lösung des achten folgt sofort die Lösung des neunten Problems. Das neunte Projecteuler-Problem beschäftigt sich mit dem Satz von Pythagoras und der Bildung von sogenannten Pythagoras-Tripeln. Wie gewohnt, erfolgt auch diesmal die Lösung mit Python.</p>
<p><span id="more-1351"></span></p>
<h3>Problemvorstellung</h3>
<p>Das <a href="http://projecteuler.net/index.php?section=problems&#038;id=9">neunte Projecteuler-Problem</a> dreht sich um den <a href="http://de.wikipedia.org/wiki/Satz_des_Pythagoras">Satz von Pythagoras</a>, welcher eine Aussage über die Seitenlängen eines rechtwinkligen Dreiecks liefert. Wie die meisten Schüler mehr oder weniger leidvoll erfahren haben, ergibt sich aus der Addition der Quadrate der zwei kürzeren Seiten, der Katheten, eines rechtwinkligen Dreiecks genau das Quadrat der längsten Seite, der Hypotenuse. Dass der Satz des Pythagoras auch heute noch bei Schülern sehr gefragt  ist, lässt sich auf <a href="http://www.gutefrage.net/frage/mathe-pythagoras-pendel-hilfe">gutefrage.net</a> nachlesen.</p>
<p>Ist nun die Länge der zwei Katheten und der Hypotenuse eines Dreiecks durch natürliche Zahlen (ganze Zahlen) beschreibbar, so bezeichnet man die drei Zahlen als pythagoreisches Tripel.</p>
<p>In dem neunten Projecteuler-Problem geht es darum, ein bestimmtes pythagoreisches Tripel zu finden. Dieses Tripel soll folgende Bedingungen erfüllen:</p>
<ol>
<li><code>a + b + c = 1000</code>,</li>
<li><code>a < b < c </code> und natürlich</li>
<li><code>a^2 + b^2 = c^2</code></li>
</ol>
<p>So viel sei zur Aufgabenstellung angemerkt.</p>
<p>Obwohl der Satz des Pythagoras eine elementare Unterrichtseinheit in der Schule darstellt, haben zum heutigen Zeitpunkt trotzdem nur 52711 der insgesamt 114860 Projecteuler-Teilnehmer die Aufgabe mit Erfolg gelöst und das richtige Ergebnis eingegeben.</p>
<p>Als Ergebnis werden übrigens nicht die drei Zahlen <code>a, b, c</code> erwartet, sondern ihr Produkt: <code>a * b * c</code>.</p>
<h3>Problemeingrenzung</h3>
<p>Geht man ganz unbedarft an das Problem heran, kommt man schnell auf die Lösung, einfach alle Zahlen für a und b einzusetzen, die die Bedingung <code>a < b</code> erfüllen. Dann muss die Hypotenuse errechnet werden. Was noch bleibt, ist zu testen, ob die Summe der drei Zahlen auch wirklich 1000 ergibt.</p>
<p>Damit hätte man zwei <code>for</code>-Schleifen und eine <code>if</code>-Abfrage und natürlich die Lösung des Problems. Eine elegante Lösung ist jedoch etwas anderes!</p>
<p>Ebenso unbedarft kann das Problem nur ein wenig genauer angeschaut werden. Ein Quäntchen Glück vorausgesetzt, erkennt man dabei, dass man bei drei Unbekannten genau zwei Gleichungen gegeben hat. Dies kann ausgenutzt werden, um die Lösung etwas komplizierter erscheinen zu lassen.</p>
<p>Dabei lässt sich zum Beispiel die erste Bedingung <code>a + b + c = 1000</code> nach <code>c</code> auflösen und in die dritte einsetzen:<br />
<code class="bash">a + b + c = N<br />
c = N - a - b<br />
a^2 + b^2 - N^2 - 2*N*(a+b) - (a+b)^2 = 0</code></p>
<p>Die letzte Gleichung kann nun nach zum Beispiel <code>b</code> aufgelöst werden:<br />
<code class="bash">b = (0.5*N^2 - N*a)/(N - a)</code></p>
<p>Das Auflösen nach <code>b</code> lässt sich über die zweite Bedingung motivieren. Wenn wir nun Zahlen von 1 ausgehend für a einsetzen, dann wird die zweite Bedingung immer erfüllt bleiben.</p>
<p>Damit müssen wir nur noch die Zahlen für a vorgeben und testen, ob der Quotient eine natürliche Zahl ergibt.</p>
<p>Weiter wollen wir das Problem nicht mehr mit mathematischem Hintergrund aufblasen und gehen zur Lösung mit Python über.</p>
<h3>Problemlösung</h3>
<p>Abgesehen davon, dass dieses Problem eigentlich keiner Implementierung in einer Programmiersprache bedarf, wenn die Informationen zur <a href="http://de.wikipedia.org/wiki/Pythagoreisches_Tripel">Erzeugung eines pythagoreischen Tripels</a> ausgenutzt werden, ist es wohl eines der kürzesten Lösungen, die ich im Rahmen dieser Serie bisher vorgestellt habe.</p>
<pre class="brush:python">def search(a,N):
    found = 0

    while (found == False):
        for i in a:
            num = 0.5*N*N - N * i
            denom = N - i
            if (num%denom == 0.0):
                found = 1
                result = np.array([i,num/denom])
    return result

N = 1000.0

aa = np.arange(int(N)/3)

erg = search(aa,N)

a = erg[0]
b = erg[1]
c = N-a-b

print(a,b,c,a*b*c)</pre>
<p>Innerhalb dieser Zeilen habe ich die wenigen Gedanken aus der Problemeingrenzung verarbeitet. Der aufmerksame Leser wird gemerkt haben, dass noch eine zusätzliche Vereinfachung im Code berücksichtigt wurde.</p>
<p>Aufgrund der gegebenen Bedingungen wurde für <code>a</code> ein etwas kleinerer Suchbereich von maximal bis 300 eingestellt. Gehen wir von einem Extremfall aus:<br />
<code class="bash">a = 300<br />
b = 301<br />
a^2 + b^2 = c^2 = 180601<br />
=> c = 424.972<br />
</code></p>
<p>Prüfen wir die erste Bedingung, so finden wir, dass die Summe bereits ca. 1026 beträgt. Das ist schon zu viel.</p>
<p>Lässt man sich nun das Ergebnis berechnen, so erhält man folgende Ausgabe:<br />
<code class="bash">(200.0, 375.0, 425.0, 31875000.0)</code></p>
<p>Damit wäre die gesuchte Zahl: <code>31875000</code>.</p>
<h3>Schlusswort</h3>
<p>Ich gebe zu, dass der Lösungsvorschlag nicht der Weisheit letzter Schluss ist, doch für dieses Problem funktioniert er gut und zuverlässig. Die Grenzen, die Projecteuler vorgibt, werden nicht annähernd erreicht.</p>
<p>Natürlich wäre ich daher besonders froh, den einen oder anderen Lösungsvorschlag in den Kommentaren zu sehen <img src='http://www.muvik.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> .</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/07/26/projecteuler-loesung-zu-problem-9/">Permalink</a> |
<a href="http://www.muvik.de/2010/07/26/projecteuler-loesung-zu-problem-9/#comments">keine Kommentare</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/07/26/projecteuler-loesung-zu-problem-9/&title=Projecteuler: Lösung zu Problem 9">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/07/26/projecteuler-loesung-zu-problem-9/&title=Projecteuler: Lösung zu Problem 9">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/07/26/projecteuler-loesung-zu-problem-9/&title=Projecteuler: Lösung zu Problem 9">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/pythagoras/" rel="tag">Pythagoras</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/07/26/projecteuler-loesung-zu-problem-9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 8</title>
		<link>http://www.muvik.de/2010/07/22/projecteuler-loesung-zu-problem-8/</link>
		<comments>http://www.muvik.de/2010/07/22/projecteuler-loesung-zu-problem-8/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 07:41:04 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=1291</guid>
		<description><![CDATA[Und weiter geht es in der Lösungen zu Projecteuler Problemen mit Python Serie. Heute steht das achte Problem auf dem Plan. Dieses etwas andere Problem als die bisherigen wird, wie gewohnt, erläutert, die Herausforderung hierbei werden eingegrenzt und die Lösung mit Python nach bestem Wissen und Gewissen herausgefunden. Problemvorstellung Die Aufgabenstellung des achten Problems ist, [...]]]></description>
			<content:encoded><![CDATA[<img class="cat-img-wide" alt="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" title="Projecteuler: Lösungen mit Python und C++" width="443" height="98" />
<p class="preview">Und weiter geht es in der Lösungen zu Projecteuler Problemen mit Python Serie. Heute steht das achte Problem auf dem Plan. Dieses etwas andere Problem als die bisherigen wird, wie gewohnt, erläutert, die Herausforderung hierbei werden eingegrenzt und die Lösung mit Python nach bestem Wissen und Gewissen herausgefunden.</p>
<p><span id="more-1291"></span></p>
<h3>Problemvorstellung</h3>
<p>Die <a href="http://projecteuler.net">Aufgabenstellung des achten Problems</a> ist, wie bereits beim siebten, sehr kurz geraten. Und trotzdem bekommt der unvorbereitete Besucher der Projekteuler-Seite etwas das Grausen, wenn er die Aufgabenstellung sieht. Neben der textlichen Anweisung, was zu tun ist, wird nämlich das Untersuchungsobjekt gleich mitgeliefert.</p>
<p>Aber nur der Reihe nach: zuerst die Aufgabenstellung ins Deutsche übersetzten:</p>
<p><strong>Finde das größte Produkt von fünf aufeinander folgenden Ziffern innerhalb einer Zahl mit 1000-Stellen.</strong></p>
<p>Nach der Problembeschreibung folgt das Untersuchungsobjekt:<br />
<code class="bash">73167176531330624919225119674426574742355349194934<br />
96983520312774506326239578318016984801869478851843<br />
85861560789112949495459501737958331952853208805511<br />
12540698747158523863050715693290963295227443043557<br />
66896648950445244523161731856403098711121722383113<br />
62229893423380308135336276614282806444486645238749<br />
30358907296290491560440772390713810515859307960866<br />
70172427121883998797908792274921901699720888093776<br />
65727333001053367881220235421809751254540594752243<br />
52584907711670556013604839586446706324415722155397<br />
53697817977846174064955149290862569321978468622482<br />
83972241375657056057490261407972968652414535100474<br />
82166370484403199890008895243450658541227588666881<br />
16427171479924442928230863465674813919123162824586<br />
17866458359124566529476545682848912883142607690042<br />
24219022671055626321111109370544217506941658960408<br />
07198403850962455444362981230987879927244284909188<br />
84580156166097919133875499200524063689912560717606<br />
05886116467109405077541002256983155200055935729725<br />
71636269561882670428252483600823257530420752963450</code></p>
<p>Zum heutigen Zeitpunkt haben sich genau 52538 mutige Projecteuler-Teilnehmer an die Aufgabe mit erfolgreichem Ausgang getraut. Das entspricht grob der Hälfte der insgesamt 115013 registrierten Leidensgenossen.</p>
<h3>Problemeingrenzung</h3>
<p>Unbeeindruckt von der Wucht großer Zahlen machen wir uns an die Problemanalyse und -eingrenzung heran.</p>
<p>Die erste Idee, welche sich beinahe sofort in die Gedanken einmischt, ist die straight-forward-Methode: Man nehme die ersten fünf Ziffern, multipliziere sie und vergleiche sie mit dem Produkt der Ziffern 2-6. So läuft man durch das ganze Feld, bis man am Ende angekommen ist. Das ist eine sehr simple Methode, die todsicher zum richtigen Ergebnis führt.</p>
<p>Doch so einfach möchten wir uns das ganze bloß nicht machen. Nach dem Motto &#8220;<em>Warum einfach, wenn es auch kompliziert geht?</em>&#8221; überdenken wir die offensichtlichen Nachteile der simplen, ersten Idee:</p>
<ol>
<li>In erster Linie wäre die Aufgabe so viel zu einfach. Der Reiz des Unmöglichen geht verloren!</li>
<li>In zweiter Linie sind wir sparsame Menschen und sehen sofort, dass bei der trivialen Lösung sehr oft multipliziert wird. Genauer betrachtet, stellen wir fest, dass in einer Reihe wie <code>(2 3 4 5 0 5 5 2 3)</code> genau 20 mal eine Multiplikation durchgeführt wird, ohne dass ein Produkt größer als 0 herauskommt.</li>
</ol>
<p>Ok, das sind uns Nachteile genug, um die Lösung nochmal zu überdenken.</p>
<p>Schauen wir uns einen Ausschnitt aus der ersten Ziffernreihe an und veranschaulichen uns, wie die Produkte gebildet werden:</p>
<p><code class="bash">624919225119674426574742355349194934<br />
62491<br />
_24919<br />
__49192<br />
___91922<br />
...</code></p>
<p>Was erkennen wir daraus?</p>
<ol>
<li>Zuerst muss ein reguläres Produkt aus fünf Ziffern gebildet werden.</li>
<li>Das nachfolgende Produkt besteht zu einem Großteil aus den Ziffern seines Vorgängers. Lediglich die erste Ziffer entfällt und eine neue kommt hinzu.</li>
</ol>
<p>Diese Erkenntnisse können wir uns nun zu Nutze machen, indem wir vom Vorgänger stets die erste Zahl dividieren und die nächste multiplizieren! Dadurch haben wir die Anzahl an Rechenoperationen halbiert.</p>
<p>Da der neue Vorschlag nun neben der Multiplikation auch eine Division aufweist, müssen wir zusätzliche Vorsicht walten lassen, denn durch Null teilen ist verboten.</p>
<p>Nach dem Motto &#8220;<em>Vorbeugen ist besser als Bekämpfen</em>&#8221; sieht jeder ein, dass das Problem mit der Division durch Null nicht auftreten kann, wenn keine Vorgänger null sind, also kein Quintett eine Null enthält. Das realisieren wir folgendermaßen:</p>
<ol>
<li>Solange keine Null auftritt, die zur Bildung eines neuen Produkts nötig wäre, kann der bisher beschriebene Algorithmus durchgeführt werden.</li>
<li>Sobald eine Null auftritt, wird die Bildung des Quintetts abgebrochen. Danach wird versucht, ein neues Quintett aus den fünf Ziffern nach der Null zu bilden. Sollte hierbei wieder eine Null vorkommen, so wird der Vorgang wieder abgebrochen und ein neues Quintett mit den Ziffern nach dieser zweiten Null gebildet.</li>
</ol>
<p>Was haben wir damit erreicht? In erster Linie teilen wir nie wieder durch Null und in zweiter Linie werden kein Quintett mit einer Null gebildet und somit diese unnötigen Multiplikationen eingespart.</p>
<p>Damit sind wir erst einmal zufrieden. Wie das in Python-Code aussieht, steht im folgenden Abschnitt.</p>
<h3>Problemlösung</h3>
<p>Neben den rein mathematischen Schwierigkeiten bei dem 8.Problem, treffen wir noch auf ein rein programmiertechnisches Problem, nämlich dem Import der gegebenen Zahl. Ich habe mich dafür entschieden, die Zahl von der Projecteuler-Webseite in eine einzelne Datei (<code>data.dat</code>) zu kopieren und im Python-Programm nur die Datei zu importieren. Dabei bietet es sich an, die Zeilenumbrüche zu ignorieren und die ganze Zahl in einem eindimensionalen Numpy-Array zu speichern.</p>
<p>Der langen Rede kurzer Sinn, heute mal am Stück:</p>
<pre class="brush:python">import numpy as np
import time as t

fileO =  open('data.dat','r')
peData = fileO.read()

def create_long_array(data):
    fdata = np.array([])

    print("Following data will be red:")
    print(data+"\n")

    for lines in data:
        for item in lines:
            if (item != "\n"):
                fdata = np.append(fdata,float(item))
    return fdata

def search_greatest_product(data,N):
    Ndata = len(data)
    print("%i values will be checked!" %Ndata)
    print("Product interval: %i\n" %N)

    greatest = 1
    for i in range(0,N):
        greatest = greatest * data[i]

    greater = greatest

    i = N
    while (i <= Ndata-1):

        factor = data[i]
        if (factor == 0):
            j = 1
            k = i
            greater = 1

            while ((j <= N) &#038; (k<=Ndata-N)):
                k = i + j
                factor = data[k]
                if (factor == 0):
                    j = 1
                    i = k
                    greater = 1
                else:
                    greater = greater * data[k]
                    j = j + 1

            i = i+j-1

        else:
            greater = greater / data[i-N] * data[i]

        if (greater > greatest):
            print("Found greater product: %i - %i" %(greatest, greater))
            greatest = greater

        i = i + 1

    return greatest

fdata = create_long_array(peData)

t0 = t.time()
greatest = search_greatest_product(fdata,5)
tn = t.time()

print("\nFound solution: %i in %.15f seconds!" %(greatest,tn-t0))</pre>
</p>
<p>Wie elegant die Realisierung des Lösungsvorschlags ist, kann ich als Anfänger nicht wirklich beurteilen. Das Gute an dem gesamten Konzept ist auf jede Fall, dass beliebige Zahlen eingegeben werden können. Es wird immer das größte Produkt der N aufeinander folgenden Zahlen gefunden.</p>
<h3>Lösungsanalyse</h3>
<p>Wird das vorgeschlagene Programm auf das 8.Projecteuler-Problem losgelassen, so liefert es folgende Ausgabe in der Konsole:</p>
<p><code class="bash">Following data will be red:<br />
73167176531330624919225119674426574742355349194934<br />
96983520312774506326239578318016984801869478851843<br />
85861560789112949495459501737958331952853208805511<br />
12540698747158523863050715693290963295227443043557<br />
66896648950445244523161731856403098711121722383113<br />
62229893423380308135336276614282806444486645238749<br />
30358907296290491560440772390713810515859307960866<br />
70172427121883998797908792274921901699720888093776<br />
65727333001053367881220235421809751254540594752243<br />
52584907711670556013604839586446706324415722155397<br />
53697817977846174064955149290862569321978468622482<br />
83972241375657056057490261407972968652414535100474<br />
82166370484403199890008895243450658541227588666881<br />
16427171479924442928230863465674813919123162824586<br />
17866458359124566529476545682848912883142607690042<br />
24219022671055626321111109370544217506941658960408<br />
07198403850962455444362981230987879927244284909188<br />
84580156166097919133875499200524063689912560717606<br />
05886116467109405077541002256983155200055935729725<br />
71636269561882670428252483600823257530420752963450<br />
1000 values will be checked!<br />
Product interval: 5<br />
Found greater product: 882 -> 1764<br />
Found greater product: 1764 -> 6048<br />
Found greater product: 6048 -> 15552<br />
Found greater product: 15552 -> 16128<br />
Found greater product: 16128 -> 18144<br />
Found greater product: 18144 -> 40824<br />
Found solution: 40824 in 0.022379159927368 seconds!</code></p>
<p>Mit diesem Ergebnis bewegen wir uns erwartungsgemäß in den Grenzen, die von Projecteuler vorgegeben sind und haben auf Anhieb die richtige Zahl gefunden.</p>
<h3>Schlusswort</h3>
<p>Wahrscheinlich merken die Leser schon an der Länge der Artikels, dass es mir viel Spaß bereitet hat, dieses Problem zu lösen, obwohl es eher eines von den einfacheren Problem war. Wie auch immer, es ist gelöst und vielleicht auf einem nicht ganz konventionellen Wege.</p>
<p>Andere Lösungsvorschläge in den Kommentaren, oder Aussagen zu meinem Lösungsvorschlag sind wie immer sehr willkommen.</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/07/22/projecteuler-loesung-zu-problem-8/">Permalink</a> |
<a href="http://www.muvik.de/2010/07/22/projecteuler-loesung-zu-problem-8/#comments">keine Kommentare</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/07/22/projecteuler-loesung-zu-problem-8/&title=Projecteuler: Lösung zu Problem 8">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/07/22/projecteuler-loesung-zu-problem-8/&title=Projecteuler: Lösung zu Problem 8">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/07/22/projecteuler-loesung-zu-problem-8/&title=Projecteuler: Lösung zu Problem 8">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/07/22/projecteuler-loesung-zu-problem-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 7</title>
		<link>http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/</link>
		<comments>http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 09:12:21 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Eratosthenes]]></category>
		<category><![CDATA[Primzahlen]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=1050</guid>
		<description><![CDATA[Diese Woche geht es gleich weiter mit der Lösung des siebten Projecteuler-Problems mit Python. Die guten Vorsätze von letzter Woche scheinen noch nicht abgelegt zu sein, deswegen beschäftigen wir uns in diesem Artikel wieder etwas mit Primzahlen und dem Sieb des Eratosthenes. Natürlich wird das Problem mit der Programmiersprache Python angegangen und gelöst! Problemvorstellung Das [...]]]></description>
			<content:encoded><![CDATA[<img class="cat-img-wide" alt="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" title="Projecteuler: Lösungen mit Python und C++" width="443" height="98" />
<p class="preview">Diese Woche geht es gleich weiter mit der Lösung des siebten Projecteuler-Problems mit Python. Die guten Vorsätze von letzter Woche scheinen noch nicht abgelegt zu sein, deswegen beschäftigen wir uns in diesem Artikel wieder etwas mit Primzahlen und dem Sieb des Eratosthenes. Natürlich wird das Problem mit der Programmiersprache Python angegangen und gelöst!</p>
<p><span id="more-1050"></span></p>
<h3>Problemvorstellung</h3>
<p>Das <a href="http://projecteuler.net/index.php?section=problems&#038;id=7">siebte Projecteuler-Problem</a> ist ein sehr kurzes Problem! Zumindest was die textliche Beschreibung angeht. Laut dem Motto &#8220;In der Kürze liegt die Würze&#8221; lautet die Aufgabenstellung folgendermaßen:</p>
<p>
<strong>Finde die 10001.Primzahl!</strong>
</p>
<p>Also kann mit drei Worten, einer Zahl und zwei Satzzeichen etwas formuliert werden, was jedes Grüblerherz höher schlagen lässt.</p>
<p>Diejenigen Leser, die meine Serie &#8220;Projecteuler: Lösungen mit Python und C++&#8221; bisher mitverfolgt haben, auch ohne aktives Eingreifen in Form von Kommentaren im Blog oder auch ohne die Probleme selber gelöst zu haben, werden wissen, dass es bereits eine Aufgabe gab, die Primzahlen zum Thema hatte.</p>
<p>Im Rahmen der <a href="http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/">Lösung zum dritten Problem</a>, wo es um eine Primfaktorenzerlegung ging, finden wir wichtige Werkzeuge auch zur Lösung des siebten Problems. Doch dazu später mehr, zuvor etwas Statistik:</p>
<p>Ganz aktuell gemessen, haben von insgesamt 112279 registrierten Projecteuler-Nutzern genau 57841 das Problem mit Bravour gelöst. Das entspricht ziemlich genau der Hälfte der Nutzer. Und wir sind dabei <img src='http://www.muvik.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> !</p>
<h3>Problemeingrenzung</h3>
<p>Die Schwierigkeiten bei dieser Fragestellung liegen auf der Hand: </p>
<ol>
<li>Zunächst ist es nett zu wissen, welche Zahlen denn nun überhaupt Primzahlen sind. Denn nur dann können sie auch gezählt werden. Also ist die erste Herausforderung das Filtern von Primzahlen.</li>
<li>Da nicht alle Primzahlen bis zu einer bestimmten ganzen Zahl gesucht sind, sondern eine bestimmte <em>Anzahl an Primzahlen</em>, sind die gängigsten Werkzeuge erst mal nicht zu gebrauchen, oder besser: sind zu überdenken. Es müssen weiterhin alle Primzahlen gesucht und gezählt werden, ein Limit ist jedoch nicht gegeben.</li>
</ol>
<p>Wie eingangs bereits angedeutet, können wir uns aus der Lösung zu Problem 3 eines ganz nützlichen Werkzeugs bedienen: dem <a href="http://de.wikipedia.org/wiki/Sieb_des_Eratosthenes">Sieb des Eratosthenes</a>.</p>
<p>Mit diesem Sieb lassen sich alle Primzahlen bis zu einer gegebenen ganzen Zahl N bestimmen. Wie im verlinkten Wikipedia-Artikel erläutert, müssen hierbei einfach alle Zahlen bis N &#8220;aufgeschrieben&#8221; werden. Dann werden mit der 2 beginnend alle Vielfachen wieder gestrichen. Hat man das für die 2 erledigt, so geht es in der Reihenfolge mit der nächsthöheren Zahl weiter, also der 3, dann 5, 7, 11, &#8230;</p>
<p>Das Sieb des Eratosthenes liefert uns also alle Primzahlen, die kleiner oder gleich N sind. Gesucht ist jedoch die 10001.Primzahl. Somit kommen wir mit dem Sieb des Eratosthenes nicht direkt zum Ziel.</p>
<p>Sollen nun im Zahlenbereich bis N noch keine 10001 Primzahlen identifiziert sein, so muss der Bereich erweitert und die Suche fortgesetzt werden. Wie das realisiert werden kann, steht unter der Überschrift:</p>
<h3>Problemlösung</h3>
<p>Der erste Teil der Lösung ist klar und bereits aus der <a href="http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/">Lösung zum Problem 3</a> bekannt: </p>
<pre class="brush:python">def eratosthenes_vect(N):
    primes = np.arange(3,N+1,2)  # only uneven figures
    primes = np.insert(primes,0,2,0) # ... and two

    nUneven = np.size(primes) - 1.0

    for i in np.arange(3,np.ceil(np.sqrt(N))+2,2):
        primes[(i*i+1)/2-1:nUneven+1.0:i] = 0;

    return np.trim_zeros(np.sort(primes))</pre>
</p>
<p>Damit erhalten wir alle Primzahlen bis zur Zahl N.</p>
<p>Die einfachste Lösung wäre nun, einfach einen großes N vorzugeben und zu hoffen, dass es mindestens 10001 Primzahlen im Sieb hängen bleiben. Ist man in der Lage, ein gut passendes N abzuschätzen, so hat man mit dem Sieb des Eratosthenes eine sehr effiziente Lösungsmethode gefunden.</p>
<p>Diese Tatsache möchten wir im Folgenden ausnutzen und durch eine Erweiterung etwas absichern:</p>
<pre class="brush:python">def eratosthenes_limits(StartN, EndN, Primes):
    """
    Rechnet alle Primzahlen im Zahlenraum StartN, EndN.
    Primes: alle Primzahlen bis StartN.
    """
    if (StartN%2 == 0):
        SearchField = np.arange(StartN+1,EndN+1,2)
        limitleft = StartN+1
        limitright = EndN
    else:
        SearchField = np.arange(StartN,EndN+1,2)
        limitleft = StartN
        limitright = EndN

    for item in Primes:
        itemQ = item*item
        if itemQ <= limitright:
            for i in range(0,SearchField.size,1):
                if (SearchField[i]%item == 0):
                    SearchField[i] = 0

            SearchField = np.trim_zeros(np.sort(SearchField))
            limitleft   = SearchField[0]
            limitright  = SearchField[-1]

    return np.append(Primes,SearchField)

def solver(N,NEra):
    Primes = eratosthenes_vect(NEra)

    while (Primes.size < N):
        Primes = eratosthenes_limits(NEra+1, NEra*2, Primes)
        NEra = NEra*2

    print("Suchbereich bis N=%i" %NEra)
    return Primes[N-1]</pre>
</p>
<p>Der gegebene Vorschlag ist wahrscheinlich nicht die eleganteste Methode, aber er funktioniert für das Problem recht ordentlich.</p>
<p>Die Funktion <code>eratosthenes_limits</code> kommt zum Einsatz, wenn der Zahlenbereich, den wir geschätzt haben, zu klein ist. Sie geht im Grunde genau nach dem Prinzip des Siebes von Eratosthenes vor. Es werden alle Zahlen in einem Bereich zwischen <code>StartN</code> und <code>EndN</code> auf Teilbarkeit durch die Primzahlen bis zur Zahl <code>StartN</code> untersucht. Da wir davon ausgehen, dass der zu Beginn geschätzte Zahlenbereich nicht sehr stark vergrößert werden muss, steigern wir in der <code>solver</code>-Funktion den Suchbereich um das doppelte, wenn nicht genug Primzahlen gefunden wurden.<br /> Auf diese Weise kann es nicht vorkommen, dass die Funktion <code>eratosthenes_limits</code> ins Stocken gerät, weil Primzahlen aus dem aktuellen neuen Suchbereich benötigt werden, um alle Vielfachen zu streichen. Dafür müsste der Suchbereich schon quadratisch vergrößert werden: <code>StartN = N, EndN=N*N</code>.</p>
<p><p><script type="text/javascript"><!--
google_ad_client = "pub-1356270213107195";
/* 468x60_incontent_text */
google_ad_slot = "2104479285";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p></p>
<h4>Schätzen des Suchbereichs zu Beginn</h4>
<p>Das Schätzen des richtigen Suchbereichs ist das A und O bei der vorgeschlagenen Lösung. Dazu lohnt sich ein Blick auf die Statistik. Betrachtet man bereits die Häufigkeit von Primzahlen im Bereich von 1-10 und von 20-30, so stellt man fest, dass die Anzahl abnimmt. Diese Tatsache lässt sich mathematisch beweisen, was wir hier aber nicht machen wollen.</p>
<p>In dem Zahlenbereich, der für das siebte Projecteuler-Problem interessant ist, treten laut der <a href="http://www.maerku69.ch/Primzahlen-auflisten.html">Analyse auf maerku69.ch</a> Primzahlen mit einer Häufigkeit von etwas unter 10% auf.</p>
<p>Daraus schließen wir, dass eine Schätzung des Suchbereichs mit etwas mehr als dem zehnfachen von 10001 ganz ordentlich sein sollte.</p>
<h3>Lösungsanalyse</h3>
<p>Genug der trockenen Theorie, nun kommt die Analyse:</p>
<pre class="brush:python">import time as t
import numpy as np

def eratosthenes_vect(N):
    ...

def eratosthenes_limits(StartN, EndN, Primes):
    ...

def solver(N,NEra):
    ...

N = 10001

N1 = 11*N

t0 = t.clock()
Prim = solver(N,N1)
tn = t.clock() - t0

print("Benoetigte Zeit: %15.6f" %tn)
print("Gefundene Primzahl: %i" %Prim)</pre>
</p>
<p>Mit einem derart optimierten Suchbereich (<code>11*10001</code>) ist eine Erweiterung nicht nötig, die Lösung wird allein durch das Sieb des Eratosthenes gefunden (Ausgabe):<br />
<code class="bash">Suchbereich bis N=110011<br />
Benoetigte Zeit:        0.320000<br />
Gefundene Primzahl: 104743</code></p>
<p>Unterschätzt man den Suchbereich etwas (10*10001), dann dauert die Suche schon etwas länger:<br />
<code class="bash">Suchbereich bis N=200020<br />
Benoetigte Zeit:        2.810000<br />
Gefundene Primzahl: 104743</code></p>
<p>Hierbei wurde der Suchbereich ein mal vergrößert.</p>
<p>Wird dagegen der Suchbereich überschätzt (12*10001), dann dauert die Suche nur unwesentlich länger:<br />
<code class="bash">Suchbereich bis N=120012<br />
Benoetigte Zeit:        0.350000<br />
Gefundene Primzahl: 104743<br />
</code></p>
<h3>Schlusswort</h3>
<p>Primzahlen sind immer wieder gut für Knobel-Spielchen geeignet, so auch diesmal.</p>
<p>Das Lösen des siebte Problem hat mir persönlich viel Spass bereitet. Ich hoffe, dass es meinen Lesern nicht anders ging oder noch gehen wird und freue mich auf andere Lösungsvorschläge in den Kommentaren oder vielleicht als Reaktion im eigenen Blog.</p>
<p>Meinungen, Anregungen, Verbesserungen sind immer willkommen.</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/">Permalink</a> |
<a href="http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/#comments">keine Kommentare</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/&title=Projecteuler: Lösung zu Problem 7">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/&title=Projecteuler: Lösung zu Problem 7">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/&title=Projecteuler: Lösung zu Problem 7">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/eratosthenes/" rel="tag">Eratosthenes</a>, <a href="http://www.muvik.de/tag/primzahlen/" rel="tag">Primzahlen</a>, <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/07/06/projecteuler-loesung-zu-problem-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 6</title>
		<link>http://www.muvik.de/2010/06/30/projecteuler-loesung-zu-problem-6/</link>
		<comments>http://www.muvik.de/2010/06/30/projecteuler-loesung-zu-problem-6/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 08:10:06 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Mathematik]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=918</guid>
		<description><![CDATA[Nach etwas über einem Monat kann dieser Beitrag zur Serie &#8220;Lösungen mit Python und C++&#8221; der projecteuler.net &#8211; Problemen als Lebenszeichen gedeutet werden. Die Serie gibt es noch und an dieser Stelle wird der sechste Teil vorgestellt. Wie bereits im fünften Teil der Serie, gibt es auch beim 6. eine einfache Lösung mit Papier und [...]]]></description>
			<content:encoded><![CDATA[<img class="cat-img-wide" alt="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" title="Projecteuler: Lösungen mit Python und C++" width="443" height="98" />
<p class="preview">Nach etwas über einem Monat kann dieser Beitrag zur Serie &#8220;Lösungen mit Python und C++&#8221; der <a href="http://projecteuler.net">projecteuler.net</a> &#8211; Problemen als Lebenszeichen gedeutet werden. Die Serie gibt es noch und an dieser Stelle wird der sechste Teil vorgestellt. Wie bereits im fünften Teil der Serie, gibt es auch beim 6. eine einfache Lösung mit Papier und Bleistift und eine kurze Lösungen in Python.</p>
<p><span id="more-918"></span></p>
<h3>Problemvorstellung</h3>
<p>Projecteuler bietet mittlerweile gut 300 Aufgabe, die mehr oder weniger herausfordernd sind. In meiner Serie habe ich bisher erst fünf Lösungen vorgestellt und heute kommt die sechste hinzu. Dabei muss ich zu meiner Schande gestehen, ist die Frequenz, mit der neue Probleme hinzukommen höher als die Veröffentlichungsfrequenz der Lösungen. Aber ich möchte mich bessern <img src='http://www.muvik.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> !</p>
<p>Die <a href="http://projecteuler.net/index.php?section=problems&#038;id=6">sechste Aufgabe</a> stellt für alle, die Geschichten über den <a href="http://de.wikipedia.org/wiki/Carl_Friedrich_Gau%C3%9F">Mathematiker Gauss</a> als kleinen Jungen kennen, kein Problem dar. Ehrlich gesagt, ist es auch für Leute, welche die Geschichten nicht kennen, keine größere Herausforderung.</p>
<p>Ins Deutsche übersetzt, lautet die Aufgabe folgendermaßen:</p>
<p><strong>Finde die Differenz zwischen dem Quadrat der Summe und der Quadratsumme der natürlichen Zahlen bis einschließlich 100.</strong></p>
<p>Laut der Statistik von Projecteuler.net haben bis zum heutigen Tag genau 68751 Teilnehmer das Problem gelöst. Das entspricht grob gesagt der Hälfte aller registrierten User (112160).</p>
<h3>Problemeingrenzung</h3>
<p>Abgesehen von der rein mathematischen Lösung durch etwas nachdenken und Anwenden der Summenformeln, sehe ich bei dieser Aufgabe lediglich die Herausforderung, sich nicht mit einer straight-forward Lösung zufrieden zu geben, sondern zu versuchen, die Anzahl an Rechenoperationen zu minimieren.</p>
<p>Läge der Schwerpunkt in dieser Artikelserie auf der Mathematik, die hinter den Lösungen steckt, so müssten die Summenformeln hergeleitet werden. Damit wäre der Beweis der Summenformeln die Herausforderung. In unserem Fall soll die Kernaufgabe jedoch mit Hilfe von Python gelöst werden, daher sehe ich keine weitere Herausforderung.</p>
<h3>Der Problemlösung erster Teil</h3>
<p>Im ersten Lösungsvorschlag geht es darum, wie das 6.Problem gelöst werden kann, wenn man lediglich Papier und einen Bleistift zur Verfügung hat. Des Weiteren müssen wir die zusätzliche Einschränkung einführen, dass nicht viel Zeit benötigt werden darf. Nicht, dass noch jemand auf die Idee kommt alles von Hand oder im Kopf zu rechnen.</p>
<p>Wenden wir uns der ersten Teilaufgabe zu: Berechnung des Quadrats der Summe von 1 bis 100.</p>
<p>Hierfür können wir erst einmal die <a href="http://de.wikipedia.org/wiki/Formelsammlung_Algebra#Summenformeln">Gauss-Formel</a> verwenden:<br />
<code class="bash">1 + 2 + 3 + ... + 98 + 99 + 100 = n (n+1) * 0.5 = 5050</code></p>
<p>Wird das Ergebnis der Summenformel (5050) noch quadriert, so erhalten wird schon den ersten Teil der Lösung:<br />
<code class="bash">5050 * 5050 = 25502500</code></p>
<p>Der zweite Teil, also die Quadratsumme, macht uns das Leben nicht so einfach. Aber mit Hilfe einer zweiten Summenformel auch nicht wirklich schwer:<br />
<code class="bash">1*1 + 2*2 + 3*3 + ... + 98*98 + 99*99 + 100*100 = n * (n+1) * (2n+1) * (1/6) = 338350</code></p>
<p>Damit wäre das 6.Projecteuler-Problem gelöst:<br />
<code class="bash">25502500 - 338350 = 25164150</code></p>
<h3>Der Problemlösung zweiter Teil</h3>
<p>Kommen wir zu der versprochenen Implementierung in Python:</p>
<pre class="brush:python">def direct(N):
    SOSq = 0
    SqOS = 0

    for i in range(1,N+1):
        SOSq = SOSq + i*i
        SqOS = SqOS + i

    return SqOS*SqOS - SOSq</pre>
</p>
<p>Zugegebenermaßen ist dieser Vorschlag nun wirklich ganz einfach und leicht nach zu vollziehen. Die Variable <em>SOSq</em> speichert hierbei die Summe der Quadrate und <em>SqOS</em> das Quadrat der Summe. Ausgegeben wird die gesuchte Differenz.</p>
<p>Natürlich habe ich an dieser Stelle auch etwas weiter gedacht und versucht die Lösung zu optimieren. Jedoch führten meine Gedanken mich immer wieder in Richtung der bereits vorgestellten Summenformeln.</p>
<h3>Schlusswort</h3>
<p>Das war nun wieder ein Lebenszeichen der Serie zu Lösungen von Projecteuler-Problemen. Der Python-Teil ist diesmal etwas kurz ausgefallen, was in Anbetracht des Problems aber nicht wirklich verwunderlich ist. Sollte ein Leser eine raffinierte Lösung parat haben, so freue ich mich auf den Kommentar.</p>
<p>An dieser Stelle sei allen, die neben der Mathematik und vielen Stunden Programmierarbeit noch etwas Zeit finden zum Lesen, das Buch <a href="http://www.amazon.de/gp/product/3499241005?ie=UTF8&#038;tag=wwwmuvikde-21&#038;linkCode=as2&#038;camp=1638&#038;creative=19454&#038;creativeASIN=3499241005">Die Vermessung der Welt*</a><img src="http://www.assoc-amazon.de/e/ir?t=wwwmuvikde-21&#038;l=as2&#038;o=3&#038;a=3499241005" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> von Daniel Kehlmann empfohlen. Es geht um zwei herausragende deutsche Wissenschaftler: Carl Friedrich Gauss und Alexander von Humboldt. Es ist ein interessantes Buch, welches durch einen lockeren Schreibstil gekennzeichnet ist, perfekt um in den Kopf zweier Genies einzutauchen.</p>
<p>*: Partnerlink</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/06/30/projecteuler-loesung-zu-problem-6/">Permalink</a> |
<a href="http://www.muvik.de/2010/06/30/projecteuler-loesung-zu-problem-6/#comments">keine Kommentare</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/06/30/projecteuler-loesung-zu-problem-6/&title=Projecteuler: Lösung zu Problem 6">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/06/30/projecteuler-loesung-zu-problem-6/&title=Projecteuler: Lösung zu Problem 6">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/06/30/projecteuler-loesung-zu-problem-6/&title=Projecteuler: Lösung zu Problem 6">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/mathematik/" rel="tag">Mathematik</a>, <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/06/30/projecteuler-loesung-zu-problem-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 5</title>
		<link>http://www.muvik.de/2010/05/17/projecteuler-loesung-zu-problem-5/</link>
		<comments>http://www.muvik.de/2010/05/17/projecteuler-loesung-zu-problem-5/#comments</comments>
		<pubDate>Mon, 17 May 2010 11:46:47 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Primzahlen]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=617</guid>
		<description><![CDATA[In langsamen Schritten mehren sich die Lösungsvorschläge zu den projecteuler.net Problemen in dieser Serie. Nun sind es fünf an der Zahl. Zur Feier des Tages werden heute eine ganz simple, handschriftliche Lösung vorgestellt und die dazu äquivalente Implementierung in Python gezeigt. Problemvorstellung Die Probleme von projecteuler.net sind aufgrund des meist recht hohen Rechenaufwands nicht nur [...]]]></description>
			<content:encoded><![CDATA[<p><img class="cat-img-wide" title="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" alt="Projecteuler: Lösungen mit Python und C++" width="443" height="98" /></p>
<p class="preview">In langsamen Schritten mehren sich die Lösungsvorschläge zu den projecteuler.net Problemen in dieser Serie. Nun sind es fünf an der Zahl. Zur Feier des Tages werden heute eine ganz simple, handschriftliche Lösung vorgestellt und die dazu äquivalente Implementierung in Python gezeigt.</p>
<p><span id="more-617"></span></p>
<h3>Problemvorstellung</h3>
<p>Die Probleme von <a href="http://projecteuler.net" target="_blank">projecteuler.net</a> sind aufgrund des meist recht hohen Rechenaufwands nicht nur durch Überlegen mit Bleistift und Papier zu lösen. Zumindest nicht in einem vertretbaren zeitlichen Rahmen. Ebenso häufig, wie die Probleme nicht ohne weiteres mit Bleistift und Papier lösbar sind, helfen diese Mittel das Problem besser zu verstehen und eine elegante Lösung zu erarbeiten.</p>
<p>Wie bereits bei der <a href="http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/">Lösung des vierten Problems</a>, lassen sich auch hier einige Gedanken machen, die schnell zur Lösung führen. Diesmal geht es sogar soweit, dass eine rein schriftliche Lösung ohne großen Aufwand eingereicht werden kann.</p>
<p>Obwohl das Problem an sich keine Herausforderung mehr darstellt, wenn die Probleme 1 bis 4 gelöst sind, habe von derzeit 1802789 Projecteuler-Mitgliedern nur 64072 es auch gelöst.</p>
<p>Doch worum handelt das Problem, welches spätestens auf den zweiten Blick einfach erscheint?</p>
<p><strong>Finde die kleinste Zahl, welche durch alle Zahlen von 1 bis 20 gerade teilbar ist!</strong></p>
<p>Als Beispiel zu dieser Fragestellung haben die Macher hinter Projecteuler.net das gleiche Problem mit den Zahlen von 1 bis 10  gelöst. Hiernach ergibt sich als Lösung: 2520.</p>
<h3>Problemeingrenzung</h3>
<p>Spätestens seit der <a href="http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/">Lösung des dritten Projecteuler-Problems</a> wissen wir, dass alle Zahlen eine eindeutige Primfaktorenzerlegung besitzen. Ebenfalls aus dem dritten Problem ist bekannt, wie wir eine Primfaktorenzerlegung durchführen können, dieses Wissen hilft uns an dieser Stelle weiter.</p>
<p>Wie können wir das bereits erworbene Wissen auf dieses Problem übertragen?</p>
<p>Gesucht ist eine Zahl, die durch alle Zahlen von 1 bis 20 ohne Rest teilbar ist. Gleichwertig kann auch eine Zahl gefunden werden, welche durch alle Primfaktoren der Zahlen 1 bis 20 ohne Rest teilbar ist. Also suchen wir erst einmal eine Menge an Primzahlen, welche die Zahlen 1 bis 20 abbilden kann. Dabei ist es nicht wichtig, dass alle 21 Zahlen gleichzeitig aus der Menge heraus gebildet werden können.</p>
<p>In Kürze ergibt sich aus den Überlegungen und dem bereits vorhandenen Wissen folgendes Vorgehen:</p>
<ol>
<li>Suchen aller Primzahlen bis 20 entweder im Kopf oder mit dem Sieb des Eratosthenes.</li>
<li>Suchen der Primfaktorenzerlegung aller Zahlen von 1 bis 20 und zusammenfassen aller Primfaktoren mit ihren Häufigkeiten in einer Menge.</li>
<li>Reduzieren der Häufigkeiten, damit jede Zahl mindestens ein Mal aus den Primfaktoren gebildet werden kann.</li>
</ol>
<p>Also beschränkt sich die Herausforderung der Aufgabe lediglich auf eine Primfaktorenzerlegung und etwas Abzählen der Häufigkeiten. Gehen wir es an!
</p>
<h3>Problemlösung</h3>
<p>Wie bereits in der Einleitung angedroht, versuche ich mich zum ersten Mal in dieser Serie mit einer einfachen, handschriftlichen Rechnung. Dazu gehe ich zielführenden nach den Punkten 1-3 aus dem vorangegangenen Abschnitt vor:</p>
<ol>
<li>Die Primzahlen bis 20 inkl. der 1:<code class="bash">1 2 3 5 7 11 13 17 19</code></li>
<li>Primfaktoren aller Zahlen außer der Primzahlen von 1 bis 20:<br />
<code class="bash">4: 2 2<br />
6: 2 3<br />
8: 2 2 2<br />
9: 3 3<br />
10: 2 5<br />
12: 2 2 3<br />
14: 2 7<br />
15: 3 5<br />
16: 2 2 2 2<br />
18: 2 3 3<br />
20: 2 2 2 5</code><br />
Daraus ergibt sich die folgende Gesamtverteilung:<br />
<div id="attachment_634" class="wp-caption alignnone" style="width: 410px"><img src="http://www.muvik.de/wp-content/uploads/2010/05/primefactors-e1274094265862.png" alt="Häufigkeitsverteilung der Primfaktoren" title="Primfaktoren" width="400" height="299" class="size-full wp-image-634" /><p class="wp-caption-text">Häufigkeitsverteilung der Primfaktoren</p></div><br />
Zur Lösung des Problems ist eine solche Darstellung nicht nötig. Um jedoch zu verdeutlichen, wie viel kleiner die gesuchte Zahl ist, wenn alle Faktoren, die zu viel sind, gestrichen werden, eignet sie sich hervorragend.
</li>
<li>Jetzt bleibt nur noch die einzelnen Primfaktorzerlegungen durch zu gehen und die Häufigkeiten der Primfaktoren zu zählen. Daraus ergibt sich folgende Verteilung:<br />
<div id="attachment_638" class="wp-caption alignnone" style="width: 410px"><img src="http://www.muvik.de/wp-content/uploads/2010/05/primefactor_red-e1274094888619.png" alt="Reduzierte Primfaktoren" title="Reduzierte Primfaktoren" width="400" height="300" class="size-full wp-image-638" /><p class="wp-caption-text">reduzierte Häufigkeitsverteilung</p></div><br />
Das war es schon! Das Multiplizieren aller verbleibenden Faktoren führt zu der gesuchten Zahl:<br />
<code class="bash">1*2*2*2*2*3*3*5*7*11*13*17*19 = 232792560</code>
</li>
</ol>
<h3>Alternative Lösung</h3>
<p>Als alternative Lösung verkaufe ich heute einfach die Python-Implementierung des zuvor beschriebenen handschriftlichen Lösungswegs:</p>
<pre class="brush:python">import numpy as np

def eratosthenes(N):
    """liefert alle Primzahlen bis N"""
    primes = np.arange(1,N+1,1)

    for i in np.arange(2,np.ceil(np.sqrt(N))+1,1):
        primes[i*i-1:N:i] = 0;

    return primes

def prime_fact_counter(N,testPrimes):
    nPrimes = np.size(testPrimes)
    countPrimes = np.zeros_like(testPrimes)

    for i in range(1,nPrimes,1):
        actPrime = testPrimes[i]
        while ((N%actPrime == 0) &#038; (N >= actPrime)):
            N = N / actPrime;
            countPrimes[i] = countPrimes[i] + 1
        countPrimes[0] = 1
    return countPrimes

def solver(N):
    searchProduct = 1.0
    testPrimes = np.trim_zeros(np.sort(eratosthenes(N)))

    freq = np.zeros_like(testPrimes) # array of prime occurance for each factor 1..20
    totFreq = np.zeros_like(testPrimes) # array of total prime occurance

    print(testPrimes)

    for i in range(1,N+1,1):
        freq = prime_fact_counter(i,testPrimes)
        for j in range(0,freq.size,1):
            if (freq[j] > totFreq[j]):
                totFreq[j] = freq[j]

    print(totFreq)

    for j in range(0,totFreq.size,1):
        searchProduct = searchProduct * (testPrimes[j])**(totFreq[j])

    return searchProduct

N = 20

print(solver(N))</pre>
<p>Insgesamt habe ich drei Funktionen definiert. Die erste Funktion ist der bereits bekannte Sieb des Eratosthenes. Sie berechnet alle Primzahlen bis zu einer Zahl N, oder anders ausgedrückt, alle in der Primfaktorenzerlegung vorkommenden Primzahlen der Zahl N.</p>
<p>Die zweite Funktion zählt die Anzahl der Primfaktoren einer bestimmten Zahl N. Das ist wichtig, um die maximale Häufigkeit eines Faktors in einer Zahl festzustellen. Zum Beispiel enthält die 16 genau vier mal die 2 als Faktor: <code class="bash">2*2*2*2 = 16</code>
</p>
<p>Die solver-Funktion durchläuft alle Zahlen von 1 bis 20, berechnet die Primfaktorenzerlegung und überprüft die Häufigkeiten. Am Ende wird aus der reduzierten Häufigkeitsverteilung die gesuchte Zahl errechnet.</p>
<p>Damit wäre das fünfte Problem von Projecteuler gelöst!</p>
<h3>Schlusswort</h3>
<p>Aufgrund des niedrigen Schwierigkeitsgrades des fünften Problems konnte zum ersten Mal in dieser Serie eine rein handschriftliche Lösung präsentiert werden. Alternativ dazu wurde auch eine Python-Implementierung aufgeführt, welche auch für Zahlen größer als N=20 geeignet ist.</p>
<p>In der Hoffnung, dass die simple Idee, die hinter dem Lösungsvorschlag steckt, klar geworden ist, freue ich mich wie immer auf Kommentare und Verbesserungsvorschläge.</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/05/17/projecteuler-loesung-zu-problem-5/">Permalink</a> |
<a href="http://www.muvik.de/2010/05/17/projecteuler-loesung-zu-problem-5/#comments">keine Kommentare</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/05/17/projecteuler-loesung-zu-problem-5/&title=Projecteuler: Lösung zu Problem 5">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/05/17/projecteuler-loesung-zu-problem-5/&title=Projecteuler: Lösung zu Problem 5">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/05/17/projecteuler-loesung-zu-problem-5/&title=Projecteuler: Lösung zu Problem 5">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/primzahlen/" rel="tag">Primzahlen</a>, <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/05/17/projecteuler-loesung-zu-problem-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 4</title>
		<link>http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/</link>
		<comments>http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 09:00:10 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Palindrom]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=493</guid>
		<description><![CDATA[Heute wird die Lösung des vierten Projekteuler-Problems vorgestellt. Es ist nun ein guter Monat vergangen, seit ich das Problem gelöst habe, deswegen hoffe ich, dass ich noch alles zusammenbekomme. Problemvorstellung Das Durchlesen des vierten Problems hat mir wieder einmal vor Augen geführt, warum die Mathematik auf viele Menschen eine abschreckende Wirkung hat. In der Aufgabe [...]]]></description>
			<content:encoded><![CDATA[<img class="cat-img-wide" alt="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" title="Projecteuler: Lösungen mit Python und C++" width="443" height="98" />
<p class="preview">Heute wird die Lösung des vierten Projekteuler-Problems vorgestellt. Es ist nun ein guter Monat vergangen, seit ich das Problem gelöst habe, deswegen hoffe ich, dass ich noch alles zusammenbekomme.</p>
<p><span id="more-493"></span></p>
<h3>Problemvorstellung</h3>
<p>Das Durchlesen des vierten Problems hat mir wieder einmal vor Augen geführt, warum die Mathematik auf viele Menschen eine abschreckende Wirkung hat. In der Aufgabe gilt es das größte Palindrom zu finden, welches sich aus zwei dreistelligen Zahlen ergibt.</p>
<p>Da ist mir erstmal durch den Kopf gegangen: Pali&#8230;was?</p>
<p>Dabei ist die Mathematik doch viel einfacher als es klingt, der Blick hinter den Vorhang lohnt sich immer. Gesagt, getan und herausgefunden, dass Palindrome keine Medikamente und auch nichts zum Essen sind, sondern Zahlen, welche von vorne oder von hinten gelesen, den selben Wert ergeben:<br />
<code class="bash">22, 232, 23232, 996676699, ...</code><br />
Der Fantasie kann hierbei freier Lauf gewährt werden. Es gibt jedoch nicht nur Palindrom-Zahlen, sondern auch Namen, wie zum Beispiel Anna.</p>
<p>Um die Aufgabenstellung nochmal hervorzuheben, sei sie nochmal besonders genannt:</p>
<p><strong>Finde das größte Palindrom, welches sich multiplikativ aus zwei dreistelligen Zahlen ergibt.</strong></p>
<p>Aufgrund des Fremdwortes, welches genauer betrachtet nur für eine optisch besondere Zahlenmenge steht, hört sich die Aufgabe erstmal abschreckend an. Jedoch haben sich inklusive meiner Wenigkeit bis heute 54282 Projecteuler-Aktivisten an das Problem mit erfolgreichem Ausgang getraut. Verglichen mit den vorangehenden Problemen <a href="http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/">3</a> und <a href="http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/">2</a> haben sich an dieser Aufgabe noch etwas mehr Menschen die Zähne aus gebissen. Das hat dann dazu geführt, dass nochmal weniger Lösungen eingereicht wurden. Aber wir lassen uns doch nicht von irgendwelchen Statistiken abschrecken <img src='http://www.muvik.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  und grenzen das Problem etwas näher ein.</p>
<h3>Problemeingrenzung</h3>
<p>Hat man sich erstmal klar gemacht, was nun Palindrome sind, so stellt sich sogleich die Frage, wie man mit Hilfe einer Programmiersprache überprüfen kann, ob eine Zahl die besondere Eigenschaft der Palindrome besitzt oder nicht. Dies betrachte ich zunächst als erste kleine Herausforderung bei dem Problem.</p>
<p>Die zweite Herausforderung ist in meinen Augen, eine sinnvolle Suche nach Palindromen zu gestalten. Die straight forward Methode wäre alle Zahlen zu multipilzieren und das Produkt auf die Palindrom-Eigenschaft zu prüfen. Doch diesmal dachte ich mir, biete ich keine straight forward Lösung an, sondern steige gleich mit ein Paar Gedanken ins Programmieren ein.</p>
<p>Das Resultat einiger Gedanken kann zum Beispiel sein:</p>
<ul>
<li>Die größte Zahl aus einem Produkt zweier dreistelliger Zahlen ergibt sich aus den Zahlen 999 und 999, deswegen lassen wir die Suche von diesen Zahlen beginnen.</li>
<li>Das größte Palindrom hat wahrscheinlich eine 9 an der ersten und somit auch an der letzten Stelle. Daher sind nur Faktoren interessant, die definitiv eine 9 an letzter Stelle ergeben. Dazu zählen folgende Paare: <code class="bash">(7,7) (3,3) (1,9) (9,1)</code></li>
<li>Um garantiert das größte Palindrom mit dem Musters 9*****9 zu finden, muss in erster Annahme lediglich die Zehner-Stelle der Faktoren variiert werden. Diese wird in jedem Test um 1 reduziert. Sobald an der Hunderttausender-Stelle eine 8 auftaucht, wird angenommen, dass es schon nicht das größte Palindrom sein kann.</li>
</ul>
<p>Mit diesem &#8220;Wissen&#8221; im Hinterkopf, lässt sich das vierte Projecteuler Problem schnell lösen.
</p>
<h3>Problemlösung</h3>
<p>Aus der Problemeingrenzung wissen wir, dass es zwei Herausforderungen bei dieser Aufgabe gibt. Die erste ist der Palindromtest, die zweite die sinnvolle Suche nach dem größten Palindrom. Dazu habe ich folgenden Code geschrieben:</p>
<pre class="brush:python">import numpy as np

def test_palindrom(x):
    return x == int(str(x)[::-1])

#    return x == reverse_int(x)

def solver(L,R):
    chL = np.array([-2,-6,-8,0])
    chR = np.array([-2,-6,0,-8])

    maxChange = range(0,11,1)

    palindroms = np.array([[1,2,3]],ndmin=2)

    for k in [0,1,2,3]:
        for i in maxChange:

            LFact = L + chL[k] - i*10

            for j in maxChange:

                RFact =  R + chR[k] - j*10
                testFig = LFact * RFact

                if test_palindrom(testFig):
                    palindroms = np.append(palindroms, [[testFig, LFact, RFact]],axis=0)

    return palindroms

L = 999
R = 999

print(solver(L,R))</pre>
</p>
<p>Die zu Beginn definierte Funktion test_palindrom(x) überprüft die Palindromeigenschaft. Dies geschieht auf eine einfache Weise: zuerst wird die Zahl x in einen String umgewandelt, dann wird der String gedreht und wieder in einen Integer-Wert konvertiert. Auf diese Weise kann getestet werden, ob x von beiden Seiten gelesen den selben Wert besitzt.</p>
<p>Die Doppelpunktnotation, welche ich zum Umdrehen des Strings verwendet habe, kennt wahrscheinlich jeder Matlab-Nutzer. Der erste Doppelpunkt steht für den ersten Wert, der ausgegeben werden soll, der zweite für den Letzten und die &#8220;-1&#8243; zeigt an, dass jeder 1-ste Wert ausgegeben werden soll, aber von hinten.</p>
<p>Wenn nun x kein Palindrom ist, dann spuckt die Funktion den wert &#8220;0&#8243; oder &#8220;false&#8221; aus.</p>
<p>Die solver-Funktion baut auf den zuvor gemachten Gedanken auf. Als Eingabewerte werden jeweils 999 erwartet. Die numpy-Vektoren &#8220;chL&#8221; und &#8220;chR&#8221; beinhalten die Variation der Suchzahlen. Damit werden folgende Zahlen als Startzahlen verwendet:<br />
<code class="bash">(997,997) (993,993) (991,999) (999,991)</code></p>
<p>Der Vektor maxChange bewirkt, dass von den Startwerten maximal Zehn mal die Zehn abgezogen wird.</p>
<p>Durch die drei Schleifen wird sichergestellt, dass auch jede Zahl mit jeder multipliziert wird, die nach der Eingrenzung noch übrig geblieben sind. Ist eine Zahl ein Palindrom, so wird sie in einem Feld samt der Faktoren gespeichert und zurückgegeben.</p>
<p>Der langen Rede kurzer Sinn besteht dann aus drei Zeilen:<br />
<code class="bash">[[     1      2      3]<br />
 [906609    993    913]<br />
 [906609    913    993]]<br />
</code> Erwartungsgemäß trat zumindest ein Palindrom mit einer äußeren 9 auf. Da habe ich ziemlich Glück gehabt <img src='http://www.muvik.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Ebenfalls war zu erwarten, dass das Palindrom doppelt vorkommt, weil mit der gezeigten Methode jedes Zahlenpaar zwei Mal multipliziert wird. Da wäre also noch etwas Optimierungspotential vorhanden.</p>
<h3>Fazit</h3>
<p>Da es heute keine alternativen Lösungen gibt, komme ich gleich zum Fazit. Das vierte Problem war für mich eine interessante Aufgabe, bei der ich Python etwas besser lernen konnte. Zum Beispiel war mir nicht bekannt, dass in Python die Doppelpunkt-Notation auch mit negativen Zahlen funktioniert. Also wieder etwas gelernt.</p>
<p>Nun hoffe ich, dass es euch auch Spass gemacht hat, das Problem und die Lösung nachzuvollziehen und freue mich über Kommentare.</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/">Permalink</a> |
<a href="http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/#comments">ein Kommentar</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/&title=Projecteuler: Lösung zu Problem 4">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/&title=Projecteuler: Lösung zu Problem 4">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/&title=Projecteuler: Lösung zu Problem 4">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/palindrom/" rel="tag">Palindrom</a>, <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/04/30/projecteuler-loesung-zu-problem-4/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 3</title>
		<link>http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/</link>
		<comments>http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 09:00:16 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Primzahlen]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=413</guid>
		<description><![CDATA[Nach einer etwas längeren Pause geht es heute mit der Projecteuler-Serie weiter. In diesem Artikel stelle ich meine Lösung des dritten Problems dar. Wie bereits bei den vorangehenden Teilen gibt es auch hier wieder alternative Ansätze. Problemvorstellung Das dritte Problem von Projecteuler.net dreht sich allgemein gesprochen um die Primfaktorzerlegung. Aus grauer Schulzeit wissen wir, dass [...]]]></description>
			<content:encoded><![CDATA[<img class="cat-img-wide" alt="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" title="Projecteuler: Lösungen mit Python und C++" width="443" height="98" />
<p class="preview">Nach einer etwas längeren Pause geht es heute mit der Projecteuler-Serie weiter. In diesem Artikel stelle ich meine Lösung des dritten Problems dar. Wie bereits bei den vorangehenden Teilen gibt es auch hier wieder alternative Ansätze.</p>
<p><span id="more-413"></span></p>
<h3>Problemvorstellung</h3>
<p>Das dritte Problem von Projecteuler.net dreht sich allgemein gesprochen um die Primfaktorzerlegung. Aus grauer Schulzeit wissen wir, dass jede natürliche Zahl in Primfaktoren zerlegt werden kann. Des Weiteren haben Primzahlen die berüchtigte Eigenschaft nur durch sich selber und durch die Eins teilbar zu sein. Danach hat jede natürliche Zahl mindestens zwei Faktoren, wobei die Eins als trivialer Faktor beinahe vernachlässigt werden kann. Nicht-Primzahlen, also die zusammengesetzten Zahlen, können folglich in ihre kleinsten Bestandteile, die Primzahlen getrennt werden.</p>
<p>Ich muss zugeben, dass es nun wirklich keine wissenschaftliche Erklärung und kein Beweis für die Existenz einer exakten Primfaktorzerlegung ist, was ich aufgeführt habe. Den Zweck einer netten Einführung erfüllt es jedoch und ich bin glücklich <img src='http://www.muvik.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . Sollte jemand weiterführende Informationen benötigen, so möge Er oder Sie sich im Web umschauen oder einen Hinweis in den Kommentaren hinterlassen, dann lässt sich sicher noch etwas machen.</p>
<p>Also wir wissen nun, wohin das dritte Problem führen wird, doch wie lautet die Aufgabenstellung genauer? Die Auflösung:</p>
<p><strong>Finde den größten Primfaktor der Zahl 600851475143.</strong></p>
<p>Ja, das war es schon! Hört sich doch ganz machbar an, oder? Das haben sich 56838 der derzeit 100370 Hobbymathematiker auch gedacht und die Aufgabe erfolgreich gelöst. Im Vergleich zum ersten und zweiten Problem entspricht dies schon deutlich weniger eingereichten Lösungen. Bisher sind es grob abgeschätzt etwa 50% aller Projecteuler.net Aktivisten. Schlussendlich kann diese Entwicklung auf einen steigenden Schwierigkeitsgrad oder einen sinkenden Motivationsgrad hindeuten, also ein typisches Glas-halb-leer bzw. Glas-halb-voll Problem, welches auf in einem anderen Artikel gelöst wird <img src='http://www.muvik.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<h3>Problemeingrenzung</h3>
<p>Kommen wir nun zum Kern der Geschichte: Das erste Durchlesen dieses Problems hinterließ bei mir zwei Gedanken. Der erste Gedanke war, wie finde ich raus, ob eine Zahl nun eine Primzahl ist oder nicht und der zweite Gedanke beschäftigte sich mit dem Prüfen des größten Teilers.</p>
<p>Das erste Teilproblem gehe ich im folgenden mit dem <a href="http://de.wikipedia.org/wiki/Sieb_des_Eratosthenes" target="_blank">Sieb des Erathosthenes (Wikipedia)</a> an.</p>
<p>Das zweite Teilproblem wird ganz simpel gelöst, indem die gegebene Zahl auf Teilbarkeit durch die gefundenen Primzahlen untersucht wird.</p>
<h3>Problemlösung</h3>
<p>Das Sieb des Erathostenes ist eine recht einfache Methode alle Primzahlen bis zu einer bestimmten Zahl N zu finden. Wie im verlinkten Wiki-Artikel schön dargestellt ist, schreibt man alle Zahlen bis einschließlich N auf und beginnt das Sieben. Dazu fängt man mit der kleinsten bekannten Primzahl, also der zwei, an und streicht alle Vielfachen dieser Zahl, dann macht man dasselbe mit der nächsten nicht gestrichenen Zahl nach der Zwei weiter. Auf diese Weise bleiben am Ende alle Primzahlen bis N übrig.</p>
<p>Der langen Rede kurzer Sinn ist in Python-Code im Folgenden dargestellt.</p>
<pre class="brush:python">import time as t
import numpy as np
from math import ceil, sqrt

def eratosthenes_direct(N):
    """
    Berechnet alle Primzahlen bis N mit dem Sieb des Eratosthenes
    """
    primes = np.arange(3,N+1,2)  # only uneven figures
    primes = np.insert(primes,0,2,0) # ... and two

    testFigs = np.arange(3,np.ceil(np.sqrt(N))+2,2)

    for i in testFigs:
        if (primes[((i+1)/2-1)] != 0):
            noPrime = i*i
            while noPrime <= N:
                primes[((noPrime+1)/2-1)] = 0
                noPrime = noPrime + 2 * i

    return np.trim_zeros(np.sort(primes))

def eratosthenes_vect(N):
    primes = np.arange(3,N+1,2)  # only uneven figures
    primes = np.insert(primes,0,2,0) # ... and two

    nUneven = np.size(primes) - 1.0

    for i in np.arange(3,np.ceil(np.sqrt(N))+2,2):
        primes[(i*i+1)/2-1:nUneven+1.0:i] = 0;

    return np.trim_zeros(np.sort(primes))</pre>
<p>In dem Code-Abschnitt habe ich gleich zwei alternative Beispiele für den Sieb des Eratosthenes aufgeführt. Beide Funktionen gehen nach dem gleichen Prinzip vor; der kleine Unterschied ist beim Streichen der Vielfachen zu finden.</p>
<p>Da von vornherein klar ist, dass keine gerade Zahl außer der Zwei Primzahl sein kann, werden nur die ungeraden Zahlen bis N im Vektor <em>primes</em> gespeichert. Bevor ich den Code getippt habe, führte ich das Sieben auf dem Papier aus und bin dann darauf gekommen, dass die größte, auf Vielfache zu prüfende Primzahl die Wurzel von N sein muss. Alle Zahlen die größer als die Wurzel von N sind, müssen demnach Primzahlen sein oder werden beim Sieben gestrichen.</p>
<p>Die an zweiter Stelle aufgeführte Funktion nutzt die Möglichkeiten von Numpy aus, indem keine while-Schleife verwendet wird, sondern das Streichen über eine Indexauswahl des Vektors stattfindet.</p>
<p>Zuletzt werden mit den Numpy-Funktionen <em>sort</em> und <em>trim_zeros</em> die Primzahlen von den Nullen getrennt.</p>
<p>So weit so gut! Nun liefert uns das Sieb einen Vektor an Primzahlen bis zu einer bestimmten Zahl N. Um die Projecteuler-Aufgabe zu lösen, muss noch der größte Primfaktor gefunden werden:</p>
<pre class="brush:python">def solver(N,primes):
    rebuild = 1.0
    prob    = N
    for i in primes:
        while (N%i == 0):
            N = N/i
            found = i
            rebuild = rebuild * found

            if (rebuild/prob > 0.9):
                print(rebuild)
                return found

    return 0.0</pre>
<p>Der Solver durchläuft alle Primzahlen, prüft Sie auf Teilbarkeit und, wenn die Zahl ein Teiler ist, so wird sie als ein Lösungskandidat gespeichert. Die while-Schleife soll doppelte Primzahlen ebenfalls erfassen.</p>
<p>Der Solver wurde von mir nicht weiter validiert und könnte durchaus noch das eine oder andere Problem bereiten, aber für die von mir getesteten Zahlen hat alles funktioniert.</p>
<h3>Lösungsanalyse</h3>
<p>Kommen wir nun zur Anwendung des Siebs und des Solvers.</p>
<p>Zunächst muss eine Grenze für das Sieb festgelegt werden. Da ich den Solver so geschrieben habe, dass er mir nur einen Lösungskandidaten ausgibt, wenn die Zahl von Projecteuler rekonstruiert werden konnte, habe ich als Grenze zunächst 1000 ausprobiert. Das war zu wenig und ich erhöhte die Grenze auf 10000, was eine Lösung ausspuckte.</p>
<p>Der Aufruf:</p>
<pre class="brush:python">N  = 10000
Pe = 600851475143
#
t0 = t.clock()
primes = eratosthenes_direct(N)
prim = solver(Pe,primes)
tn = t.clock()

print("Zeit fuer Primzahlensieb: %.15f" %(tn-t0))
print("Primzahl: ")
print(prim)

t0 = t.clock()
primes2 = eratosthenes_vect(N)
prim2 = solver(Pe,primes2)
tn = t.clock()

print("Zeit fuer Primzahlensieb: %.15f" %(tn-t0))
print("Primzahl: ")
print(prim2)</pre>
<p>Und die Ausgabe:</p>
<p><code class="bash">600851475143.0<br />
Zeit fuer Primzahlensieb: 0.080000000000000<br />
Primzahl:<br />
6857<br />
600851475143.0<br />
Zeit fuer Primzahlensieb: 0.030000000000000<br />
Primzahlen:<br />
6857</code></p>
<p>Abgesehen davon, dass das Ergebnis die richtige Lösung für das dritte Projecteuler-Problem ist, kann festgestellt werden, dass der Sieb ohne die while-Schleife um mehr als das doppelte schneller ist. Das war zu erwarten, denn die Numpy-Funktionen werden sicherlich nicht von Anfängern, wie ich einer bin, geschrieben. </p>
<h3>Fazit</h3>
<p>Damit wäre das dritte Problem gelöst. Auch diesmal gibt es eine kleine Neuerung im Blog: mit dem Sieb des Eratosthenes wurde der erste Algorithmus vorgestellt. Ich denke, dass ich in nächster Zeit wieder etwas mehr Zeit für den Blog haben werde und daher öfter etwas schreiben kann.</p>
<p>Jetzt sind aber erstmal die Leser wieder an der Reihe mit Verbesserungsvorschlägen und weiteren Lösungsansätzen. Ich freue mich darauf.</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/">Permalink</a> |
<a href="http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/#comments">2 Kommentare</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/&title=Projecteuler: Lösung zu Problem 3">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/&title=Projecteuler: Lösung zu Problem 3">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/&title=Projecteuler: Lösung zu Problem 3">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/primzahlen/" rel="tag">Primzahlen</a>, <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/04/03/projecteuler-loesung-zu-problem-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 2</title>
		<link>http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/</link>
		<comments>http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 10:49:44 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Rekursion]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=177</guid>
		<description><![CDATA[Die &#8220;Lösungen in Projecteuler&#8221;-Serie geht mit dem zweiten Teil und dem zweiten Problem weiter. Heute stelle ich wieder kurz das Problem vor und einige kleine Statistiken aus Projecteuler.net-Seite und dann gibt es zunächst eine straight-forward Lösung und zwei alternative Ansätze, die eventuell etwas schneller oder eleganter sind. Problemvorstellung Das zweite Problem von Projecteuler.net dreht sich [...]]]></description>
			<content:encoded><![CDATA[<p><img class="cat-img-wide" title="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" alt="Projecteuler: Lösungen mit Python und C++" width="443" height="98" /></p>
<p class="preview">Die &#8220;Lösungen in Projecteuler&#8221;-Serie geht mit dem zweiten Teil und dem zweiten Problem weiter. Heute stelle ich wieder kurz das Problem vor und einige kleine Statistiken aus Projecteuler.net-Seite und dann gibt es zunächst eine straight-forward Lösung und zwei alternative Ansätze, die eventuell etwas schneller oder eleganter sind.</p>
<p><span id="more-177"></span></p>
<h3>Problemvorstellung</h3>
<p>Das zweite Problem von Projecteuler.net dreht sich um eine Zahlenfolge, die bei allen Mathematik- und Informatiklehrern beliebt zu sein scheint. Es handelt sich dabei um die Fibonacci-Folge, eine unendliche Folge von Zahlen, die sich jeweils aus den zwei vorhergehenden Zahlen durch Addition ergeben.</p>
<p>Im folgenden Beispiel beginnt die Fibonacci-Folge mit zwei Einsen:<br />
<code class="bash">1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233 ...</code></p>
<p>Ein Herr Fibonacci hat der Legende nach versucht, eine ideal wachsende Kaninchenpopulation damit zu beschreiben. Er ist von zwei Kaninchen ausgegangen und ist auf diese Zahlenfolge mit folgenden Regeln gekommen:</p>
<ul>
<li>das Spiel beginnt mit einem Kaninchenpärchen</li>
<li>pro Zyklus wirft jedes geschlechtsreife Pärchen ein weiteres Pärchen</li>
<li>jedes Pärchen wird im zweiten Zyklus geschlechtsreif</li>
<li>kein Tier stirbt, kein Tier kommt zusätzlich hinzu</li>
</ul>
<p>Wendet man die Regeln an, so lebt im ersten Zyklus ein Pärchen. Im zweiten Zyklus leben schon 2 Pärchen, aber nur eines ist geschlechtsreif und wirft im dritten Zyklus ein weiteres Pärchen. Im vierten Zyklus werden zwei weitere Pärchen geworfen, weil es bereits zwei geschlechtsreife Pärchen gibt, das erste und das zweite Pärchen, welches inzwischen im zweiten Zyklus lebt. Auf diese Weise ergibt sich anschaulich die Fibonacci-Folge. Vielleicht lieben es die Lehrer deswegen so sehr <img src='http://www.muvik.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>Etwas mathematischer ausgedrückt sieht es so aus:</p>
<img src='http://s.wordpress.com/latex.php?latex=a_%7B1%7D%3D1%20%5Cnewline%20a_%7B2%7D%3D2%20%5Cnewline%20%20a_%7Bi%7D%20%3D%20a_%7Bi-2%7D%2Ba_%7Bi-1%7D&#038;bg=ffffff&#038;fg=000000&#038;s=1' alt='a_{1}=1 \newline a_{2}=2 \newline  a_{i} = a_{i-2}+a_{i-1}' title='a_{1}=1 \newline a_{2}=2 \newline  a_{i} = a_{i-2}+a_{i-1}' class='latex' />
<p>Damit haben wir das zweite Problem von Projecteuler.net etwas eingegrenzt und das Verständnis für die Fibonacci-Folge bildlich untermauert.</p>
<p>Doch worum geht es in dem Problem?</p>
<p><strong>In der zweiten Aufgabe sollen wir alle Zahlen der Fibonacci-Folge, die kleiner als vier Millionen und gleichzeitig gerade sind, addieren.</strong></p>
<p>Das war es schon.</p>
<p>Die Aufgabe gehört genauso, wie die erste zu den einfacheren Problemen. Zum heutigen Zeitpunkt haben 73397 der derzeit 95331 registrierten Hobbymathematiker diese Aufgabe gelöst, das sind immerhin stolze 77%.</p>
<h3>Problemeingrenzung</h3>
<p>Um der Herausforderung dieses Problems etwas auf die Schliche zu kommen, habe ich mir einfach alle Zahlen der Fibonacci-Folge ausgeben lassen, die kleiner als 4000000 sind. Dazu habe ich folgende kleine Funktion geschrieben:</p>
<pre class="brush:python">def print_fibos(N):
    i = 1;

    fibs = np.zeros(1)
    fibs[0] = 1
    fibs = np.append(fibs,[2.],axis=0)
    while (fibs[i]+fibs[i-1])</pre>
<p>Die Ausgabe zeigt genau 32 Zahlen. Würde man alle Zahlen addieren wollen, dann wären das 31 Additionen von Ganzzahlen, was nicht wirklich aufwendig ist. Deswegen denke ich, dass es eher sinnvoll ist, die Lösung dahingehend zu optimieren, dass möglichst wenige Tests durchgeführt werden müssen, ob eine Zahl gerade ist oder nicht.</p>
<h3>Problemlösung</h3>
<p>Wie bereits angekündigt stelle ich zunächst eine straight-forward Lösung vor. Hierbei geht Python alle Fibonacci-Zahlen durch und überprüft, ob sie kleiner als die Grenze von 4000000 ist und ob sie gerade ist. Sind beide Bedingungen erfüllt, so wird die Zahl zu einem Zähler addiert.<br />
So sieht das in Python-Code aus:</p>
<pre class="brush:python">import time as t
import numpy as np

def straight_forward(N):
    count  = 2;
    first  = 2;
    second = 3;
    next   = 0;

    while next &lt; N:
        next = first+second;
        first = second;
        second = next;

        if next%2 == 0:
            count = count + next

    return count;

# max. fibo
N = 4000000

print_fibos(N);

t0 = t.time();
erg = straight_forward(N);
tn = t.time();

print("The straight-forward method needed %.15f seconds.\nThe sum is: %12i" %(tn-t0,erg));</pre>
<p>Die Funktion gibt auf Anhieb die richtige Lösung von 4613732 aus.</p>
<h3>Lösungsanalyse</h3>
<p>In dem Code der straight-forward Lösung habe ich bereits die Zeitmessung mit eingebaut. Die Ausgabe des kleinen Programms liefert:</p>
<p><code class="bash">The straigt-forward method needed 0.000010013580322 seconds.<br />
The sum is:      4613732</code><br />
Ehrlich gesagt, ist die Ausgabe der Zeit in diesem Fall wohl eher nicht sehr zuverlässig. Mir geht es jedoch mehr um die Tendenz, weniger um den absoluten Wert, daher ist es ok.</p>
<p>Also hat die straight-forward Lösung in einer Zeit von 10 Mikrosekunden 10 Zahlen addiert und 31 Zahlen auf die Teilbarkeit durch zwei geprüft. Da die Aufgabe noch recht leicht ist, muss es ja auch besser gehen. Darum geht es im nächsten Abschnitt.</p>
<h3>alternative Lösung</h3>
<p>Die Problemeingrenzung hat uns gezeigt, dass es gilt, die Teilbarkeitstest durch zwei so selten wie nur möglich durchzuführen sind. Am Besten wären gar keine Tests. </p>
<p>Schauen wir uns die Folge der geraden Fibonacci-Zahlen näher an:<br />
<code class="bash">1, <strong>2</strong>, 3, 5,<strong> 8</strong>, 13, 21, <strong>34</strong>, 55, 89, <strong>144</strong>, 233 ...</code><br />
Es wird deutlich, dass ab der &#8220;2&#8243; jede dritte Zahl eine gerade Zahl ist. Folglich müssen auch nur diese summiert werden. Aus diesen Überlegungen hat sich dann folgender Code ergeben:</p>
<pre class="brush:python">import time as t
import numpy as np

def only_even(N):
    count = 2;
    a = 1;
    b = 2;
    next = 0;

    while count < N:
        next = 2*a+3*b
        a = 2*b+a
        b = next
        count = count + next;
    return count;

N=4000000;

t0 = t.time();
erg = only_even(N);
tn = t.time();

print("The only_even method needed %.15f seconds.\nThe sum is: %12i" %(tn-t0,erg));
</pre>
<p>Die Anweisung zur Berechnung der nächsten gerade Fibonacci-Zahl ergibt sich aus folgender Betrachtung:</p>
<img src='http://s.wordpress.com/latex.php?latex=next%20%3D%20a%20%2B%20b%3B%20%5C%3A%20a%5E%7B%27%7D%3Db%3B%5C%3A%20b%5E%7B%27%7D%3Dnext%20%5Cnewline%20next%5E%7B%27%7D%20%3D%20a%5E%7B%27%7D%20%2B%20b%5E%7B%27%7D%3B%20%5C%3A%20a%5E%7B%27%27%7D%3Db%5E%7B%27%7D%3B%5C%3A%20b%5E%7B%27%27%7D%3Dnext%5E%7B%27%27%7D%20%5Cnewline%20next%5E%7B%27%27%7D%20%3D%20a%5E%7B%27%27%7D%20%2B%20b%5E%7B%27%27%7D%3B%20%5C%3A%20a%5E%7B%27%27%27%7D%3Db%5E%7B%27%27%7D%3B%5C%3A%20b%5E%7B%27%27%27%7D%3Dnext%5E%7B%27%27%27%7D%20%5Cnewline&#038;bg=ffffff&#038;fg=000000&#038;s=1' alt='next = a + b; \: a^{&#039;}=b;\: b^{&#039;}=next \newline next^{&#039;} = a^{&#039;} + b^{&#039;}; \: a^{&#039;&#039;}=b^{&#039;};\: b^{&#039;&#039;}=next^{&#039;&#039;} \newline next^{&#039;&#039;} = a^{&#039;&#039;} + b^{&#039;&#039;}; \: a^{&#039;&#039;&#039;}=b^{&#039;&#039;};\: b^{&#039;&#039;&#039;}=next^{&#039;&#039;&#039;} \newline' title='next = a + b; \: a^{&#039;}=b;\: b^{&#039;}=next \newline next^{&#039;} = a^{&#039;} + b^{&#039;}; \: a^{&#039;&#039;}=b^{&#039;};\: b^{&#039;&#039;}=next^{&#039;&#039;} \newline next^{&#039;&#039;} = a^{&#039;&#039;} + b^{&#039;&#039;}; \: a^{&#039;&#039;&#039;}=b^{&#039;&#039;};\: b^{&#039;&#039;&#039;}=next^{&#039;&#039;&#039;} \newline' class='latex' />
<p>Setzt man nun von unten nach oben die jeweiligen Variablen ein, so ergibt sich die oben aufgeführte Formel.</p>
<p>Doch welche Vorteile bringt diese Lösung? Folgende Ausgabe erhält man beim Ausführen:<br />
<code class="bash">The only_even method needed 0.000007867813110 seconds.<br />
The sum is:      4613732</code> Also haben wir damit etwas weniger Wartezeit und sind somit effizienter. </p>
<p>Ok, das ist schon besser, aber ich war noch nicht zufrieden und habe noch eine Lösung ausgetestet:</p>
<h3>alternative Lösung 2</h3>
<p>Mit der zweite alternative Lösung habe ich einen rekursiven Ansatz verfolgt:</p>
<pre class="brush:python">import time as t
import numpy as np
def rec_fibo(a,b,N):
    next = 2*a + 3*b;
    if (next < N):
        return next + rec_fibo(2*b+a,next,N);
    else:
        return 0;

t0 = t.time();
erg = rec_fibo(1,2,N);
tn = t.time();

print("The recursive method needed %.15f seconds.\nThe sum is: %12i" %(tn-t0,erg));
</pre>
<p>Wie du bestimmt festgestellt hast, verwendet auch die rekursive Lösung keine Gradheitsüberprüfung der Fibonacci-Zahlen. Hier habe ich genauso, wie bei der ersten alternativen Lösung nur die geraden Zahlen betrachtet.</p>
<p>Die Rekursion bietet sich oft für Probleme wie dieses an. Es ergibt meist eine recht elegante und kurze Lösung, die aber nicht zwangsläufig auch weniger Rechenzeit benötigt, wie die Ausgabe zeigt:<br />
<code class="bash">The straigt-forward method needed 0.000010013580322 seconds.<br />
The sum is:      4613732<br />
The only_even method needed 0.000007867813110 seconds.<br />
The sum is:      4613732<br />
The recursive method needed 0.000009059906006 seconds.<br />
The sum is:      4613730</code></p>
<p>Zusammengefasst ist die einfache Lösung ohne Gradheitsüberprüfung die schnellste, jedoch sind die Zeiten bei dieser Dimension des Problems mit Vorsicht zu genießen, sie sind ziemlich klein.</p>
<h3>Fazit</h3>
<p>Damit wäre ich am Ende meiner Lösungsvorstellung des zweiten Projecteuler.net Problems. Diesmal gab es wieder eine Neuerung, die bisher in der Form in meinem Weblog noch nicht vorkam: die Rekursion.</p>
<p>Jetzt ist wieder deine Meinung gefragt: Was hat dir gefallen, was nicht und was würdest du mir als Tipp für die nächste Folge "Lösungen mit Python und C++" mitgeben?</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/">Permalink</a> |
<a href="http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/#comments">keine Kommentare</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/&title=Projecteuler: Lösung zu Problem 2">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/&title=Projecteuler: Lösung zu Problem 2">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/&title=Projecteuler: Lösung zu Problem 2">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a>, <a href="http://www.muvik.de/tag/rekursion/" rel="tag">Rekursion</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/02/17/projecteuler-loesung-zu-problem-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Projecteuler: Lösung zu Problem 1</title>
		<link>http://www.muvik.de/2010/02/11/projecteuler-loesung-zu-problem-1/</link>
		<comments>http://www.muvik.de/2010/02/11/projecteuler-loesung-zu-problem-1/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 09:25:24 +0000</pubDate>
		<dc:creator>Viktor Müller</dc:creator>
				<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Projecteuler]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.muvik.de/?p=73</guid>
		<description><![CDATA[Im ersten Teil der Serie über Lösungen zu Aufgaben von Projecteuler geht es um das erste Problem. Nach der Vorstellung des Problems und der Lokalisierung der kritischen Stelle wird zunächst eine straight-forward Lösung beschrieben. Eine alternative Lösung stellt schließlich das Ende des ersten Teils der Lösungen zu Projekteuler-Serie dar. Problemvorstellung Im ersten Problem auf Projecteuler.net [...]]]></description>
			<content:encoded><![CDATA[<img class="cat-img-wide" alt="Projecteuler: Lösungen mit Python und C++" src="http://muvik.de/categorie_images/projecteuler_serie_start.gif" title="Projecteuler: Lösungen mit Python und C++" width="443" height="98" />
<p class="preview">Im ersten Teil der Serie über Lösungen zu Aufgaben von Projecteuler geht es um das erste Problem. Nach der Vorstellung des Problems und der Lokalisierung der kritischen Stelle wird zunächst eine straight-forward Lösung beschrieben. Eine alternative Lösung stellt schließlich das Ende des ersten Teils der Lösungen zu Projekteuler-Serie dar.</p>
<p><span id="more-73"></span></p>
<h3>Problemvorstellung</h3>
<p>Im ersten Problem auf Projecteuler.net geht es darum, eine Summenformel auf zu stellen, welche alle Zahlen addiert, die kleiner als 1000 sind und durch drei oder fünf teilbar sind.</p>
<img src='http://s.wordpress.com/latex.php?latex=%5Csum%5E%7B1000%7D_%7Bi%3D1%7D%7Bi%7D%20%5C%3B%20%5Cforall%20%5C%3B%20i%5C%2Cmod%7B%5C%7B3%2C5%5C%7D%7D%3D0&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\sum^{1000}_{i=1}{i} \; \forall \; i\,mod{\{3,5\}}=0' title='\sum^{1000}_{i=1}{i} \; \forall \; i\,mod{\{3,5\}}=0' class='latex' />
<p>Das ist wohl das einfachste Problem. Diese Vermutung wird durch eine ebenfalls einfache statistische Betrachtung bestätigt: Auf Projecteuler.net sind derzeit 94426 Benutzer angemeldet. Davon haben genau 87185 das erste Problem gelöst. Prozentual betrachtet sind das etwa 92.33%. In Kürze: jeder hat das Problem gelöst, die restlichen 7.67% haben sich nur angemeldet um einmal hinter die Kulissen von Projecteuler.net zu schauen. </p>
<h3>Problemeingrenzung</h3>
<p>Das Problem ist wirklich einfach und es sollte auch mit der langsamsten Programmiersprache innerhalb von einer Minute zu schaffen sein. Nichtsdestotrotz nehme ich an, dass das Ziel einer Optimierung der Lösung die Anzahl der benötigten Rechenoperationen sein könnte, insbesondere die Anzahl der nötigen Überprüfungen, ob ein bestimmtes i durch drei oder durch fünf teilbar ist.</p>
<h3>Problemlösung</h3>
<p>Das erste, was mir bei dem Durchlesen des Problems eingefallen war, ist die einfachste straight-forward Lösung, wie sie in der Latexformel gezeigt ist. In Worten heißt es: Addiere alle Zahlen, die durch drei oder fünf teilbar sind und kleiner als 1000 sind. Dies kann in Python direkt so hingeschrieben werden:</p>
<pre class="brush:python">
count = 0;
N = 1000
for i in range(3,N):
    if i%3==0 or i%5==0:
        count = count + i;
</pre>
<p>Zwar ist das aus mathematischer Sicht sicherlich nicht die eleganteste Lösung, aber es ist die einfachste. Als Ergebnis kommt übrigens 233168 heraus.</p>
<h3>Lösungsanalyse</h3>
<p>Die Rechenzeit ist bei Projekeuler.net auf maximal eine Minute begrenzt, was hier jedoch kein Problem darstellen sollte. Und tut es auch nicht.<br />
Da ich ein Python-Anfänger bin, habe ich an dieser Stelle nicht aufgehört, sondern mich gefragt, wie lange die Lösung den nun wirklich braucht. Dazu habe ich wieder auf eine möglichst einfache Weise die Zeit vor dem Ausführen der Schleife und danach gemessen:</p>
<pre class="brush:python">
import time as t
count = 0;
tin = t.time();
N = 1000
for i in range(3,N):
    if i%3==0 or i%5==0:
        count = count + i;
tout = t.time();
</pre>
<p>Eine auf diese Weise gemessene Zeitspanne beträgt für die Summation 0.000219 Sekunden. </p>
<h3>alternative Lösung</h3>
<p>Mit der bereits vorgestellten Lösung hätten wir das erste Problem aus der Welt geschafft und könnten uns dem nächsten widmen. Da dieser Ansatz aber nicht wirklich elegant ist, habe ich mir noch eine Lösung überlegt. Fast jeder hat in der Schule einmal die Geschichte vom kleinen Gauss gehört. Darin geht es um den Schuljungen Gauss, welcher schnell rechnen konnte und dadurch seinem Lehrer auf den Geist ging. Daraufhin hat sich der Lehrer gedacht, Gauss die Aufgabe zu geben, alle Zahlen von 1 bis 100 zusammen zu zählen, was ja dem ersten Projecteuler-Problem ganz nahe kommt. Wäre der Gauss ein einfacher Junge gewesen, so hätte er die Summe, wie ich in der ersten Lösung, gebildet. Damit wäre er eine Weile beschäftigt gewesen.<br />
Jedoch hat er sich eine <a href="http://de.wikipedia.org/wiki/Formelsammlung_Algebra#Summenformeln" target="_blank">Summenformel</a> ausgedacht, mit welcher er in drei Operationen das Ergebnis hatte. Meine alternative Lösung wendet nun eine ähnliche Summenformel an:</p>
<pre class="brush:python">
def pr1_littlegauss(N):
    N=N-1
    cthree = (N-(N%3)+3)*(N-N%3)/3/2;
    cfive  = (N-(N%5)+5)*(N-N%5)/5/2;
    cfifteen = (N-(N%15)+15)*(N-N%15)/15/2;
    return cthree+cfive-cfifteen;
</pre>
<p>Hierbei werden zunächst alle Zahlen, die durch drei teilbar sind in die Variable cthree gespeichert, entsprechend auch alle durch fünf teilbaren in cfive. Da nun alle Zahlen die durch drei und gleichzeitig durch fünf teilbar sind, doppelt in der Summe vorkommen würden, müssen alle fünfzehn-fachen abgezogen werden. Das sieht schon viel eleganter aus.<br />
Misst man die Zeit, wie oben beschrieben, so komme ich dabei auf 0.000005 Sekunden. Wie man leicht sieht ist da ein Faktor von 44 dazwischen!<br />
Um den Unterschied in tatsächlich messbaren Zeiten zu messen habe ich beide Funktionen alle Zahlen, die durch drei und fünf teilbar sind und kleiner als 10000000 sind, addieren lassen:<br />
<code class="bash">Straigt-Forward<br />
The sum is: 23333331666668<br />
used time for the calculation: 2.965809822082520<br />
Little-Euler<br />
The sum is: 23333331666668<br />
used time for the calculation: 0.000020980834961</code> Und das ist schon ein beträchtlicher Unterschied.</p>
<h3>Fazit</h3>
<p>Das war die erste Vorstellung eines Projecteuler.net Problem. Ich hoffe, dass es verständlich geschrieben ist und würde mich über Kommentare, Anmerkungen und Verbesserungsvorschläge freuen.</p>
<p><a href="http://partners.webmasterplan.com/click.asp?ref=515746&site=6989&type=text&tnb=1" target="_blank">
Deine Stadt - Dein Preis</a><br />Mit CityDeal und vielen Anderen
den Preis drücken!<br /><img src="http://banners.webmasterplan.com/view.asp?ref=515746&site=6989&type=text&tnb=1&js=1" BORDER="0" WIDTH="1" HEIGHT="1" /></p>
<hr />
<p><small>© Muvik for <a href="http://www.muvik.de">muvik-multigrid</a>, 2010. |
<a href="http://www.muvik.de/2010/02/11/projecteuler-loesung-zu-problem-1/">Permalink</a> |
<a href="http://www.muvik.de/2010/02/11/projecteuler-loesung-zu-problem-1/#comments">ein Kommentar</a> |
Teile es mit deinen Freunden:
<a href="http://del.icio.us/post?url=http://www.muvik.de/2010/02/11/projecteuler-loesung-zu-problem-1/&title=Projecteuler: Lösung zu Problem 1">del.icio.us</a>
<a href="http://www.mister-wong.de/addurl/?bm_url=http://www.muvik.de/2010/02/11/projecteuler-loesung-zu-problem-1/&title=Projecteuler: Lösung zu Problem 1">MisterWong</a>
<a href="http://twitter.com/home?status=http://www.muvik.de/2010/02/11/projecteuler-loesung-zu-problem-1/&title=Projecteuler: Lösung zu Problem 1">Twitter</a>
<br/>
Tags: <a href="http://www.muvik.de/tag/projecteuler/" rel="tag">Projecteuler</a>, <a href="http://www.muvik.de/tag/python/" rel="tag">Python</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://www.muvik.de/2010/02/11/projecteuler-loesung-zu-problem-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

