Schreiben Sie ein Sortierprogramm, das fehlerhaft aussieht, aber tatsächlich korrekt ist. [Closed]


12

Schreiben Sie ein Programm, das einen Zahlenvektor (oder einen beliebigen Elementtyp) sortiert, der wie ein oder mehrere Bugs aussieht, aber eigentlich in Ordnung ist.

  • Der Code muss klar sein. Jemand, der sich den Code ansieht, muss leicht erkennen, dass es sich um einen Sortieralgorithmus handelt, und muss leicht ein korrektes Stück Code mit einem Fehler verwechseln.
  • Der (scheinbare) Fehler kann durch alles, was den Code syntaktisch oder semantisch falsch formuliert (z. B. das Programm nicht kompilieren / ausführen lassen, UB anzeigen, wenn es ausgeführt wird), dazu führen, dass das Programm falsche Ergebnisse erzeugt, nicht beendet oder nicht deterministisch ist.
  • Der Code muss tatsächlich wohlgeformt sein und das Programm muss deterministisch die korrekte Ausgabe in einer endlichen Zeit erzeugen.
  • Die Eingabe kann im Programm fest codiert oder gelesen werden (vom Benutzer, aus der Datei usw.).
  • Die Eingabe wird als gültig betrachtet und das Programm wird nicht benötigt, um die Richtigkeit der Eingabe zu überprüfen.
  • Jeder Sortieralgorithmus wird akzeptiert. Die Datenstruktur zum Halten der Zahlen muss kein tatsächlicher Vektor sein. Das Programm kann so gestaltet werden, dass eine variable Anzahl von Zahlen oder eine feste Anzahl von Zahlen sortiert wird (z. B. ist ein Programm zum Sortieren von 3 Zahlen in Ordnung ). Die Sortierung kann stabil sein oder nicht (Anmerkung: Ein Programm, das für die Ausführung einer stabilen Sortierung entwickelt wurde, hat einen offensichtlichen Fehler, der die Sortierung instabil erscheinen lässt, aber in Wirklichkeit ist es kein Fehler: Das Programm führt tatsächlich eine stabile Sortierung durch - ist eine gültige Antwort ).
  • (einschließlich Sortierfunktionen) außer 3rd - Party - Tools können Sie alle Funktionen aufrufen (es sei denn , sie weiter verbreitete zB sind boosfür C++, JQueryfür Javascript- das sind ok zu verwenden)
  • geben Sie die Sprache an
  • Kommentieren Sie in Code den Teil, der wie ein Fehler aussieht.
  • Erklären Sie, wie der Fehler aussieht, wenn Sie etwas falsch machen.
  • erkläre (in einer Spoilerbox), warum es eigentlich kein Bug ist.

Dies ist ein Beliebtheitswettbewerb. Die Antwort mit den meisten Stimmen gewinnt.


Diese Herausforderung ist nun vorbei. Der Gewinner ist @Clueless /codegolf//a/30190/11400 mit 8 Stimmen. Vielen Dank an alle Einsender!

Wenn Sie nach der Vergabe des Gewinners teilnehmen möchten, können Sie gerne eine neue Antwort hinzufügen. Sie sind aus dem Rennen, aber wir sind alle daran interessiert, interessante Antworten zu sehen.


Kann ich nilable Booleans anstelle von Zahlen verwenden?
Urous

ja, die
frage auch

1
Ich stimme dafür, diese Frage als "Off-Topic" zu schließen, da hinterhältige Herausforderungen auf dieser Site nicht mehr zum Thema gehören. meta.codegolf.stackexchange.com/a/8326/20469
cat

Antworten:


11

C ++

Inspiriert von Apple goto fail; Fehler .

#include <vector>
#include <map>
#include <iostream>

/**
 * Sorts a vector of doubles in reverse order using the bucket sort algorithm.
 */
std::vector<double> reverse_bucket_sort(const std::vector<double>& input) {
    // put each element into a bucket as many times as it appears
    std::map<double, int> bucket_counts;
    for (auto it : input)
        ++bucket_counts[it];

    std::vector<double> sorted_elements; // the return value

    // loop until we are done
    while (bucket_counts.size() > 0) {
        // find the largest element
        double maximum = std::numeric_limits<double>::lowest();
        for (auto it : bucket_counts) {
            if (it.first > maximum)
                maximum = it.first;
                maximum = it.first;
        }

        // add the largest element N times to our sorted vector
        for (int i = 0; i < bucket_counts[maximum]; ++i)
            sorted_elements.push_back(maximum);

        // and now erase the bucket
        bucket_counts.erase(maximum);
    }

    return sorted_elements;
}

int main(int argc, const char * argv[]) {
    std::vector<double> test_case = { 0, 1, 2.5, 10, 2.5, 2 };

    std::cout << "unsorted:";
    for (auto it : test_case) std::cout << " " << it;
    std::cout << std::endl;

    std::cout << "sorted:";
    for (auto it : reverse_bucket_sort(test_case)) std::cout << " " << it;
    std::cout << std::endl;

    return 0;
}

Ungefähr in der Mitte der Seite ist ein Fehler aufgetreten: Wir haben nach unserer ifPrüfung eine doppelte Zeile ! Wir werden das Maximum immer mit dem zuletzt eingegebenen Wert aktualisieren bucket_count. Zum Glück sind wir in Ordnung. In C ++ std::mapwird nach Schlüsseln sortiert. Wir drehen also nur die Eimer um, was wir wollen.


Sie haben nicht verwendet goto, daher gibt es keinen Fehler. (Bezogen auf all die Leute, die sagten, dass der Fehler niemals passiert wäre, wenn Apple ihn nicht verwendet hätte goto)
user253751

Herzlichen Glückwunsch, Sie haben diese Herausforderung mit den meisten Stimmen gewonnen (8 Stimmen nach 7 Tagen). Außerdem mag ich Ihre Antwort sehr, weil Sie einen echten Fehler ausprobiert haben.
Bolov

8

Python2.x

import random
L = [random.randrange(20) for x in range(20)]
print "Unsorted:", L

def sort(L):
    # terminal case first. Otherwise sort each half recursively and combine
    return L.sort() if L > 1 else sort(L[:len(L)//2]) + sort(L[len(L)//2:])

sort(L)
print "Sorted:", L

Testlauf

list.sortkehrt zurück None, also der Teil nach dem elseist None + None. Zum Glück ist dies kein Problem, da der Vergleich einer Liste und eines Int (L > 1)immer ist True. Die Funktion kehrt immer zurück, Noneso dass wir den Rückgabewert ignorieren und Just print, Ldas an Ort und Stelle sortiert wurde. Das Zusammenführen der sortierten Hälften durch Verketten hätte auch dann nicht funktioniert, wenn die Ausführung dort angekommen wäre.


Herzlichen Glückwunsch, Sie haben nach 7 Tagen mit 6 Stimmen den zweiten Platz belegt. Vielen Dank für Ihren Beitrag.
Bolov

5

C

Falsche Sortierung - auf einem 64-Bit-System sind intes 4 Byte und char *8 Byte, sollte also nicht funktionieren.

Code:

#include <stdlib.h>
#include <stdio.h>

/* Compare integers to sort in reverse order */
int compare(const void *p, const void *q)
{
    const int *a = p;
    const int *b = q;

    return *b - *a;
}

int main()
{
    char *strings[] = {"B", "Que", "Ro", "Sum", "T"};
    int i;

    /* Let's use the integer compare to sort strings */
    qsort(&strings, sizeof(strings) / sizeof(char *), sizeof(char *), compare);

    /* Output the sorted results */
    for (i = 0; i < sizeof(strings) / sizeof(char *); i++)
        printf("%s\n", strings[i]);

    return 0;
}

Bauen:

$ gcc -o sort-no-sort sort-no-sort.c 

Lauf:

$ ./sort-no-sort 
T
Sum
Ro
Que
B

Ja, irgendwie okay!

Fünf Dinge gehen vor sich: 1) qsortÜbergibt Zeiger an Ganzzahlen, die die gleiche Größe haben wie Zeiger an Zeichen. 2) Die Zeichenfolgen sind nicht länger als vier Bytes (drei + ein Abschlusszeichen) = die Größe einer Ganzzahl, die die Sortierroutine gerne als Ganzzahl behandelt. 3) Die meisten Compiler erzwingen die Ausrichtung von Datenstrukturen, sodass kürzere Zeichenfolgen denselben Platz beanspruchen. Jeder größere aber und für Ausfälle vorbereitet sein. 4) Endian-ness. 5) Nullinitialisierung der internen Bytes.


Vielen Dank für Ihren Beitrag. Sie haben den 3. Platz belegt. Glückwunsch!
Bolov

2

Kobra

class Program
    var _target as List<of bool?> = [true, true, false, true, true, nil, nil, false, true, nil, true]
    def main
        .sort(_target)
        print _target
    def sort(target as List<of bool?>)
        for i in target.count, for n, in target.count -1, if target[n] <> target[n + 1] and (target[n] or target[n + 1] == nil), target[n], target[n + 1] = target[n + 1], target[n]
            #should return sorted as [nil][false][true]

Oh je, ich habe anscheinend falsch zugeordnet n... und wie sind all diese Kommas dahin gekommen?

Wann n Zuweisung geht der Compiler davon aus, dass er die erste Hälfte eines Schlüssel-Wert-Paares erhält (aufgrund des Kommas), aber es gibt kein Schlüssel-Wert-Paar, sodass der Compiler sich nicht beschwert, wenn er die zweite Hälfte nicht zuweisen kann davon zu einer nicht existierenden Variablen. Dies führt dazu, dass neinfach der Schlüsselwert angegeben wird, der in diesem Fall eine Indexnummer ist. Alle anderen falsch aussehenden Kommas in der letzten Zeile sind Teil der Standard-Cobra-Syntax.


Vielen Dank für Ihren Beitrag. Sie haben den 3. Platz belegt. Glückwunsch!
Bolov

2

Java

public final class WeirdSort {
    public static void main(final String[] args) {

        //Random
        final Random random = new Random(441287210);

        //Some numbers:
        final List<Integer> list = new ArrayList<Integer>();
        list.add(9);
        list.add(11);
        list.add(3);
        list.add(5);
        list.add(7);

        //Sort randomly:
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(final Integer o1, final Integer o2) {
                return (o1 - o2) + random.nextInt(10);
            }
        });

        //Print
        for(final Integer i:list) {
            System.out.print(i + " ");
        }
    }
}

Prints: 3 5 7 9 11 

Funktioniert, weil dieser bestimmte Zufallswert für die ersten 10 Ergebnisse '1' zurückgibt


1
Welche Sprache benutzt du?
Knerd

Java, leider vergessen zu erwähnen, dass (bearbeitet).
Roy van Rijn

2

Perl

Auftragnehmer in diesen Tagen! Wissen sie das nicht?<=> Operator (auch "Raumschiff" genannt) nur für die numerische Sortierung verwendet wird?

Und warum vergleichen sie Betreiber?

Wie hat dieser Code unsere strengen Tests überhaupt bestanden ?? !! Es nutzt sogar strictund warnings!

use strict;
use warnings;

sub asciibetically { 0-($a lt $b) || 0+($a gt $b) || <=><=><=> }
                                                   #  ^  ^  ^
                                                   # What?? How did Perl even compile??!!

my @sorted = sort asciibetically qw( bravo charlie alpha );

print "@sorted";   # "alpha bravo charlie"
                   # And how come it works??!!

Warum kompiliert Perl?

Der einzige echte <=>Operator ist der in der Mitte. Die anderen beiden sind nur eine andere Schreibweise glob("="). Dies bedeutet, dass <=><=><=>(mit dem Spitznamen "Raumflotte") ausgewertet wird 0.


Warum es funktioniert

Die asciibeticallySubroutine ist eine Implementierung des cmpstrangVergleichsOperator: Binary „ cmp“ zurückkehrt -1, 0oder 1je nachdem , ob das linke Argument ist stringwise weniger als, gleich oder größer ist als das rechte Argument.


3
Nun, Perl sieht für mich sowieso wie ein
Käfer aus
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.