Inverser une chaîne par morceaux

34

Votre tâche consiste à écrire un programme qui, à partir d’un nombre et d’une chaîne, divise la chaîne en morceaux de cette taille et les inverse.

Règles

Votre programme recevra un entier positif n, ainsi qu'une chaîne sd'au moins une longueur composée uniquement d'ASCII imprimable (sans les espaces). La chaîne doit ensuite être divisée en morceaux de longueur n. Si la longueur de la chaîne n'est divisible par naucun reste à la fin, elle doit être considérée comme son propre morceau. Ensuite, inversez l’ordre des morceaux et remettez-les ensemble.

Cas de 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

C'est du , vous devriez donc viser le moins d'octets possible.

Pavel
la source
Connexes .
AdmBorkBork

Réponses:

29

Gelée , 2 octets

sṚ

Un programme complet qui imprime le résultat.

Essayez-le en ligne!

Comment?

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
la source
28
J'aime comment deux octets ont généré 4 lignes d'explication.
Pavel
16

Python 3 , 35 octets

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

Essayez-le en ligne!

Dennis
la source
Comment fonctionne le andmot clé ici? @Dennis
ShinMigami13
2
@ ShinMigami13 chaîne vide n'est pas la vérité, donc cela met fin à la récursivité
Michael Klein
9

05AB1E , 5 4 3 octets

-1 grâce à Dennis
-1 grâce à carusocomputing

ôRJ

Essayez-le en ligne!

     # Implicit: push input
 ô   # Split in pieces of length b
  RJ # Reverse and join
Riley
la source
¹n'est pas nécessaire.
Urne magique Octopus
8

JavaScript (ES6), 37 octets

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

Prend les entrées en currying: nombre d’abord, puis chaîne, comme f(2)("abcdefgh").

ETHproductions
la source
7

Perl 6 ,  28  20 octets

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

L'essayer

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

L'essayer

Étendu:

{  # 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
la source
7

Bash + coreutils, 22

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

Essayez-le en ligne .

Trauma numérique
la source
1
J'ai appris 4 nouvelles commandes linux cette semaine sur PPCG, l'une d'entre elles, merci!
Wossname
4

PHP, 53 octets

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

Röda , 36 octets

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

Essayez-le en ligne!

C'est une fonction qui prend un argument. Les caractères de la chaîne doivent être dans le flux.

tryest utilisé pour supprimer les erreurs dans le cas où la headfonction ne peut pas liren-1 valeurs.

Explication:

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

Pas aussi obscurci que d'habitude. Je pense que c'est assez beau. :)

Fergusq
la source
5
Vous avez réussi à rendre un programme moins lisible que la solution Jelly.
Pavel
Pourquoi ne [[try head n]]travaille pas au lieu de [[_]..[try head n-1]]?
Kritixi Lithos
@KritixiLithos Since _boucle l'expression. [[try head n]]prendrait n valeurs une fois , mais [[_]..[try head n-1]]prend n valeurs tant qu'il reste des valeurs.
Fergusq
4

CJam , 5 octets

q~/W%

L'entrée est un nombre et une chaîne entre guillemets, séparés par des espaces.

Essayez-le en ligne!Ou vérifiez tous les cas de test .

Explication

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
la source
4

Lot, 74 octets

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

Plutôt ennuyeux, cela finit par être récursif plutôt que final.

Neil
la source
4

V , 13 à 10 octets

òÀ|lDÏpòÍî

Essayez-le en ligne!

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

abcdefghijkl

se transforme en

efghijkl
abcd

qui devient

ijkl
efgh
abcd

avant que toutes les nouvelles lignes soient supprimées

nmjcman101
la source
4

brainfuck , 78 octets

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

Le premier octet de l'entrée est la taille du bloc, donnée par la valeur d'octet. Le reste des octets est considéré comme la chaîne.

Essayez-le en ligne!

Développé et commenté

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
 <<<
]
Chat d'affaires
la source
4

PowerShell, 56 à 49 octets

-7 octets grâce à mazzy

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

Essayez-le en ligne!

Andrei Odegov
la source
1) 49 octets 2) Envoyez un programme complet et non un code de code. Comment vérifier? Extrayez votre code dans un fichier séparé avec l'extension .ps1et essayez d'appeler ce script à la place de votre code. Si cela fonctionne, le test a réussi.
mazzy
3

Mathematica, 46 octets

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

Fonction anonyme. Prend un nombre et une chaîne en entrée et retourne une chaîne en sortie. Pas grand chose à voir ici.

LegionMammal978
la source
3

Javascript - 54 47 46 octets

Refait:

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

Utilisé comme

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

Merci à @ETHproductions pour quelques quick Reg RegEx Merci à @Shaggy pour un octet supplémentaire dans l'eval!

Original:

(s,n)=>s.match(new RegExp('.{1,'+n+'}','g')).reverse()
Okiris Bleu
la source
1
Bonne réponse! Je crois que vous pouvez économiser quelques octets en créant la regex aveceval('/.{1,'+n+'}/g')
ETHproductions
@ETHproductions Ah oui. C'est ce que j'ai essayé de faire. Cependant, je n'étais pas assez familiarisé avec regex pour le faire!
Blue Okiris
Je pense que vous pouvez économiser un octet en currying,s=>n=> ...
Pavel
Enregistrez un octet avec eval("/.{1,${n}}/g"), en utilisant des guillemets au lieu de guillemets.
Shaggy
3

Pyth, 5 octets

s_c.*

Essayez-le en ligne .

Explication

   .*  splat implicit input
  c    split into chunks length n
 _     reverse
s      join
Trauma numérique
la source
3

Retina , 38 octets

1 octet enregistré grâce à @LeakyNun

^

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

(Notez l'espace sur la deuxième ligne et l'espace de fin)

Ce programme prend en entrée unaire sur la première ligne et la chaîne sur la seconde.

Essayez-le en ligne!

Suite de tests! (légèrement modifié)

Explication

La première étape consiste à prévoir un espace (qui deviendra important par la suite).

^
 

Maintenant nous inversons. Ceci utilise les groupes d'équilibrage .NET. Il est important de noter que les groupes ici agissent comme des piles, de sorte que chaque match est essentiellement poussé sur la pile. Ici, nous capturons chaque chiffre du nombre unaire dans le groupe 2. Maintenant, chaque fois qu'un caractère de la chaîne est trouvé, une correspondance est extraite du groupe 2. Cela garantit que le nombre de caractères ne dépasse pas celui du nombre unaire.

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

Et enfin, supprimez le nombre unaire et la nouvelle ligne.

 1+¶

Kritixi Lithos
la source
Je pense qu'il est acceptable de prendre le nombre unaire.
Leaky Nun
Quoi qu'il en soit, vous pouvez remplacer \dpar .pour sauvegarder un octet.
Leaky Nun
La seconde ^est également redondante.
Leaky Nun
@LeakyNun Le programme prend maintenant les entrées unaires, donc je n'en ai plus besoin \d. Et merci d'avoir joué au golf :)
Kritixi Lithos le
33 octets en utilisant une correspondance paresseuse (non gourmande).
Leaky Nun
3

Java, 147 138 octets

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

9 octets sauvés grâce à 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;}

Sous forme développée:

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

C’est en fait mon premier essai de codegolf, alors tout commentaire est le bienvenu!

bruderjakob17
la source
Bienvenue chez PPCG!
Pavel
1
Bonjour, bienvenue sur PPCG! C’est déjà très bien, mais il ya encore quelques petites choses à int l=s.length();for(int i=l/n*n;faire int l=s.length(),i=l/n*n;for(;pour jouer au golf: peut-être que vous n’avez qu’une int fois. Et if(!(i>=l))peut être if(l<i). Et r+=(i+n)>=l?peut être sans la parenthèse: r+=i+n>=l?. De plus, si vous ne l'avez pas encore vu, je vous conseillerais de consulter Conseils pour le golf en Java pour obtenir des conseils de golf très intéressants. :) Encore une fois, bienvenue.
Kevin Cruijssen le
3

Perl 5 , 25 octets

Utilise les -lnM5.010drapeaux.

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

Essayez-le en ligne!

Shoutout to Grinnz pour m'avoir parlé de =~ m/.{1,$n}/g

-M5.010active l'utilisation de la sayfonction qui, pour nous, est une impression avec un nom plus court.

-nmet la première ligne d'entrée dans $_, et-l écrase la nouvelle ligne.

Nous obtenons ensuite la deuxième ligne d’entrée en utilisant <>, et nous l’appliquons à la regex .{1,$_}: n’importe quel caractère, compris entre 1 et $ _ (la première entrée) fois. Comme cela est gourmand par défaut, il essaie de toujours faire correspondre les caractères $ _. Le 1,est nécessaire pour le reste de morceau possible à la fin.

Le /gmodificateur nous donne chaque correspondance de cette expression rationnelle dans la chaîne d'entrée sous forme de liste, qui est ensuite inversée et imprimée. En Perl, passer une liste à la sayjoindre sans aucun délimiteur par défaut.

Pavel
la source
3

Dyalog APL Extended , 16 à 15 octets

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

Essayez-le en ligne!

dzaima
la source
Vous n'avez pas besoin def←
Pavel
Pourquoi, ,/
Adám
@ Adám Oh, ça s'applique aussi à ma réponse, merci
Pavel
Pavel: Oui, évidemment .. @ Merci Adám!
dzaima
14:∊∘⌽⊢⊂⍨≢⍤⊢⍴1↑⍨⊣
Ven
2

Python, 62 octets

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

Essayez-le en ligne!

ovs
la source
La réponse de Python3 est plus courte et fonctionne également pour Python 2.7:f=lambda n,s:s and f(n,s[n:])+s[:n]
F1Rumors
2

QBIC , 24 octets

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

Cela fait un excellent usage de la nouvelle fonction de sous-chaîne que j'ai récemment ajoutée à 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
la source
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);}

Result is printed out to the standard output.

2501
la source
2

Scala, 57 55 bytes

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

Thanks Jacob! Try it here.

Note: By using the symbol form of foldLeft ("/:"), I was able to take off a couple more bytes.

jkeatley
la source
make it anonymous function, and use mkString instead of reduceLeft, and shave off 7 bytes: (n:Int,s:String)=>s.grouped(n).toSeq.reverse.mkString("")
Jacob
2

Ohm, 5 bytes

σ]QWJ

Try it online!

Explanation

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

R, 69 60 bytes

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

Try it online!

Thanks to Kirill L. for the suggestion to remove seq.

Giuseppe
la source
Looks like this works too for 66.
Kirill L.
@KirillL. we can go to 60 bytes if we reverse the order of arguments to : and some manipulation lets us get rid of the trailing -1.
Giuseppe
Smart, very nice!
Kirill L.