Rosencrantz et Guildenstern sont Code

10

Dans la pièce absurde Rosencrantz et Guildenstern are Dead , les deux personnages principaux Rosencrantz et Guildenstern (ou sont-ils?) Mélangent toujours lequel d'entre eux est qui - ou parfois lequel de leurs propres parties du corps est lequel - en raison d'un manque perçu de identité individuelle. Ne serait-il pas absurde qu'ils remuent même leurs noms?

Votre tâche consiste à écrire une fonction qui prend une chaîne de longueur paire (et par conception, un multiple de 4) supérieure à 7 caractères, la diviser et la mélanger.

Le fractionnement doit être le suivant : la chaîne sera de format "abscd", avec s agissant comme un caractère séparateur. La première section et le séparateur absseront la première moitié de la chaîne, tandis que la seconde moitié seracd

La durée de asera(string length / 4) - 1

La durée de bsera(string length / 4)

La durée de ssera1

La durée de csera(string length / 4) + 1

La durée de dsera(string length / 4) - 1

Cela peut être très déroutant, alors laissez-moi vous montrer quelques exemples

("a" + "bb" + "s" + "ccc" + "d").length //8
  1     2      1      3      1
|-------4--------|  |----4-----| <--- (4 is half of 8)

("rosen" + "crantz" + "&" + "guilden" + "stern").length  //24
    5         6        1        7          5

("foo" + "barr" + "?" + "barry" + "foo").length
   3       4       1      5         3

Finalement:

Vous mélangez ensuite les pièces autour, en sortant adscb

ex. "rosencrantz&guildenstern" --> "rosenstern&guildencrantz"

"foobarr?barryfoo" --> "foofoo?barrybarr"

Rulez:

  1. Les échappatoires standard sont interdites
  2. Réponses acceptables: une fonction qui prend une entrée via une chaîne d'entrée et renvoie une chaîne de sortie
  3. Si la chaîne d'entrée ne correspond pas aux exigences fournies ci-dessus, votre code DOIT faire une erreur (peu importe le type de Exceptionou Error)
  4. C'est code-golf, donc la réponse la plus courte (valide) (dans chaque langue) gagne!
  5. Points bonus pour un one-liner :-) (Pas vraiment, mais des points sympas)
Michael
la source
6
Concernant votre gangsta rulez: Il est généralement déconseillé de privilégier les "fonctions" , car elles sont difficiles à définir en général. En outre, la gestion des entrées non valides est également évitée, car elle se résume généralement à un code de plaque de chaudière ennuyeux.
Jonathan Frech
@JonathanFrech Je pense que le défi de la validation des entrées est un problème intéressant, car il peut être géré de différentes manières, de la traversée du tableau à la logique de branchement en passant par les tests RegEx, donc l'optimisation de ceux-ci peut ajouter un défi supplémentaire ¯_ (ツ) _ / ¯ Je vais essayer ça pour un autre défi de golf de code :-)
Michael
2
tfw tout le monde essaie d'obtenir des méthodes io plus flexibles pour créer le code dans leur langue de golf préférée. et tfw cela se produit sur presque toutes les questions
Windmill Cookies
1
@NathanMerrill Il est mentionné dans la spécification que l'entrée doit être supérieure à 7 caractères et que sa longueur doit être divisible par quatre, Jo King proposait une entrée de
scénario de

Réponses:

11

K (oK) , 35 34 33 octets

{$[8>#x;.;<x!4!-&4#-1 0 2+-4!#x]}

Essayez-le en ligne!

Sans validation d'entrée (pour la prime de ngn), 25 24 23 octets

{<x!4!-&4#-1 0 2+-4!#x}

Essayez-le en ligne!

J'ai rapidement appris un peu de K et, en regardant la liste des verbes, j'ai pensé qu'une approche alternative ( sans utiliser cut) pourrait fonctionner ici. Et cela a parfaitement fonctionné.

Comment ça fonctionne

{<x!4!-&4#-1 0 2+-4!#x}
                 -4!#x    Length divided by four (floor division)
        4#-1 0 2+         Generate lengths (x/4-1, x/4, x/4+2, x/4-1)
       &                  Generate that many 0, 1, 2, 3's
    4!-                   Negate and modulo 4; effectively swap 1 and 3
 <x!                      Sort the original string by above

{$[8>#x;.; <code> ]}  Input validation
 $[8>#x           ]   If the length is less than 8
        .             Dynamically generate an error
           <code>     Otherwise, run the main code
Bubbler
la source
@ngn Qu'est-il arrivé à mes yeux Oo
Bubbler
3

Perl 6 , 60 58 octets

-2 octets grâce à Jo King

{[~] .rotor($_/4 X-1,0,+^-$_+>2,-1,1)[0,4,2,3,1;*]}o*.comb

Essayez-le en ligne!

Lance "Rotorizing sublist length is out of range" en cas d'erreur.

Explication

{               # Anonymous block
 [~]            # Join
   .rotor(      # Split into sublists of specific length
     $_/4 X-    # Subtract from len/4
     1,
     0,
     +^-$_+>2,  # (len-1)>>2
                #   subtraction yields 1 if len is multiple of 4
                #   otherwise a value less than 1 causing an error
     -1,       
     1)
   [0,4,2,3,1;*]  # Rearrange sublists and take inner elements
}o*.comb          # Split into characters and feed into block
nwellnhof
la source
3

J , 36 35 octets

5;@A.](<;.2~;)1<@{."+~1 0 _2 1-4%~#

Essayez-le en ligne!

-1 octet par {.+ longueurs négatives et ;.2qui les coupe comme marqueurs de "fin" à la place.

Réponse originale, 36 octets

5;@A.](<;.1~;)1<@{."+~_1 0 2 _1+4%~#

Essayez-le en ligne!

ngn a mentionné "couper" dans un commentaire à une réponse précédente de K , et cela m'a fait essayer J qui a le même "coupé" (je n'ai aucune idée de la façon dont K fonctionne).

Comment ça fonctionne

5;@A.](<;.1~;)1<@{."+~_1 0 2 _1+4%~#  Monadic train.
                                4%~#  Length divided by four
                      _1 0 2 _1+      Generate the four segment lengths
              1<@{."+~  Generate [1 0 0...] boxed arrays of those lengths
      (     ;)          Raze; unbox and concatenate
     ] <;.1~            Cut the input string on ones as starting marker, then box each
5  A.  Rearrange the boxes in the order 0 3 2 1
 ;@    Raze again

Notez que cette fonction gère automatiquement les entrées non valides:

  • Si la longueur en entrée n'est pas un multiple de quatre, {.lance domain errorpuisque son argument de longueur doit être des entiers.
  • Si la longueur d'entrée est 4, la coupe ne produit que deux segments et 5 A.lance index error.
  • Si la longueur d'entrée est 0, les deux arguments à couper n'ont pas la même longueur, donc length errorest levé.
Bubbler
la source
3

Python 3 , 103 102 101 97 88 86 84 octets

def f(s):l=len(s);l//=4*(l%4<1<l/4);return s[:l-1]+s[1-l:]+s[2*l-1:1-l]+s[l-1:2*l-1]

Essayez-le en ligne!

Pas vraiment une ligne, mais ;c'est un octet de moins par ligne que le saut de ligne et le retrait.

Lance ZeroDivisionErrorsi la longueur de la chaîne d'entrée est inférieure à 8 ou non un multiple entier de 4.

Fonctionne également en Python 2.

-4 octets grâce à Jo King

-9 octets grâce aux ovs

-2 octets grâce à Jonathan Frech

-2 octets grâce à Bubbler

Axim
la source
@JoKing merci pour les conseils, très appréciés :)
Axim
1
88 octets
ovs
@ovs belle prise sur les index adjacents, comme pour les parens, j'ai essayé pendant au moins 20 minutes pour voir si je pouvais me débarrasser de certains d'entre eux, puis j'ai complètement raté cela avec le changement de //=la paire la plus externe devenue redondante. Merci beaucoup!
Axim
2
-l+1<-> 1-l?
Jonathan Frech
1
Fusionnez les deux inégalités pour atteindre 84 octets .
Bubbler
2

Perl 6 , 78 octets

*.comb[0..*/4-2,3* */4+1..*,*/2-1/(*>7)..3* */4,*/4-1/(*%%4)..*/2-2].flat.join

Essayez-le en ligne!

Bloc de code anonyme qui prend une chaîne et renvoie la chaîne modifiée si elle est valide, sinon renvoie une division par zéro erreur. Je sais que je peux modifier un tableau directement, donc je pourrais échanger les deux sections de la chaîne, mais je ne peux pas vraiment le comprendre.

Jo King
la source
2

K (NGN / k) , 120 113 103 99 95 octets

{$[(r>7)&0=4!r:#:x;{g:(s:*|(y*2)#x)\x;((y-1)#*g),((-y-1)#*|g),s,((y+1)#*|g),(-y)#*g}[x;r%4];l]}

Avec un peu de chance, il est possible de jouer plus bas, inclus une fonction supplémentaire pour tester si la longueur de la chaîne est divisible par quatre, génère une erreur en référence à une variable non déclarée si l'entrée n'est pas valide

EDIT: état manquant sur une longueur supérieure à 7, inclus

EDIT: combiné en une fonction, suppression des déclarations de variables redondantes

Essayez-le en ligne!

Thaufeki
la source
1
cela pourrait être beaucoup plus court. connaissez-vous "cut" ( indices_string)? me cingler dans le verger si je devais l'expliquer
ngn
1
je peux le faire en 34 octets :)
ngn
Je connais la coupe, mais je n'ai pas pensé à l'utiliser ... 34 octets?! Je vais devoir
essayer à
je dois mentionner: ma solution ne s'assure pas que les entrées invalides (longueur <= 7) provoquent une erreur
ngn
1

Retina 0.8.2 , 58 ou 73 ou 83 ou 93 octets

((((.)))*?)(.(?<-2>.)+)(...(?<-3>.)+)((?<-4>.)+)$
$1$7$6$5

Essayez-le en ligne! Explication:

((((.)))*?)

Capture adans $1, et de le rendre aussi courte que possible *?. $#2, $#3et $#4finir comme la longueur de a.

(.(?<-2>.)+)

Capturer bdans $4. Le (?<-2>.)+capture jusqu'à la longueur de a, tandis que l'autre .ajoute 1 à sa longueur selon les besoins.

(...(?<-3>.)+)

Capturez set cdans $6. Leur longueur combinée est trois de plus que la longueur de a.

((?<-4>.)+)

Capturer ddans $7. Sa longueur ne dépasse pas la longueur de a.

$

Nous avons fait le aplus court possible, mais nous voulons toujours atteindre la fin de l'entrée.

$1$7$6$5

Échange bet d.

L'étape ci-dessus ne valide pas son entrée. Comme Retina ne présente aucune erreur d'exécution, il existe un certain nombre d'options pour la validation des entrées:

G`^(....){2,}$

N'affiche rien si la longueur est inférieure à 8 ou non un multiple de 4. (+15 octets)

^(?!(....){2,}$).*
Error

Sorties Errorsi la longueur est inférieure à 8 ou non multiple de 4. (+25 octets)

+`^(....)*..?.?$|^(....)?$
.....$1

Se bloque si la longueur est inférieure à 8 ou non un multiple de 4. (+35 octets)

Neil
la source
Cela ne jette pas d'erreur sur les entrées invalides (aussi ennuyeux que cela soit)
Jo King
1

C (gcc) avec -Dx=memcpyet -DL=(l-1), 154 158 160 octets

Renvoie NULL si la longueur de la chaîne d'entrée n'est pas divisible par 4 ou inférieure à 8 caractères.

Merci à Rogem et Jonathan Frech pour les suggestions.

EDIT: le préprocesseur déplacé définit la ligne de commande et a fait l'allocation dynamique de la chaîne pour se conformer strictement au puzzle.

f(s,t,l)char*s,*t;{l=strlen(s);l%4|l<8?t=0:(t=malloc(l+1),l/=4,x(t,s,L),x(t+L,s+3*l+1,L),x(t+2*L,s+L+l,l+2),x(t+3*l,s+L,l),t[4*l]=0);l=t;}//-Dx=memcpy -DL=(l-1)

Essayez-le en ligne!

ErikF
la source
Pourquoi t[80]? Il ne semble pas y avoir de limite supérieure concernant la longueur d'entrée.
Jonathan Frech
@JonathanFrech Je l'ai fait pour économiser des octets mais vous avez raison. J'ai changé la solution à utiliser à la malloc()place.
ErikF
Renvoie par modification, la valeur de retour est NULLpour une sortie non valide, utilise les valeurs de retour de memcpy(), une macro de type fonction pour ignorer les types et les tableaux de longueur variable C99 à ignorer malloc().
Pourquoi 160 octets, comptez-vous le //ou le -w?
l4m2
@ l4m2 -west juste une commodité pour supprimer les avertissements (donc les erreurs sont plus faciles à trouver). J'ajoute généralement des arguments de ligne de commande après a //pour que TIO compte leurs octets pour moi, puis je déduis 1 du total pour tenir compte du caractère supplémentaire nécessaire pour le faire.
1

Gelée , 28 octets

L7»4ḍİ×L:4;;ĖÄƲFÄœṖ⁸⁽%[D¤ị$F

(Si un programme complet est autorisé, nous pouvons supprimer la fin F)
Si la longueur est inférieure à 8 ou non divisible par quatre, un ValueErrorest augmenté pendant la division entière de inf(un flottant) par 4- la division donne NaN(également un flottant) qui ne peut alors pas être jeté à un int.

Essayez-le en ligne!

Comment?

L7»4ḍİ×L:4;;ĖÄƲFÄœṖ⁸⁽%[D¤ị$F - Link: list of characters
L                            - length
 7                           - literal seven
  »                          - maximum (of length & 7)
   4ḍ                        - divisible by four? (yields 1 for good inputs; 0 otherwise)
     İ                       - inverse (1 yields 1; 0 yields inf)
      ×L                     - multiply by length (length or inf)
        :4                   - integer divide by 4 (errors given inf)
              Ʋ              - last four links as a monad (f(x)):
          ;                  -   concatenate -> [x,x]
            Ė                -   enumerate -> [1,x]
           ;                 -   concatenate -> [x,x,[1,x]]
             Ä               -   cumulative sum (vectorises at depth 1) -> [x,x,[1,1+x]]
               F             - flatten -> [x,x,1,1+x]
                Ä            - cumulative sum -> [x,2x,2x+1,3x+2]
                   ⁸         - chain's left argument (the input)
                 œṖ          - partition at indices (chops up as per requirements)
                          $  - last two links as a monad (f(z)):
                        ¤    -   nilad followed by link(s) as a nilad:
                    ⁽%[      -     10342
                       D     -     decimal digits -> [1,0,3,4,2]
                         ị   -   index into z (rearranges the pieces as per requirements)
                           F - flatten (back to a list of characters)
Jonathan Allan
la source
1

Gelée , 25 octets

L:4’+“¡¢¢£¡‘Ṡ3¦ÄṬk⁸Ṛ2,5¦Ẏ

Essayez-le en ligne!

Le peut être supprimé pour en faire un programme complet.

Erik le Outgolfer
la source
1

JavaScript (ES6), 97 89 octets

8 octets enregistrés grâce à @ l4m2

s=>(l=s.length/4)<2||l%1?Z:s.replace(eval(`/(.{${l}})(.{${l+2}})(.{${l-1}})$/`),'$3$2$1')

Essayez-le en ligne!

Arnauld
la source
1
89B
l4m2
0

Java 8, 135 octets

s->{int l=s.length();l=l>7&l%4<1?l/4:l/0;return s.substring(0,l-1)+s.substring(3*l+1)+s.substring(2*l-1,3*l+1)+s.substring(l-1,2*l-1);}

Lance ArithmeticException(divise par zéro) si la chaîne d'entrée ne correspond pas aux exigences. Essayez-le en ligne ici .

Non golfé:

s -> { // lambda function taking a String argument and returning a String
    int l = s.length(); // take the length of the input ...
    l = l > 7 &         // ... if it's  greater than 7 and ...
        l % 4 < 1       // ... a multiple of 4 ...
      ? l / 4           // ... divide by 4; otherwise ...
      : l / 0;          // ... error out (division by zero throws ArithmeticException)
    return // concatenate and return:
           s.substring(0, l - 1)             // a
         + s.substring(3 * l + 1)            // d
         + s.substring(2 * l - 1, 3 * l + 1) // sc
         + s.substring(l - 1, 2 * l - 1);    // b
}
OOBalance
la source
Suggérer à la l/=l>7&l%4<1?4:0;place del=l>7&l%4<1?l/4:l/0;
plafondcat
0

C (gcc) , 129 octets

Renvoie par modification. Compiler avec:

-Df(s)=({char t[l=strlen(s)];l%4|l<8?0:(l/=4,x(t,s+l*2-1,l-~l),x(x(x(s+l*3,s+l-1,l)-l-2,t,l+2)-l+1,t+l+2,l-1),s);}) -Dx=memcpy

Fichier source:

l;

Essayez-le en ligne!

Degolf

-Df(s)=({ // Function-like macro f. Takes a char* as a parameter.
          // Return value is a pointer to s if successful, and to NULL if string was invalid.
     char t[l=strlen(s)]; // Allocate a local temp string.
     l%4|l<8?0: // Detect invalid strings. Return 0 (NULL) on invalid string.
         (l/=4, // We're only really concerned with floor(len/4), and this will yield that.
             memcpy(t,s+l*2-1,l-~l), // Copy the second half of chars to the temp storage.
             memcpy( // Because memcpy returns the address of the destination, we can chain
                     // the calls to save quite a few bytes, even after x->memcpy substitution.
                 memcpy(memcpy(s+l*3,s+l-1,l) // Next, copy the second quarter to the end.
                     -l-2,t,l+2) // After that, we copy back the third quarter to its place.
                          -l+1,t+l+2,l-1) // Finally, copy the fourth quarter to where the second
                                          // quarter was.
                      ,s);}) // And return the pointer.

la source