Напишіть програму сортування, яка виглядає помилково, але насправді це правильно [закрито]


12

Напишіть програму, яка сортує вектор чисел (або будь-який тип елемента), схожий на наявність однієї чи декількох помилок, але насправді це нормально.

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

Це конкурс на популярність. Відповідь з більшістю голосів виграє.


Зараз цей виклик закінчений. Переможець - @Clueless /codegolf//a/30190/11400 з 8 голосами. Дякуємо всім подаючим!

Якщо ви хочете прийти після нагородження переможця, не соромтесь додати нову відповідь. Ви поза гонкою, але всім нам цікаво побачити цікаві відповіді.


Чи можна використовувати мінливі булеві замість цифр?
Οurous

так, редагував і питання: будь-які елементи
bolov

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. На щастя, це не викликає проблем, оскільки порівняння списку та int (L > 1)є завжди True. Функція завжди повертається, Noneтому ми ігноруємо повернене значення та просто роздруковуємо, Lяке було відсортовано на місці Злиття відсортованих половинок за допомогою катетації не працювало б навіть у тому випадку, якщо виконання потрапило б туди.


Вітаємо, ви посіли друге місце з 6 голосами через 7 днів. Дякую за подання
болов

5

С

Неправильне використання сортування - у 64-бітовій системі int4 байти та 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просто надається ключове значення .. що в даному випадку є індексним номером. Усі інші коси, що не шукають місця, у заключному рядку насправді є частиною стандартного синтаксису Кобри.


Дякую за подання Ви посіли 3 місце. Вітаємо!
болов

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 

Працює, оскільки це конкретне випадкове значення повертає "1" за перші 10 результатів


1
Якою мовою ви користуєтесь?
Кнерд

Ява, вибачте забув це згадати (відредаговано).
Рой ван Рійн

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
Ну Перл все одно для мене схожий на помилку ...
chill0r
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.