Rosencrantz e Guildenstern são Code

10

Na peça absurda Rosencrantz e Guildenstern estão mortos , os dois personagens principais Rosencrantz e Guildenstern (ou estão?) Estão sempre misturando qual deles é quem - ou, às vezes, qual parte do corpo é quem - por causa de uma falta percebida de identidade individual. Não seria absurdo se eles trocassem seus nomes?

Sua tarefa é escrever uma função que tenha uma sequência de tamanho uniforme (e por design, um múltiplo de 4) com mais de 7 caracteres, divida-a e embaralhe-a.

A divisão deve ser a seguinte : a sequência terá o formato "abscd", com s atuando como um caractere separador. A primeira seção e o separador absserão a primeira metade da corda, enquanto a segunda metade serácd

O comprimento de aserá(string length / 4) - 1

O comprimento de bserá(string length / 4)

O comprimento de sserá1

O comprimento de cserá(string length / 4) + 1

O comprimento de dserá(string length / 4) - 1

Isso pode ser realmente confuso, então deixe-me mostrar alguns exemplos

("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

Finalmente:

Em seguida, você embaralha as peças, produzindo adscb

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

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

Rulez:

  1. As brechas padrão são proibidas
  2. Respostas aceitáveis: uma função que recebe a entrada através de uma sequência de entrada e retorna uma sequência de saída
  3. Se a string de entrada não corresponder aos requisitos fornecidos acima, seu código DEVE errar (não importa que tipo Exceptionou Error)
  4. Esta é code-golf, portanto, o mais curto de resposta (válido) (em cada língua) ganha!
  5. Pontos de bônus para uma fila :-) (Na verdade não, mas apenas pontos interessantes)
Michael
fonte
6
Em relação ao seu gangsta rulez: Geralmente é desencorajado a favor de "funções" , pois são difíceis de definir em geral. Além disso, o manuseio de entrada inválida também é evitado, pois geralmente se resume a um código irritante de placa de caldeira.
Jonathan Frech
@ JonathanFrech Acho que o desafio da validação de entrada é um problema interessante, pois pode ser tratado de várias maneiras, desde a travessia do array até a lógica de ramificação, até o teste RegEx, de modo que a otimização destes pode adicionar um desafio extra ¯_ (ツ) _ / ¯ vou tentar isso para outro desafio golf código que :-)
Michael
2
tfw todo mundo está tentando obter métodos io mais flexíveis para tornar o código em sua linguagem de golfe favorita. e tfw isso acontece em quase todas as perguntas
Moinho de biscoitos
11
@NathanMerrill É mencionado na especificação que a entrada deve ter mais de 7 caracteres e seu comprimento deve ser divisível por quatro, Jo King estava sugerindo uma entrada de caso de teste de comprimento 4, como "abcd", que deveria ter erro
Thaufeki

Respostas:

11

K (oK) , 35 34 33 bytes

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

Experimente online!

Sem validação de entrada (para a recompensa de ngn), 25 24 23 bytes

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

Experimente online!

Aprendi rapidamente um pouco de K e, olhando a lista de verbos, pensei que uma abordagem alternativa ( sem usar cut) poderia funcionar aqui. E funcionou perfeitamente.

Como funciona

{<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
fonte
@ngn O que aconteceu com meus olhos Oo
Bubbler
3

Perl 6 , 60 58 bytes

-2 bytes graças a Jo King

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

Experimente online!

Lança "O comprimento da sublist da rotorização está fora do intervalo" em caso de erro.

Explicação

{               # 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
fonte
3

J , 36 35 bytes

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

Experimente online!

-1 byte por {.+ comprimentos negativos e ;.2que corta aqueles como marcadores "finais".

Resposta original, 36 bytes

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

Experimente online!

ngn mencionou "cut" em um comentário para uma resposta anterior do K , e me fez tentar J, que tem o mesmo "cut" (não tenho idéia de como o K funciona).

Como funciona

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

Observe que esta função lida automaticamente com entradas inválidas:

  • Se o comprimento da entrada não for múltiplo de quatro, {.lança domain errorporque seu argumento de comprimento deve ser um número inteiro.
  • Se o comprimento da entrada for 4, o corte produz apenas dois segmentos e 5 A.lança index error.
  • Se o comprimento da entrada for 0, os dois argumentos a serem cortados não terão o mesmo comprimento e, portanto, serão length errorlançados.
Bubbler
fonte
3

Python 3 , 103 102 101 97 88 86 84 bytes

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]

Experimente online!

Não é realmente uma linha, mas ;é menos um byte por linha do que quebra de linha e recuo.

Lança ZeroDivisionErrorse o comprimento da sequência de entrada for menor que 8 ou não for um múltiplo inteiro de 4.

Também funciona em Python 2.

-4 bytes graças a Jo King

-9 bytes graças a ovs

-2 bytes graças a Jonathan Frech

-2 bytes graças ao Bubbler

Axim
fonte
@JoKing obrigado pelas dicas, muito apreciada :)
Axim
11
88 bytes
ovs 04/11/19
@ovs boa captura nos índices adjacentes, quanto às parênteses, tentei por pelo menos 20 minutos para ver se conseguia me livrar de alguns deles, então perdi completamente isso com a mudança para //=o par mais externo se tornando redundante. Muitíssimo obrigado!
Axim
2
-l+1<-> 1-l?
Jonathan Frech
11
Mesclar as duas desigualdades para chegar a 84 bytes .
quer
2

Perl 6 , 78 bytes

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

Experimente online!

Bloco de código anônimo que pega uma string e retorna a string modificada, se válida, caso contrário, retorna uma divisão por erro zero. Eu sei que posso modificar uma matriz diretamente, para poder trocar as duas seções da string, mas não consigo entender direito.

Brincadeira
fonte
2

K (ngn / k) , 120 113 103 99 95 bytes

{$[(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]}

Esperançosamente, você pode jogar mais, incluindo uma função extra para testar se o comprimento da string é divisível por quatro, gera um erro com referência a variável não declarada se a entrada for inválida

EDIT: condição perdida no comprimento maior que 7, incluída

EDIT: Combinado em uma função, removeu declarações de variáveis ​​redundantes

Experimente online!

Thaufeki
fonte
11
isso poderia ser muito mais curto. você conhece "cut" ( indices_string)? ping-me no pomar, se eu deveria explicá-lo
ngn
11
eu posso fazê-lo em 34 bytes :)
NGN
Eu sei sobre corte, mas não pensei em usá-lo ... 34 bytes ?! Vou ter que dar a este outro ir quando eu chegar em casa e ver se eu chegar perto que
Thaufeki
devo mencionar: minha solução não garante que entradas inválidas (comprimento <= 7) causem um erro
ngn
1

Retina 0.8.2 , 58 ou 73 ou 83 ou 93 bytes

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

Experimente online! Explicação:

((((.)))*?)

Captura aem $1, e torná-lo o mais curto possível *?. $#2, $#3E $#4acabam-se como o comprimento de a.

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

Capturar bem $4. As (?<-2>.)+capturas até o comprimento de a, enquanto o outro .adiciona 1 ao comprimento, conforme necessário.

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

Capturar se cno $6. Seu comprimento combinado é três a mais que o comprimento de a.

((?<-4>.)+)

Capturar dem $7. Seu comprimento não é maior que o comprimento de a.

$

Fizemos o amais curto possível, mas ainda queremos chegar ao final da entrada.

$1$7$6$5

Troca be d.

O estágio acima não valida sua entrada. Como o Retina não possui erros de tempo de execução, existem várias opções para validação de entrada:

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

Não produz nada se o comprimento for menor que 8 ou não for múltiplo de 4. (+15 bytes)

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

Saída Errorse o comprimento for menor que 8 ou não for múltiplo de 4. (+25 bytes)

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

Trava se o comprimento for menor que 8 ou não for múltiplo de 4. (+35 bytes)

Neil
fonte
Isso não lançar um erro de entradas inválidas (tão irritante quanto que é)
Jo rei
1

C (gcc) com -Dx=memcpye -DL=(l-1), 154 158 160 bytes

Retorna NULL se o comprimento da string de entrada não for divisível por 4 ou menor que 8 caracteres.

Obrigado a Rogem e Jonathan Frech pelas sugestões.

EDIT: O pré-processador movido define para a linha de comando e fez com que a sequência seja alocada dinamicamente para estar em conformidade com o quebra-cabeça.

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)

Experimente online!

ErikF
fonte
Por que t[80]? Não parece haver um limite superior em relação ao comprimento da entrada.
Jonathan Frech
@ JonathanFrech Fiz isso para salvar bytes, mas você está correto. Eu mudei a solução para usar em seu malloc()lugar.
ErikF
Retorna por modificação, valor de retorno é NULLpara saída inválida, usa valores de retorno de memcpy(), uma macro semelhante a uma função para ignorar os tipos e matrizes de tamanho variável C99 para ignorar malloc().
Por que 160 bytes, você conta o //ou o -w?
L4m2 13/11/19
@ l4m2 -wé apenas uma conveniência para suprimir avisos (portanto, é mais fácil encontrar erros). Normalmente, adiciono argumentos de linha de comando após a //para que o TIO conte seus bytes para mim e deduzo 1 do total para contabilizar o caractere extra necessário para fazer isso.
1

Gelatina , 28 bytes

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

(Se um programa completo é permitido, podemos remover o final F).
Se o comprimento for menor que 8 ou não divisível por quatro, a ValueErroré aumentada durante a divisão inteira de inf(um flutuador) por 4- a divisão produz NaN(também um flutuador) que então não pode ser lançado para um int.

Experimente online!

Como?

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
fonte
1

Gelatina , 25 bytes

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

Experimente online!

O pode ser removido para transformar isso em um programa completo.

Erik, o Outgolfer
fonte
1

JavaScript (ES6), 97 89 bytes

Guardado 8 bytes graças a @ l4m2

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

Experimente online!

Arnauld
fonte
11
89B
l4m2
0

Java 8, 135 bytes

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);}

Lança ArithmeticException(divide por zero) se a sequência de entrada não corresponder aos requisitos. Experimente online aqui .

Ungolfed:

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
fonte
Sugerir em l/=l>7&l%4<1?4:0;vez del=l>7&l%4<1?l/4:l/0;
ceilingcat 20/09/19
0

C (gcc) , 129 bytes

Retorna por modificação. Ajuntar com:

-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

Arquivo fonte:

l;

Experimente online!

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.

fonte