Die seltsame Unsortiermaschine für ruchlose Zwecke

18

Guten Abend Golfer!

Ihre Herausforderung besteht darin, eine Reihe von Zahlen vollständig zu sortieren.

Eingang

Es werden genau 100 Ganzzahlen in Ihr Programm eingegeben. Ihr Programm akzeptiert die Eingabe entweder als Datei oder über stdin. Jede Ganzzahl wird durch ein Zeilenumbruchzeichen getrennt.

Diese 100 Ganzzahlen reichen von den minimalen bis zu den maximalen Werten einer vorzeichenbehafteten Ganzzahl in der von Ihnen gewählten Sprache.

Es gibt keine doppelten Werte. Die Werte können geordnet, ungeordnet oder teilweise geordnet sein - Ihr Programm sollte in der Lage sein, jeden Fall zu behandeln.

Ausgabe

Die Ausgabe muss jede der 100 Ganzzahlen sein, die vollständig unsortiert und jeweils durch ein Zeilenumbruchzeichen getrennt sind. Die Ausgabe kann über stdout oder in eine Datei erfolgen.

Völlig unsortiert bedeutet, dass keinem Wert ein Wert benachbart ist, zu dem er benachbart wäre, wenn die Liste vollständig in einer geordneten Reihenfolge sortiert wäre.

Ergebnis

1 Punkt pro Charakter und die niedrigste Punktzahl gewinnt. Es gibt einen Bonus von -100 für jede Lösung, die keine eingebauten oder Bibliotheks-Sortierfunktionen verwendet. Es gibt einen Bonus von -20 für alle Lösungen, die keine eingebauten Zufallszahlenfunktionen verwenden.

Ich habe versucht, diese Frage so vollständig wie möglich zu definieren. Wenn Sie Fragen haben, wenden Sie sich bitte. Wenn Sie Kommentare dazu haben, wie ich es beim nächsten Mal besser machen könnte, lassen Sie es mich bitte wissen.

Vordergrund!

Lochok
quelle
Es gibt genau 100 Ganzzahlen und es gibt keine doppelten Werte (siehe unter "Eingabe")
Lochok
Richtig, Sie haben das nicht bemerkt.
Strigoides
2
Es ist kein Duplikat, aber es unterscheidet sich nicht wesentlich
Peter Taylor
So viele kluge Antworten! Ich wähle die kürzeste Antwort am 31. Oktober um 8: 10-Zulu
lochok

Antworten:

9

GolfScript (Punktzahl 27 - 120 = -93)

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

Hinweis: Das $verweist auf ein Element auf dem Stapel. Es wird sortiert, aber mit einer manuell codierten Blasensortierung.

Dank Howard für -90 => -92; und Ilmari, der -92 => -93 inspirierte.

Peter Taylor
quelle
Wir danken für eine so präzise Antwort, aber (verzeihen Sie mir, da ich GolfScript nicht verstehe oder spreche) - würden Sie es nicht vom -100-Bonus ausschließen?
Lochok
1
@lochok, die eingebaute Sortierfunktion ist $- deshalb habe ich erwähnt, dass die $im Programm nicht sortieren (es ist kontextabhängig). Der größte Teil des Programms (28 der 42 Zeichen) definiert die Funktion ^; Die erste Version, die die eingebaute Sortierung verwendete, bestand nur aus 14 Zeichen.
Peter Taylor
Ahh - richtig. Danke für die Klarstellung!
Lochok
1
Sie können zwei Zeichen mit folgenden Ausgangsschleife sparen: 2/{~p}%n*.
Howard
1
2/zip~+n*und .);\+2%n*mache den Trick auch für die gleiche Anzahl von Zeichen wie @ Howards Version. Leider habe ich es noch nicht geschafft, etwas kürzer zu finden.
Ilmari Karonen
6

Python -26

(94-120): Neuer, roher Ansatz. Fügen Sie die niedrigsten Elemente in die neue Liste ein, um die Elemente zu sortieren, und wiederholen Sie sie dann:

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): Erster Ansatz: Entfernt vier niedrigste Elemente gleichzeitig und druckt diese vier in einer anderen Reihenfolge aus:

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
daniero
quelle
t=l=[]und exec't+=[input()];'*100würde Ihnen ein paar Zeichen sparen
Quasimodo
Sie können auch eine execAnweisung für mehr als eine Schleife verwenden.
Quasimodo
@quasimodo Ich habe so etwas versucht, aber mit t=l=[]t und l zeige ich auf dasselbe Objekt und es funktioniert nicht. Klammern überspringen execist aber schön.
Daniero
Sie können dies verwenden t=t+[input()];, um jedes Mal ein neues Objekt zu erstellen. Und Sie können sogar die Druckschleife in der exec - Anweisung tun: ';i+=1;print l[i*3%100]'*100.
Quasimodo
Du hast wieder recht. Vielen Dank! %3Fügte auch etwas anderes Golfspielen wie das Entfernen und das Vermeiden der Wiederholung von hinzu 100.
Daniero
4

C: 11 (131-120)

Das Programm liest von stdin und führt eine einfache Einfügesortierung durch. Anschließend wird, wie bei vielen anderen Lösungen, die n-te zusammen mit der n + 50-ten Zahl gedruckt.

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--);}
quasimodo
quelle
3

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

Bearbeiten :

Diese Version basiert weder auf integrierten Funktionen zum Sortieren von Listen noch auf Randomisierungsfunktionen.

Riffle[RotateLeft[#[[All, 2]], 2], #[[All, 1]]] &
[Partition[l //. {x___, a_, b_, y___} /; b < a :> {x, b, a, y}, 2]]
DavidC
quelle
Ist das Sortnicht eine eingebaute Sortierfunktion?
Peter Taylor
Du hast Recht! Ich habe die Einschränkung bezüglich der Sortierung verpasst.
DavidC
Ich habe eine handgerollte Sortierung gemacht.
DavidC
3

J, -63 (57-120) Zeichen

Da alle anderen den selbstgeschriebenen Weg gehen ...

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

Verwendet weder eine Zufallszahlenfunktion noch eine eingebaute Sortierung.

Verwendet eine einfache rekursive Auswahlsortierung, um die Eingabe zu sortieren.

Gareth
quelle
3

Rubin 1,9, -59

(61-120)

Rekursion! Im Gegensatz zu meinen vorherigen Ruby-Versuchen sortiert dieser die Liste tatsächlich ungeachtet ihrer ursprünglichen Reihenfolge.

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

Bisherige Versuche

Niedlicher Einzeiler, der jetzt die eingebaute Sortierung verwendet, um richtig zu funktionieren:

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

Erster - Die letzten 4 Werte mussten nicht unbedingt sortiert werden:

l=$<.map &:to_i
48.times{l-=p *l.minmax}
a,b,c,d=l
p b,d,a,c
daniero
quelle
1
Ihre -72-Lösung geht davon aus, dass die Liste sortiert beginnt, was nicht der Fall ist.
Histokrat
Hoppla. Anscheinend habe ich die Frage nicht gründlich durchgelesen, als ich sie noch einmal durchgesehen habe. Ich werde versuchen, mir etwas anderes auszudenken.
Daniero
@histocrat das sollte es tun.
Daniero
1

Python 2: 90 Zeichen

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]

fauler Versuch, aber nur für den Anfang

Meilen
quelle
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

Habe dies nicht getestet, weil es nicht garantiert (oder wahrscheinlich) in einer angemessenen Zeitspanne ausgeführt werden kann, aber theoretisch in einer unendlichen Zeit funktionieren sollte.

scleaver
quelle
1
x=map(input,['']*100)
Ugoren
Und ich glaube, Sie brauchen nicht einmal die zusätzlichen []Zeichen, sondern nur eine einzelne Zeichenfolge.
Job
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]

Hinweis: Die Leerzeichen davor if L[i]>...sollten ein Tabulator sein, werden jedoch anscheinend als Leerzeichen in einem Codeblock angezeigt.

Matt
quelle
Mit R=rangekönnten Sie 5 Zeichen speichern.
Scleaver
a=map(input,['']*100)
Ugoren
1

Perl 5: 95-120 = -25 Zeichen

Zählen Sie die folgende Befehlszeile:

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

Rubin: -50 (70 Zeichen - 120)

Ich habe das Gleiche getan wie bei vielen anderen Antworten: Entfernen Sie das Maximum und das Minimum iterativ aus der Eingabeliste und hängen Sie sie an die Ausgabe an. Ich habe jedoch festgestellt, dass die Ausgabe falsch ist, wenn die 2 Zahlen auf beiden Seiten des Medians aufeinander folgen (da diese 2 aufeinander folgenden Zahlen am Ende der Ausgabe zusammen angezeigt werden). Um dies zu beheben, drehe ich die "unsortierte" Liste um 1 Element:

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

Oder um mit beliebig vielen Eingaben zu arbeiten (mit nur 4 weiteren Zeichen):

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

Hinweis: Einige Ruby-Antworten mit weniger Zeichen wurden bereits veröffentlicht, aber diese Lösungen haben das Median-Problem nicht behoben (und / oder eine sortierte Eingabeliste angenommen).

Jonathan Hefner
quelle
1

J 37-100 = -63

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

Verwendet keine Sortierung (obwohl Rang aufsteigend verwendet wird). Verwendet Zufallszahlen.

Erläuterung:

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

Brachylog , 22 Bytes - 120 = -98

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

Probieren Sie es online!

Die TIO-Verbindung hat nur eine Eingabe von acht statt von einhundert Ganzzahlen, da diese so schrecklich langsam ist, dass sie in 60 Sekunden nicht mehr verarbeitet werden kann. Der Grund dafür ist unter anderem, dass ich der Kürze halber, anstatt einen einfachen, aber normalen Sortieralgorithmus für den obligatorischen Bonus zu implementieren, das verwendet habe, was einem deterministischen Bogosort gleichkommt: Durchläuft p≤₁jede Permutation der Eingabe, bis sie einen findet Das ist nicht abnehmend. Ein größerer Grund wäre wahrscheinlich, dass es einen ähnlichen Grad an Brute Force verwendet, um die Ausgabe zu finden, und dass es jedes Mal die sortierte Version neu berechnet ... Ich habe versucht, es an einer tatsächlichen Eingabe der Größe 100 zu testen, aber ich bin Ich bin mir nicht sicher, wie viele Tage es dauern wird.

Eine insgesamt bessere Version:

Brachylog , 14 Bytes - 20 = -6

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

Probieren Sie es online!

Dies ignoriert die veralteten E / A-Anforderungen für die Kürze und vernachlässigt es, den -100-Bonus einzunehmen, damit er möglicherweise ohne einen Supercomputer getestet werden kann (obwohl ich ihn zum Zeitpunkt des Schreibens für mehrere Minuten auf nur 20 Elementen laufen ließ und so weiter) hat mir noch nichts gegeben).

 .                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.
Nicht verwandte Zeichenfolge
quelle
Dies ist zwar keine praktische Antwort, kann jedoch zur Validierung der Ausgabe anderer Programme hilfreich sein, da das meiste lediglich die für die Ausgabe geltende Einschränkung beschreibt.
Unrelated String
0

Viertens (gviertens) , 79-120 = -21 Bytes

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

Probieren Sie es online!

Ignorieren Sie veraltete Eingabeanforderungen und nehmen Sie die Eingabe als Adresse in den Speicher, in dem die Zahlen gespeichert sind.

Erläuterung

Durchläuft alle Zahlen von 0 bis 99. Für jede Zahl (n):

  • Wenn n 0 ist:
    • Den Wert an der Array-Adresse + 1 ausgeben
  • Andernfalls, wenn n 99 ist:
    • Den Wert an der Array-Adresse + 98 ausgeben
  • Andernfalls, wenn n ungerade ist:
    • den Wert an der Array-Adresse + (n + 2) ausgeben
  • Sonst (n ist gerade):

    • den Wert an der Array-Adresse + (n - 2) ausgeben
  • Geben Sie eine neue Zeile aus

Code-Erklärung

: 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
reffu
quelle