Dziwna niesortująca maszyna do niecnych celów


18

Dobry wieczór golfistów!

Twoim wyzwaniem jest całkowite posortowanie szeregu liczb.

Wejście

Dokładnie 100 liczb całkowitych zostanie podanych do twojego programu. Twój program może zaakceptować dane wejściowe jako plik lub przez stdin. Każda liczba całkowita będzie oddzielona znakiem nowej linii.

Te 100 liczb całkowitych będzie mieścić się w zakresie od minimalnej do maksymalnej wartości liczby całkowitej ze znakiem w wybranym języku.

Nie będzie zduplikowanych wartości. Wartości mogą być uporządkowane, nieuporządkowane lub częściowo uporządkowane - Twój program powinien być w stanie obsłużyć każdą sprawę.

Wynik

Wyjściem musi być każda ze 100 liczb całkowitych, całkowicie nieposortowanych, każda oddzielona znakiem nowej linii. Dane wyjściowe mogą być przesyłane przez stdout lub do pliku.

Całkowicie nieposortowane oznacza, że ​​żadna wartość nie sąsiaduje z żadną wartością, do której byłaby przyległa, gdyby lista została całkowicie posortowana w uporządkowanej kolejności.

Wynik

1 punkt na postać, a najniższy wynik wygrywa. Istnieje premia w wysokości -100 za każde rozwiązanie, które nie korzysta z żadnych wbudowanych funkcji ani funkcji sortowania bibliotek. Istnieje premia w wysokości -20 za dowolne rozwiązania, które nie wykorzystują wbudowanych funkcji liczb losowych.

Próbowałem zdefiniować to pytanie tak dokładnie, jak to możliwe. Jeśli masz jakieś pytania, zapytaj. Jeśli masz jakieś uwagi na temat tego, jak mógłbym lepiej zrobić następnym razem, daj mi znać.

Dziobowy!


Wprowadzono dokładnie 100 liczb całkowitych i nie ma zduplikowanych wartości (patrz „Wejście”)
lochok

Masz rację, nie zauważyłeś tego.
Strigoides,

2
Nie jest to duplikat jako taki, ale nie różni się bardzo od codegolf.stackexchange.com/questions/6487/…
Peter Taylor

Tyle sprytnych odpowiedzi!
Wybiorę

Odpowiedzi:


9

GolfScript (wynik 27-120 = -93)

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

Uwaga: $dotyczy elementu na stosie. Istnieje sortowanie, ale odbywa się to za pomocą ręcznie kodowanego sortowania bąbelkowego.

Dzięki Howard za -90 => -92; i Ilmari, który zainspirował -92 => -93.


Uznanie za tak zwięzłą odpowiedź, ale (wybaczcie, bo nie mówię ani nie rozumiem GolfScript) - czy ^ nie dyskwalifikuje go z premii -100?
lochok

1
@lochok, wbudowana funkcja sortowania jest $- dlatego wspomniałem, że $w programie nie ma sortowania (zależy od kontekstu). Większość programu (28 z 42 znaków) określa funkcję ^; pierwsza wersja, wykorzystująca wbudowane sortowanie, miała tylko 14 znaków.
Peter Taylor

Ahh - racja. Dziękuję za wyjaśnienie!
lochok

1
Można zapisać dwa znaki z poniższej pętli wyjściowej: 2/{~p}%n*.
Howard

1
2/zip~+n*a .);\+2%n*także wykonać lewę dla tej samej liczby znaków, co wersja @ Howarda. Niestety, nie udało mi się znaleźć czegoś krótszego.
Ilmari Karonen,

6

Python -26

(94–120): Nowe, surowe podejście. Przechowuj najniższe elementy na nowej liście, aby posortować elementy, a następnie iteruj:

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): Pierwsze podejście: Usuwa cztery najniższe elementy jednocześnie, a następnie drukuje te cztery w innej kolejności:

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=[]i exec't+=[input()];'*100uratowałbym ci kilka znaków
quasimodo

możesz także użyć jednej execinstrukcji dla więcej niż jednej pętli.
quasimodo

@ quasimodo Próbowałem czegoś takiego, ale t=l=[]zt i l wskazują na ten sam obiekt i to nie działa. Pomijanie nawiasów execjest jednak miłe.
daniero

Możesz użyć t=t+[input()];, za każdym razem tworzy to nowy obiekt. I można nawet zrobić pętlę drukowania w exec: ';i+=1;print l[i*3%100]'*100.
quasimodo

Znowu masz rację. Dzięki! Dodano także inne gry w golfa, takie jak usuwanie %3i unikanie powtarzania 100.
daniero

4

C: 11 (131–120)

Program odczytuje ze standardowego wejścia i wykonuje prosty rodzaj wstawiania, po czym drukuje n-ty razem z th n + 50-tą liczbą, jak wiele innych rozwiązań.

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

Edytuj :

Ta wersja nie opiera się ani na wbudowanych funkcjach sortowania list, ani na funkcjach losowych.

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

Czy Sortnie jest wbudowana funkcja sortowania?
Peter Taylor

Masz rację! Brakowało mi ograniczenia dotyczącego sortowania.
DavidC

Zrobiłem ręcznie walcowane sortowanie.
DavidC

3

J, -63 (57-120) znaków

Ponieważ wszyscy idą własną drogą sortowania ...

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

Nie używa funkcji liczb losowych ani żadnego wbudowanego sortowania.

Używa prostego sortowania rekurencyjnego do sortowania danych wejściowych.


3

Ruby 1.9, -59

(61-120)

Rekurencja! W rzeczywistości ten, w przeciwieństwie do moich poprzednich prób Ruby, nie sortuje listy bez względu na ich pierwotną kolejność.

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

Poprzednie próby

Śliczny jednowarstwowy, teraz wykorzystujący wbudowane sortowanie do poprawnego działania:

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

Pierwszy - niekoniecznie posortował ostatnie 4 wartości:

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

1
Twoje rozwiązanie -72 zakłada, że ​​lista zaczyna się posortowana, co nie jest prawdą.
histocrat

Ups Wydaje mi się, że nie ponownie dokładnie przeczytałem pytania, kiedy ponownie je odwiedziłem. Spróbuję wymyślić coś innego.
daniero

@histocrat, który powinien to zrobić.
daniero

1

Python 2: 90 znaków

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]

leniwa próba, ale tylko na początek


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

Nie przetestowałem tego, ponieważ nie jest gwarantowane (lub prawdopodobne), że będzie działać w rozsądnym czasie, ale powinno działać teoretycznie, biorąc pod uwagę nieskończony czas.


1
x=map(input,['']*100)
ugoren

I nie sądzę, że potrzebujesz nawet dodatkowych []liter, tylko jednego ciągu znaków.
praca

1

Python 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]

Uwaga: wcześniejsze spacje if L[i]>...powinny być tabulatorami, ale najwyraźniej powinny pojawiać się jako spacje w bloku kodu.


Dzięki niemu R=rangemożesz zapisać 5 znaków.
scleaver

a=map(input,['']*100)
ugoren

1

Perl 5: 95 - 120 = -25 znaków

Liczenie następującego wiersza poleceń:

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

1

Rubin: -50 (70 znaków - 120)

Zrobiłem to samo, co wiele innych odpowiedzi: iteracyjnie usuwam max i min z listy danych wejściowych i dołączam je do wyniku. Jednak zdałem sobie sprawę, że jeśli 2 liczby po obu stronach mediany same są kolejne, wynik będzie niepoprawny (ponieważ te 2 kolejne liczby pojawią się razem na końcu wyniku). Aby to naprawić, obracam listę „nieposortowane” o 1 element:

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

Lub, aby pracować z dowolnie wieloma wejściami (używając tylko 4 dodatkowych znaków):

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

Uwaga: Niektóre Ruby odpowiedzi o mniejszej liczbie znaków zostały już opublikowane, ale te rozwiązania nie rozwiązały problemu mediany (i / lub przyjęły posortowaną listę danych wejściowych).


1

J 37-100 = -63

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

Nie używa sortowania (chociaż używa rangi). Używa liczb losowych.

Wyjaśnienie:

({~?~@#)             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

Brachylog , 22 bajty - 120 = -98

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

Wypróbuj online!

Łącze TIO ma tylko osiem liczb całkowitych zamiast stu, ponieważ jest tak strasznie powolne, że nie jest w stanie obsłużyć więcej w 60 sekund. Powodem tego jest, między innymi, że zamiast wdrożyć prosty, ale normalny algorytm sortowania dla obowiązkowej premii, dla zwięzłości zastosowałem to, co stanowi deterministyczny bogosort: cofa się p≤₁przez każdą permutację danych wejściowych, aż znajdzie jedną który nie zmniejsza się. Chociaż większym powodem byłby prawdopodobnie fakt, że wykorzystuje on podobny stopień brutalnej siły do ​​znalezienia wyniku i że za każdym razem przelicza posortowaną wersję ... Próbowałem go przetestować na rzeczywistym wejściu o wielkości 100, ale jestem nie jestem pewien, ile dni to zajmie.

Ogólnie lepsza wersja:

Brachylog , 14 bajtów - 20 = -6

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

Wypróbuj online!

Ignoruje to przestarzałe wymagania wejścia / wyjścia dla zwięzłości i zaniedbuje wzięcie bonusu -100, aby można go było przetestować bez superkomputera (chociaż w chwili pisania tego tekstu działałem tylko na 20 elementach przez kilka minut i to wciąż nic mi nie dał).

 .                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.

Chociaż nie jest to do końca praktyczna odpowiedź, może być przydatna do sprawdzania poprawności danych wyjściowych z innych programów, ponieważ większość z nich opisuje jedynie ograniczenia nałożone na dane wyjściowe.
Niepowiązany ciąg

0

Dalej (gforth) , 79-120 = -21 bajtów

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

Wypróbuj online!

Zignoruj ​​przestarzałe wymagania dotyczące wprowadzania i pobiera dane jako adres w pamięci, w której przechowywane są liczby.

Wyjaśnienie

Pętle przechodzą przez wszystkie liczby od 0 do 99. Dla każdej liczby (n):

  • Jeśli n wynosi 0:
    • wypisz wartość pod adresem tablicy + 1
  • W przeciwnym razie, jeśli n wynosi 99:
    • wypisz wartość pod adresem tablicy + 98
  • W przeciwnym razie, jeśli n jest nieparzyste:
    • wyprowadza wartość na adres tablicy + (n + 2)
  • W przeciwnym razie (n jest parzyste):

    • wyprowadza wartość na adres tablicy + (n - 2)
  • Wyjście nowego wiersza

Objaśnienie kodu

: 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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.