[ Последнее обновление: эталонная программа и предварительные результаты доступны, см. Ниже]
Поэтому я хочу проверить компромисс между скоростью и сложностью с классическим приложением: сортировка.
Напишите функцию ANSI C, которая сортирует массив чисел с плавающей точкой в порядке возрастания .
Вы не можете использовать любые библиотеки, системные вызовы, многопоточность или встроенный ASM.
Записи оцениваются по двум компонентам: длина кода и производительность. Оценки следующим образом: записи будут отсортированы по длине (журнал #characters без пробелов, так что вы можете сохранить некоторое форматирование) и производительности (журнал #seconds за тест), и каждый интервал [лучший, худший] линейно нормализуется до [ 0,1]. Общий балл программы будет средним из двух нормализованных баллов. Самый низкий балл побеждает. Одна запись на пользователя.
Сортировка должна (в конечном итоге) быть на месте (т. Е. Входной массив должен содержать отсортированные значения во время возврата), и вы должны использовать следующую подпись, включая имена:
void sort(float* v, int n) {
}
Подсчитываемые символы: символы в sort
функции, включая подпись, плюс дополнительные функции, вызываемые ею (но не включая код тестирования).
Программа должна обрабатывать любые числовые значения float
и массивы длиной> = 0, вплоть до 2 ^ 20.
Я подключу sort
и его зависимости к тестирующей программе и скомпилирую на GCC (никаких изящных опций). Я добавлю в него кучу массивов, проверим правильность результатов и общее время выполнения. Тесты будут проводиться на Intel Core i7 740QM (Clarksfield) под Ubuntu 13.
Длины массивов будут охватывать весь допустимый диапазон с более высокой плотностью коротких массивов. Значения будут случайными, с распределением «толстый хвост» (как в положительном, так и в отрицательном диапазонах). Дублированные элементы будут включены в некоторые тесты.
Тестовая программа доступна здесь: https://gist.github.com/anonymous/82386fa028f6534af263.
Импортирует отправку как user.c
. Количество тестовых случаев ( TEST_COUNT
) в фактическом тесте будет 3000. Пожалуйста, оставьте любые отзывы в комментариях к вопросу.
Срок подачи заявок: 3 недели (7 апреля 2014 года, 16:00 по Гринвичу). Я опубликую тест через 2 недели.
Может быть целесообразно размещать сообщения ближе к крайнему сроку, чтобы избежать раздачи вашего кода конкурентам.
Предварительные результаты, по состоянию на публикацию тестов:
Вот некоторые результаты. В последнем столбце отображается процентное соотношение, чем выше, тем лучше, ставя Джонни Кейджа на первое место. Алгоритмы, которые были на несколько порядков медленнее остальных, выполнялись на подмножестве тестов, и время экстраполировалось. Собственное С qsort
включено для сравнения (Джонни быстрее!). Я сделаю окончательное сравнение во время закрытия.
Ответы:
150 символов
Quicksort.
Сжатый.
источник
150 символов (без пробелов)
источник
if(*w<*v) { t=v[++l]; v[l]=*w; *w=t; }
может бытьif(*w<*v) t=v[++l], v[l]=*w, *w=t;
67 7069 символовСовсем не быстро, но невероятно мало. Я полагаю, что это гибрид между сортировкой выбора и алгоритмом пузырьковой сортировки. Если вы на самом деле пытаетесь это прочитать, то вы должны знать, что
++i-v-n
это то же самое, что и++i != v+n
.источник
if(a)b
->a?b:0
сохраняет символ++i-v-n
это так же, как++i != v+n
только в условных, конечно.if(*i>v[n])...
->*i>v[n]?...:0
123 символа (+3 новых строки)
Стандартная сортировка Shell, сжатая.
PS: обнаружил, что это все еще в 10 раз медленнее, чем быстрая сортировка. Вы могли бы также проигнорировать эту запись.
источник
395 символов
Сортировка слиянием.
Отформатирован.
источник
331326327312 символовДелает ли основание сортировку по 8 битам за раз. Использует причудливый битхак для правильной сортировки отрицательных чисел (украдено с http://stereopsis.com/radix.html ). Это не так компактно, но это действительно быстро (~ в 8 раз быстрее, чем самый быстрый предварительный вход). Я надеюсь на скорость, превышающую размер кода ...
источник
511424 символовВнутренний радиксорт
Обновление: переключается на сортировку вставкой для меньших размеров массива (увеличивает производительность в 4,0 раза).
Отформатирован.
источник
void*
inqsort
(строка 88) отбрасывает арифметику указателя.121114111 символовПросто быстрая и грязная пузырьковая сортировка с рекурсией. Вероятно, не очень эффективно.
Или длинная версия
источник
221193172 персонажаHeapsort - не самый маленький, но на месте и гарантирует поведение O (n * log (n)).
Сжатый.
источник
TEST_COUNT
= 3000, кажется, что она не прошла хотя бы один тест.154166 символовХорошо, здесь более длинная, но более быстрая сортировка.
Вот исправление, чтобы выжить отсортированные входы. И отформатированный, так как пробелы не учитываются.
источник
150 символов
Шеллсорт (с Кнутом).
Отформатирован.
источник
C 270 (игра в гольф)
Объяснение: Пустой массив используется для хранения каждого последующего минимального числа. Массив int - это маска с 0, указывающая, что число еще не было скопировано. После получения минимального значения маска = 1 пропускает уже использованные числа. Затем массив копируется обратно в оригинал.
Я изменил код, чтобы исключить использование библиотечных функций.
источник
144
Я бесстыдно взял код Джонни, добавил крошечную оптимизацию и сжал код очень грязным способом. Это должно быть короче и быстрее.
Обратите внимание, что в зависимости от вашего компилятора sort (q, v + n- ++ q) должен быть заменен sort (++ q, v + nq).
Ну, на самом деле, я начал формировать свой код и оптимизировать его, но, кажется, Джонни уже сделал правильный выбор. Так что я закончил с квази-его кодом. Я не думал о трюке с Гото, но я мог обойтись без.
источник
228 символов
RadixSort.
источник