40
\$\begingroup\$

Your task is to write a program which, given a number and a string, splits the string into chunks of that size and reverses them.

Rules

Your program will receive a positive integer n, as well as a string s with length at least one consisting of only printable ASCII (not including whitespace). The string should then be split into chunks of length n, if the length of the string isn't divisible by n any leftover at the end should be considered its own chunk. Then, reverse the order of the chunks and put them together again.

Test Cases

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

This is , so you should aim for as few bytes as possible.

\$\endgroup\$
1

58 Answers 58

1
2
2
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ Looks like this works too for 66. \$\endgroup\$
    – Kirill L.
    Commented Mar 20, 2019 at 19:43
  • \$\begingroup\$ @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. \$\endgroup\$
    – Giuseppe
    Commented Mar 20, 2019 at 19:48
  • \$\begingroup\$ Smart, very nice! \$\endgroup\$
    – Kirill L.
    Commented Mar 20, 2019 at 19:49
2
\$\begingroup\$

><>, 37 34 bytes

1[&\&
0=?\i:0(?v}l&:&%
28o ]!?l~<.

Try it online!

\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Unicode), 14 bytesSBCS

∊∘⌽⊢⊂⍨⊢∘≢⍴1↑⍨⊣

Try it online!

Explanation:

∊∘⌽⊢⊂⍨⊢∘≢⍴1↑⍨⊣ ⍝ This is a giant composed function, made of all these pieces:
               ⍝ Left argument: ⍺, the split size (refered as ⊣)
               ⍝ Right argument: ⍵, the string (refered as ⊢)
          1↑⍨⊣ ⍝ Swapped operator ↑:
               ⍝     Start with a 1, then pads with `0` until size ⍺
      ⊢∘≢      ⍝ Get the tally (≢) composed with ⊢, gives the of length ⊢
         ⍴     ⍝ Reshape the list of 1 0 0... into the size of the string:
               ⍝     As opposed to ↑, this will repeat the sequence instead of padding with 0. Gives (1 0 0 1 0 0) for a string of length 6.
   ⊢⊂⍨         ⍝ Swapped operator ⊂:
               ⍝ Split the string at all the 1s
  ⌽            ⍝ Reverse the list
∊              ⍝ Enlist, flattens
 ∘             ⍝ (composition necessary for parsing precedence)

Works similarly to @dzaima's, though it took me a lot of attempts to get there.

¹

\$\endgroup\$
2
\$\begingroup\$

PHP, 78 bytes

function h($n,$s){return$n>strlen($s)?$s:h($n,substr($s,$n)).substr($s,0,$n);}

Try it online!

Shockingly, there's no other submission for this using recursion in PHP. I mean, when you think PHP you think recursion, right?

Ungolfed

function g($n, $s) {
    if ( $n > strlen( $s ) ) {
        return $s;
    } else {
        return g( $n, substr( $s, $n ) ) . substr( $s, 0, $n );
    }
}
\$\endgroup\$
2
\$\begingroup\$

J-uby, 25 bytes

~:each_slice%A|A|:~|:join

Attempt This Online!

\$\endgroup\$
2
\$\begingroup\$

Arturo, 32 bytes

$=>[split.every:&&|reverse|join]

Try it!

\$\endgroup\$
1
\$\begingroup\$

C++, 111 bytes

#import<string>
using S=std::string;S f(S s,int n){S r;for(int i=0;i<s.size();i+=n)r=s.substr(i,n)+r;return r;}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Octave, 44 bytes

@(n,s){[~,I]=sort(-ceil(find(s)/n));s(I)}{2}

Try it online!

or

Verify all test cases!

Explanation:

Example input: s = 'abcdefgh' and n = 3

-ceil(          %round and negate
    find(s)     %generate a range from 1 to len(s)
    /n          %divide by n
    )       
       
a=-ceil([1 2 3 4 5 6 7 8]/3) =
 
    a = -1  -1  -1  -2  -2  -2  -3  -3
 
[~,I] = sort(a)  %return index of sorted elements

    I = 7   8   4   5   6   1   2   3
s(I)             %sort s by I
      = ghdefabc    
\$\endgroup\$
1
\$\begingroup\$

k, 13 bytes

{,/|(x,0N)#y}

Takes in a number x, and a string y. Splits the string y into a list of strings of length x with (x,0N)#y, reverses the list with |, and turns it into one string by folding join through the list with ,/.

\$\endgroup\$
1
\$\begingroup\$

Haskell, 40 37 bytes

n#""=""
n#s|(a,b)<-splitAt n s=n#b++a

Usage example: 2 # "abcdefgh" -> "ghefcdab". Try it online!

Split the input string s at position n and into a (first part) and b (second part). Return a recursive call with b appended by a. The base case is the empty input string, where the result is also the empty string.

Note: splitAt returns the whole string as the first part and the empty string as the second part if the position is greater than the length of the string (splitAt 5 "a" -> ("a","")).

Edit: @Ørjan Johansen saved 3 bytes. Thanks!

\$\endgroup\$
2
  • \$\begingroup\$ It's shorter to make a pattern match with n#""="". \$\endgroup\$ Commented Apr 15, 2017 at 2:26
  • \$\begingroup\$ non-competing pointfree version, just for fun: import Data.Lists;((concat.reverse).).chunk \$\endgroup\$ Commented Apr 15, 2017 at 18:03
1
\$\begingroup\$

Cheddar, 25 bytes

s->n->s.chunk(n).rev.fuse

Try it online!

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 75 bytes

$n,$r=$args;if($r-match"(.{1,$n})(.*)"){$s=&$f $n $matches.2;$s+$matches.1}

*I'm guessing that it may be a repeating in a some sense but it's the Recursion
** It's a few bit of fat-free version

Try it online

\$\endgroup\$
1
\$\begingroup\$

Clojure, 50 bytes

#(apply str(flatten(reverse(partition-all % %2))))

Just following the spec, couldn't figure how to make it any shorter.

\$\endgroup\$
1
\$\begingroup\$

Implicit, 4 3 bytes

×®"

Try it online!

×®"    « input: string, integer               »;
×      « split string into chunks of integer  »;
 ®     « reverse entire stack                 »;
  "    « stringify entire stack               »;
       « implicit string output               »;
\$\endgroup\$
1
\$\begingroup\$

REXX, 69 bytes

parse arg s,n,c
do length(s)%n+1
  parse var s b+(n) s
  c=b||c
  end
say c

Explanation:

  1. Get arguments s and n. Given that there are only two arguments, c will be initialized as empty.
  2. Loop for the length of s MOD n adding 1 to account for leftovers.
  3. For each iteration, chop off n characters from beginning of s and store them in b, then append b to beginning of c.
\$\endgroup\$
1
\$\begingroup\$

Husk, 3 bytes

Σ↔C

Try it online!

Takes input as two separate command-line arguments, which thanks to Husk's strong typing and overloaded builtins, don't actually need to be in any particular order since they both get fed directly into C, which cuts whichever one of its arguments is a list into sublists of the length given by whichever argument is a number.

Σ      Concatenate
 ↔     the reversed
  C    chunks of the given length of the string input.
\$\endgroup\$
1
\$\begingroup\$

Forth (gforth), 101 bytes

: f >r dup i mod tuck - dup 3 pick + rot type i - -1 max r> -1 rot ?do over i + over type dup -loop ;

Try it online!

Definitely not the most golfed it could be, but this one requires more stack manipulation than usual, so it's a bit more complicated to golf.

Explanation

  • Get string-length % chunk-size
  • Print string-length % chunk-size characters starting from addr + (string-length - (string-length % chunk-size)) [effectively, we're printing the last chunk separate, since it's size might be smaller than the chunk-size]
  • Loop backwards from the start of the last chunk to the beginning of the string, printing the appropriate chunk for each iteration of the loop

Code Explanation

: f            \ start a new word definition
  >r           \ stick chunk-size on the return stack (accessible by i)
  dup i mod    \ duplicate string-length and length%chunk-size (size of last chunk)
  tuck -       \ make copy of last-chunk-size then get last-chunk start position
  dup 3 pick + \ add last-chunk position to string address to get address of last-chunk
  rot type     \ print last-chunk
  i -          \ subtract chunk-size from last-chunk position to get second-to-last chunk position
  -1 max       \ change to -1 in case string is smaller than chunk-size
  r> -1 rot    \ move chunk-size off return stack, end loop at -1, and arrange params for loop
  ?do          \ start loop from last-chunk-pos to -1
    over i +   \ get current chunk start address
    over type  \ print current chunk
    dup        \ duplicate chunk-size
  -loop        \ subtract chunk-size from loop-index and end loop body
;              \ end word definition
\$\endgroup\$
1
\$\begingroup\$

APL (Dyalog Classic), 22 bytes

{0~⍨∊⊖(⌈⍺÷⍨≢⍵)⍺⍴⍵,⍺⍴0}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 74 bytes

	S =INPUT
	N =INPUT
S	S LEN(N) . X REM . S	:F(O)
	O =X O
O	OUTPUT =S O
END

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt -P, 4 bytes

òV w

Try it

òV w     :Implicit input of string U and integer V
òV       :Split U into chunks of length V
   w     :Reverse
         :Implicitly join & output
\$\endgroup\$
1
\$\begingroup\$

Elixir, 35 bytes

&Enum.reverse Enum.chunk_every&2,&1

Try it online!

\$\endgroup\$
1
\$\begingroup\$

APL(NARS), 73 chars, 146 bytes

r←a f w;k;i;j
k←≢w⋄i←1⋄j←a⋄r←⍬
→3×⍳i>k⋄r←r,⊂w[i..k⌊j]⋄i+←a⋄j+←a⋄→2
r←∊⌽r

This is better because easier to write and to read... test:

  2 f '123'
312
 2 f 'abcdefgh'
ghefcdab
  3 f 'foobarbaz'
bazbarfoo
  2 f 'aaaaaa'
aaaaaa
  2 f 'baaaab'
abaaba
  50 f 'abcdefgh'
abcdefgh
  6  f  'abcdefghi' 
ghiabcdef
\$\endgroup\$
1
  • \$\begingroup\$ @dzaima now it is ok that input output \$\endgroup\$
    – user58988
    Commented Mar 20, 2019 at 19:26
1
\$\begingroup\$

Perl 5, 29 bytes

My solution is almost the same as @Pavel. Uses the -lnM5.010 flags. Just another 4-byte longer way to split line with unpack instead regexp match. Needs one to calc penalty bytes for 3 flags? Takes flag M5.010 only one byte penalty?

say reverse unpack"(A$_)*",<>

Try it online!

\$\endgroup\$
0
1
\$\begingroup\$

q, 20 bytes

An anonymous composition of built-ins:

'[raze reverse@;cut]

Example:

q)'[raze reverse@;cut][2;"abcdefghi"]
"ighefcdab"

(equivalent to lambda {raze reverse x cut y})

\$\endgroup\$
2
  • \$\begingroup\$ Where can I find an interpreter or compiler for this language? \$\endgroup\$
    – Pavel
    Commented Sep 23, 2019 at 8:57
  • \$\begingroup\$ See kx.com/connect-with-us/download \$\endgroup\$
    – skeevey
    Commented Sep 23, 2019 at 17:10
1
\$\begingroup\$

Perl 6, 11 bytes

&[R~]o&comb

Try it online!

Anonymous combination of two functions, &comb, which splits a string into chunks of size n, and &[R~], which reverse concatenates a list.

\$\endgroup\$
1
\$\begingroup\$

Vyxal s, 2 bytes

/Ṙ

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Factor, 24 bytes

[ group reverse concat ]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Thunno 2 J, 2 bytes

ẇr

Attempt This Online!

Explanation

ẇr  # Implicit input
ẇ   # Split (input 1) into chunks of length (input 2)
 r  # Reverse the resulting list
    # Implicit output, joined
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.