Invertire una stringa di blocchi


34

Il tuo compito è quello di scrivere un programma che, dato un numero e una stringa, divide la stringa in blocchi di quella dimensione e li inverte.

Regole

Il tuo programma riceverà un numero intero positivo n, oltre a una stringa sdi lunghezza almeno una composta solo da ASCII stampabile (escluso lo spazio bianco). La stringa dovrebbe quindi essere suddivisa in blocchi di lunghezza n, se la lunghezza della stringa non è divisibile per neventuali avanzi alla fine dovrebbe essere considerata la sua parte. Quindi, invertire l'ordine dei blocchi e rimetterli insieme.

Casi test

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

Questo è , quindi dovresti puntare al minor numero di byte possibile.


Risposte:


29

Gelatina , 2 byte

sṚ

Un programma completo che stampa il risultato.

Provalo online!

Come?

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
Mi piace come due byte abbiano generato 4 righe di spiegazione.
Pavel,



8

JavaScript (ES6), 37 byte

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

Prende l'input dal curry: numero prima, quindi stringa, come f(2)("abcdefgh").


7

Perl 6 ,  28  20 byte

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

Provalo

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

Provalo

Allargato:

{  # 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 byte

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

Provalo online!

È una funzione che accetta un argomento. I caratteri della stringa devono essere nello stream.

tryviene utilizzato per eliminare gli errori nel caso in cui la headfunzione non sia in grado di leggere i n-1valori.

Spiegazione:

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

Non così offuscato come al solito. Penso che sia abbastanza bello. :)


5
Sei riuscito a rendere un programma meno leggibile della soluzione gelatina.
Pavel,

Perché non [[try head n]]funziona invece di [[_]..[try head n-1]]?
Kritixi Lithos,

@KritixiLithos Perché esegue il _loop dell'espressione. [[try head n]]prenderà n valori una volta , ma [[_]..[try head n-1]]accetta n valori fintanto che rimangono valori.
Fergusq,

4

CJam , 5 byte

q~/W%

L'input è un numero e una stringa racchiusi tra virgolette doppie, separati da spazi bianchi.

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

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

Lotto, 74 byte

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

Piuttosto fastidioso questo finisce per essere ricorsivo piuttosto che ricorsivo di coda.


4

V , 13 10 byte

òÀ|lDÏpòÍî

Provalo 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

In azione:

abcdefghijkl

diventa

efghijkl
abcd

che diventa

ijkl
efgh
abcd

prima che tutte le nuove righe vengano rimosse


4

Brainfuck , 78 byte

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

Il primo byte dell'ingresso è la dimensione del blocco, data dal valore del byte. Il resto dei byte è considerato la stringa.

Provalo online!

Ampliato e commentato

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 byte

-7 byte grazie a mazzy

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

Provalo online!


1) 49 byte 2) Per favore, pubblica un programma completo, non un frammento di codice. Come controllare? Estrai il tuo codice in un file separato con l'estensione .ps1e prova a chiamare questo script invece del tuo codice. Se funziona, il test ha avuto esito positivo.
mazzy

3

Mathematica, 46 byte

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

Funzione anonima. Accetta un numero e una stringa come input e restituisce una stringa come output. Non c'è molto da vedere qui.


3

Javascript - 54 47 46 byte

rifatto:

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

Usato come

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

Grazie a @ETHproductions per alcune accelerazioni di RegEx Grazie a @Shaggy per un byte extra in valutazione!

Originale:

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

1
Bella risposta! Credo che puoi salvare un paio di byte creando il regex coneval('/.{1,'+n+'}/g')
ETHproductions

@ETHproductions Ah sì. Questo è quello che ho cercato di fare. Non avevo abbastanza familiarità con regex per farlo!
Blue Okiris,

Penso che puoi salvare un byte con il curry,s=>n=> ...
Pavel

Salvare un byte con eval("/.{1,${n}}/g"), usando i backtick invece delle virgolette.
Shaggy,


3

Retina , 38 byte

1 byte salvato grazie a @LeakyNun

^

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

(Nota lo spazio sulla seconda riga e lo spazio finale)

Questo programma accetta l'input come unario sulla prima riga e la stringa sulla seconda.

Provalo online!

Test Suite! (leggermente modificato)

Spiegazione

Il primo passo è anteporre uno spazio (diventerà importante in seguito).

^
 

Adesso facciamo il contrario. Questo utilizza i gruppi di bilanciamento di .NET. È importante notare che i gruppi qui agiscono come pile, quindi ogni partita viene essenzialmente messa in pila. Qui catturiamo ogni cifra nel numero unario nel gruppo 2. Ora ogni volta che viene trovato un carattere nella stringa, viene spuntata una corrispondenza dal gruppo 2. Questo assicura che il numero di caratteri non superi quello del numero unario.

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

E infine rimuovere il numero unario e la nuova riga.

 1+¶


Penso che sia accettabile prendere il numero in unario.
Leaky Nun,

Ad ogni modo, puoi sostituirlo \dcon .per salvare un byte.
Leaky Nun,

Anche il secondo ^è ridondante.
Leaky Nun,

@LeakyNun Il programma ora accetta input in unario, quindi non ne ho più bisogno \d. E grazie per aver lasciato il golf :)
Kritixi Lithos,

33 byte utilizzando la corrispondenza lazy (non avida).
Leaky Nun,

3

Java, 147 138 byte

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

Salvataggio di 9 byte grazie 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;}

In forma estesa:

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

Questo è in realtà il mio primo tentativo di codegolf di sempre, quindi qualsiasi feedback è il benvenuto!


Benvenuti in PPCG!
Pavel

1
Ciao, benvenuto in PPCG! Questo è già abbastanza buono, ma ci sono ancora alcune cose da golf in più: int l=s.length();for(int i=l/n*n;può essere int l=s.length(),i=l/n*n;for(;così ce l'hai solo una int volta. E if(!(i>=l))può essere if(l<i). E r+=(i+n)>=l?può essere senza la parentesi: r+=i+n>=l?. Inoltre, se non l'hai ancora visto, posso consigliare di consultare Suggerimenti per il golf in Java per alcuni suggerimenti per il golf piuttosto interessanti da usare. :) Ancora una volta, benvenuto.
Kevin Cruijssen,

3

Perl 5 , 25 byte

Usa le -lnM5.010bandiere.

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

Provalo online!

Shoutout a Grinnz per avermene parlato =~ m/.{1,$n}/g

-M5.010 consente l'uso di say funzione, che per i nostri scopi è la stampa con un nome più breve.

-ninserisce la prima riga di input in $_, e-l cancella la nuova riga finale.

Otteniamo quindi la seconda riga di input usando <>e la applichiamo alla regex.{1,$_} : qualsiasi carattere, tra 1 e $ _ (il primo input) volte. Dal momento che questo è avido per impostazione predefinita, cerca di abbinare sempre $ _ caratteri. Il1, è necessario per l'eventuale porzione rimanente alla fine.

Il /gmodificatore ci fornisce ogni corrispondenza di quella regex nella stringa di input come un elenco, che viene quindi invertito e stampato. In Perl, passare un elenco per sayunirlo senza delimitatore per impostazione predefinita.



2

Python, 62 byte

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

Provalo online!


La risposta di Python3 è più breve e funziona anche con Python 2.7:f=lambda n,s:s and f(n,s[n:])+s[:n]
F1Rumors


2

QBIC , 24 byte

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

Questo fa un uso eccellente della nuova funzione di sottostringa che ho recentemente aggiunto 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$



2

C, 69 byte

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

Il risultato viene stampato sull'output standard.


2

Scala, 57 55 byte

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

Grazie Jacob! Provalo qui .

Nota: utilizzando la forma del simbolo di foldLeft ("/:"), sono stato in grado di rimuovere un altro paio di byte.


rendila funzione anonima, e usa mkStringinvece di reduceLeft, e depila 7 byte:(n:Int,s:String)=>s.grouped(n).toSeq.reverse.mkString("")
Jacob,

2

Ohm , 5 byte

σ]QWJ

Provalo online!

Spiegazione

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.