Invertir una cuerda por trozos

34

Su tarea es escribir un programa que, dado un número y una cadena, divide la cadena en trozos de ese tamaño y los invierte.

Reglas

Su programa recibirá un número entero positivo n, así como una cadena scon una longitud de al menos uno que consta de solo ASCII imprimible (sin incluir espacios en blanco). La cadena se debe dividir en trozos de longitud n, si la longitud de la cadena no es divisible por nlas sobras al final se debe considerar su propio fragmento. Luego, invierta el orden de los trozos y júntelos nuevamente.

Casos de prueba

n   s           Output

2   abcdefgh    ghefcdab
3   foobarbaz   bazbarfoo
3   abcdefgh    ghdefabc
2   a           a
1   abcdefgh    hgfedcba
2   aaaaaa      aaaaaa
2   baaaab      abaaba
50  abcdefgh    abcdefgh
6   abcdefghi   ghiabcdef

Este es el , por lo que debe apuntar a la menor cantidad de bytes posible.

Pavel
fuente
Relacionados .
AdmBorkBork

Respuestas:

29

Jalea , 2 bytes

sṚ

Un programa completo que imprime el resultado.

Pruébalo en línea!

¿Cómo?

sṚ - Main link: string, number                                   e.g. 'abcdefg', 3
s  - split string into chunks of length number (keeping any overflow) ["abc","def","g"]
 Ṛ - reverse the resulting list                                       ["g","def","abc"]
   - implicit print                                                   gdefabc
Jonathan Allan
fuente
28
Me gusta cómo dos bytes generaron 4 líneas de explicación.
Pavel
16

Python 3 , 35 bytes

f=lambda s,n:s and f(s[n:],n)+s[:n]

Pruébalo en línea!

Dennis
fuente
¿Cómo funciona la andpalabra clave aquí? @Dennis
ShinMigami13
2
@ ShinMigami13 cadena vacía no es verdad, así que esto termina la recursión
Michael Klein
9

05AB1E , 5 4 3 bytes

-1 gracias a Dennis
-1 gracias a carusocomputing

ôRJ

Pruébalo en línea!

     # Implicit: push input
 ô   # Split in pieces of length b
  RJ # Reverse and join
Riley
fuente
¹no es necesario
Magic Octopus Urn
8

JavaScript (ES6), 37 bytes

n=>F=s=>s&&F(s.slice(n))+s.slice(0,n)

Toma la entrada al curry: número primero, luego cadena, como f(2)("abcdefgh").

ETHproducciones
fuente
7

Perl 6 ,  28  20 bytes

{$^b.comb($^a).reverse.join}

Intentalo

{[R~] $^b.comb($^a)}

Intentalo

Expandido:

{  # bare block lambda with placeholder parameters 「$a」 and 「$b」
  [R[~]] # reduce the following using the reverse meta operator `R`
         # combined with the string concatenation operator

    # `comb` with a number splits the invocant into chunks of that size
    $^b.comb($^a)
}
Brad Gilbert b2gills
fuente
7

Bash + coreutils, 22

fold -$1|tac|tr -d \\n

Pruébalo en línea .

Trauma digital
fuente
1
Aprendí 4 nuevos comandos de Linux esta semana en PPCG fold, es uno de ellos, ¡gracias!
Wossname
7

Haskell , 32 bytes

n#""=""
n#s=n#drop n s++take n s

Pruébalo en línea!

xnor
fuente
1
Bonita. Es agradable cuando la precedencia funciona en el golf
Michael Klein
4

PHP, 53 bytes

<?=join(array_reverse(str_split($argv[2],$argv[1])));
Jörg Hülsermann
fuente
4

Röda , 36 bytes

f n{[[_]..[try head n-1]]|reverse|_}

Pruébalo en línea!

Es una función que toma un argumento. Los caracteres de la cadena deben estar en la secuencia.

tryse usa para descartar errores en caso de que la headfunción no pueda leer n-1valores.

Explicación:

f n{[[_]..[try head n-1]]|reverse|_}
f n{                               } /* Function declaration */
                                     /* In a loop: */
      _                              /*   Pull one value */
           try head n-1              /*   Pull n-1 values (or less) */
     [ ]..[            ]             /*   Make an array */
    [                   ]            /*   Push it to the stream */
                         |reverse    /* Reverse all values in the stream */
                                 |_  /* Flat all arrays in the stream */
                                     /* Characters in the stream are printed */

No tan ofuscado como de costumbre. Creo que es bastante hermoso. :)

fergusq
fuente
55
Has conseguido que un programa sea menos legible que la solución de gelatina.
Pavel
¿Por qué no [[try head n]]funciona en lugar de [[_]..[try head n-1]]?
Kritixi Lithos
@KritixiLithos Porque repite _la expresión. [[try head n]]tomaría n valores una vez , pero [[_]..[try head n-1]]toma n valores siempre que queden valores.
fergusq
4

CJam , 5 bytes

q~/W%

La entrada es un número y una cadena entre comillas dobles, separados por espacios en blanco.

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

q~   e# Read all input and evaluate: pushes a number and a string
/    e# Split string into chunks of that size. Last chunk may be
     e# smaller. Gives an array of strings
W%   e# Reverse the array. Implicitly display
Luis Mendo
fuente
4

Lote, 74 bytes

@if %2=="" (echo %~3)else set s=%~2&call %0 %1 "%%s:~%1%%" "%%s:~,%1%%%~3"

Más bien molesto, esto termina siendo recursivo en lugar de recursivo de cola.

Neil
fuente
4

V , 13 10 bytes

òÀ|lDÏpòÍî

Pruébalo en línea!

ò      ò    ' Recursively
 À|         ' Go to the "nth" column
   l        ' Move one character right (breaks loop when no more chunks)
    D       ' Delete from here to the end of the line
     Ï      ' Add a line above the current line (now contains one chunk)
      p     ' Paste the remainder of the line that was deleted
        Íî  ' Remove all newlines

En acción:

abcdefghijkl

se convierte en

efghijkl
abcd

que se convierte

ijkl
efgh
abcd

antes de que se eliminen todas las líneas nuevas

nmjcman101
fuente
4

brainfuck , 78 bytes

,<<<+[[>]>+>[[>],<[<]>+>-]<-[->>[>]>>+<<<[<]<]>>]<<<<[[<]>[-[+.[-]]+>]<[<]<<<]

El primer byte de la entrada es el tamaño del fragmento, dado por el valor del byte. El resto de los bytes se consideran la cadena.

Pruébalo en línea!

Ampliado y comentado

Read the chunk size byte
This cell will become a counter cell
,

Move left a few cells an increment; 
this is to make the starting position 
line up with the relative positioning
needed to fit in with the loop
<<<+

While the current cell is nonzero:
[

 Move right to the first zero cell
 [>]

 Move right once and increment and then move right to the counter cell
 The increment is required because of "move to zero cell" loops
 >+>

 This loop will store one chunk of the input in consecutive memory cells
 [
  [>]   Move right until a zero cell is hit
  ,     Store 1 byte of input there
  <[<]  Move back left until a zero cell (other than the current one) is hit
  >+>-  Increment the temporary cell by 1 and decrement the counter
 ] (end loop once the counter hits zero)

 Decrement the temp cell (because we needed to have 1 there initially to make the cell location work)
 <-

 Move the temp cell to three cells after the end of the chunk
 This is the new counter cell for the next chunk
 [->>[>]>>+<<<[<]<]

 Move two cells right from where the temp cell was
 This is the first cell of the chunk; if it's 0
 then the input is finished and the loop should end
 >>
]

Due to the way the counter is kept track of the tape head
will always be four cells to the right of the last input cell
when the loops breaks
<<<<

Now the chunks are printed one by one
At the start of an iteration the tape head is at the end of a chunk
[
 Locate the start of the last chunk
 [<]>

 Print the chunk:
 [
  Print the byte held in the current cell if it isn't 1
  This is necessary because we left a stray 1 in a cell at
  the start which shouldn't be printed
  -[+.[-]]+

  Move to the next cell
  >
 ]

 Move to just left of the chunk
 <[<]

 Move three cells over to the end of the next chunk
 <<<
]
Gato de negocios
fuente
4

PowerShell, 56 49 bytes

-7 bytes gracias a mazzy

param($n,$s)$s-split"(.{$n})"-ne''|%{$r=$_+$r};$r

Pruébalo en línea!

Andrei Odegov
fuente
1) 49 bytes 2) Por favor, publique un programa completo, no un código. ¿Como revisar? Extraiga su código en un archivo separado con la extensión .ps1e intente llamar a este script en lugar de su código. Si funciona, entonces la prueba fue exitosa.
mazzy
3

Mathematica, 46 bytes

""<>Reverse@Partition[Characters@#2,#,#,1,{}]&

Función anónima. Toma un número y una cadena como entrada y devuelve una cadena como salida. No hay mucho que ver aqui.

LegionMammal978
fuente
3

Javascript - 54 47 46 bytes

Rehecho:

(s,n)=>s.match(eval(`/.{1,${n}}/g`)).reverse()

Usado como

f=(s,n)=>s.match(eval(`/.{1,${n}}/g`)).reverse()
alert(f("abcdefgh",2));

Gracias a @ETHproductions por alguna aceleración de RegEx ¡Gracias a @Shaggy por un byte adicional en la evaluación!

Original:

(s,n)=>s.match(new RegExp('.{1,'+n+'}','g')).reverse()
Okiris Azul
fuente
1
¡Buena respuesta! Creo que puede guardar un par de bytes creando la expresión regular coneval('/.{1,'+n+'}/g')
ETHproductions
@ETHproductions Ah sí. Eso es lo que he estado intentando hacer. ¡Aunque no estaba lo suficientemente familiarizado con regex para hacerlo!
Blue Okiris
Creo que puedes guardar un byte con curry,s=>n=> ...
Pavel
Guarde un byte con eval("/.{1,${n}}/g"), utilizando comillas invertidas en lugar de comillas.
Shaggy
3

Pyth, 5 bytes

s_c.*

Pruébalo en línea .

Explicación

   .*  splat implicit input
  c    split into chunks length n
 _     reverse
s      join
Trauma digital
fuente
3

Retina , 38 bytes

1 byte guardado gracias a @LeakyNun

^

+`(.* (1)+¶)((?<-2>.)+)
$3$1
 1+¶

(Tenga en cuenta el espacio en la segunda línea y el espacio final)

Este programa toma la entrada como unaria en la primera línea y la cadena en la segunda.

Pruébalo en línea!

¡Banco de pruebas! (ligeramente modificado)

Explicación

El primer paso es anteponer un espacio (será importante más adelante).

^
 

Ahora retrocedemos. Esto utiliza los grupos de equilibrio de .NET. Es importante tener en cuenta que los grupos aquí actúan como pilas, por lo que cada partida se empuja esencialmente a la pila. Aquí capturamos cada dígito del número unario en el grupo 2. Ahora, cada vez que se encuentra un carácter en la cadena, aparece una coincidencia del grupo 2. Esto asegura que el número de caracteres no exceda el del número unario.

+`(.* (1)+¶)                       Capture the unary number in group 2
             ((?<-2>.)+)           Balancing group for substrings
$3$1                               Reverse

Y finalmente elimine el número unario y la nueva línea.

 1+¶

Kritixi Lithos
fuente
Creo que es aceptable tomar el número en unario.
Leaky Nun
De todos modos, puede reemplazar \dpor .para guardar un byte.
Leaky Nun
El segundo ^también es redundante.
Leaky Nun
@LeakyNun El programa ahora toma entradas en unario, por lo que ya no necesito \dmás. Y gracias por jugar al golf con el caret :)
Kritixi Lithos
33 bytes mediante el uso de la coincidencia perezosa (no codiciosa).
Leaky Nun
3

Java, 147138 bytes

String r(String s,int n){String r="";int l=s.length();for(int i=l/n*n;i>=0;i-=n)if(!(i>=l))r+=(i+n)>=l?s.substring(i):s.substring(i,i+n);return r;}

¡Salvado 9 Bytes gracias a Kevin Cruijssen!

String r(String s,int n){String r="";int l=s.length(),i=l/n*n;for(;i>=0;i-=n)if(i<l)r+=i+n>=l?s.substring(i):s.substring(i,i+n);return r;}

En forma expandida:

String r(String s,int n){
    String r="";
    int l=s.length(),i=l/n*n;
    for(;i>=0;i-=n)
        if(i<l)
            r+=i+n>=l?s.substring(i):s.substring(i,i+n);
    return r;
}

Este es mi primer intento de codegolf, así que cualquier comentario es bienvenido.

bruderjakob17
fuente
Bienvenido a PPCG!
Pavel
1
Hola, bienvenido a PPCG! Esto ya es bastante bueno, pero todavía hay algunas cosas para jugar al golf más: int l=s.length();for(int i=l/n*n;puede ser int l=s.length(),i=l/n*n;for(;así que solo tienes int una vez. Y if(!(i>=l))puede ser if(l<i). Y r+=(i+n)>=l?puede estar sin el paréntesis: r+=i+n>=l?. Además, si aún no lo ha visto, le puedo recomendar que consulte los Consejos para jugar golf en Java para obtener algunos consejos geniales para usar. :) Una vez más, bienvenido.
Kevin Cruijssen
3

Perl 5 , 25 bytes

Utiliza las -lnM5.010banderas.

say reverse<>=~/.{1,$_}/g

Pruébalo en línea!

Grito a Grinnz por contarme sobre =~ m/.{1,$n}/g

-M5.010permite el uso de la sayfunción, que para nuestros propósitos es imprimir con un nombre más corto.

-npone la primera línea de entrada $_y -lcorta la nueva línea final.

Luego obtenemos la segunda línea de entrada <>y la aplicamos a la expresión regular .{1,$_}: cualquier carácter, entre 1 y $ _ (la primera entrada) veces. Como esto es codicioso por defecto, siempre trata de hacer coincidir $ _ caracteres. Se 1,necesita para el posible fragmento sobrante al final.

El /gmodificador nos da cada coincidencia de esa expresión regular en la cadena de entrada como una lista, que luego se invierte e imprime. En Perl, pasar una lista para sayunirse sin ningún delimitador de forma predeterminada.

Pavel
fuente
3

Dyalog APL Extended , 16 15 bytes

{∊⌽⍵⊂⍨(≢⍵)⍴=⍳⍺}

Pruébalo en línea!

dzaima
fuente
No necesitas elf←
Pavel
Por qué, ,/
Adám
@ Adám Oh, oye, eso también se aplica a mi respuesta, gracias
Pavel
Pavel: sí, obviamente .. @ Adám gracias!
dzaima
14:∊∘⌽⊢⊂⍨≢⍤⊢⍴1↑⍨⊣
Ven
2

Python, 62 bytes

lambda n,s:''.join([s[i:i+n]for i in range(0,len(s),n)][::-1])

Pruébalo en línea!

ovs
fuente
La respuesta de Python3 es más corta y también funciona para Python 2.7:f=lambda n,s:s and f(n,s[n:])+s[:n]
F1Rumors
2

QBIC , 24 bytes

:;[1,_lA|,a|Z=_sA,b,a|+Z

Esto hace un excelente uso de la nueva función de subcadena que agregué recientemente a QBIC:

:;          Read in the cmd line params a (number) and A$ (text)
[1,_lA|,a|  Set up a FOR loop: FOR b = 1; b <= A$.length; b += a
Z=          Modify Z$; Z$ is autoprinted at the end of QBIC code
_sA,b,a|    SUBSTRING: _s is the function followed by the string 
               to take from, the starting pos and the # of chars
+Z          Take chunks from further into A$, put them before Z$
Steenbergh
fuente
2

C, 69 bytes

i;f(s,n)char*s;{i=strlen(s);for(i-=i%n;printf("%.*s",n,s+i),i;i-=n);}

El resultado se imprime en la salida estándar.

2501
fuente
2

Scala, 57 55 bytes

(n:Int,s:String)=>(""/:s.grouped(n).toSeq.reverse)(_+_)

Gracias Jacob! Probarlo aquí .

Nota: Al usar la forma de símbolo de foldLeft ("/:"), pude despegar un par de bytes más.

jkeatley
fuente
haga que sea una función anónima, y ​​use en mkStringlugar de reduceLeft, y elimine 7 bytes:(n:Int,s:String)=>s.grouped(n).toSeq.reverse.mkString("")
Jacob
2

Ohm , 5 bytes

σ]QWJ

Pruébalo en línea!

Explicación

σ]QWJ
σ         # Split input1 into input2 pieces
 ]        # Flatten array
  Q       # Reverses stack
   W      # Wraps stack to array
    J     # Joins stack
          # Implicit print
Datboi
fuente
2

R , 69 60 bytes

function(s,n)cat(substring(s,(x=nchar(s):0*n)+1,x+n),sep="")

Pruébalo en línea!

Gracias a Kirill L. por la sugerencia de eliminar seq.

Giuseppe
fuente
Parece que esto también funciona para 66.
Kirill L.
@KirillL. podemos pasar a 60 bytes si invertimos el orden de los argumentos :y alguna manipulación nos permite deshacernos del final -1.
Giuseppe
Inteligente, muy agradable!
Kirill L.