Напишите программу сортировки, которая выглядит ошибочно, но на самом деле она корректна [закрыто]


12

Напишите программу, которая сортирует вектор чисел (или элемент любого типа), который выглядит как имеющий одну или несколько ошибок, но на самом деле это нормально.

  • Код должен быть понятным. Кто-то просматривает код, должен легко определить, что это алгоритм сортировки, и должен легко спутать правильный фрагмент кода с ошибкой.
  • (Очевидная) ошибка может быть вызвана чем-либо, что делает код синтаксически или семантически некорректным (например, заставить программу не компилироваться / запускаться, показывать UB при запуске), заставлять программу давать неверные результаты, не завершать или недетерминировать.
  • На самом деле код должен быть правильно сформирован, и программа должна детерминистически производить правильный вывод за конечное время.
  • Ввод может быть жестко запрограммирован в программе или может быть прочитан (из пользователя, из файла и т. Д.).
  • Ввод считается действительным, и программа не требуется для проверки правильности ввода.
  • Любой алгоритм сортировки принят. Структура данных для хранения чисел не обязательно должна быть фактическим вектором. Программа может быть разработана для сортировки переменного числа или фиксированного числа (например, программа для сортировки 3 чисел в порядке ). Сортировка может быть стабильной или нет (примечание: программа, разработанная для стабильной сортировки, которая имеет явную ошибку, из-за которой сортировка выглядит нестабильной, но на самом деле это не ошибка: программа фактически выполняет стабильную сортировку - это правильный ответ ).
  • Вы можете вызывать любые функции (включая функции сортировки), за исключением сторонних инструментов (если они не получили широкого распространения и не используются, например, boosдля C++, JQueryдля Javascript- те, которые можно использовать)
  • указать язык
  • закомментируйте в коде ту часть, которая выглядит как ошибка.
  • объясните, как выглядит ошибка, поступающая неправильно.
  • объясните (в коробке спойлера), почему это на самом деле не ошибка.

Это конкурс популярности. Ответ с большинством голосов выигрывает.


Эта проблема теперь закончена. Победитель - @Clueless /codegolf//a/30190/11400 с 8 голосами. Спасибо всем представителям!

Если вы хотите войти после того, как победитель был награжден, пожалуйста, не стесняйтесь добавлять новый ответ. Вы вне гонки, но нам всем интересно видеть интересные ответы.


Могу ли я использовать nilable booleans вместо чисел?
Οurous

да, тоже редактировал вопрос: любые элементы
болов

1
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что скрытые вызовы больше не обсуждаются на этом сайте. meta.codegolf.stackexchange.com/a/8326/20469
кошка,

Ответы:


11

C ++

Вдохновленный Apple goto fail; ошибка .

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

Примерно на полпути вниз по странице есть ошибка: у нас есть повторяющаяся строка после нашей ifпроверки! Мы всегда будем обновлять максимум с тем, что является последним значением в bucket_count. К счастью, мы в порядке. В C ++ std::mapсортируется по ключам. Таким образом, мы просто переворачиваем ведра, чего мы и хотим.


Вы не использовали goto, поэтому нет ошибки. (Ссылаясь на всех людей, которые сказали, что ошибка не произошла бы, если бы Apple не использовала goto)
user253751

Поздравляем, вы выиграли этот конкурс, набрав наибольшее количество голосов (8 голосов за 7 дней). Кроме того, мне очень нравится ваш ответ, потому что вы использовали реальную ошибку.
Болов

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

Тестовый забег

list.sortвозвращается None, поэтому часть после того , как elseэто None + None. К счастью, это не вызывает проблем, потому что сравнение списка и целого (L > 1)всегда True. Функция всегда возвращает значение, Noneпоэтому мы игнорируем возвращаемое значение и просто выводим печать, Lкоторая была отсортирована по месту. Объединение отсортированных половинок путем объединения не сработало бы, даже если бы выполнение все же получилось.


Поздравляем, вы заняли второе место с 6 голосами после 7 дней. Спасибо за ваше предложение.
Болов

5

С

Неправильное использование сортировки - в 64-битной системе intэто 4 байта и char *8 байтов, поэтому не должно работать.

Код:

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

Телосложение:

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

Бегать:

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

Да, вроде как!

Происходит пять вещей: 1) qsortпередает указатели на целые числа, которые имеют такой же размер, что и указатели на символы. 2) Строки имеют длину не более четырех байтов (три + один терминатор) = размер целого числа, которое подпрограмма сортировки с радостью воспринимает как целое число. 3) Большинство компиляторов принудительно выравнивают структуры данных, поэтому более короткие строки занимают одинаковое пространство. Хоть и побольше и будь готов к неудачам. 4) Порядковый номер. 5) Нулевая инициализация внутренних байтов.


Спасибо за ваше предложение. Вы заняли 3-е место. Поздравляем!
Болов

2

кобра

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]

О, дорогой, я, кажется, неправильно назначил n... и как все эти запятые попали туда !?

Когда nназначено, компилятор предполагает, что ему дается первая половина пары ключ-значение (из-за запятой), но пары ключ-значение не существует, поэтому компилятор не будет жаловаться, когда не может назначить вторую половину из этого в несуществующую переменную. Это приводит к тому, что nпросто дается ключевое значение, которое в данном случае является индексным числом. Все остальные запятые в последней строке запятые на самом деле являются частью стандартного синтаксиса Cobra.


Спасибо за ваше предложение. Вы заняли 3-е место. Поздравляем!
Болов

2

Джава

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 

Работает, потому что это конкретное случайное значение возвращает «1» для первых 10 результатов


1
Какой язык вы используете?
Knerd

Ява, извините, забыл упомянуть об этом (отредактировано).
Рой ван Рейн

2

Perl

Подрядчики в эти дни! Разве они не знают, что <=>оператор (он же "космический корабль") используется только для числовой сортировки?

И почему они сравнивают операторов?

Как этот код даже прошел наши строгие тесты ?? !! Он даже использует strictи 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??!!

Почему Perl компилируется

Единственный реальный <=>оператор - тот, кто посередине. Два других - просто еще один способ написания glob("="). Это означает, что <=><=><=>(по прозвищу "космический флот") оценивается в 0.


Почему это работает

asciibeticallyПодпрограмма является реализацией строкового сравнения cmpоператора: Binary « cmp» возвращается -1, 0или в 1зависимости от того , левого аргумент stringwise меньше, равно или больше , чем правый аргумент.


3
Ну, Perl все равно выглядит для меня как ошибка ...
chill0r
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.