Advertisement
madegoff

C_Kurs_4Blatt

Nov 8th, 2023
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.79 KB | None | 0 0
  1. /*
  2. Willkommen zum vierten Aufgabenblatt vom Programmierkurs. Auf diesem Aufabenblatt geht es darum, ein komplizierteres Problem wiederholt in Teilprobleme zu zerlegen.
  3.  
  4. Um die Tests für dieses Blatt zu kompilieren und zu starten, führen Sie den folgenden Befehl aus:
  5. cc -std=c11 -g -Wall 04ex_test.c 04ex_helpers.c -o 04ex_test.o -lm && ./04ex_test.o
  6. */
  7.  
  8. #include "04_canvas.h"
  9. #include "04ex_helpers.h"
  10. #include <stdio.h>
  11.  
  12. /*
  13. Aufgabe 1a:
  14. In diesem Aufgabenblatt schreiben wir eine Funktion, um auf der Canvas gefüllte Kreise zu zeichnen. Kreise sind konzeptionell einfach:
  15. Haben wir einen Mittelpunkt und einen Radius, können wir alle Punkte schwarz färben, deren Distanz zum
  16. Mittelpunkt kleiner oder gleich des Radius ist.
  17.  
  18. Für diese Aufgabe, implementieren Sie eine Funktion die genau das tut. Gegeben sind die Koordinaten `x` und `y` des
  19. Mittelpixels und ein Radius. Nun sollen alle Pixel, die innerhalb der Distanz um diesen Mittelpixel liegen schwarz
  20. gefärbt werden. Durch diese Methode entstehen immer Kreise mit ungeradem Durchmesser, da wir mit diskreten Pixeln arbeiten.
  21. Der Mittelpixel hat eine Distanz von 0 zu sich selbst, und daher muss er immer schwarz gefärbt werden, selbst bei Radius 0.
  22. Nutzen Sie für die Distanzbestimmung die `distance` Funktion aus `04ex_helpers.h`.
  23. Headerfile und die zugehörige Implementierung sind bereits eingebunden, die Funktion kann
  24. also einfach verwendet werden.
  25. */
  26. Canvas draw_odd_circle(Canvas c, int x, int y, int radius_from_middle) {
  27.  
  28.     int total_width = canvas_width(c)-1;
  29.     int total_height = canvas_height(c)-1;
  30.  
  31.     for (int i = 0; i<=total_width; i++){ //alle x koordinaten durchschauen
  32.         for(int j = total_height; j>=0; j--){ //alle y koordinaten -//-
  33.  
  34.             if(distance(x, y, i, j) <= radius_from_middle) canvas_set_black(c,i,j); //wenn distance zw dem punkt und zentrum = radius
  35.         }
  36.     }
  37.     return c;
  38. }
  39.  
  40. /*
  41. Aufgabe 1b:
  42. Implementieren Sie nun selbst eine Funktion, welche die abgerundete Distanz zwischen zwei Punkten (`x0`, `y0`)
  43. und (`x1`, `y1`) berechnet.
  44. Sei `a := x1 - x0` und `b := y1 - y0`. Dann liefert uns der Satz des Pythagoras die Distanz zwischen den Punkten als
  45. `c := quadratwurzel(a^2 + b^2)`.
  46. Die Datei `04ex_helpers.h` mit den Hilsfunktionen enthält eine Funktion `squareroot`. Nutzen Sie diese Funktion, um die
  47. Distanz zu berechnen.
  48. */
  49. int my_distance(int x0, int y0, int x1, int y1) {
  50.  
  51.     int a = x1-x0;
  52.     //printf("a = x0 - x1 = %d\n", a);
  53.     a = a*a;
  54.     //printf("a^2 = %d\n", a);
  55.  
  56.     int b = y1-y0;
  57.     //printf("b = y0 - y1 = %d\n", b);
  58.     b = b*b;
  59.     //printf("b^2 = %d\n", b);
  60.  
  61.     int res = squareroot(a+b);
  62.     //printf("%d\n", res);
  63.  
  64.     return res;
  65. }
  66.  
  67. /*
  68. Aufgabe 1c:
  69. Implementieren Sie nun selbst die Berechnung der abgerundeten Quadratwurzel von `n`.
  70. Tipp: Finden Sie die größte natürliche Zahl, deren Quadrat kleiner oder gleich `n` ist. Es muss nicht effizient sein, wir
  71. testen nur mit relativ kleinen Zahlen.
  72. */
  73. int my_squareroot(int n) {
  74.  
  75.     int res = 0;
  76.  
  77.     for(int i = 1; i<=n; i++){
  78.         if (i*i <= n) res = i;
  79.     }
  80.  
  81.     return res;
  82. }
  83.  
  84. /*
  85. Aufgabe 1d:
  86. Die Kreisfunktion aus Aufgabe 1a erstellt immer nur Kreise mit ungeradem Durchmesser. Kreise mit einem
  87. geraden Durchmesser haben keinen einzelnen Mittelpixel, demnach benötigen wir eine flexiblere Kreis-Zeichnungs Funktion
  88. mit anderen Parametern, um diese Kreise zeichnen zu können.
  89. `x` ist die x-Koordinate der linkesten Pixel des Kreises, `y` ist die y-koordinate der untersten Pixel des Kreises,
  90. `diameter` ist der Durchmesser. Dadurch ist `(x,y)` die Koordinate der unteren linken Ecke des kleinsten Quadrats (der
  91. Länge und Breite `diameter`) welches den erwünschten Kreis vollständig enthält.
  92.  
  93. Um Kreise mit _ungeradem_ Durchmesser zu erstellen, können Sie einfach Ihre `draw_odd_circle` Funktion ein mal aufrufen.
  94. Für Kreise mit _geradem_ Durchmesser rufen Sie Ihre `draw_odd_circle` vier mal auf: Einmal für jeden der vier Pixel
  95. welche den exakten Mittelpunkt des erwünschten Kreises umgeben.
  96. */
  97. Canvas draw_circle(Canvas c, int x, int y, int diameter) { //funktioniert noch nicht ganz
  98.  
  99.     //printf("durchmesser = %d\n", diameter);
  100.     int radius = diameter/2;
  101.     //printf("radius = %d\n", radius);
  102.  
  103.     if(diameter%2){ // ungrader durchmesser
  104.         c = draw_odd_circle(c, x+radius, y+radius, radius);
  105.     }
  106.     else{// grader durchmesser
  107.  
  108.         radius--;
  109.  
  110.         //printf("gegebene x-koordinate = %d\n", x);
  111.         //printf("gegebene y-koordinate = %d\n", y);
  112.  
  113.         int x_middle = x+radius;
  114.         int y_middle = y+radius;
  115.  
  116.         //printf("berechnete x-koordinate = %d\n", x_middle);
  117.         //printf("berechnete y-koordinate = %d\n", y_middle);
  118.  
  119.  
  120.         c = draw_odd_circle(c, x_middle+1, y_middle+1, radius); //der punkt rechts oben
  121.         c = draw_odd_circle(c, x_middle+1, y_middle, radius); //der punkt rechts unten
  122.         c = draw_odd_circle(c, x_middle, y_middle+1, radius); //der punkt links oben
  123.         c = draw_odd_circle(c, x_middle, y_middle, radius);//der mittelpunkt (links unten)
  124.  
  125.  
  126.     }
  127.     return c;
  128. }
  129.  
  130. /*
  131. Aufgabe 1e:
  132. Dadurch, dass Sie das Problem in kleinere Subprobleme geteilt haben, haben Sie gerade eine vollständige Funktion zum
  133. Kreisezeichnen implementiert. Das ist ziemlich cool!
  134. Geben Sie zur Feier `5` zurück.
  135. */
  136. int high_five() {
  137.     return 5;
  138. }
  139.  
  140. /*
  141. Aufgabe 2a:
  142. Gegeben sei eine natürliche Zahl `n`. Falls sie gerade ist, teilen Sie sie durch zwei, ansonsten multiplizieren Sie sie
  143. mit drei und addieren eins. Wiederholen Sie dies bis Sie als Ergebnis die Zahl `1` erreichen. Die Anzahl Wiederholungen
  144. die Sie dafür benötigen ist die _Hailstone-Zahl von `n`_.
  145. Zum Beispiel `hailstone(1) == 0`, `hailstone(4) == 2` (4 -> 2 -> 1), und `hailstone(5) == 5` (5 -> 16 -> 8 -> 4 -> 2 -> 1).
  146. Berechnen Sie die Hailstone-Zahl vom Parameter `n`.
  147. */
  148. int hailstone(int n) {
  149.     int res = 0;
  150.     int steps = 0;
  151.     int zahl = 1;
  152.     printf("%d\n", zahl);
  153.  
  154.     while(res!=1){
  155.  
  156.         if(zahl%2 == 0){ //n grade
  157.             zahl/=2;
  158.         }
  159.         else{
  160.             zahl*=3;
  161.             zahl+=1;
  162.         }
  163.         steps++;
  164.     }
  165.     printf("%d\n", steps);
  166.     return steps;
  167. }
  168.  
  169. /*
  170. Aufgabe 2b:
  171. Unser Testrunner hat keine Tests für Aufgabe 2a. Falls Sie Ihre Lösung selber testen wollen, erstellen Sie am besten
  172. eine separate C-Datei wo Sie Ihre Lösung hineinkopieren und gegen einige Beispielwerte testen.
  173. Falls Sie keine Beispielwerte von Hand berechnen wollen, schauen Sie am besten hier nach:  https://oeis.org/A006577
  174.  
  175. Für die _Bewertung_ von diesem Aufgabenblatt lassen wir Tests für Aufgabe 2a laufen, zum Debuggen müssen Sie
  176. allerdings Ihre eigenen Tests schreiben.
  177. Lassen Sie `99` von dieser Funktion zurückgeben um zu zeigen, dass Sie das verstanden haben.
  178. */
  179. int bring_your_own_tests() {
  180.     return 99;
  181. }
  182.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement