english translation started

This commit is contained in:
2026-02-22 18:22:46 +01:00
parent 19c67a3c9b
commit 9e418381ca
17 changed files with 1915 additions and 1907 deletions

View File

@@ -9,43 +9,44 @@ engine: julia
using InteractiveUtils
```
# Erste Miniprogramme
# First Small Programs
## Was sollte man zum Programmieren können?
## What Should One Be Able to Do for Programming?
- **Denken in Algorithmen:**
Welche Schritte sind zur Lösung des Problems nötig? Welche Daten müssen gespeichert, welche Datenstrukturen angelegt werden? Welche Fälle können auftreten und müssen erkannt und behandelt werden?
- **Umsetzung des Algorithmus in ein Programm:**
Welche Datenstrukturen, Konstrukte, Funktionen... stellt die Programmiersprache bereit?
- **Formale Syntax:**
Menschen verstehen 'broken English'; Computer verstehen kein 'broken C++' oder 'broken Julia'. Die Syntax muss beherrscht werden.
- **„Ökosystem“ der Sprache:**
Wie führe ich meinen Code aus? Wie funktionieren die Entwicklungsumgebungen? Welche Optionen versteht der Compiler? Wie installiere ich Zusatzbibliotheken? Wie lese ich Fehlermeldungen? Wo kann ich mich informieren?
- **die Kunst des Debugging:**
Programmieranfänger sind oft glücklich, wenn sie alle Syntaxfehler eliminiert haben und das Programm endlich 'durchläuft'. Bei komplexeren Programmen fängt die Arbeit jetzt erst an, denn nun muss getestet und die Fehler im Algorithmus gefunden und behoben werden.
- **Gefühl für die Effizienz und Komplexität von Algorithmen**
- **Besonderheiten der Computerarithmetik**, insbesondere der Gleitkommazahlen
- **Thinking in algorithms:**
What steps are required to solve the problem? What data must be stored, what data structures must be created? What cases can occur and must be recognized and handled?
- **Implementation of the algorithm into a program:**
What data structures, constructs, functions... does the programming language provide?
- **Formal syntax:**
Humans understand 'broken English'; computers don't understand 'broken C++' or 'broken Julia'. The syntax must be mastered.
- **The "ecosystem" of the language:**
How do I run my code? How do the development environments work? What options does the compiler understand? How do I install additional libraries? How do I read error messages? Where can I get information?
- **The art of debugging:**
Programming beginners are often happy when they have eliminated all syntax errors and the program finally 'runs'. For more complex programs, the work only just begins, as testing and finding and fixing errors in the algorithm must now be done.
- **Sense of the efficiency and complexity of algorithms**
- **Specifics of computer arithmetic**, especially floating point numbers
Das erschließt sich nicht alles auf einmal. Haben Sie Geduld mit sich und 'spielen' Sie mit der Sprache.
These cannot all be mastered at once. Be patient with yourself and 'play' with the language.
The following should serve as a small inspiration.
Das Folgende soll eine kleine Anregung dazu sein.
## Project Euler
Eine hübsche Quelle für Programmieraufgaben mit mathematischem Charakter und sehr unterschiedlichen Schwierigkeitsgraden ist [Project Euler](https://projecteuler.net/).
Die Aufgaben sind so gestaltet, dass keinerlei Eingaben notwendig und das gesuchte Ergebnis eine einzige Zahl ist. So kann man sich voll auf das Programmieren des Algorithmus konzentrieren.
A nice source for programming tasks with mathematical character and very different levels of difficulty is [Project Euler](https://projecteuler.net/).
The tasks are designed so that no inputs are necessary and the desired result is a single number. This allows you to fully concentrate on programming the algorithm.
---------
### Beispiel 1
### Example 1
::::::{.content-hidden unless-format="xxx"}
::::::::{.content-hidden unless-format="xxx"}
https://github.com/luckytoilet/projecteuler-solutions/blob/master/Solutions.md
https://math.stackexchange.com/questions/3370978/iterating-sum-of-squares-of-decimal-digits-of-an-integer-how-big-can-it-grow
aufg. 92
Aufg. 92
:::
@@ -58,36 +59,36 @@ Find the sum of all the multiples of 3 or 5 below 1000.
:::
1. Algorithmus:
- Teste alle natürlichen Zahlen <1000 auf Teilbarkeit durch 3 oder durch 5 und
- summiere die teilbaren Zahlen auf.
1. Algorithm:
- Test all natural numbers <1000 for divisibility by 3 or 5 and
- sum the divisible numbers.
2. Umsetzung:
2. Implementation:
Wie liefert Julia den Rest der Ganzzahldivision? Solche Funktionen heißen typischerweise `rem()` (für *remainder*) oder `mod()`. [Nachlesen in der Doku](https://docs.julialang.org/en/v1/base/math/#Base.rem) oder ausprobieren von `?rem` und `?mod` in der Julia-REPL zeigt, dass es beides gibt. Der Unterschied liegt in der Behandlung negativer ganzer Zahlen. Für natürliche Zahlen `n,m` liefern `mod(n,m)` und `rem(n,m)` dasselbe und letzteres hat auch noch die Infix-Form `n % m`.
Wie testet man eine Reihe von Werten durch und summiert auf? Da gibt es ein Standardmuster: `for`-Schleife und Akkumulatorvariable:
How does Julia provide the remainder of integer division? Functions like this are typically called `rem()` (for *remainder*) or `mod()`. [Look it up in the documentation](https://docs.julialang.org/en/v1/base/math/#Base.rem) or try `?rem` and `?mod` in the Julia REPL shows that there are both. The difference lies in the treatment of negative integers. For natural numbers `n,m`, `mod(n,m)` and `rem(n,m)` give the same result, and the latter also has the infix form `n % m`.
How does one test a sequence of values and sum them up? There is a standard pattern: `for` loop and accumulator variable:
:::{.callout-caution icon="false" collapse="true" .titlenormal}
## Eine Lösungsvariante:
## One possible solution:
```{julia}
s = 0 # Akkumulatorvariable initialisieren
for i in 1:999 # Schleife
if i % 3 == 0 || i % 5 == 0 # Test
s += i # Zu Akkumulator addieren
end # Ende Test
end # Ende Schleife
println(" Die Antwort ist: $s") # Ausgabe des Ergebnisses
s = 0 # initialize accumulator variable
for i in 1:999 # loop
if i % 3 == 0 || i % 5 == 0 # test
s += i # add to accumulator
end # end test
end # end loop
println(" The answer is: $s") # output result
```
:::
Natürlich geht das auch etwas kürzer:
Of course, this can also be done a bit shorter:
:::{.callout-caution icon="false" collapse="true" .titlenormal}
## Noch eine Lösungsvariante:
## Another solution:
```{julia}
sum([i for i in 1:999 if i%3==0||i%5==0])
@@ -98,7 +99,7 @@ sum([i for i in 1:999 if i%3==0||i%5==0])
-----------
### Beispiel 2
### Example 2
::: {.callout-note icon=false .titlenormal}
@@ -115,41 +116,41 @@ Therefore any chain that arrives at 1 or 89 will become stuck in an endless loop
How many starting numbers below ten million will arrive at 89?
:::
Programme kann man [*top-down* und *bottom-up*](https://de.wikipedia.org/wiki/Top-Down-_und_Bottom-Up-Design) entwickeln.
*Top-down* würde hier wohl bedeuten: „Wir fangen mit einer Schleife `for i = 1:9999999` an.“ Der andere Weg führt über einzeln testbare Komponenten und ist oft zielführender. (Und ab einer gewissen Projektgröße nähert man sich sowieso von 'top' und 'bottom' gleichzeitig dem Ziel.)
Programs can be developed [*top-down* and *bottom-up*](https://en.wikipedia.org/wiki/Top-down_and_bottom-up_design).
*Top-down* would probably mean here: "We start with a loop `for i = 1:9999999`." The other way leads over individually testable components and is often more effective. (And with a certain project size, one approaches the goal from both 'top' and 'bottom' simultaneously.)
##### Funktion Nr. 1
Es soll untersucht werden, wie sich die Zahlen unter dem wiederholten Berechnen der 'Quadratquersumme' (Summe der Quadrate der Ziffern) verhalten. Also sollte man eine Funktion schreiben und testen, die diese 'Quadratquersumme' berechnet.
##### Function No. 1
It should be investigated how numbers behave under repeated calculation of the 'square digit sum' (sum of squares of digits). Therefore, one should write and test a function that calculates this 'square digit sum'.
:::{.callout-caution icon="false" collapse="true" .titlenormal}
## `q2sum(n)` berechnet die Summe der Quadrate der Ziffern von n im Dezimalsystem:
## `q2sum(n)` calculates the sum of the squares of the digits of n in the decimal system:
```{julia}
#| output: false
function q2sum(n)
s = 0 # Akkumulator für die Summe
while n > 9 # solange noch mehrstellig...
q, r = divrem(n, 10) # berechne Ganzzahlquotient und Rest bei Division durch 10
s += r^2 # addiere quadrierte Ziffer zum Akkumulator
n = q # mache weiter mit der durch 10 geteilten Zahl
s = 0 # accumulator for the sum
while n > 9 # as long as still multi-digit...
q, r = divrem(n, 10) # calculate integer quotient and remainder of division by 10
s += r^2 # add squared digit to accumulator
n = q # continue with the number divided by 10
end
s += n^2 # addiere das Quadrat der letzten Ziffer
s += n^2 # add the square of the last digit
return s
end
```
:::
... und das testen wir jetzt natürlich:
... and let's test it now:
```{julia}
for i in [1, 7, 33, 111, 321, 1000, 73201]
j = q2sum(i)
println("Quadratquersumme von $i = $j")
println("Square digit sum of $i = $j")
end
```
Im Sinne der Aufgabe wenden wir die Funktion wiederholt an:
In the spirit of the task, we apply the function repeatedly:
```{julia}
n = 129956799
@@ -158,48 +159,48 @@ for i in 1:14
println(n)
end
```
... und haben hier einen der '89er Zyklen' getroffen.
... and we have here hit one of the '89-cycles'.
#### Funktion Nr. 2
#### Function No. 2
Wir müssen testen, ob die wiederholte Anwendung der Funktion `q2sum()` schließlich zu **1** führt oder in diesem **89er**-Zyklus endet.
We need to test whether repeated application of the function `q2sum()` finally leads to **1** or ends in this **89**-cycle.
:::{.callout-caution icon="false" collapse="true" .titlenormal}
## `q2test(n)` ermittelt, ob wiederholte Quadratquersummenbildung in den 89er-Zyklus führt:
## `q2test(n)` determines whether repeated square digit sum calculation leads to the 89-cycle:
```{julia}
#| output: false
function q2test(n)
while n !=1 && n != 89 # solange wir nicht bei 1 oder 89 angekommen sind....
n = q2sum(n) # wiederholen
while n !=1 && n != 89 # as long as we have not reached 1 or 89....
n = q2sum(n) # repeat
end
if n==1 return false end # keine 89er-Zahl
return true # 89er-Zahl gefunden
if n==1 return false end # not an 89-number
return true # 89-number found
end
```
:::
... und damit können wir die Aufgabe lösen:
... and with this, we can solve the task:
```{julia}
c = 0 # mal wieder ein Akkumulator
for i = 1 : 10_000_000 - 1 # so kann man in Julia Tausenderblöcke zur besseren Lesbarkeit abtrennen
if q2test(i) # q2test() gibt einen Boolean zurück, kein weiterer Test nötig
c += 1 # 'if x == true' ist redundant, 'if x' reicht völlig
c = 0 # once again an accumulator
for i = 1 : 10_000_000 - 1 # this is how you can separate thousands for better readability in Julia
if q2test(i) # q2test() returns a boolean, no further test needed
c += 1 # 'if x == true' is redundant, 'if x' is perfectly sufficient
end
end
println("$c numbers below ten million arrive at 89.")
```
Zahlen, bei denen die iterierte Quadratquersummenbildung bei 1 endet, heißen übrigens [fröhliche Zahlen](https://de.wikipedia.org/wiki/Fr%C3%B6hliche_Zahl) und wir haben gerade die Anzahl der traurigen Zahlen kleiner als 10.000.000 berechnet.
Numbers for which the iterative square digit sum calculation ends at 1 are called [happy numbers](https://en.wikipedia.org/wiki/Happy_number), and we have just calculated the number of sad numbers less than 10,000,000.
Hier nochmal das vollständige Programm:
Here is the complete program again:
:::{.callout-caution icon="false" collapse="true" .titlenormal}
## unsere Lösung von Project Euler No 92:
## our solution to Project Euler No 92:
```{julia}
function q2sum(n)