Voilà comment nous roulons

18

Piet est un langage de programmation intéressant pour plusieurs raisons. Aujourd'hui, nous allons nous concentrer sur une raison: la commande roll . La commande roll était à l'origine de PostScript et est un moyen puissant pour manipuler la pile.

La commande roll fait apparaître les deux premiers éléments de la pile et les utilise comme paramètres. Nous appellerons la première valeur sautée turnset la seconde depth. Un virage à la profondeur n prendra l'élément le plus haut de la pile, en fera le nième élément de la pile, et déplacera chacun des éléments au-dessus de celui-ci. Si turns est négatif, cela se fait dans la direction opposée. Autrement dit, le nième élément est déplacé vers le haut et les autres éléments sont déplacés vers le bas. C'est répété plusieurs abs(turns)fois.

Défi

Écrivez un programme ou une fonction qui prend une pile et retourne cette pile après avoir exécuté un rouleau.

Règles

  • L'entrée et la sortie peuvent être dans une liste, un tableau, une chaîne avec un délimiteur, passées dans un élément à la fois, ou tout autre format raisonnable. La sortie doit être au même format que l'entrée.
  • depth ne sera jamais négatif et ne sera jamais supérieur à la longueur de la pile.
  • La pile d'entrée contiendra toujours au moins deux éléments.
  • Il s'agit de donc la réponse la plus courte dans chaque langue l'emporte. En tant que tel, je n'accepterai pas de réponse.
  • Les failles standard sont interdites.

Cas de test

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
Mike Bufardeci
la source
2
la réponse la plus courte dans chaque langue gagne , ce n'est pas ainsi que fonctionne [code-golf]. La réponse la plus courte l'emporte. Période.
mbomb007
4
@ mbomb007 ahem qu'en est-il
Christopher
7
J'ai été très déçu que cela n'implique aucunement un roulement de rick
Christopher
2
@ mbomb007 Je ne vois pas cela dans la description du tag ou dans une recherche rapide sur les méta donc je ne pense pas que ce soit le cas.
Mike Bufardeci
2
@ mbomb007 Si vous souhaitez que je le modifie, veuillez fournir une sorte d'argument autre que de dire "vous avez tort et j'ai raison" encore et encore. Il y a un précédent à cela, que vous avez rejeté, et nulle part cela ne dit que les défis nécessitent exactement un gagnant ou qu'une réponse doit être acceptée.
Mike Bufardeci

Réponses:

8

Haskell , 64 62 octets

Edit: -2 octets: @xnor a vu quelque chose que je pensais mal.

rprend et retourne une liste de Ints.

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

Essayez-le en ligne!

splitAt n ldivise une liste là l'index n, modcalcule le reste de la division, ++concatène les listes.

Ørjan Johansen
la source
1
Je pense que vous pouvez couper 2 octets en définissant (%)=splitAtinfix.
2017
@xnor Oh, je m'étais en quelque sorte convaincu que ça ne marcherait pas
Ørjan Johansen
8

JavaScript (ES6), 49 47 octets

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

Edit: sauvé 2 octets grâce à @Shaggy en prenant les éléments de la pile comme paramètres séparés. Explication:

  • Lorsque le virage est un multiple de la profondeur, rien ne se passe. La première étape consiste donc à calculer la profondeur du virage modulo. Comme JavaScript ne sait que calculer le reste, je dois le faire en deux étapes.
  • Un tour de 1déplace l'élément supérieur vers l' depthélément. Une rotation de 2déplace les deux éléments supérieurs, etc. Cependant, vous pouvez également y parvenir en déplaçant les éléments entre la rotation et la profondeur vers l'avant. splicesupprime ces éléments et les concatajoute aux éléments restants. (J'aurais pu utiliser une compréhension de tableau à la place car c'est la même longueur.)
  • Contrairement sliceau deuxième paramètre, splicec'est le nombre d'éléments à supprimer.
Neil
la source
N'est-ce pas (t%d+d)%dla même chose que t%d?
Luke
@Luke Non, %est un reste, donc il donne une réponse négative quand il test négatif.
Neil
Vous pouvez économiser 2 octets en utilisant (t,d,...a)=>car les règles permettent à l'entrée d'être passée dans un élément à la fois.
Shaggy
@Shaggy Merci, je ne l'avais pas remarqué.
Neil
7

CJam, 31 octets

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

L'entrée et la sortie sont des tableaux sur la pile, le dernier élément représentant le haut de la pile.

Trace de la pile:

                   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]
Esolanging Fruit
la source
6

Mathematica, 58 50 octets

Edit: Merci à Martin Ender pour avoir économisé 8 octets.

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

Explication:

Fonction pure qui attend une liste où le début de la liste représente le haut de la pile. Nous passons les éléments de la liste dans la fonction pure Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&. xest défini sur la séquence d'éléments commençant par le troisième argument., puis nous faisons pivoter les premiers #2(deuxième argument) éléments de xvers la gauche #(premier argument) fois, puis Joinles éléments restants de x.

Cela économiserait des 3octets si nous venions de passer directement les éléments de la pile en tant qu'arguments à la fonction plutôt que d'être initialement dans une liste, mais les formats d'entrée et de sortie ne correspondraient pas.

Solution originale:

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

Il y a quelque chose de vraiment satisfaisant dans cette chaîne de fonctions d'infixe. Remplace une liste par le premier élément t, le deuxième élément det les éléments restants xavec pour résultat de faire tourner les premiers déléments de {x}vers la gauche tet de joindre les éléments restants de {x}.

ngenisis
la source
1
Agréable! Vous pouvez économiser 3 octets en utilisant une fonction de préfixe d'un octet ±insérée dans une règle de remplacement, et un autre 1 octet en exploitant TakeDropcomme suit: ±{t_,d_,x___}:=#~RotateLeft~t~Join~#2&@@{x}~TakeDrop~d
Greg Martin
J'allais juste commenter la même chose que Greg, mais vous pouvez en fait aller encore plus court. Soit créer une fonction variadic sans nom (bien que ce soit un peu douteux car cela prend des entrées ...&[1, 1, 3, 4]et des retours {3, 4}ou faites-le manuellement avec un Applyau début: Take[x={##3},#2]~RotateLeft~#~Join~Drop[x,#2]&@@#&(juste pour être clair, ma première suggestion omet le @@#&.))
Martin Ender
5

Rubis, 40 octets

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

Essayez-le en ligne!

Prend l'entrée comme une liste, renvoie une liste. Le fait qu'il rotateexiste un système intégré capable de gérer à la fois les rotations positives et négatives rend cela trivial.

Ventero
la source
5

Python, 141 98 87 74 octets

11 octets économisés grâce à @Cole

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]

Reçoit l'entrée sous forme de liste, où le dernier élément est le haut de la pile.

Utilise l'astuce 0ⁿ pour filtrer la profondeur nulle et l'opérateur modulo d'ajustement de signe de python pour déterminer la partie de la liste à couper.

Uriel
la source
Pourquoi ne pas simplement prendre f(s,t,d)?
cole
@Cole Merci pour le déballage! Cependant, je ne vois pas ce que vous vouliez dire f(s,t,d)(l'entrée est la pile entière).
Uriel
idée géniale pour le déballage, bien que je ne pense pas que vous devriez me croire pour cela (je proposais juste de prendre les variables séparément). La spécification d'entrée semble vous laisser prendre la profondeur et les virages comme des variables distinctes de la pile: "L'entrée et la sortie peuvent être dans une liste, un tableau, une chaîne avec un délimiteur, passées dans un élément à la fois, ou tout autre format raisonnable. La sortie doit être au même format que l'entrée. "
cole
Vous pouvez enregistrer 1 octet avec r=-t%d-d. En outre, le remplacement s*0**dpar s*(d<1)maintient le nombre d'octets, mais améliore peut-être la lisibilité (ce n'est pas l'objectif). Je ne savais pas cela 0**0==1en Python cependant, c'est intéressant.
Ben Frankel
@BenFrankel Je ne peux pas enregistrer en -t%d-dtant que valeur (comme je l'ai fait auparavant), car lorsqued est 0cela déclencherait une exception division par zéro.
Uriel
3

JavaScript ES6, 109 92 octets

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}

Essayez-le en ligne!

Reçoit une entrée sous la forme d'un tableau d'entiers.
A également le nombre de flèches: P

Explication:

Le code utilise la fonction shift pour extraire les deux premiers éléments de la liste.

Il obtient alors la valeur absolue du premier élément, qui est le nombre de tours.

Étant donné que Javascript est indexé zéro, l'indice de profondeur doit être diminué de 1.

Si l'indice de profondeur était 0 ou 1, rien ne devrait changer, mais en raison de la diminution, l'indice de 0 entraînerait des changements. Quittez donc la boucle si l'indice de profondeur n'est pas <= 0.

La fonction splice (a, b) renvoie le sous-tableau de longueur b avec l'index de départ a du tableau et laisse le tableau d'origine sans ces éléments.

Lorsqu'il est concaténé avec le reste du tableau d'origine, il s'agit d'une seule rotation du tableau à l'indice de profondeur.

En effectuant cette opération n fois, où n est le nombre de tours, la matrice résultante est le résultat de l'opérateur de roulis.

fəˈnɛtɪk
la source
2

TI-Basic, 141 150 octets (sans concurrence)

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: cas fixe où la profondeur est nulle (+9 octets)

TI-Basic ne prend pas en charge les listes de longueur 0, donc cette approche ne fonctionnera pas pour une entrée à deux longueurs.

Explication:

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
pizzapants184
la source
Je pense que vous avez également besoin de code pour gérer le cas de liste à 2 éléments; actuellement, il produira une erreur au niveau de seq(.
lirtosiast
1

Lot, 163 octets

@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%

Prend l'entrée en tant que paramètres de ligne de commande et génère une liste séparée par des espaces. Les paramètres entre tet dsont extraits dans la rvariable afin de pouvoir être ajoutés à la svariable, qui reçoit tous les autres paramètres.

Neil
la source