Napisz program sortujący, który wygląda na błędny, ale w rzeczywistości jest poprawny [zamknięty]

12

Napisz program, który sortuje wektor liczb (lub dowolnego rodzaju elementu), który wygląda tak, jakby zawierał jeden lub więcej błędów, ale w rzeczywistości jest w porządku.

  • Kod musi być wyraźny. Ktoś przeglądający kod musi łatwo zidentyfikować, że jest to algorytm sortowania i musi łatwo pomylić poprawny fragment kodu z błędem.
  • (Widoczny) błąd może powodować wszystko, co powoduje, że kod jest źle sformatowany lub semantycznie źle sformułowany (np. Powoduje, że program się nie kompiluje / nie uruchamia, wyświetla UB po uruchomieniu), powoduje, że program generuje niepoprawne wyniki, nie kończy lub nie jest deterministyczny.
  • Kod musi być właściwie dobrze sformułowany, a program musi deterministycznie wygenerować poprawne wyjście w skończonym czasie.
  • Dane wejściowe mogą być zakodowane na stałe w programie lub mogą zostać odczytane (od użytkownika, z pliku itp.).
  • Dane wejściowe są uważane za prawidłowe i program nie jest potrzebny do weryfikacji poprawności danych wejściowych.
  • Każdy algorytm sortowania jest akceptowany. Struktura danych do przechowywania liczb nie musi być faktycznym wektorem. Program można zaprojektować do sortowania zmiennej liczby lub stałej liczby (np. Program do sortowania 3 liczb jest w porządku ). Sortowanie może być stabilne lub nie (uwaga: program zaprojektowany do wykonywania stabilnego sortowania, który ma widoczny błąd, który sprawia, że ​​sortowanie wygląda niestabilnie, ale w rzeczywistości nie jest to błąd: program faktycznie wykonuje stabilne sortowanie - jest poprawną odpowiedzią ).
  • możesz wywoływać dowolne funkcje (w tym funkcje sortowania) oprócz narzędzi innych firm (chyba że są one szeroko rozpowszechnione i używane np. boosdo C++, JQuerydla Javascript- są one w porządku do użycia)
  • określ język
  • komentuj w kodzie część, która wygląda jak błąd.
  • wyjaśnij, jak błąd wygląda źle.
  • wyjaśnij (w polu spoilera), dlaczego tak naprawdę nie jest to błąd.

To konkurs popularności. Odpowiedź z większością głosów wygrywa.


To wyzwanie już się skończyło. Zwycięzcą jest @Clueless /codegolf//a/30190/11400 z 8 głosami. Dziękujemy wszystkim zgłaszającym!

Jeśli chcesz przyjść po przyznaniu zwycięzcy, dodaj nową odpowiedź. Nie jesteś w wyścigu, ale wszyscy jesteśmy zainteresowani, aby zobaczyć ciekawe odpowiedzi.

bolov
źródło
Czy mogę używać zerowalnych boolanów zamiast liczb?
Οurous
tak, zredagował też pytanie: wszelkie elementy
bolov
1
Głosuję za zamknięciem tego pytania jako nie na temat, ponieważ słabe wyzwania nie są już na ten temat na tej stronie. meta.codegolf.stackexchange.com/a/8326/20469
kot

Odpowiedzi:

11

C ++

Zainspirowany przez Apple goto fail; błąd .

#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;
}

Mniej więcej w połowie strony jest błąd: po ifsprawdzeniu mamy zduplikowaną linię ! Zawsze będziemy aktualizować maksimum o dowolną ostatnią wartość bucket_count. Na szczęście mamy się dobrze. W C ++ std::mapjest posortowane według kluczy. Więc po prostu cofamy wiadra, a tego właśnie chcemy.

bezradny
źródło
Nie używałeś goto, dlatego nie ma błędu. (Odnosząc się do wszystkich osób, które twierdziły, że błąd nigdy by się nie zdarzył, gdyby Apple nie używał goto)
user253751
Gratulacje, wygrałeś to wyzwanie, zdobywając najwięcej głosów (8 głosów po 7 dniach). Ponadto bardzo podoba mi się twoja odpowiedź, ponieważ użyłeś prawdziwego błędu w życiu.
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

Testowe uruchomienie

list.sortzwraca None, więc część po elsejest None + None. Na szczęście nie stanowi to problemu, ponieważ porównanie listy i int (L > 1)jest zawsze True. Funkcja zawsze zwraca, Nonewięc ignorujemy zwracaną wartość i po prostu drukuj, Lktóry został posortowany na miejscu Scalanie posortowanych połówek przez catenation również nie zadziałałoby, nawet gdyby wykonanie się tam udało.

gnibbler
źródło
Gratulacje, zająłeś drugie miejsce 6 głosami po 7 dniach. Dziękujemy za zgłoszenie.
bolov
5

do

Niepoprawne użycie sortowania - w systemie 64-bitowym intma 4 bajty i char *8 bajtów, więc nie powinno działać.

Kod:

#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;
}

Budować:

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

Biegać:

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

Tak, wszystko w porządku!

Pięć rzeczy się dzieje: 1) qsortprzekazuje wskaźniki do liczb całkowitych, które są tego samego rozmiaru co wskaźniki do znaków. 2) Ciągi mają długość nie większą niż cztery bajty (trzy + jeden terminator) = rozmiar liczby całkowitej, którą procedura sortowania szczęśliwie traktuje jako liczbę całkowitą. 3) Większość kompilatorów wymusza wyrównanie struktur danych, więc krótsze łańcuchy zajmują to samo miejsce. Większy i bądź przygotowany na awarie. 4) Endianowość. 5) Zerowa inicjalizacja bajtów wewnętrznych.


źródło
Dziękujemy za zgłoszenie. Umieściłeś na 3 miejscu. Gratulacje!
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]

Ojej, wydaje mi się, że niepoprawnie przypisałem n... i jak się tam dostały wszystkie przecinki !?

Po nprzypisaniu kompilator zakłada, że ​​podaje pierwszą połowę pary klucz-wartość (ze względu na przecinek), ale nie ma pary klucz-wartość, więc kompilator nie narzeka, gdy nie może przypisać drugiej połowy z tego na nieistniejącą zmienną. W nrezultacie otrzymuje się po prostu kluczową wartość ... która w tym przypadku jest numerem indeksu. Wszystkie inne niecodzienne przecinki w ostatnim wierszu są w rzeczywistości częścią standardowej składni Cobry.

Obrzydliwe
źródło
Dziękujemy za zgłoszenie. Umieściłeś na 3 miejscu. Gratulacje!
bolov
2

Jawa

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 

Działa, ponieważ ta konkretna losowa wartość zwraca „1” dla pierwszych 10 wyników

Roy van Rijn
źródło
1
Z jakiego języka korzystasz?
Knerd
Java, przepraszam, zapomniałem o tym wspomnieć (edytowane).
Roy van Rijn
2

Perl

Kontrahenci w tych dniach! Czy nie wiedzą, że <=>operator (aka „statek kosmiczny”) służy wyłącznie do sortowania numerycznego?

I dlaczego porównują operatorów?

Jak ten kod przeszedł nawet nasze rygorystyczne testy? !! To nawet używa stricti 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??!!

Dlaczego Perl się kompiluje

Jedynym prawdziwym <=>operatorem jest ten w środku. Pozostałe dwa są po prostu innym sposobem pisania glob("="). Oznacza to, że <=><=><=>(nazywana „flotą kosmiczną”) ocenia na 0.


Dlaczego to działa?

asciibeticallyPodprogram jest realizacja string-porównywaniu cmpoperatora: Binary „ cmp” powraca -1, 0lub 1w zależności od tego, czy lewy argument jest łańcuchowo mniejszy, równy lub większy niż prawy argument.

Zaid
źródło
3
Cóż, Perl i tak wygląda dla mnie jak błąd ...
chill0r