Странная сортировочная машина для гнусных целей


18

Добрый вечер, гольфисты!

Ваша задача состоит в том, чтобы полностью перебрать ряд чисел.

вход

Точно 100 целых чисел будет передано в вашу программу. Ваша программа может принять ввод либо в виде файла, либо через стандартный ввод. Каждое целое число будет разделено символом новой строки.

Эти 100 целых чисел будут варьироваться от минимальных до максимальных значений целого числа со знаком на выбранном вами языке.

Там не будет повторяющихся значений. Значения могут быть упорядочены, неупорядочены или частично упорядочены - ваша программа должна иметь возможность обрабатывать каждый случай.

Выход

Выходными данными должно быть каждое из 100 целых чисел, полностью не отсортированных, каждое из которых должно быть разделено символом новой строки. Вывод может быть через стандартный вывод или в файл.

Полностью не отсортированный означает, что никакое значение не является смежным с любым значением, к которому оно было бы примыкало, если бы список был полностью отсортирован в упорядоченной последовательности.

Гол

1 очко за персонажа, и выигрывает самая низкая оценка. Существует бонус -100 для любого решения, не использующего встроенные или библиотечные функции сортировки. Существует бонус -20 для любых решений, не использующих встроенные функции случайных чисел.

Я попытался определить этот вопрос максимально полно. Если у вас есть какие либо вопросы, пожалуйста спрашивайте. Если у вас есть какие-либо комментарии о том, как я мог бы сделать лучше в следующий раз, пожалуйста, дайте мне знать.

Fore!


Вводится ровно 100 целых чисел, и нет повторяющихся значений (см. «Входные данные»)
lochok

Правильно, не заметил этого.
Стригоидес

2
Это не дубликат как таковой, но он не очень отличается от codegolf.stackexchange.com/questions/6487/…
Питер Тейлор

Так много умных ответов! Я
выберу

Ответы:


9

GolfScript (оценка 27 - 120 = -93)

~].,{{.2$<{\}*}*]}*.(;+2%n*

Примечание: это $ссылка на элемент в стеке. Есть сортировка, но это делается с помощью пузырьковой сортировки, закодированной вручную.

Спасибо Говарду за -90 => -92; и Илмари, который вдохновил -92 => -93.


Признаться за такой краткий ответ, но (извините за то, что я не говорю и не понимаю GolfScript) - разве ^ не дисквалифицирует его из бонуса -100?
lochok

1
@lochok, встроенная функция сортировки $- вот почему я упомянул, что $в программе нет сортировок (это зависит от контекста). Большая часть программы (28 из 42 символов) определяет функцию ^; первая версия, использующая встроенную сортировку, была всего 14 символов.
Питер Тейлор

Ааа - верно. Благодарю за разъяснение!
lochok

1
Вы можете сохранить два символа с помощью следующего выходного контура: 2/{~p}%n*.
Говард

1
2/zip~+n*а .);\+2%n*также выполнить трюк для того же числа символов, что и версия @ Howard's. Увы, мне пока не удалось найти ничего более короткого.
Илмари Каронен

6

Python -26

(94-120): новый, грубый подход. Продолжайте вставлять самые низкие элементы в новый список, чтобы отсортировать элементы, а затем выполните итерации:

t=l=[]
i=N=100
exec't=t+[input()];'*N+'l+=[t.pop(t.index(min(t)))];'*N+'print l[i%N];i+=3;'*N

Python -13

(107-120): Первый подход: удаляет четыре младших элемента за один раз, затем выводит эти четыре в другом порядке:

exec'l=[]'+'+[input()]'*100
while l:
 a,b,c,d=eval('l.pop(l.index(min(l))),'*4)
 for e in[b,d,a,c]:print e

t=l=[]и exec't+=[input()];'*100сэкономит вам несколько символов
квазимодо

Кроме того, вы можете использовать один execоператор для более чем одного цикла.
квазимодо

@quasimodo Я пробовал что-то подобное, но с t=l=[]t и l указывают на один и тот же объект, и он не работает. Пропускать скобки execприятно.
Даниеро

Вы можете использовать t=t+[input()];, это создает новый объект каждый раз. И вы можете даже сделать цикл печати в ехесе заявления: ';i+=1;print l[i*3%100]'*100.
квазимодо

Ты снова прав. Благодарность! Также добавлены некоторые другие игры в гольф, такие как удаление %3и избегание повторения 100.
Даниеро

4

С: 11 (131 - 120)

Программа читает из stdin и выполняет простую сортировку вставки, после чего печатает n-е вместе с th n + 50-м числом, как и многие другие решения.

main(){int*i,a[101],*j=a;while(scanf("%d",a)>0)for(i=++j;i-->a;)i[1]=*i>=*a?*i:*(i=a);while(a<(i=j-50))printf("%d\n%d\n",*i,*j--);}

3

Mathematica -56 44 4 (95-120) = -25

Редактировать :

Эта версия не использует ни встроенных функций для сортировки списков, ни функций рандомизации.

Riffle[RotateLeft[#[[All, 2]], 2], #[[All, 1]]] &
[Partition[l //. {x___, a_, b_, y___} /; b < a :> {x, b, a, y}, 2]]

Разве Sortне встроенная функция сортировки?
Питер Тейлор

Ты прав! Я пропустил ограничение о сортировке.
DavidC

Я сделал рулонную сортировку.
DavidC

3

J, -63 (57-120) символов

Поскольку все остальные идут по самописному маршруту сортировки ...

,50(}.,.{.)($:@([-.m),~m=.]#~]=<./)^:(0<#),".[;._2[1!:1[3

Не использует ни функцию случайных чисел, ни встроенную сортировку.

Для сортировки входных данных используется простая рекурсивная сортировка выбора.


3

Рубин 1.9, -59

(61-120)

Рекурсия! На самом деле этот, в отличие от моих предыдущих попыток Ruby, не сортирует список независимо от их первоначального порядка.

p *(f=->l{l[1]&&f[l-m=l.minmax]+m||[]})[$<.map &:to_i].rotate

Предыдущие попытки

Симпатичный однострочник, теперь использующий встроенную сортировку для правильной работы:

$<.map(&:to_i).sort.each_slice(4){|a,b,c,d|p b,d,a,c}

Первый - необязательно отменять последние 4 значения:

l=$<.map &:to_i
48.times{l-=p *l.minmax}
a,b,c,d=l
p b,d,a,c

1
Ваше решение -72 предполагает, что список начинается с сортировки, а это не так.
гистократ

К сожалению. Кажется, я не перечитал вопрос полностью, когда снова зашел к нему. Постараюсь придумать что-то еще.
Даньеро

@histocrat, который должен это сделать.
Даньеро

1

Python 2: 90 символов

n=100
s=sorted(int(raw_input())for i in range(n))
for i in range(n):print s[(4*i+4*i/n)%n]

ленивая попытка, но только для начала


1

Python 48 = (148 - 100)

from random import*
x=[input()for i in range(100)]
while any(abs(x[i]-x[i+1])>1 for i in range(99)):n=randint(1,99);x=x[n:]+x[:n]
for j in x:print j

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


1
x=map(input,['']*100)
Угорен

И я не думаю, что вам даже нужны дополнительные []s, просто любая строка символов.
работа

1

Питон 27 (147 - 100 - 20)

R=range
def S(L):
 for i in R(len(L)-1):
    if L[i]>L[i+1]:L[i:i+2]=[L[i+1],L[i]];S(L)
a=map(input,['']*100);S(a)
for i in R(100):print a[i/2+i%2*50]

Примечание: перед пробелами if L[i]>...должна быть табуляция, но, видимо, они отображаются как пробелы в блоке кода.


С помощью R=rangeвы можете сохранить 5 символов.
scleaver

a=map(input,['']*100)
Угорен

1

Perl 5: 95 - 120 = -25 символов

Считая следующую командную строку:

perl -ne '$n=$_;splice@n,(grep{$n[$_]>$n}0..@n),0,$n}{print for map{@n[$_,$#n/2+$_+1]}0..$#n/2'

1

Рубин: -50 (70 символов - 120)

Я сделал то же самое, что и многие другие ответы: итеративно удаляю max и min из списка ввода и добавляю их к выводу. Однако я понял, что если 2 числа по обе стороны от медианы являются последовательными, выходные данные будут неправильными (потому что эти 2 последовательных числа появятся вместе в конце выходных данных). Чтобы это исправить, я поворачиваю «несортированный» список вправо на 1 элемент:

n=$*.map &:to_i;u=[];50.times{u+=n.minmax;n-=u.last 2};p *u.rotate(-1)

Или, чтобы работать с произвольным количеством входов (используя только 4 символа):

n=$*.map &:to_i;u=[];(u+=n.minmax;n-=u.last 2)while n.any?;p *u.rotate(-1)

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


1

J 37 - 100 = -63

({~?~@#)^:(+./@(1=|)@(2&(-/\))@/:)^:_

Не использует сортировку (хотя использует ранжирование вверх) Использует случайные числа.

Объяснение:

({~?~@#)             NB. Randomizes the array
^: foobar ^:_        NB. as long as
foo =: +./@(1 = |)   NB. as any 1 == absolute value of
bar =: (2&(-/\))@/:  NB. differences between adjacent ranks
foobar =: foo@bar

1

Брахилог , 22 байта - 120 = -98

ṇịᵐpX¬{p≤₁s₂.&s₂p}∧Xẉᵐ

Попробуйте онлайн!

Ссылка TIO имеет только восемь целых чисел, а не сто, потому что это так ужасно медленно, что не может больше обрабатывать в течение 60 секунд. Причина этого заключается в том, что, помимо прочего, вместо того, чтобы реализовать какой-то простой, но нормальный алгоритм сортировки для обязательного бонуса, я для краткости использовал то, что составляет детерминированный bogosort: p≤₁отслеживает каждую перестановку входных данных, пока не найдет один который не уменьшается. Хотя более важной причиной, вероятно, было бы то, что он использует подобную степень грубой силы, чтобы найти вывод, и что он пересчитывает отсортированную версию каждый раз ... Я пытался проверить это на фактическом вводе размера 100, но я не уверен, сколько дней это займет.

В целом лучшая версия:

Брахилог , 14 байтов - 20 = -6

p.¬{os₂.&s₂p}∧

Попробуйте онлайн!

Это игнорирует устаревшие требования к вводу / выводу для краткости и не учитывает бонус -100, поэтому его можно протестировать без суперкомпьютера (хотя на момент написания этого документа он работал только на 20 элементах в течение нескольких минут, и это до сих пор не дал мне ничего).

 .                The output is
p                 a permutation of
                  the input
  ¬{        }∧    such that it cannot be proven that
         s₂       a pair of adjacent values in
        &         the output
       .   p      is a permutation of
     s₂           a pair of adjacent values in
    o             the output sorted.

Хотя это не совсем практический ответ, он может быть полезен для проверки выходных данных из других программ, так как большинство из них просто описывает ограничение, накладываемое на выходные данные.
Несвязанная строка

0

Forth (gforth) , 79 - 120 = -21 байт

: f 100 0 do dup i 2 mod 4 * 2 - i + i 99 = i 0 = - 3 * + cells + @ . cr loop ;

Попробуйте онлайн!

Игнорировать устаревшие требования к вводу и принимает ввод как адрес в памяти, где хранятся числа.

объяснение

Перебирает все числа от 0 до 99. Для каждого числа (n):

  • Если n равно 0:
    • вывести значение по адресу массива + 1
  • Иначе, если n равно 99:
    • вывести значение по адресу массива + 98
  • Иначе, если n нечетно:
    • вывести значение по адресу массива + (n + 2)
  • Остальное (четное):

    • вывести значение по адресу массива + (n - 2)
  • Вывести новую строку

Код Объяснение

: f               \ start new word definition
  100 0 do        \ loop from 0 to 99
    dup           \ duplicate the array address
    i             \ place the loop index on the stack
    2 mod 4 * 2 - \ convert to 2 if it's odd and -2 if it's even
    i +           \ add the result to the the loop index
    i 99 =        \ if i = 99 place -1 on top of the stack, else place a 0
    i 0 =         \ i i = 0 place -1 on top of the stack, else place 0
    - 3 *         \ subtract previous two results from each other and multiply by 3
\ the above line is used to avoid writing if/then by instead using math to get 98 and 1
    +             \ add result to existing result from above
    cells         \ multiply by the size of a single integer in memory
    +             \ add to the array's starting address
    @ . cr        \ get the value at the calculated address, print it, then print a newline
  loop            \ end the loop
;                 \ end the word definition
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.