Escreva um programa de classificação que pareça errôneo, mas esteja correto [fechado]

12

Escreva um programa que classifique um vetor de números (ou qualquer tipo de elemento) que pareça ter um ou mais erros, mas na verdade está ok.

  • O código deve estar claro. Alguém olhando o código deve identificar facilmente que é um algoritmo de classificação e deve confundir facilmente um trecho de código correto com um bug.
  • O bug (aparente) pode, por qualquer coisa que torne o código sintático ou semanticamente mal formado (por exemplo, tornar o programa não compilar / executar, exibir UB quando executado), fazer com que o programa produza resultados incorretos, não seja finalizado ou não determinístico.
  • O código deve realmente ser bem formado e o programa deve produzir deterministicamente a saída correta em um tempo finito.
  • A entrada pode ser codificada no programa ou pode ser lida (do usuário, do arquivo etc.).
  • A entrada é considerada válida e o programa não é necessário para verificar a correção da entrada.
  • Qualquer algoritmo de classificação é aceito. A estrutura de dados para armazenar os números não é necessária para ser um vetor real. O programa pode ser projetado para classificar um número variável de números ou um número fixo de números (por exemplo, um programa para classificar 3 números está ok ). A classificação pode ser estável ou não. )
  • você pode chamar quaisquer funções (incluindo funções de ordenação), exceto ferramentas de 3 (a menos que eles são amplamente difundidos e, por exemplo utilizado boospara C++, JQuerypor Javascript- essas são OK para usar)
  • especifique o idioma
  • comente no código a parte que parece um bug.
  • explique como o bug parece estar fazendo errado.
  • explique (em uma caixa de spoilers) por que na verdade não é um bug.

Este é um concurso de popularidade. A resposta com mais votos vence.


Este desafio acabou agora. O vencedor é @Clueless /codegolf//a/30190/11400 com 8 votos. Obrigado a todos os autores!

Se você quiser entrar depois que o vencedor for premiado, fique à vontade para adicionar uma nova resposta. Você está fora da corrida, mas estamos todos interessados ​​em ver respostas interessantes.

Bolov
fonte
Posso usar booleanos nilable em vez de números?
Οurous
sim, editei a pergunta também: qualquer tipo de elementos
bolov
1
Estou votando para encerrar esta questão como fora de tópico, porque os desafios secretos não estão mais no tópico neste site. meta.codegolf.stackexchange.com/a/8326/20469
cat

Respostas:

11

C ++

Inspirado pela Apple goto fail; bug .

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

Na metade da página, há um erro: temos uma linha duplicada após a ifverificação! Sempre vamos atualizar o máximo com o que for o último valor bucket_count. Felizmente, estamos bem. Em C ++ std::mapé classificado por chaves. Então, estamos apenas revertendo os baldes, que é o que queremos.

Sem noção
fonte
Você não usou goto, portanto não há bug. (Referindo-se a todas as pessoas que disseram que o erro nunca teria acontecido se a Apple não usar goto)
user253751
Parabéns, você venceu este desafio com o maior número de votos (8 votos após 7 dias). Além disso, gosto muito da sua resposta porque você usou um bug da vida real.
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

Execução de teste

list.sortretorna None, então a parte após o elseé None + None. Felizmente, isso não causa problemas, porque a comparação de uma lista e de um int (L > 1)é sempre True. A função sempre retorna, Noneportanto ignoramos o valor de retorno e Just print, Lque foi ordenado no lugar A fusão das metades classificadas por catenação não teria funcionado, mesmo que a execução chegasse lá.

mordedor
fonte
Parabéns, você ficou em segundo lugar com 6 votos após 7 dias. Obrigado pela sua submissão.
bolov
5

C

Usando a classificação incorretamente - em um sistema de 64 bits inttem 4 bytes e char *8 bytes, portanto, não deve funcionar.

Código:

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

Construir:

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

Corre:

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

Sim, tudo bem!

Cinco coisas acontecendo: 1) qsortpassa ponteiros para números inteiros, que são do mesmo tamanho que ponteiros para caracteres. 2) As strings não têm mais que quatro bytes de comprimento (três + um terminador) = o tamanho de um número inteiro, que a rotina de classificação felizmente trata como um número inteiro. 3) A maioria dos compiladores força o alinhamento das estruturas de dados; portanto, cadeias mais curtas ocupam o mesmo espaço. Qualquer tamanho maior e esteja preparado para falhas. 4) Endianismo. 5) Inicialização zero de bytes internos.


fonte
Obrigado pela sua submissão. Você ficou em 3º. Parabéns!
bolov
2

Cobra

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, meu Deus, parece que eu designei incorretamente n... e como todas essas vírgulas chegaram lá !?

Quando né atribuído, o compilador assume que está sendo fornecida a primeira metade de um par de valores-chave (devido à vírgula), mas não há um par de valores-chave, portanto o compilador não reclama quando não pode atribuir a segunda metade para uma variável inexistente. Isso resulta em nsimplesmente receber o valor da chave .. que neste caso é um número de índice. Todas as outras vírgulas fora do lugar na linha final fazem parte da sintaxe padrão do Cobra.

Furioso
fonte
Obrigado pela sua submissão. Você ficou em 3º. Parabéns!
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 

Funciona porque esse valor aleatório específico retorna '1' para os 10 primeiros resultados

Roy van Rijn
fonte
1
Qual idioma você usa?
Knerd
Java, desculpe esqueci de mencionar isso (editado).
Roy van Rijn
2

Perl

Empreiteiros nos dias de hoje! Eles não sabem que o <=>operador (também conhecido como "nave espacial") é usado apenas para classificação numérica?

E por que eles estão comparando operadores?

Como esse código passou nos nossos testes rigorosos ?? !! Ele ainda usa stricte 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??!!

Por que o Perl compila

O único <=>operador real é aquele no meio. Os outros dois são apenas outra maneira de escrever glob("="). Isso significa que <=><=><=>(apelidado de "frota espacial") é avaliado como 0.


Por que funciona

A asciibeticallysub-rotina é uma implementação do cmpoperador de comparação de seqüências : " cmp" binário retorna -1, 0ou 1depende se o argumento esquerdo é sequencialmente menor que, igual a ou maior que o argumento correto.

Zaid
fonte
3
Bem Perl parece um bug de qualquer maneira para mim ...
chill0r