The program should receive a string/array of words as input. For each word in the string/array, it will reconstruct the word by taking characters in alternating fashion from the front and back of the word.

12345 678 9 -> 15243 687 9.

It will then rearrange the words in an alternating fashion between the earliest and the latest occurring word in the string.

15243 687 9 -> 15243 9 687

Finally, it will reconstruct the string by placing the spaces, tabs and newlines at the indexes where they were initially located before outputting the result.

12345 678 9-> 15243 687 9 -> 15243 9 687 -> 15243 968 7

Output should be the same datatype as the input.

Standard Loopholes are forbidden


The quick brown fox jumps over the lazy dog.
Teh d.ogq kucil yaz bnrwo tehf xoo rvej supm

The quick brown fox jumps
over the lazy dog.
Teh d.ogq kucil yaz bnrwo
tehf xoo rvej supm


This is so shortest code wins

  • 7
    \$\begingroup\$ This feels like a duplicate. I swear I've seen this before. \$\endgroup\$ Feb 7, 2017 at 18:49
  • \$\begingroup\$ So only tab, space and newline characters are not considered part of a word? \$\endgroup\$ Feb 7, 2017 at 18:50
  • \$\begingroup\$ @JonathanAllan that is correct \$\endgroup\$ Feb 7, 2017 at 18:51
  • \$\begingroup\$ Can we assume ASCII? or Unicode? \$\endgroup\$
    – bren
    Feb 7, 2017 at 22:29
  • \$\begingroup\$ @MayorMonty You can assume the characters are whichever form makes it easier for you so long as it treats spaces properly. \$\endgroup\$ Feb 7, 2017 at 23:20

6 Answers 6


Jelly, 15 14  8 bytes

A whopping 6 byte save from Dennis (by moving the flatten and mould inside link 1 there is no need to split into two and head, and a flatten is there already so they become one!)


(from the two lines: żṚFœs2Ḣ, and Ç€ÇFṁ⁸)

Try it online!

Takes an array of words and returns an array of new words. (The Footer at TIO calls this and joins the array with spaces so it prints out nicely.)

Note - handling a single string, splitting on tabs spaces and newlines, then reassembling was actually proving rather tricky; once I saw that a list of words was an option things got a lot easier!


Ç€Ç - Main link: list of words
Ç€  - call the last link (1) as a monad for €ach word
  Ç - call the last link (1) as a monad for the result

żṚFṁ - Link 1: Do a twist: list (here, a list of words or characters)
                            e.g. input = [A,B,C,D,E,F,G]
ż    - zip the list with                 [A,    B,    C,    D,    E,    F,    G]
 Ṛ   - the reverse of the list             [G,    F,    E,    D,    C,    B,    A]
  F  - flatten into a single list        [A,G,  B,F,  C,E,  D,D,  E,C,  F,B,  G,A]
   ṁ - mould like the input list         [A,G,B,F,C,E,D]
  • \$\begingroup\$ This should work. Try it online! \$\endgroup\$
    – Dennis
    Feb 8, 2017 at 1:52
  • \$\begingroup\$ Sweet save; too easy to forget that manoeuvre! \$\endgroup\$ Feb 8, 2017 at 15:11

JavaScript (ES6), 89 bytes

Takes and outputs an array of words.



let f =



String version, 112 bytes

Takes and outputs a string.



let f =


console.log(f(`The quick brown fox jumps over the lazy dog.`))

console.log(f(`The quick brown fox jumps
over the lazy dog.`))



Perl, 77 bytes

74 bytes of code + 3 bytes for -0pa flags.


Try it online!

Saved 8 bytes thanks to an old @Ton Hospel's post where I "stole" s/../chop/reg. (I previously had $c=y///c/2,s/.{$c}$//)


Perl 6, 84 bytes

{my &t={(|(.shift,.pop)xx*)[^$_]}
map({|t [.comb]},t [$_]).rotor($_».chars)».join}

Inputs and outputs a list of words.

How it works

Inside the lambda, I defined another lambda to perform the "taking characters in alternating fashion from the front and back" twisting:

my &t={                        }   # Lambda, assigned to a variable.
          .shift,.pop              # Remove an element from the front an back,
                      xx*          # an infinite number of times,
        |(           )             # and make sure this infinite list is flattened.
                          [^$_]    # Take as many elements as the input had elements.

This works because the xx operator is more like a macro than a function, in that it provides magic lazy evaluation.

Then in the main lambda:

                   [$_]                          # Create a fresh array from the input,
                 t                               # and twist it (destructively).
map({          },                                # For each element (i.e. word):
      t [.comb]                                  #   Split it into characters and twist them,
     |                                           #   and slip them into the outer list.
                        .rotor($_».chars)        # Partition this flat list of characters,
                               $_».chars         # using the original word lengths.
                                         ».join  # Turn each sub-list into a word.

Perl 6, 87 bytes

{my &t={(|(.shift,.pop)xx*)[^$_]}
my @a=map {|t [.comb]},t [.words];S:g/\S/{@a.shift}/}

This is a variation of the above, which inputs and outputs a string – preserving different whitespace characters.


Haskell, 115 95 93 98 95 bytes

f(a:b)=a:f(reverse b)
f e=e
a!(y:z)|elem y" \t\n"=y:a!z|b:c<-a=b:c!z

Call with (!)=<<(f=<<).f.words $ "some string". Try it online!

Thanks to @nimi for pointing out that I misread the challenge earlier.

The function f performs the twisting on a list, so it can be used on strings (list of chars) and a list of strings. a!b inserts the whitespace of string b into string a.

(!)=<<(f=<<).f.words is equivalent to \s0 -> (concatMap f . f . words $ s0) ! s0:

            s0 = "The quick brown fox jumps\nover the lazy dog."
      words s0 = ["The","quick","brown","fox","jumps","over","the","lazy","dog."] = s1
          f s1 = ["The","dog.","quick","lazy","brown","the","fox","over","jumps"] = s2
concatMap f s2 = "Tehd.ogqkucilyazbnrwotehfxoorvejsupm"                           = s3
       s3 ! s0 = "Teh d.ogq kucil yaz bnrwo\ntehf xoo rvej supm"

Husk, 14 bytes


Try it online!

This doesn't work with a reusable function since a function can only support one type of arguments.


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.