So läuft das bei uns


18

Piet ist aus mehreren Gründen eine interessante Programmiersprache. Heute konzentrieren wir uns auf einen Grund: den Rollbefehl . Der Befehl roll stammt ursprünglich aus PostScript und bietet eine leistungsstarke Möglichkeit, den Stapel zu bearbeiten.

Der Befehl roll fügt die beiden obersten Elemente des Stapels ein und verwendet sie als Parameter. Wir werden den ersten turnsund den zweiten Wert als geknallt bezeichnen depth. Eine Drehung in die Tiefe n nimmt das oberste Element des Stapels auf, macht es zum n-ten Element im Stapel und verschiebt jedes der darüber liegenden Elemente um eins nach oben. Wenn turns negativ, erfolgt dies in umgekehrter Richtung. Das heißt, das n-te Element wird nach oben und die anderen Elemente nach unten verschoben. Dies wird mehrfach wiederholt abs(turns).

Herausforderung

Schreiben Sie ein Programm oder eine Funktion, die einen Stack aufnimmt und diesen Stack nach Ausführung eines Rolls zurückgibt.

Regeln

  • Die Ein- und Ausgabe kann in einer Liste, einem Array, einer Zeichenfolge mit Trennzeichen, jeweils in einem Element oder in einem anderen vernünftigen Format erfolgen. Die Ausgabe muss dasselbe Format wie die Eingabe haben.
  • depth wird niemals negativ sein und wird niemals größer als die Länge des Stapels.
  • Der Eingabestapel enthält immer mindestens zwei Elemente.
  • Das ist also gewinnt die kürzeste Antwort in jeder Sprache. Daher werde ich keine Antwort annehmen.
  • Standardlücken sind verboten.

Testfälle

in:  out:
2    
4    
1    3
2    4
3    1
4    2
5    5
6    6

in:  out:
-2   
3
1    2
2    3
3    1

in:  out:
-42
0
1    1
2    2
3    3
4    4
5    5

2
Die kürzeste Antwort in jeder Sprache gewinnt , so funktioniert [Code-Golf] nicht. Kürzeste Antwort gewinnt. Zeitraum.
mbomb007

4
@ mbomb007 ahem was ist damit
Christopher

7
Ich war sehr enttäuscht darüber, dass dies in keinster Weise mit Rick Rolling einherging
Christopher,

2
@ mbomb007 Ich sehe das nicht in der Tag-Beschreibung oder in einer Schnellsuche nach Meta, also glaube ich nicht, dass das der Fall ist.
Mike Bufardeci

2
@ mbomb007 Wenn Sie möchten, dass ich es ändere, geben Sie bitte immer wieder ein anderes Argument als "Sie liegen falsch und ich habe Recht" an. Dafür gibt es Präzedenzfälle, die Sie abgewiesen haben, und nirgendwo heißt es, dass Herausforderungen genau einen Gewinner erfordern oder dass eine Antwort akzeptiert werden muss.
Mike Bufardeci

Antworten:


8

Haskell , 64 62 Bytes

Edit: -2 bytes: @xnor hat etwas gesehen, woran ich falsch gedacht habe.

rnimmt und gibt eine Liste von Ints zurück.

r(t:d:l)|d<1=l|(x,y)<-d%l,(z,w)<-mod t d%x=w++z++y
(%)=splitAt

Probieren Sie es online!

splitAt n lTeilt eine Liste lam Index auf n, modberechnet den Rest der Division und ++verkettet Listen.


1
Ich denke, Sie können 2 Bytes schneiden, indem Sie (%)=splitAtInfix definieren .
xnor

@xnor Oh, ich hatte mich irgendwie davon überzeugt, dass das nicht funktionieren würde
Ørjan Johansen

8

JavaScript (ES6), 49 47 Bytes

(t,d,...a)=>a.splice(t=(t%d+d)%d,d-t).concat(a)

Bearbeiten: 2 Bytes dank @Shaggy gespeichert, indem die Stack-Elemente als separate Parameter verwendet werden. Erläuterung:

  • Wenn die Kurve ein Vielfaches der Tiefe ist, passiert nichts. Der erste Schritt besteht daher in der Berechnung der Turn-Modulo-Tiefe. Da JavaScript nur weiß, wie der Rest berechnet wird, muss ich dies in zwei Schritten tun.
  • Durch Drehen von wird 1das obere Element zum depthElement verschoben. Eine Drehung 2verschiebt die beiden oberen Elemente usw. Sie können dies jedoch auch erreichen, indem Sie die Elemente zwischen Drehung und Tiefe nach vorne verschieben.spliceconcatEntfernt diese Elemente und stellt sie den übrigen Elementen voran. (Ich hätte stattdessen ein Array-Verständnis verwenden können, da es dieselbe Länge hat.)
  • Im Gegensatz dazu sliceist der zweite Parameter splicedie Anzahl der zu entfernenden Elemente.

Ist das nicht (t%d+d)%ddasselbe wie t%d?
Luke

@ Luke Nein, %ist Rest, also gibt es eine negative Antwort, wenn tes negativ ist.
Neil

Sie können 2 Bytes einsparen, indem Sie (t,d,...a)=>festlegen, dass die Eingabe jeweils in einem Element übergeben wird.
Shaggy

@ Shaggy Danke, das hatte ich nicht bemerkt.
Neil

7

CJam, 31 Bytes

)\):N@\,0a|={NW*1$1$>)\+@@<\+}*

Eingabe und Ausgabe sind Arrays auf dem Stapel, wobei das letzte Element die Oberseite des Stapels darstellt.

Stack-Trace:

                   e# Stack:                [6 5 4 3 2 1 4 2]
)                  e# Take out first value: [6 5 4 3 2 1 4] 2
\                  e# Swap:                 2 [6 5 4 3 2 1 4]
)                  e# Take out first value: 2 [6 5 4 3 2 1] 4
:N                 e# Store in N:           2 [6 5 4 3 2 1] 4; N=4
@                  e# Rotate:               [6 5 4 3 2 1] 4 2
\                  e# Swap:                 [6 5 4 3 2 1] 2 4
,                  e# Range:                [6 5 4 3 2 1] 2 [0 1 2 3]
0                  e# Push 0:               [6 5 4 3 2 1] 2 [0 1 2 3] 0
a                  e# Wrap in array:        [6 5 4 3 2 1] 2 [0 1 2 3] [0]
|                  e# Logical or:           [6 5 4 3 2 1] 2 [0 1 2 3]
                   e# (This will replace an empty array with [0] to handle a special case of n=0)
=                  e# Get array value:      [6 5 4 3 2 1] 2
{NW*1$1$>)\+@@<\+} e# Push block:           [6 5 4 3 2 1] 2 {NW*1$1$>)\+@@<\+}
*                  e# Preform n times:      [6 5 4 3 2 1]
  N                e# Push N:               [6 5 4 3 2 1] 4
  W*               e# Negate:               [6 5 4 3 2 1] -4
  1$               e# Copy element 1 back:  [6 5 4 3 2 1] -4 [6 5 4 3 2 1]
  1$               e# Copy element 1 back:  [6 5 4 3 2 1] -4 [6 5 4 3 2 1] -4
  >                e# Slice a[-4:]          [6 5 4 3 2 1] -4 [4 3 2 1]
  )                e# Take first value:     [6 5 4 3 2 1] -4 [4 3 2] 1
  \                e# Swap:                 [6 5 4 3 2 1] -4 1 [4 3 2]
  +                e# Append:               [6 5 4 3 2 1] -4 [1 4 3 2]
  @@               e# Rotate twice:         [1 4 3 2] [6 5 4 3 2 1] -4
  <                e# Slice a[:-4]:         [1 4 3 2] [6 5]
  \                e# Swap:                 [6 5] [1 4 3 2]
  +                e# Append:               [6 5 1 4 3 2]
e# Preform the block again:                 [6 5 2 1 4 3]

6

Mathematica, 58 50 Bytes

Edit: Danke an Martin Ender für das Speichern von 8 Bytes.

Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&

Erläuterung:

Reine Funktion, die eine Liste erwartet, bei der der Listenanfang die Spitze des Stapels darstellt. Wir übergeben die Elemente der Liste in die reine Funktion Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&. xwird auf die Reihenfolge der Elemente gesetzt, die mit dem dritten Argument beginnt. Dann drehen wir das erste #2(zweite Argument) Element xnach links #(erstes Argument) und dann Joindie restlichen Elemente von x.

Es würde retten 3 Bytes wenn wir die Stack-Elemente nur als Argumente an die Funktion übergeben würden, anstatt sie zunächst in einer Liste zu haben, aber dann stimmen die Eingabe- und Ausgabeformate nicht überein.

Ursprüngliche Lösung:

#/.{t_,d_,x___}:>{x}~Take~d~RotateLeft~t~Join~Drop[{x},d]&

Diese Kette von Infix-Funktionen hat etwas wirklich Befriedigendes. Ersetzt eine Liste durch das erste Element t, das zweite Element dund die verbleibenden Elemente xmit dem Ergebnis, dass die ersten dElemente {x}nach links gedreht tund die verbleibenden Elemente nach links verbunden werden {x}.


1
Nett! Sie können 3 Bytes einsparen, indem Sie eine Ein-Byte- ±Präfixfunktion anstelle einer Ersetzungsregel verwenden, und ein weiteres Byte, indem Sie TakeDropFolgendes ausnutzen : ±{t_,d_,x___}:=#~RotateLeft~t~Join~#2&@@{x}~TakeDrop~d
Greg Martin,

Ich wollte nur das Gleiche wie Greg kommentieren, aber Sie können sogar noch kürzer gehen. Entweder eine unbenannte variadische Funktion machen (obwohl das ein wenig abgenutzt ist , weil es eine Eingabe nimmt ...&[1, 1, 3, 4]und zurück {3, 4}oder tut dies manuell mit einem Applyam Anfang: Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&(nur klar sein, mein erster Vorschlag läßt die @@#&).
Martin Ender

5

Ruby, 40 Bytes

x=->s{n,d,*s=s;s[0,d]=s[0,d].rotate n;s}

Probieren Sie es online!

Nimmt die Eingabe als Liste und gibt eine Liste zurück. Die Tatsache, dass ein eingebautes Modul rotatevorhanden ist, das sowohl positive als auch negative Drehungen verarbeiten kann, macht dies trivial.


5

Python, 141 98 87 74 Bytes

Dank @Cole 11 Bytes gespart

def f(s):*s,d,t=s;n=len(s)-d;return s*0**d or s[:n]+s[-t%d-d:]+s[n:-t%d-d]

Erhält Eingaben als Liste, wobei das letzte Element oben im Stapel steht.

Verwendet den 0ⁿ-Trick, um den Modulo-Operator für die Nulltiefe und die Vorzeichenanpassung von Python zu filtern, um den Teil der Liste zu bestimmen, der zerlegt werden soll.


Warum nicht einfach nehmen f(s,t,d)?
Cole

@Cole Danke für das Auspacken! Ich kann jedoch nicht sehen, was Sie damit gemeint haben f(s,t,d)(Eingabe ist der gesamte Stapel).
Uriel

Tolle Idee zum Auspacken, obwohl ich nicht der Meinung bin, dass Sie mir das zuschreiben sollten (ich schlug vor, nur die Variablen separat zu betrachten). Mit der Eingabespezifikation können Sie die Tiefe und die Umdrehungen als separate Variablen vom Stapel nehmen: "Eingabe und Ausgabe können in einer Liste, einem Array, einer Zeichenfolge mit einem Begrenzer, jeweils in einem Element oder in einem anderen vernünftigen Format erfolgen. Die Ausgabe muss dasselbe Format haben wie die Eingabe. "
Cole

Mit können Sie 1 Byte speichern r=-t%d-d. Auch das Ersetzen s*0**ddurch s*(d<1)behält die Byteanzahl bei, verbessert aber möglicherweise die Lesbarkeit (nicht, dass dies das Ziel ist). 0**0==1In Python wusste ich das allerdings nicht , das ist interessant.
Ben Frankel

@BenFrankel Ich kann nicht speichern -t%d-dals Wert (wie ich vorher), denn wenn dsie 0diese eine Division durch Null Ausnahme auslösen würde.
Uriel

3

JavaScript ES6, 109 92 Bytes

x=>{for(i=x.shift(),i=i>0?i:-i,j=x.shift();i-->0&&j>0;)x=x.splice(j,1).concat(x);return x}

Probieren Sie es online!

Erhält Eingaben in Form eines Arrays von Ganzzahlen.
Hat auch die Zählung zum Pfeil: P

Erläuterung:

Der Code verwendet die Shift-Funktion, um die ersten beiden Elemente der Liste zu extrahieren.

Sie erhält dann den absoluten Wert des ersten Elements, dh die Anzahl der Umdrehungen.

Da Javascript mit Null indexiert ist, muss der Tiefenindex um 1 verringert werden.

Wenn der Tiefenindex 0 oder 1 war, sollte sich nichts ändern, aber aufgrund der Abnahme würde der Index 0 Änderungen verursachen. Verlassen Sie daher die Schleife, wenn der Tiefenindex nicht <= 0 ist.

Die Splice-Funktion (a, b) gibt das Unterarray der Länge b mit dem Startindex a aus dem Array zurück und lässt das ursprüngliche Array ohne diese Elemente.

In Verbindung mit dem Rest des ursprünglichen Arrays handelt es sich um eine einzelne Drehung des Arrays um den Tiefenindex.

Durch n-maliges Durchführen dieser Operation, wobei n die Anzahl der Umdrehungen ist, ist das resultierende Array das Ergebnis des Rollenoperators.



2

TI-Basic, 141 150 Bytes (nicht konkurrierend)

Prompt L1
L1(1→T
L1(2→D
seq(L1(C),C,3,dim(L1→L1
If TD>0
Then
For(A,1,T
L1(1→B
For(C,2,D
L1(C→L1(C–1
End
B→L1(D
End
End
If TD<0
Then
For(A,1,-T
L1(D→B
For(C,D,2,-1
L1(C–1→L1(C
End
B→L1(1
End
End
L1

Edit: Fehler behoben, bei dem die Tiefe Null ist (+9 Bytes)

TI-Basic unterstützt keine Listen mit der Länge 0, daher funktioniert dieser Ansatz bei Eingaben mit zwei Längen nicht.

Erläuterung:

Prompt L1                # 4 bytes, input list
L1(1→T                   # 7 bytes, turns
L1(2→D                   # 7 bytes, depth
seq(L1(C),C,3,dim(L1→L1   # 18 bytes, remove turns and depth from list
If TD>0                  # 6 bytes, if turns is positive and depth is nonzero (can't be negative)
Then                     # 2 bytes
For(A,1,T                # 7 bytes, do this 'turns' times
L1(1→B                    # 7 bytes, backup the first item
For(C,2,D                # 7 bytes, shuffle the rest along
L1(C→L1(C–1               # 12 bytes
End                      # 2 bytes
B→L1(D                   # 7 bytes, restore the backup to where it should be
End                      # 2 bytes
End                      # 2 bytes
If TD<0                  # 6 bytes, if T is negative and D is nonzero
Then                     # 2 bytes
For(A,1,-T               # 8 bytes, do this -'turns' times
L1(D→B                   # 7 bytes, backup the Dth item
For(C,D,2,-1             # 10 bytes, shuffle the items the other way
L1(C–1→L1(C              # 12 bytes
End                      # 2 bytes
B→L1(1                   # 7 bytes, restore backup to where it belongs
End                      # 2 bytes
End                      # 2 bytes
L1                       # 2 bytes, implicitly return

Ich denke, Sie brauchen Code, um mit dem 2-Element-Listenfall umzugehen. derzeit wird es am fehler seq(.
Lirtosiast

1

Batch, 163 Bytes

@set s=
@set r=
@set/ad=%2,t=(%1%%d+d)%%d
:l
@shift
@set/af=t-=1,f^^=d-=1
@if %f% lss 0 (set r=%r% %2)else set s=%s% %2
@if not "%3"=="" goto l
@echo%r%%s%

Übernimmt Eingaben als Befehlszeilenparameter und gibt eine durch Leerzeichen getrennte Liste aus. Die Parameter zwischen tund dwerden in die rVariable extrahiert , sodass sie der sVariablen vorangestellt werden können, die alle anderen Parameter empfängt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.