Let's start by defining a reflection of a character in a string:

Given a string with distinct lowercase alphabetical letters with no spaces such as abcdefg, define a reflection of a letter in the string c as moving it (without changing the order of any other letter) to a new place in the string such that the number of letters originally to the right of it is now the number of letters to the left of it.

Thus, a reflection of the letter c in abcdefg would be abdecfg. Explanation: there were 4 letters to the right of c and now, there are 4 letters to the left of c.

Some more examples:

Reflecting the character e in myfriend would form the string myefrind

Reflecting the character a in axyz would form the string xyza.

Reflecting the character b in abc would form the string abc.

Reflecting the character d in d would form the string d.

Reflecting the character e in ef would form the string fe.

For more information or to try out some test cases, here is a (somewhat long) program I wrote in C++.

The Challenge

Given a string with distinct lowercase letters, go through each character alphabetically and "reflect" it in the string.

Clarifications: The letters in the string are from a-z, there are no spaces, the letters are unique, and the string is at least 1 letter long and at most 26 letters long.


Input: dcba. Output: dcba.

Reason: First, reflect the a as it is the character in the string that comes earliest in the alphabet. You will get adcb. Then, reflect the b as it comes next in the alphabet, to get badc. Then, reflect the c to get cbad, and then the d to get dcba.

Input: myface. Output: fyecma.

Hint: Go through the letters in the order a, c, e, f, m, y.

Input: a. Output: a.

Input: acb. Output: bac.

Input: cwmfjordbankglyphsvextquiz. Output: ieabhqzugdltkfnvpjxsormycw.


  • The input and output can be given by any convenient method.
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
  • Accepting ~100 hours after posting.

Current Winner

<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 162891; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 12012; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>

  • 2
    \$\begingroup\$ Could anyone give me insight as to whether this puzzle is okay? It's my second one here (my first was closed as off-topic...whoops). I tried to make it really complete, but I'm not sure if I'm missing anything. I'd really like to improve and have fun on this SE! Thanks guys :D \$\endgroup\$ – NL628 Apr 20 '18 at 2:57
  • 7
    \$\begingroup\$ This looks good. I might give a few longer examples (in particular, it might be good for the first examples section to present more than what are seemingly edge cases). \$\endgroup\$ – Esolanging Fruit Apr 20 '18 at 3:36
  • 1
    \$\begingroup\$ Clarification request: "the letters are unique" means each letter occurs only once in input, is that correct? \$\endgroup\$ – GPS Apr 20 '18 at 5:06
  • 4
    \$\begingroup\$ Can we take the input and output in uppercase instead of lowercase? \$\endgroup\$ – Kevin Cruijssen Apr 20 '18 at 7:05
  • 5
    \$\begingroup\$ @NL628 By the way, if you want to get insight on a challenge before posting it here, then post it in the Sandbox. \$\endgroup\$ – Erik the Outgolfer Apr 20 '18 at 12:01

19 Answers 19


Brain-Flak, 188 bytes


Try it online!

In addition to the reflections described in the challenge specification, this code also reverses the string exactly 26 times. This has no effect on the final output.

# Push 26

# Do 26 times:

  # Subtract 122 from counter to get negative lowercase letter

  # For each character in string:

    # Keep a copy of pivot letter on the third stack

    # Move next letter to other stack and compare to pivot

    # If letters are equal:

      # Keep current letter separate from this transformation

      # While keeping a copy of current stack height:

        # Move all letters to one stack


      # Move a number of letters equal to old stack height back




  # Destroy pivot letter


# Switch stack for output
  • 1
    \$\begingroup\$ Wow that's pretty amazing. I can't even understand it :O +1 \$\endgroup\$ – NL628 Apr 20 '18 at 3:51

05AB1E, 20 17 bytes


Try it online!


With example for the first iteration of myface

{v                  # for each char y in sorted input
  ð.ø               # surround current string with spaces
                    # STACK: ' myface '
     y¡             # split at current letter
                    # STACK: [' myf', 'ce ']
       ۇ           # remove non-letters
                    # STACK: ['myf','ce']
         €g        # get the length of each string in the pair, reversed
                    # STACK: ['myf','ce'], [2,3]
            sJ      # join the pair back to a string
              £     # split into 2 pieces of the calculated sizes
                    # STACK: ['my','fce']
               yý   # join on the current char y
                    # STACK: 'myafce'

The string is surrounded with spaces each iteration as splitting on the first or last letter of the string would result in a length-1 list otherwise and the merge wouldn't include that letter.

  • 1
    \$\begingroup\$ 17 bytes?!??!! AMAZING..yet mnemonic is beating you by just one byte :P \$\endgroup\$ – NL628 Apr 20 '18 at 17:44
  • 1
    \$\begingroup\$ Mmmm... Wow, only thing I could see is removing the surround with spaces. Seems odd we can't find another alternative to that. \$\endgroup\$ – Magic Octopus Urn Apr 23 '18 at 0:11
  • 1
    \$\begingroup\$ @MagicOctopusUrn: It's the shortest way I've found of handling a split of the first or last character. It does feel like a lot of bytes just for that though \$\endgroup\$ – Emigna Apr 23 '18 at 6:29

Pyth, 18 16 19 16 bytes


Try it here


VSQ           )       For each character (N) in the sorted input (Q)...
          -QN         ... remove the character from Q...
      x_QN            ... get the reflected position...
     X       N        ... insert N...
   =Q                 ... and save the result into Q.
               Q      Output the final result.
  • \$\begingroup\$ Wow 16 bytes? I would upvote, but sadly I've reached my daily voting limit. Will do in 6 hours :P \$\endgroup\$ – NL628 Apr 20 '18 at 17:44

Python 3, 80 73 bytes

Thanks to Esolanging Fruit for reminding me that functions can return by modifying their argument.

lambda x:[x.insert(len(x)+~x.index(i),x.remove(i)or i)for i in sorted(x)]

Try it online!

Takes input as a list of characters.

  • 3
    \$\begingroup\$ Wow I wrote an answer in C++ and Python 3 also. My Python 3 answer was exactly twice as long as yours... +1 \$\endgroup\$ – NL628 Apr 20 '18 at 3:52

Python 2, 70 bytes

def f(t):
 for c in sorted(t):i=t.index(c);l=len(t)+~i;t[l:l]=t.pop(i)

Try it online!

Modifies the input list


Retina 0.8.2, 61 bytes


Try it online! Link includes test cases. Explanation:


Start the loop at a.


If the input contains the current letter, move it to the end, with a string of _s representing its original position.


For each _ move the letter back one character.


Increment the letter. After z change it to a ! so it doesn't match anything and the loop ends.


Delete the !.


Java 8, 140 96 92 88 87 85 bytes

s->{for(char c=9;++c>0;){int i=s.indexOf(c);if(i>=0)s.add(s.size()+~i,s.remove(i));}}

-44 bytes creating a port of @TFeld's Python 2 answer.
-6 bytes thanks to @OlivierGrégoire.

Modifies the input List instead of creating a new one.


Try it online.

s->{                     // Method with ArrayList<Character> parameter and no return-type
  for(char c=9;++c>0;){  //  Loop over all characters known
                         //  (except for the first 9 unprintables)
    int i=s.indexOf(c);  //   Index of the character, or -1 of it isn't present
    if(i>=0)             //   If the current character is present in the List
                         //    Change the position of this character to index `l-i-1`,
                         //    (where `l` is the size of the input-List)

JavaScript, 85 80 79 bytes

-6 bytes thanks to @DanielIndie


Try it online!

  • \$\begingroup\$ this doesnt "compile" a is a string and you use splice \$\endgroup\$ – DanielIndie Apr 20 '18 at 7:01
  • \$\begingroup\$ @DanielIndie Input should be passed as an array of characters, just like Jo King's Python solution. \$\endgroup\$ – Esolanging Fruit Apr 20 '18 at 7:21
  • \$\begingroup\$ 80 bytes \$\endgroup\$ – DanielIndie Apr 20 '18 at 7:33
  • \$\begingroup\$ you dont return anything from that function, or print it \$\endgroup\$ – DanielIndie Apr 20 '18 at 7:35
  • \$\begingroup\$ @DanielIndie Functions can return by modifying their arguments. \$\endgroup\$ – Esolanging Fruit Apr 20 '18 at 7:36

Ruby, 51 bytes


Try it online!

Takes an array of chars

Returns by modifying the input


Red, 96 94 bytes

2 bytes saved thanks to Kevin Cruijssen

func[x][foreach c sort copy x[i:(length? x)+ 1 - index? find x c insert at replace x c""i c]x]

Try it online!

More readable:

f: func[x][
    foreach c sort copy x[                  ; for each symbol in the sorted input
       i: (length? x) + 1 - index? find x c ; find its index and reflect it 
       insert at replace x c "" i c         ; remove it by replacing it with an empty char 
                                            ; and insert the symbol at its new index   
    x                                       ; return the transformed string
  • 1
    \$\begingroup\$ You can save 2 bytes by changing find x c replace x c""insert at x i c to find x c insert at replace x c""i c to get rid of an x and space. \$\endgroup\$ – Kevin Cruijssen Apr 20 '18 at 9:54
  • \$\begingroup\$ @Kevin Cruijssen Thank you, Kevin, it's much better now! \$\endgroup\$ – Galen Ivanov Apr 20 '18 at 10:30

R, 73 72 69 bytes

function(s){for(x in sort(s))s=append(s[x!=s],x,match(x,rev(s))-1);s}

Try it online!

Inputs and outputs a vector of characters.

  • \$\begingroup\$ ew, using c as a variable name? that's awful, even for code golf! \$\endgroup\$ – Giuseppe Apr 20 '18 at 14:37
  • \$\begingroup\$ Well, I can obviously change it, but I am really surprised to see that it could bother anybody here. I actually tend to give priority to preserving some sense in variable names (like c for char) rather than unused built-ins. \$\endgroup\$ – Kirill L. Apr 20 '18 at 16:19
  • \$\begingroup\$ well, when looking for an improvement (which, I didn't) I found myself trying to use c, and it was awful when I couldn't figure out what was happening. I typically use K or k or even C just to avoid problems like that, but I totally get it. append is def the right tool for the job. \$\endgroup\$ – Giuseppe Apr 20 '18 at 16:26
  • \$\begingroup\$ Oh, I see, sorry about that, will try to avoid setting such "traps" in future. \$\endgroup\$ – Kirill L. Apr 20 '18 at 16:37

Perl 5 -p, 37 bytes

#!/usr/bin/perl -p

Try it online!


Japt, 23 22 bytes

¬n rÈ+S kY iYJ-XbY)x}U
¬n                     // Split the input into chars and sort it.
   r                }U // Then reduce the result with initial value of the input.
    È+S                // Append a space for replacing edge cases and
        kY             // remove the current char from the string.
           iY          // Insert it back
             J-XbY     // at the calculated index,
                  )x   // and remove the unnecessary space once we're done.

Saved one byte thanks to Oliver.
Try it online!

  • 1
    \$\begingroup\$ Nice one. You can replace with J \$\endgroup\$ – Oliver Apr 20 '18 at 20:39
  • \$\begingroup\$ @Oliver Thanks a lot, I still forget to use the default variables every now and then, that's very handy. \$\endgroup\$ – Etheryte Apr 22 '18 at 10:29

Haskell, 87 bytes

s#c|(h,_:t)<-span(/=c)s,(v,w)<-splitAt(length t)$h++t=v++c:w|1<2=s
f s=foldl(#)s['a'..]

Try it online!

f s=foldl(#)s['a'..]         -- fold the function '#' into all characters from 'a'
                              -- with the starting value of the input string s
s#c=                          -- in each step (s: result so far, c: next char)
   (h,_:t)<-span(/=c)s        -- let 'h' be the substring before 'c' and
                              -- 't' the substring after 'c'. the pattern match
                              -- fails if there's no 'c' in 's'
   (v,w)<-splitAt(length t)$h++t
                              -- split the string 'h++t' at index length of t
   =v++c:w                    -- return 'v' followed by 'c' followed by 'w'
   |1<2=s                     -- if there's no 'c' in 's', return 's' unchanged             
  • \$\begingroup\$ Why does this halt? Shouldn't folding over an infinite list cause an infinite loop? Shouldn't it be f s=foldl(#)s['a'..'z']? \$\endgroup\$ – user1472751 Apr 20 '18 at 18:03
  • 1
    \$\begingroup\$ @user1472751: ['a'..] is not infinite, because Char belongs to class Bounded. A list with ..] of Bounded values stops at maxBound. Try: print [False ..]. \$\endgroup\$ – nimi Apr 20 '18 at 18:08

SNOBOL4 (CSNOBOL4), 132 128 bytes

	I ARB @S K	:F(N)
	I K =
	I =L K R	:(N)

Try it online!

Straightforward implementation of the required algorithm. Saved a few bytes by switching to a function rather than a full program; the explanation remains the same, more or less.

	I =INPUT			;* read input
	U =&LCASE			;* alias for lowercase letters (it started out as uppercase)
N	U LEN(1) . K REM . U	:F(O)	;* set K to the next lowercase letter, and when empty, goto O
	I ARB @S K	:F(N)		;* set S to the number of letters before K, or goto N
	I K =				;* remove K
	I ARB . L RPOS(S) REM . R	;* set R to the last S characters of I and L to the others
	I =L K R	:(N)		;* recombine the string and goto N
O	OUTPUT =I			;* print new string

Jelly,  12  11 bytes


A monadic link accepting a list of characters and returning a list of characters.

Try it online!


W;ṢḟṁUṣ¥jʋ/ - Link: list of characters V  e.g. "myface"  ...i.e. ['m','y','f','a','c','e']
W           - wrap V in a list                 ["myface"]
  Ṣ         - sort V                           ['a','c','e','f','m','y']
 ;          - concatenate                      ["myface",'a','c','e','f','m','y']
          / - reduce with:
         ʋ  -   last four links as a dyad:
            -   (i.e. start with "myface" on the left and 'a' on the right 
            -         2nd iteration has that result on the left and 'c' on the right
            -         and so-forth)            e.g. left = myface, right = 'a'
   ḟ        -     filter out (right from left)      "myfce"
       ¥    -     last two links as a dyad:
     U      -       upend left                      "ecafym"
      ṣ     -       split at occurrences of right   ["ec","fym"]
    ṁ       -     mould (ḟ(x,y)) like (Uṣ¥(x,y))    ["my","fce"] 
         j  -   join with right                   "myafce"
  • \$\begingroup\$ Ok well this one pretty much wrecks everything else... \$\endgroup\$ – NL628 Apr 20 '18 at 18:24
  • 1
    \$\begingroup\$ Well I think that's what Jelly is for - I half expect Dennis (Jelly's creator) to submit a shorter one! \$\endgroup\$ – Jonathan Allan Apr 20 '18 at 18:26
  • \$\begingroup\$ Lol that's pretty amazing :P but I can't upvote b/c I used up my daily vote count..rip \$\endgroup\$ – NL628 Apr 20 '18 at 18:26
  • 1
    \$\begingroup\$ ...I think there may be a way to save a byte by use of (filter out) but I have not managed it yet. \$\endgroup\$ – Jonathan Allan Apr 20 '18 at 18:36
  • 1
    \$\begingroup\$ looks like, time-wise, it's O(n log n) in the length of the input since it first uses Python's sorted and then runs through n iterations of what appear to be less complex operations (flattening, splitting at found indices, joining, reversing). -- and Python's sorted is O(n log n). \$\endgroup\$ – Jonathan Allan Apr 20 '18 at 18:41

C (clang), 164 162 bytes


Try it online!

f() takes char-array containing input string and length of this array as parameters and performs required reflections in place.

callf() does pretty-printing.


-2 bytes. @Kevin. Thanks

  • 1
    \$\begingroup\$ You can remove the space at char *s and change i=96 to i=9 to save 2 bytes. \$\endgroup\$ – Kevin Cruijssen Apr 20 '18 at 11:09
  • \$\begingroup\$ Good catch.. we needn't start from a. Thanks \$\endgroup\$ – GPS Apr 20 '18 at 18:53
  • \$\begingroup\$ 144 bytes \$\endgroup\$ – ceilingcat Nov 23 '18 at 17:23

APL+WIN, 63 bytes

Prompts for input string



l←s[⍋⎕av⍳s←,⎕] sort characters into alphabetical order

⍎∊(⍴s)⍴⊂'....' create an implicit loop for each character

s←(n←⌽~s=↑l)\s~↑l⋄((~n)/s)←↑l do the relection for first character in l

l←1↓l drop the first character in l

s display the result

⋄ statement separator

Perl, 74 70 bytes

84 80 bytes including invocation as unix filter

$ echo -e 'dcba\nmyface\na\nacb\ncwmfjordbankglyphsvextquiz' |
> perl -pE'for$c(a..z){if($p=1+index$_,$c){substr$_,$p-1,1,"";substr$_,-$p,0,$c}}'

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.