Inverter uma string por pedaços


34

Sua tarefa é escrever um programa que, dado um número e uma string, divida a string em pedaços desse tamanho e os inverta.

Regras

Seu programa receberá um número inteiro positivo n, bem como uma string scom comprimento pelo menos um que consiste apenas em ASCII imprimível (não incluindo espaço em branco). A string deve então ser dividida em pedaços de comprimento n, se o comprimento da string não for divisível por nqualquer sobra no final deve ser considerado seu próprio pedaço. Em seguida, inverta a ordem dos pedaços e junte-os novamente.

Casos de teste

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

Isso é , então você deve procurar o mínimo de bytes possível.


Respostas:


29

Geléia , 2 bytes

sṚ

Um programa completo que imprime o resultado.

Experimente online!

Quão?

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

28
Eu gosto de como dois bytes geraram 4 linhas de explicação.
Pavel



8

JavaScript (ES6), 37 bytes

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

Pega entrada currying: numere primeiro, depois string, como f(2)("abcdefgh").


7

Perl 6 ,  28  20 bytes

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

Tente

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

Tente

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




4

Röda , 36 bytes

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

Experimente online!

É uma função que leva um argumento. Os caracteres da sequência devem estar no fluxo.

tryé usado para descartar erros caso a headfunção não possa ler n-1valores.

Explicação:

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 */

Não tão ofuscado como normalmente. Eu acho muito bonito. :)


5
Você conseguiu tornar um programa menos legível que a solução de geléia.
Pavel

Por que não [[try head n]]funciona em vez de [[_]..[try head n-1]]?
Kritixi Lithos

@KritixiLithos Porque faz um _loop na expressão. [[try head n]]levaria n valores uma vez , mas [[_]..[try head n-1]]leva n valores desde que restem valores.
precisa saber é o seguinte

4

CJam , 5 bytes

q~/W%

Entrada é um número e uma cadeia de caracteres entre aspas duplas, separadas por espaços em branco.

Experimente online! Ou verifique todos os casos de teste .

Explicação

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

4

Lote, 74 bytes

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

De maneira irritante, isso acaba sendo recursivo ao invés de recursivo da cauda.


4

V , 13 10 bytes

òÀ|lDÏpòÍî

Experimente online!

ò      ò    ' 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

Em ação:

abcdefghijkl

torna-se em

efghijkl
abcd

que se torna

ijkl
efgh
abcd

antes que todas as novas linhas sejam removidas


4

brainfuck , 78 bytes

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

O primeiro byte da entrada é o tamanho do bloco, fornecido pelo valor do byte. O restante dos bytes é considerado a string.

Experimente online!

Expandido e 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
 <<<
]

4

PowerShell, 56 49 bytes

-7 bytes graças ao mazzy

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

Experimente online!


1) 49 bytes 2) Poste um programa completo, não um código de código. Como verificar? Extraia seu código em um arquivo separado com a extensão .ps1e tente chamar esse script em vez de seu código. Se funcionar, o teste foi bem-sucedido.
mazzy 20/03

3

Mathematica, 46 bytes

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

Função anônima. Pega um número e uma sequência como entrada e retorna uma sequência como saída. Não há muito para ver aqui.


3

Javascript - 54 47 46 bytes

Remade:

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

Obrigado a @ETHproductions por algumas atualizações da RegEx Obrigado a @Shaggy por um byte extra na avaliação!

Original:

(s,n)=>s.match(new RegExp('.{1,'+n+'}','g')).reverse()

1
Boa resposta! Eu acredito que você pode salvar um par de bytes criando o regex comeval('/.{1,'+n+'}/g')
ETHproductions

@ETHproductions Ah sim. É o que tenho tentado fazer. Eu não estava familiarizado o suficiente com regex para fazê-lo!
Azul Okiris

Eu acho que você pode salvar um byte com currying,s=>n=> ...
Pavel

Salve um byte com eval("/.{1,${n}}/g"), usando backticks em vez de aspas.
Shaggy


3

Retina , 38 bytes

1 byte salvo graças a @LeakyNun

^

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

(Observe o espaço na segunda linha e o espaço à direita)

Este programa considera a entrada como unária na primeira linha e a sequência na segunda.

Experimente online!

Suíte de teste! (ligeiramente modificado)

Explicação

O primeiro passo é acrescentar um espaço (será importante mais tarde).

^
 

Agora nós invertemos. Isso usa grupos de balanceamento do .NET. É importante notar que os grupos aqui atuam como stacks, portanto, cada partida é essencialmente empurrada para a pilha. Aqui capturamos todos os dígitos do número unário no grupo 2. Agora, sempre que um caractere na cadeia é encontrado, uma correspondência é exibida no grupo 2. Isso garante que o número de caracteres não exceda o número unário.

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

E, finalmente, remova o número unário e a nova linha.

 1+¶


Eu acho que é aceitável levar o número em unário.
Leaky Nun

De qualquer forma, você pode substituir \dpor .para salvar um byte.
Leaky Nun

O segundo ^também é redundante.
Leaky Nun

@LeakyNun O programa agora recebe informações unárias, então não preciso \dmais disso. E obrigado por jogar golfe afastado o acento circunflexo :)
Kritixi Lithos

33 bytes usando a correspondência lenta (não gananciosa).
Leaky Nun

3

Java, 147 138 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;}

Guardado 9 bytes graças 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;}

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

Esta é realmente a minha primeira tentativa de codegolf, então qualquer comentário é bem-vindo!


Bem-vindo ao PPCG!
Pavel

1
Olá, seja bem-vindo ao PPCG! Isso já é muito bom, mas ainda há algumas coisas para jogar um pouco mais: int l=s.length();for(int i=l/n*n;pode ser int l=s.length(),i=l/n*n;for(;assim que você só tem int uma vez. E if(!(i>=l))pode ser if(l<i). E r+=(i+n)>=l?pode ser feito sem o parêntese: r+=i+n>=l?. Além disso, se você ainda não o viu, recomendo consultar Dicas de golfe em Java para obter algumas dicas bem legais de golfe. :) Mais uma vez, bem-vindo.
Kevin Cruijssen

3

Perl 5 , 25 bytes

Usa as -lnM5.010bandeiras.

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

Experimente online!

Grite para Grinnz por me falar sobre =~ m/.{1,$n}/g

-M5.010permite o uso da sayfunção, que para nossos propósitos é impressa com um nome mais curto.

-ncoloca a primeira linha de entrada $_e -lmastiga a nova linha à direita.

Em seguida, obtemos a segunda linha de entrada usando <>e a aplicamos ao regex .{1,$_}: qualquer caractere, entre 1 e $ _ (a primeira entrada) vezes. Como isso é ganancioso por padrão, ele tenta sempre corresponder $ _ caracteres. A 1,é necessária para a possível pedaço de sobra no final.

O /gmodificador nos fornece todas as correspondências desse regex na cadeia de entrada como uma lista, que é então revertida e impressa. No Perl, passar uma lista para sayse juntar a ela sem nenhum delimitador por padrão.



2

Python, 62 bytes

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

Experimente online!


A resposta do Python3 é mais curta e também funciona para o python 2.7:f=lambda n,s:s and f(n,s[n:])+s[:n]
F1Rumors 20/03


2

QBIC , 24 bytes

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

Isso faz excelente uso da nova função de substring que adicionei recentemente ao 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$



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

O resultado é impresso na saída padrão.


2

Scala, 57 55 bytes

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

Obrigado Jacob! Experimente aqui .

Nota: Usando a forma de símbolo foldLeft ("/:"), consegui extrair mais alguns bytes.


torná-lo função anônima e uso mkString, em vez de reduceLeft, e raspar 7 bytes:(n:Int,s:String)=>s.grouped(n).toSeq.reverse.mkString("")
Jacob

2

Ohm , 5 bytes

σ]QWJ

Experimente online!

Explicação

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.