Twisting Sentences

17

1

Rules

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

Examples

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

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

Input:
Aflack
Output:
Akfcla

This is so shortest code wins

fəˈnɛtɪk

Posted 2017-02-07T18:44:38.270

Reputation: 4 166

6This feels like a duplicate. I swear I've seen this before. – Addison Crump – 2017-02-07T18:49:17.860

So only tab, space and newline characters are not considered part of a word? – Jonathan Allan – 2017-02-07T18:50:21.497

@JonathanAllan that is correct – fəˈnɛtɪk – 2017-02-07T18:51:41.750

Can we assume ASCII? or Unicode? – MayorMonty – 2017-02-07T22:29:28.267

@MayorMonty You can assume the characters are whichever form makes it easier for you so long as it treats spaces properly. – fəˈnɛtɪk – 2017-02-07T23:20:04.770

Answers

3

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

żṚFṁ
Ç€Ç

(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!

How?

Ç€Ç - 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]
                                        [[A,G],[B,F],[C,E],[D,D],[E,C],[F,B],[G,A]]
  F  - flatten into a single list        [A,G,  B,F,  C,E,  D,D,  E,C,  F,B,  G,A]
                                         [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]

Jonathan Allan

Posted 2017-02-07T18:44:38.270

Reputation: 67 804

This should work. Try it online!

– Dennis – 2017-02-08T01:52:56.220

Sweet save; too easy to forget that manoeuvre! – Jonathan Allan – 2017-02-08T15:11:42.727

2

JavaScript (ES6), 89 bytes

Takes and outputs an array of words.

a=>a.map(w=>(F=([a,...b])=>a?a+(b.pop()||'')+F(b):'')(a.map(F)).slice(p,p+=w.length),p=0)

Test

let f =

a=>a.map(w=>(F=([a,...b])=>a?a+(b.pop()||'')+F(b):'')(a.map(F)).slice(p,p+=w.length),p=0)

console.log(
  JSON.stringify(
    f(["The","quick","brown","fox","jumps","over","the","lazy","dog."])
  )
);

String version, 112 bytes

Takes and outputs a string.

s=>s.replace(/\S+/g,w=>(F=([a,...b])=>a?a+(b.pop()||'')+F(b):'')(s.split(/\s/).map(F)).slice(p,p+=w.length),p=0)

Test

let f =

s=>s.replace(/\S+/g,w=>(F=([a,...b])=>a?a+(b.pop()||'')+F(b):'')(s.split(/\s/).map(F)).slice(p,p+=w.length),p=0)

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

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

console.log(f(`Aflack`))

Arnauld

Posted 2017-02-07T18:44:38.270

Reputation: 111 334

2

Perl, 77 bytes

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

map{s/.\K/chop/ge,s/../chop/reg}@F;s/\S/($r||=$F[$i++].pop@F)=~s%.%%,$&/ge

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

Dada

Posted 2017-02-07T18:44:38.270

Reputation: 8 279

0

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.

smls

Posted 2017-02-07T18:44:38.270

Reputation: 4 352

0

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
a!z=z
(!)=<<(f=<<).f.words

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"

Laikoni

Posted 2017-02-07T18:44:38.270

Reputation: 23 676