15
\$\begingroup\$

Intro/Background

I was looking at a Flybuys card at Coles recently and noticed that if I took something like this:

Flybuys Source, randomly found on the Internet

And swapped some words around, I'd get this:

Buyflys

After I finished laughing (don't judge my sense of humour please), I said to myself: "I need a program that can generate text like that". So I devised a set of rules for substring swapping and wrote yet another CGCC challenge!

The Challenge

Given a single string as input, output a string with its substrings swapped. This can be done by:

  • Splitting the string into chunks of three. The last triplet can possibly be shorter. (abcdefgh => [abc, def, gh])
  • Swap every triplet with every other triplet, leaving the last triplet in place if there is an odd amount of triplets.

The above bullet point more succinctly:

[D]ivide the list into adjacent pairs and swap each pair ~ @FlipTack

Test Cases

Input->Output 
flybuys->buyflys
Once->eOnc
Triplet->pleTrit
Code Golf->e GCodolf
TopAnswers!->AnsTops!wer
Never gonna let you down->er Nevna gon yoletownu d
I'm Sorry, I Haven't a Clue-> SoI'm, Irryven Haa C't lue
Can I please have my vegetables back?-> I Canasepleve  havegmy bleetaacks b?
You are filled with determination-> arYouille fwited eteh dnatrmiion
->

Reference Program

Some Test Cases Explained

flybuys
[fly, buy, s] (split)
[buy, fly, s] (swapped)
buyflys

Once
[Onc, e] (split)
[e, Onc] (swapped)
eOnc

Triplet
[Tri, ple, t] (split)
[ple, Tri, t](swapped)
pleTrit

Code Golf
[Cod, e G, olf] (split)
[e G, Cod, olf] (swapped)
e GCodolf

TopAnswers!
[Top, Ans, wer, s!] (split)
[Ans, Top, s!, wer] (swapped)
AnsTops!wer

Rules

  • Input/output can be taken/given in any reasonable and convenient format
  • The input will not contain newlines
  • Strings can be of any length, and can be empty
  • Input will only contain printable ASCII characters
  • All standard loopholes are forbidden

Scoring

This is , so the answer with the lowest bytes wins

\$\endgroup\$
  • 1
    \$\begingroup\$ Maybe this could use some better wording - how about "divide the list into adjacent pairs and swap each pair"? \$\endgroup\$ – FlipTack Feb 2 at 11:10
  • 4
    \$\begingroup\$ No, the output for Input should be putIn. \$\endgroup\$ – S.S. Anne Feb 2 at 16:55
  • 3
    \$\begingroup\$ @S.S.Anne I assume you mean output for Input should be utInp per the Reference Program. Though I get you were saying that humorously. :) \$\endgroup\$ – 640KB Feb 2 at 20:52

26 Answers 26

8
\$\begingroup\$

J, 13 bytes

[:;_2|.\_3<\]

Try it online!

Example input: 'flybuys'

  • _3<\] Box every group of 3

    ┌───┬───┬─┐
    │fly│buy│s│
    └───┴───┴─┘
    
  • _2|. Split that into groups of 2, and reverse each one:

    ┌───┬───┐
    │buy│fly│
    ├───┼───┤
    │s  │   │
    └───┴───┘
    
  • [:; Raze the result:

    buyflys
    
|improve this answer|||||
\$\endgroup\$
7
\$\begingroup\$

Perl 6, 24 bytes

{S:g/(...)(..?.?)/$1$0/}

Try it online!

Simple regex substitution that swaps every pair of three and up to three.

|improve this answer|||||
\$\endgroup\$
5
\$\begingroup\$

Gema, 13 characters

<u3><u3>=$2$1

Sample run:

bash-5.0$ echo -n 'flybuys' | gema '<u3><u3>=$2$1'
buyflys

Try it online! / Try all test cases online!

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I immediately thought of Gema when I saw this challenge and was wondering if you'd reply. It's as elegant as I thought it would be. \$\endgroup\$ – Jonah Feb 2 at 11:53
5
\$\begingroup\$

Brainfuck, 37 33 bytes

,[>,>,>>,>,>,<<[.>]<[<]<<<[.>]>,]

-4 bytes thanks to @JoKing

You can try it online

Cell layout is |a|b|c|0|d|e|f|, I read unconditionally and then print what is there to be printed.

Probably still golfable...

|improve this answer|||||
\$\endgroup\$
5
\$\begingroup\$

APL (Dyalog Unicode), 17 bytesSBCS

⍬∘(⍋⍋-6×3≤6|⍋)⊃¨⊂

Try it online!

Uses ⎕IO←0, i.e. 0-based indexing.

How it works

Uses ⍬⍋ generating index trick, though simply using ⍳≢ gives the same byte count here (thanks @ngn for pointing this out).

⍬∘(⍋⍋-6×3≤6|⍋)⊃¨⊂
⍬∘( ⍋-6×3≤6|⍋)     ⍝ Generate some numbers to apply "sortBy" on the input
⍬∘          ⍋        ⍝ Generate 0-based indexes
          6|         ⍝ Modulo 6
        3≤           ⍝ 1 if 3≤x is true, 0 otherwise
      6×             ⍝ 6 times
⍬∘  ⍋-               ⍝ Subtract from the original 0-based indexes;
                     ⍝ the result looks like 0 1 2 ¯3 ¯2 ¯1 6 7 8 3 4 5 12 13 ..
   ⍋          ⊃¨⊂  ⍝ "sortBy"; sort the input in the increasing order of above
|improve this answer|||||
\$\endgroup\$
4
\$\begingroup\$

Jelly, 5 bytes

s3ṭ2/

A full program accepting a string which prints the result.

Try it online!

How?

s3ṭ2/ - Main Link: list of characters
s3    - split into threes
   2/ - 2-wise reduce with:
  ṭ   -   tack
      - implicit, smashing print
|improve this answer|||||
\$\endgroup\$
4
\$\begingroup\$

PHP, 60 57 bytes

for($a=str_split($argn,3);$b=$a[$i++|0];)echo$a[$i++],$b;

Try it online!

|improve this answer|||||
\$\endgroup\$
3
\$\begingroup\$

W, 5 bytes

"jC?┐

Uncompressed

3,2,_r

Explained

3,%Split the input into chunks of three
2,%Group the inputs into chunks of two
_r%Reverse every two-chunk of the input
|improve this answer|||||
\$\endgroup\$
3
\$\begingroup\$

JavaScript (Node.js), 36 bytes

x=>x.replace(/(...)(..?.?)/g,"$2$1")

Try it online!

Simple regex substitution.

|improve this answer|||||
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 6 bytes

3ô2ôíS

Outputs as a list of characters.

Try it online or verify all test cases.

Explanation:

3ô      # Split the (implicit) input-string into parts of size 3
  2ô    # Split this list into parts of size 2
    í   # Reverse each inner pair of triplets
     S  # Convert it to a flattened list of characters
        # (after which this is output implicitly)
|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

GolfScript, 10 bytes

3/2/{-1%}%

Try it online!

Explanation

3/         # Split the input into chunks of three
  2/       # Group the inputs into chunks of two
    {-1%}% # Reverse every two-chunk of the input
           # This deals with the last two-chunk, in which
           # no reversing is done
|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

Jelly, 6 bytes

s3s2Ṛ€

Try it online!

A full program taking a string and implicitly printing the rearranged string. This could be turned into a monadic link that returns a Jelly string by adding F (flatten) to the end.

Explanation

s3     | Split into sublists length 2
  s2   | Split into sublists length 2
    Ṛ€ | Reverse each
|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

Charcoal, 10 bytes

⭆⪪S⁶⪫⮌⪪ι³ω

Try it online! Link is to verbose version of code. Splitting into groups of 6 and splitting those works out shorter because it keeps the two numbers separate. Explanation:

  S         Input string
 ⪪ ⁶        Split into substrings of 6 characters
⭆           Map over substrings and join
       ι    Current substring
      ⪪ ³   Split into substrings of 3 characters
     ⮌      Reverse the substrings
    ⪫    ω  Join together
            Implicitly print
|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

Haskell, 50 42 bytes

s(a:b:c:d)=take 3d++a:b:c:s(drop 3d)
s x=x

-8 bytes thanks to Post Rock Garf Hunter.

Try it online!

|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), 15 bytes

,//|'0N 2#0N 3#

Try it online!

0N 3# chunks of 3; last may be shorter

0N 2# pairs of chunks; last may be a singleton list

|' reverse each

,// flatten

|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

Factor, 62 bytes

: f ( s -- s ) 3 group 2 group [ reverse concat ] map concat ;

Try it online!

Factor defies golfing :)

|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

Burlesque, 13 bytes

3co2co)<-FL\[

Try it online!

3co # Chunks of 3
2co # Chunks of 2
)<- # Map - Reverse
FL  # Flatten
\[  # Concatenate
|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Japt -P, 7 bytes

ò3 ò cw

Try it

|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

PHP, 153 bytes

$c=($h='array_chunk')($h(str_split($argn),3),2);foreach($c as&$i)count($i)-1&&[$i[0],$i[1]]=[$i[1],$i[0]];echo implode(($m='array_merge')(...$m(...$c)));

Try it online!

|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Lua, 43 bytes

print(((...):gsub('(...)(.?.?.?)','%2%1')))

Try it online!

Take input as argument, print result to stdout. TIO link include program that check all testcases given in question. Uses Lua patterns to capture three and up to three characters, then swap those groups.

|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 21 bytes

s/(...)(..?.?)/$2$1/g

Try it online!

|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Red, 59 bytes

func[s][until[move/part skip s 3 s 3""= s: skip s 6]head s]

Try it online!

|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Ruby, 33 bytes

->s{s.gsub /(...)(.{,3})/,'\2\1'}

Try it online!

|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Python 3, 67 77 75 63 bytes

s is the variable holding the string to manipulate.

''.join(sum([(s[k+3:k+6],s[k:k+3]) for k in range(0,len(s),6)],()))

Try it online!

Edit: 77 bytes to respect the rules of Code Golf

f=lambda s:''.join(sum([(s[k+3:k+6],s[k:k+3])for k in range(0,len(s),6)],()))

Try it online!

Edit 2: Dropped the f=

lambda s:''.join(sum([(s[k+3:k+6],s[k:k+3])for k in range(0,len(s),6)],()))

Try it online!

Edit 3: Post Rock Garf Hunter made this version which gets rid of the sum(...,()) call, bringing the byte count down to 63!

lambda s:''.join(s[k+3:k+6]+s[k:k+3]for k in range(0,len(s),6))

Try it online!

|improve this answer|||||
\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome to the site. We don't do input from variables here for a number of reasons. You should rewrite your submission to either define a function or be a complete program. \$\endgroup\$ – Ad Hoc Garf Hunter Feb 3 at 4:51
  • \$\begingroup\$ You can read about how we do input on this post. Prepending your answer with lambda s: will make it valid, but will cost you \$\endgroup\$ – Ad Hoc Garf Hunter Feb 3 at 4:52
  • \$\begingroup\$ Thank you! I modified the entry accordingly. I added a f= so that it is callable. From my understanding prepending lambda s: creates an anonymous lambda which would need to be called right away? \$\endgroup\$ – Maxime Alvarez Feb 3 at 5:44
  • 1
    \$\begingroup\$ I don't think you can, but the rest can be Try it online!. \$\endgroup\$ – Ad Hoc Garf Hunter Feb 3 at 14:02
  • 1
    \$\begingroup\$ Oh yes, the concatenation instead of tuples, makes the list 1-dimensional which allows us to get rid of the sum(...), very nice! \$\endgroup\$ – Maxime Alvarez Feb 4 at 0:33
1
\$\begingroup\$

naz, 210 190 bytes

2a2x1v1x1f1r3x1v2e2x2v1r3x1v3e2x3v1r3x1v4e2x4v1r3x1v5e2x5v1r3x1v6e2x6v1r3x1v7e2x7v5v1o6v1o7v1o2v1o3v1o4v1o1f0x1x2f0a0x1x3f2v1o0x1x4f2v1o3v1o0x1x5f2v1o3v1o4v1o0x1x6f5v1o5f0x1x7f5v1o6v1o5f0x1f

I finally fixed the bug in the linked implementation that made solving challenges like this one impossible!

The main part of this program uses a ton of conditional instructions to properly split strings of any length, so I've split it onto multiple lines in the below explanation to aid readability.

Works for any input string terminated with the control character STX (U+0002).

Edit: Saved 20 bytes by calling function 5 directly from functions 6 and 7 instead of repeating its logic verbatim.

Explanation (with 0x commands removed)

2a2x1v                       # Set variable 1 equal to 2
1x1f1r3x1v2e2x2v             # Function 1
                             # Read a byte of input
                             # Jump to function 2 if it equals variable 1
                             # Otherwise, store it in variable 2
  1r3x1v3e2x3v               # This pattern continues for the next 5 bytes of input
  1r3x1v4e2x4v               # ...
  1r3x1v5e2x5v               # ...
  1r3x1v6e2x6v               # ...
  1r3x1v7e2x7v               # ...
  5v1o6v1o7v1o2v1o3v1o4v1o   # Output variables 5, 6, and 7, then variables 2, 3, and 4
                          1f # Then, jump back to the start of the function
1x2f0a                       # Function 2
                             # Add 0 to the register
1x3f2v1o                     # Function 3
                             # Output variable 2
1x4f2v1o3v1o                 # Function 4
                             # Output variables 2 and 3
1x5f2v1o3v1o4v1o             # Function 5
                             # Output variables 2, 3, and 4
1x6f5v1o5f                   # Function 6
                             # Output variable 5, then variables 2, 3, and 4
1x7f5v1o6v1o5f               # Function 7
                             # Output variables 5 and 6, then variables 2, 3, and 4
1f                           # Call function 1
|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Kotlin, 64 bytes

{chunked(3).chunked(2).fold(""){a,v->a+v.getOrElse(1){""}+v[0]}}

{chunked(3)                                                       // split string into triplets
           .chunked(2)                                            // group triplets by two
                      .fold(""){a,v->a+                           // join to string
                                       v.getOrElse(1){""}+v[0]}}  // putting second before first (if exists) 

Try it online!

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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