Zum Einen zählst Du alle Tage seit dem 0. Januar 0. Wäre das wirklich ein Sonntag gewesen? Wenn nicht, musst Du noch einen konstanten Offset zu complete_days addieren.

Zum Anderen zählst Du jedes Jahr als Schaltjahr, auch wenn das gegebene Datum vor dem 1. März liegt.

Noch ein kleiner Tipp:

Mit weekdays = ("Sunday", "Monday", ...) kannst Du die lange if-else-Kette am Ende streichen. Schreibe einfach:

return weekdays[complete_days % 7]
...zur Antwort

115 lb ist das Papiergewicht in imperialer Einheit. Es gibt das Gewicht in Pfund für 500 Blatt Papier in „Standardgröße“ an. Diese hängt vom Papiertyp ab (und ja, das ist so dämlich wie alles andere imperiale).

Dein Zeichenblock hat den Typ Bristol mit der Standardgröße 22,5"×28,5", also:

115 lb ≈ 52 kg, und 500·22,5"×28,5" ≈ 320625 in² ≈ 207 m²

Das deckt sich in etwa mit der Angabe 250 g/m².

...zur Antwort

Das Adverb „noch“ ist hier ein Attribut zu „kein Blatt“.

Dass es kein Satzglied ist, erkennt man, wenn man den Satz umstellt:

  • Noch kein Blatt habe ich mit meinen Augen gesehen.

An Position 1 (vor dem finiten Verb „habe“) darf nur ein Satzglied stehen.

...zur Antwort

Was ist ein Duplikat? Dein Beispiel hat:

  • n=6 Elemente
  • u=1 Unikate (3)
  • v=3 verschiedene Elemente (5, 3, 4)
  • w=n−v=3 Wiederholungen (5: 2×, 4: 1×)
  • m=n−u=5 Mehrfachvorkommen (5: 3×, 4: 2×)

Dein Code kopiert alle Wiederholungen w (=alle Elemente, die einen identischen Nachfolger haben). Nach meinem Verständnis sind genau diese Wiederholungen die Duplikate, und Dein Beispiel {5, 3, 5, 4, 4, 5} gibt korrekt w=3 und (5, 5, 4) aus.

Offenbar willst Du aber m=5 und (5, 5, 4, 4, 5) haben. Dazu musst Du für jedes Element die ganze Liste (j=0...) durchsuchen und darfst bestenfalls bei der ersten echten Kopie (i≠j) abbrechen:

    int is_duplicate = 0;
    for (size_t j = 0; j < len; j++) {
        if( i!=j && src[i] == src[j] ) {
            is_duplicate = 1;
            break;
        }
    }

Ich würde mir diese Optimierung sparen und einfach stur zählen:

    int count = 0;
    for (size_t j = 0; j < len; j++) {
            if( src[i] == src[j]) {
                ++count;
            }
        }

Bei count==1 ist src[i] ein Unikat (u), sonst ein Mehrfaches (m). Also:

        if (count != 1) {
            dst[n] = src[i];
            n++;
        }

Dann tut das Programm so, wie Du es erwartest.

...zur Antwort

Du verwechselst die Schreibweise der Mathematiker für Kongruenz mit dem Modulo-Operator in Programmiersprachen:

ab (mod n) (sprich "a kongruent b, modulo n") heißt, dass a und b derselben Restklasse modulo n angehören.

b mod n ist eine zweistellige Funktion, die den ganzzahligen Rest von b/n liefert. In manchen Programmiersprachen schreibt man dafür auch b % n.

Die zweite Variante ist zum Rechnen ganz nett, aber für formale Beweise ist die erste Darstellung wesentlich praktischer. Wenn Du damit nicht klar kommst, kannst Du umformen:

  • ab (mod n) ⇔ a%n = b%n

Das gilt aber nur für a, b≥0 und n>0. Bei negativen Zahlen klappt das nur, wenn der Modulo-Operator einen Wertebereich der Größe n hat. Das ist in vielen Programmiersprachen leider nicht der Fall.

...zur Antwort
WIE KANN ICH IN C DAS ◻️und das ◼️ auf der Console ausgeben?

Hab diesen Code geschrieben:

#include <stdio.h>
#include <stdlib.h>
#include "console.h"
#define SIZE 8 // Größe des Schachbretts
char *schachbrett[SIZE][SIZE];// 2D-Array für das Schachbrett
void initSpielfeld();
void ausgabeSpielfeld();
void spielBeenden();
int main() {
initSpielfeld();
initConsole();

        ausgabeSpielfeld();
        getch();
        clrscr();
        gotoxy(0,0);

}
void initSpielfeld(){
    // Fülle das Schachbrett mit den richtigen Symbolen
    for (int i = 0; i < SIZE; i++) { // Zeilen
        for (int j = 0; j < SIZE; j++) { // Spalten
            // Wenn die Summe der Indizes gerade ist, ist das Feld weiß
            if ((i + j) % 2 == 0) {
                schachbrett[i][j] = "◻"; // Weißes Quadrat
            } else {
                schachbrett[i][j] = "◼"; // Schwarzes Quadrat
            }
        }
    }
}
void ausgabeSpielfeld(){
    // Gebe das Schachbrett aus
    for (int i = 0; i < SIZE; i++) { // Zeilen
        for (int j = 0; j < SIZE; j++) { // Spalten
            printf("%s ", schachbrett[i][j]); // Quadrat ausgeben
        }
        printf("\n"); // Neue Zeile nach jeder Zeile im Schachbrett
    }
}

void spielBeenden(){
    return 0;
}

Bei mir kommt da aber immer das raus:

Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝

Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗

Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝

Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗

Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝

Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗

Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝

Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗ Ôù╝ Ôù╗

Aber das ist nicht mein ziel.

Ich möchte einfach nur ein schönes Schachbrett ausgeben.

Kann mir da jemand helfen?

...zur Frage

Bei mir tut's :-)

> gcc -std=c99 -Wall chessboard.c && ./a.out 
◻ ◼ ◻ ◼ ◻ ◼ ◻ ◼ 
◼ ◻ ◼ ◻ ◼ ◻ ◼ ◻ 
◻ ◼ ◻ ◼ ◻ ◼ ◻ ◼ 
◼ ◻ ◼ ◻ ◼ ◻ ◼ ◻ 
◻ ◼ ◻ ◼ ◻ ◼ ◻ ◼ 
◼ ◻ ◼ ◻ ◼ ◻ ◼ ◻ 
◻ ◼ ◻ ◼ ◻ ◼ ◻ ◼ 
◼ ◻ ◼ ◻ ◼ ◻ ◼ ◻ 

Aber Du verwendest vermutlich ein MS-DOS-Terminal aus der Steinzeit. Mit einem einigermaßen aktuellen Windows kannst Du diese Konsole via „chcp 65001" auf UTF-8 umschalten, und dann musst Du einen Font wählen, der diese Quadrate anzeigen kann.

Wenn Dein "console.h" auch Farbe oder die ANSI-Sequenzen "\33[7m" (invertiert) und "\33[m" (normal) unterstützt, wird es einfacher sein, normale und invertierte Leerzeichen auszugeben. Mit 2 Leerzeichen je Feld sieht das bei mir etwa so aus:

Bild zum Beitrag

...zur Antwort

Alle drei while-Schleifen sind Endlosschleifen. Wirf sie raus und schreibe stattdessen:

if (lichtl>800 || lichtm>800 || lichtr>800)
    digitalWrite(13, HIGH); // mind. ein Sensor ist an
else
    digitalWrite(13, LOW);  // alle Sensoren sind aus
...zur Antwort
  • Wenn Du programmierst oder auf der Kommandozeile arbeitest: Die Zeichen \/[]{}@ sind auf QWERTY super bequem erreichbar.
  • Ctrl-Z/X/C/V liegen im US-Layout direkt nebeneinander. Das ist kein Zufall!
  • Unter Unix kannst Du äöüß (und vieles mehr) dort platzieren, wo Du die Zeichen haben magst (ich habe sie auf r-alt a/o/u/s gelegt). Unter Windows brauchst Du dafür ein externes Programm (AutoHotkey?)
  • Das US-Layout hat eine Taste weniger (links vom Z). Beim Überkleben der US-Tasten fehlen Dir dann <, > und |.
  • Die Entertaste (US) ist einzeilig und breiter, die Returntaste (DE) hat doppelte Höhe, ist aber schmäler. Das kann ganz schön nerven, wenn Du eine Version schon gewohnt bist.

Fazit: Wenn Du viel programmierst oder sowieso Dein persönliches Tastaturlayout konfigurieren willst, behalte das Teil unbedingt. Wenn Du vorwiegend deutsche Texte in MS-Word bearbeitest, ist der Umstieg wohl zu aufwendig. Dann verscherbel das Ding wieder.

Aber entscheide Dich frühzeitig: Für unbenutzte, original-verpackte Neuware müsstest Du hierzulande dein Geld fast wieder hereinholen können. Bei „kaum benutzt“ fällt der Preis schon drastisch.

...zur Antwort

In a) wird schwarz zu grün, in b) wird grün zu rot. Die blauen Linien kommen von c).

...zur Antwort
Binärer Suchalgorithmus - wo liegt der Fehler?

Hallo liebe Community,

ich arbeite an einem Suchalgorithmus, der in einer sortierten Liste das Element finden soll, das einem gegebenen Wert am nächsten liegt. Trotz ausführlicher Tests mit über 100 Edge Cases, die alle fehlerfrei terminiert haben, liegt noch ein Fehler im Code. Bisher konnte ich jedoch keinen Fall finden, der nicht korrekt funktioniert.
Kann jemand von euch vielleicht einen Blick darauf werfen und mir helfen, mögliche Schwachstellen oder Fehler zu identifizieren? Ich wäre für jeden Tipp oder Testfall, der mein Problem offenlegen könnte, sehr dankbar!

  1.  Suche nach einem Wert 5 of 7 tests passing
  2. Die Methode 
  3. int search(int[] sortedData, int value, Result result)
  4.  soll mittels binärer Suche nach dem Index vom übergebenen Wert suchen.
  5. Dabei wird immer der mittlere Wert vom Suchbereich angesehen. Falls dies der gesuchte Wert ist, kann dessen Index zurück gegeben werden. Ansonsten verkleinert sich der Suchbereich auf die Indices, in denen der gesuchte Wert noch liegen kann. Falls der Suchbereich nur noch einen Wert enthält, soll ebenfalls abgebrochen werden.
  6. Wenn der Wert nicht im Array enthalten ist, soll stattdessen der Index vom nächst größeren oder nächst kleineren Wert zurückgegeben werden. Welcher der beiden Indices ist dabei egal, solange der zurückgegebene Index im Array liegt.
Code: 

public static int search(int[] sortedData, int value, Result result) {
     int left = 0;
    int right = sortedData.length - 1;
    int nearestindex = -1;
    int currentSmallest = Integer.MAX_VALUE;

    while(left <= right) {
        int middle = left + (right - left) / 2;
        int difference = Math.abs(value - sortedData[middle]);

        if(difference < currentSmallest) {
            currentSmallest = difference;
            nearestindex = middle;
        } else if(difference == currentSmallest) {
            if(Math.abs(value - nearestindex) > Math.abs(value - middle)) {
                nearestindex = middle;
            }
        }
        result.addStep(middle);

        if(sortedData[middle] == value) {
            return middle;
        }
        if (sortedData[middle] < value) {
            left = middle + 1;
        } else {
            right = middle - 1;
        }
    }
    return nearestindex;
}
...zur Frage
    while(left <= right) {

Du hörst erst auf, wenn das Intervall leer ist. Ich hätte erwartet, dass die Suche zu Ende ist, wenn zwei benachbarte Werte l, r mit l≤value≤r gefunden wurden.

        int middle = left + (right - left) / 2;
        int difference = Math.abs(value - sortedData[middle]);

        if(difference < currentSmallest) {

Wozu diese Abfrage? In einem sortierten Array kann doch difference>currentSmallest gar nicht passieren.

            currentSmallest = difference;
            nearestindex = middle;

Wieso middle? Könnte bei middle+1 oder middle-1 nicht ein besserer Wert stehen? Ich bin mir nicht sicher, ob das im nächsten Durchlauf (falls es noch einen gibt) repariert wird.

  if(Math.abs(value - nearestindex) > Math.abs(value - middle)) {

Das ist gruselig. Bei hinreichend großem value testest Du nearestindex<middle (was auch immer das bezwecken soll). Wenn value kleiner als die betrachteten Indizes ist, testest Du nearestindex>middle. Und bei einem value dazwischen passieren seltsame Dinge.

Besonders schräg wird diese Sache dadurch, dass nearestindex=middle in nächsten Durchlauf garantiert außerhalb des Intervalls liegt, weil Du ja entweder vor oder hinter middle weitersuchst.

Ich denke, Du hast Dir mit dem Tracken der Differenz einen Knoten ins Hirn gemacht. Implementiere einfach eine Intervallschachtelung bis runter zur Intervalllänge ≤2, und gib dann die bessere Grenze zurück.

Vergiss nicht zu prüfen, ob die Sonderfälle value<sortedData[0] und value>sortedData[len-1] sauber durchlaufen. Falls nicht, musst Du das getrennt abbacken.

...zur Antwort

Deine Begründung reicht nicht. Wenn erst steigt, dann fällt, kann ja der Startwert wieder erreicht werden. Es kommt nicht nur auf die Intervalllängen an, sondern auch darauf, wie stark sie dort steigt bzw. fällt.

Letztendlich läuft das aufs Integrieren hinaus: h ist eine Stammfunktion von h', und h(0)=h(4) sagt, dass die orientierte Fläche „unter“ h zwischen 0 und 4 den Inhalt 0 hat. Das ist aber offensichtlich nicht der Fall, denn der positive Anteil (von 0 bis ca. 1,3) ist deutlich kleiner als der negative (von ca. 1,3 bis 4).

...zur Antwort

Du kannst die Übung deutlich abkürzen, wenn Du weißt, dass eine Äquivalenzrelation die Grundmenge A in Äquivalenzklassen zerlegt. Bestimme also zuerst alle möglichen Zerlegungen von A (nicht-leere, disjunkte Teilmengen, die A überdecken). Davon gibt es nur 8.

Die zugehörige Äquivalenzrelation konstruierst Du dann nach dem Schema „jeder mit jedem aus derselben Klasse“. Der Beweis der Reflektivität, Symmetrie und Transitivität ist bei diesem Schema ( xRy ⇔ x, y liegen in derselben Klasse) trivial.

...zur Antwort
  1. Das ist kein vollständiger Satz. Das Prädikat fehlt.
  2. „At first“ heißt u. a. „anfangs, zuerst“. Du meintest vermutlich „Mainly/Firstly“ oder ähnliches.
  3. „Cat sitting“ wird auseinandergeschrieben. Wenn Du Dir unsicher bist, verwende bestenfalls einen Bindestrich. Zusammengesetzte Wörter sind im Englischen recht selten.
...zur Antwort

zu a) In Toms Skizze liegt der Kreis für den Boden neben dem Mantel-Rechteck. Also gilt 2r+h=20, und der Umfang ist auf 15 cm begrenzt. Tom hat h=20−2r in die V-Formel eingesetzt, nach r abgeleitet (V'=−6πr²+40πr) und davon die Nullstellen berechnet. Bei r=0 hat V ein Minimum, bei r=20/3≈6,67 ein Maximum.

zu b) Dummerweise ist wegen U≤15 bei r = 15/(2π) ≈ 2,39 Schluss. Nebenbedingungen können echte Spaßbremsen sein!

zu c) Mit Toms Ansatz steigt das Volumen zwischen r=0 und r=2,39 monoton. Das Maximum bekommt er also wegen U≤15 am Rand bei r=2,39. Berechne das entsprechende Volumen.
Ein anderer Ansatz wäre, das Blech um 90⁰ zu drehen. Dann hast Du 2r+h=15 und als Randbedingung U≤20. Rechne auch das (genau wie oben) durch und nimm das bessere Ergebnis.

Ich selbst würde an der Unterkante des Mantels Fransen der Länge r lassen und diese dann für den Boden nach innen biegen. Das verschwendet weniger Material und wird sicher eine deutlich größere Dose ergeben. Auch hier muss man die Rechnung für beide Blech-Orientierungen getrennt durchführen und die Ergebnisse vergleichen.

Allerdings bleibt offen, ob jemand Anderes eine bessere Idee hat, das Blech mit noch weniger Abfall zu zerschneiden. Eine echte Obergrenze erreicht man nur, indem man das Blech einschmelzt und daraus ohne Materialverlust die Dose gießt.

...zur Antwort