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.


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.


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.


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.


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.


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


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.


3
Cóż, Perl i tak wygląda dla mnie jak błąd ...
— chill0r
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.