Algorithmen und Programmierung 2 Aufgabenlösung zum Übungsblatt 4 Aufgabe Punkte 1 /8 2 /5 3 /7 Ø /20 % Tutor: Nils Barnickel - Freitag 14h-16h Gruppe: Stephan Scheerer (3790010), Tobias Losch (3675100) Lösung zum Aufgabenblatt 4 Aufgabe 1 (a) sei {P} {u>=1 v>=1} wähle I: { ggT(x,y) = ggT(u,v) } 1) {ggT(x,y-x)=ggT(u,v) x=<y} S2 {I} =ggT(x,y) {ggT(x-y,y)=ggT(u,v) x=y} S1 {I} =ggT(x,y) => {ggT(x,y)=ggT(u,v)} Sif {I} {I’} also gilt {I’} Sif {I} 2) es ist {IB}={x≠y ggT(x,y)=ggT(u,v)} also {IB} => {I’} außerdem {IB} => {ggT(x,y)=gg(u,v) x=y} {ggT(x,x)=ggT(u,v)} {x=ggT(u,v)} also {IB}=>{Q} damit {I}w{Q} und: {u>=1 v>=1}z{I} {P} zw {Q} => {P} P {Q} damit ist die potentielle Korrektheit bewiesen. Beweisen der Termination Wir zeigen: in jedem Durchlauf wird x oder y um mindestens 1 verringert, aber werden nie <1 => x ist spätestens gleich y, wenn x=y=1 Fall 1: x>y und x>1,y>=1 nach {P} => x>x-y>=1 wie gefordert. Fall 2: x<y und x>=1, y>1 nach {P} Nicht gleich, sonst bricht die Schleife ab. => y>y-x>=1 wie gefordert. Also x oder y verringern sich in jedem Durchlauf der Schleife und werden nie <1. => Die Schleife terminiert. (b) {P} = {n>1} c=n; S1 z=0; SSch while (c != 1) SSch1 if (c%2 == 0) c=c/2; SSch2 else c=3*c+1; SSch3 z=z+1 ; {Q} = {z 1 c=1} Invariante {I} = {n 1 z 0 c 1} Schritt 1 : {P} S1{I} {n 1} {0 0} {c c} c=n; {c 1} {0 0} {n c} z=0; {n 1} {z 0} {n c} => {I} Schritt 2 : {I BSch} SSch {I} 2a: {I BSch Bif} SSch1/3 {I} {n 1 z 0 c 1} {c ! 1} {c%2 0} {n 1 z 1 - 1 0 c 1} {c%2 0} {n 1 z 1 - 1 0 c/2 1} {c/2%2 0} c=c/2 ; {n 1 z - 1 0 c/2 1} {c/2%2 0} z=z+1; {n 1 z 1 c/2 1} {c/2%2 0} => {I} 2b: {I BSch Bif} SSch2/3 {I} {n 1 z 0 c 1} {c ! 1} {c%2 ! 0} {n 1 z 1 - 1 0 c 1} {c ! 1} {c%2 ! 0} c=3*c+1; {n 1 z 1 - 1 0 3 * c 1 1} {3 * c 1! 1} {3 * c 1%2 ! 0} {n 1 z - 1 0 3 * c 1 1} {3 * c 1! 1} {3 * c 1%2 ! 0} z=z+1; {n 1 z 1 c 0} {c ! 0} {3 * c 1%2 ! 0} => {I} Schritt 3: {I BSch} nop {Q} //nop = no Operation {n 1 z 0 c 1} {c 1} {n 1 z 0 c 1} wegen n>1 ist mindestens 1 Schleifendurchlauf nötig, daher ist z > 0 =>{Q} =>Programm ist partiell korrekt Die totale Korrektheit kann für dieses Programm nicht bewiesen werden, da bisher noch keine Terminierungsfunktion für die „3-n-Funktion“ gefunden wurde. Lösung zum Aufgabenblatt 3 Aufgabe 2 Die funktionale Programmiersprache Haskell sowie die Logikprogrammiersprache PROLOG gehören zu den deklarativen Programmiersprachen. Sie werden z.B. durch einfache formale – meist auch mathematische Beschreibungen definiert. Bei Ausführung wird durch den Interpreter in diese Formeln Werte eingesetzt und diese Formeln werden dann mit Hilfe von Musteranpassung ausgewertet oder durch einfaches Auswerten ausgewertet. Da diesen einfache mathematische Regeln zu Grunde liegen, ist es einfacher diese Sprache auszuwerten, als z.B. bei C oder anderen höheren Programmiersprachen. Die Befehle beschränken sich auch ebenfalls auf einfache Befehle und eine einfache Werteausgabe, es gibt z.B. keine komplexe grafische Oberfläche. Dadurch, dass die Sprachen einer mathematischen Definition folgen, ist es nicht notwendig bzw. überflüssig ein Compiler zu schreiben, da diese Sprache leichter eine Eingabe interpretieren kann. Lösung zum Aufgabenblatt 3 Aufgabe 3 (a) // Lösung zu Übungsblatt 4 - Aufgabe 3a // Tutor: Nils Barnickel / Freitag 14-16h // Gruppe: Stephan Scheerer, Tobias Losch public class ALP20403a { public static void main(String[] args) { System.out.println("Die ersten 40 Fibonacci Zahlen"); int d=1; // a0 int f=1; // a1 for (int i=1; i<=20 ; i++ ) // 2*20 Berechnungen an+2=an+1+an { System.out.println(d+"\n"+f); // Fibonacci Zahlen ausgeben d=d+f; // Neue Fibonacci Zahlen ausrechnen f=d+f; } } } /* ###################################################################### Testeingabe: >java ALP20403a Die ersten 40 Fibonaccizahlen 1 1 2 3 5 8 13 … 63245986 102334155 ###################################################################### */ (b) // Lösung zu Übungsblatt 4 - Aufgabe 3b // Tutor: Nils Barnickel / Freitag 14-16h // Gruppe: Stephan Scheerer, Tobias Losch public class ALP20403b { public static void main(String[] args) { System.out.println("Alle Primzahlen zwischen 1 und 1000"); for(int i=1; i<=1000; i++) // Schleife für alle Zahlen zwischen 1 und 1000 { boolean isPrime=true; // Variable, ob Zahl Primzahl ist for(int j=1; j<=i/2; j++) if(((i%j)==0)&&(j>1)) isPrime=false; // Teilt i von 1 bis i/2 und falls ein Rest nicht 0 ist, ist keine Primzahl if(isPrime) System.out.println(i); // Primzahl ermittelt? Dann ausgeben } } } /* ###################################################################### Testeingabe: >java ALP20403b Alle Primzahlen zwischen 1 und 1000 1 2 3 5 7 11 13 … 991 997 ###################################################################### */