Simple String Reflection

26

3

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.

Examples

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.

Scoring

  • 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>

NL628

Posted 2018-04-20T02:45:40.970

Reputation: 673

2Could 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 – NL628 – 2018-04-20T02:57:13.147

6This 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). – Esolanging Fruit – 2018-04-20T03:36:04.150

@EsolangingFruit Okay, thank you so much for your comment! I really appreciate it. Will do :D – NL628 – 2018-04-20T03:36:32.230

1Clarification request: "the letters are unique" means each letter occurs only once in input, is that correct? – GPS – 2018-04-20T05:06:22.777

4Can we take the input and output in uppercase instead of lowercase? – Kevin Cruijssen – 2018-04-20T07:05:20.813

5

@NL628 By the way, if you want to get insight on a challenge before posting it here, then post it in the Sandbox.

– Erik the Outgolfer – 2018-04-20T12:01:53.773

@GPS That is correct. – NL628 – 2018-04-20T17:25:59.493

@EriktheOutgolfer Oh no! Was I supposed to post there instead? Aiyaa sorry about that...I'm really sorry :( – NL628 – 2018-04-20T17:26:19.530

@KevinCruijssen I would prefer it to be in lowercase, but if you think of a really cool one, I'll edit the question to allow either ALL uppercase or ALL lowercase. – NL628 – 2018-04-20T17:26:55.440

1@NL628 No, nobody ever has to post it there, it's just a recommendation. – Erik the Outgolfer – 2018-04-21T09:11:54.423

Okay @EriktheOutgolfer Thank you so much! – NL628 – 2018-04-21T18:19:57.917

Answers

8

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

Nitrodon

Posted 2018-04-20T02:45:40.970

Reputation: 9 181

1Wow that's pretty amazing. I can't even understand it :O +1 – NL628 – 2018-04-20T03:51:47.793

7

05AB1E, 20 17 bytes

{vð.øy¡€á€gsJ£yý

Try it online!

Explanation

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.

Emigna

Posted 2018-04-20T02:45:40.970

Reputation: 50 798

117 bytes?!??!! AMAZING..yet mnemonic is beating you by just one byte :P – NL628 – 2018-04-20T17:44:48.230

1Mmmm... Wow, only thing I could see is removing the surround with spaces. Seems odd we can't find another alternative to that. – Magic Octopus Urn – 2018-04-23T00:11:32.320

1@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 – Emigna – 2018-04-23T06:29:10.600

5

Pyth, 18 16 19 16 bytes

VSQ=QXx_QN-QNN)Q

Try it here

Explanation

VSQ=QXx_QN-QNN)Q
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.

user48543

Posted 2018-04-20T02:45:40.970

Reputation:

Wow 16 bytes? I would upvote, but sadly I've reached my daily voting limit. Will do in 6 hours :P – NL628 – 2018-04-20T17:44:13.560

4

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.

Jo King

Posted 2018-04-20T02:45:40.970

Reputation: 38 234

3Wow I wrote an answer in C++ and Python 3 also. My Python 3 answer was exactly twice as long as yours... +1 – NL628 – 2018-04-20T03:52:27.513

4

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

TFeld

Posted 2018-04-20T02:45:40.970

Reputation: 19 246

3

JavaScript, 85 80 79 bytes

-6 bytes thanks to @DanielIndie

a=>[...a].sort().map(i=>a.splice(s=a.indexOf(i),1)&&a.splice(a.length-s,0,i))&&a

Try it online!

Esolanging Fruit

Posted 2018-04-20T02:45:40.970

Reputation: 13 542

this doesnt "compile" a is a string and you use splice – DanielIndie – 2018-04-20T07:01:31.467

@DanielIndie Input should be passed as an array of characters, just like Jo King's Python solution. – Esolanging Fruit – 2018-04-20T07:21:10.290

80 bytes – DanielIndie – 2018-04-20T07:33:16.620

you dont return anything from that function, or print it – DanielIndie – 2018-04-20T07:35:02.963

@DanielIndie Functions can return by modifying their arguments. – Esolanging Fruit – 2018-04-20T07:36:51.397

79 bytes – DanielIndie – 2018-04-20T07:58:39.377

You can save 4 bytes by changing a.length-s to -s|1e9. – Rick Hitchcock – 2018-04-20T17:57:25.853

@RickHitchcock Wait, how does that work? – Esolanging Fruit – 2018-04-20T22:08:58.117

If the first parameter to splice is a negative number, it's taken from the end. So a.length-s is the same as -s unless s is zero. In that case, we use 1e9, which will be treated as the length of the array. – Rick Hitchcock – 2018-04-20T23:51:17.043

Any number between -1 and -512 bitwise or'd with 1e9 won't change. – Rick Hitchcock – 2018-04-20T23:52:53.470

3

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.

Explanation:

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
      s.add(s.size()+~i,s.remove(i));}}
                         //    Change the position of this character to index `l-i-1`,
                         //    (where `l` is the size of the input-List)

Kevin Cruijssen

Posted 2018-04-20T02:45:40.970

Reputation: 67 575

1@OlivierGrégoire Thanks. And 1 more looping over more than just the alphabet characters. :) – Kevin Cruijssen – 2018-04-20T08:55:10.460

2Well, if you go that road, for(char c=9;++c>1;) is better ;-) – Olivier Grégoire – 2018-04-20T08:57:10.240

@OlivierGrégoire Ah of course, char also wraps around like Integer.MAX_VALUE + 1 == Integer.MIN_VALUE.. Smart! – Kevin Cruijssen – 2018-04-20T08:58:19.900

@OlivierGrégoire s is an ArrayList, so indexOf will be of generic type T (which is Character for this input list). – Kevin Cruijssen – 2018-04-20T12:59:56.233

Pffff... That's it: mixed the input type in my golfs... My bad. sorry. Deleting all my comments – Olivier Grégoire – 2018-04-20T13:04:09.470

3

Retina 0.8.2, 61 bytes

$
a
{`(.)(.*)\1$
$2$.`$*_$1$1
+`(.)_(_*.)
$2$1
}T`_l`l!`.$
!

Try it online! Link includes test cases. Explanation:

$
a

Start the loop at a.

{`(.)(.*)\1$
$2$.`$*_$1$1

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

+`(.)_(_*.)
$2$1

For each _ move the letter back one character.

}T`_l`l!`.$

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

!

Delete the !.

Neil

Posted 2018-04-20T02:45:40.970

Reputation: 95 035

2

Ruby, 51 bytes

->s{s.sort.map{|c|s.insert~s.index(c),s.delete(c)}}

Try it online!

Takes an array of chars

Returns by modifying the input

Asone Tuhid

Posted 2018-04-20T02:45:40.970

Reputation: 1 944

2

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.

Kirill L.

Posted 2018-04-20T02:45:40.970

Reputation: 6 693

ew, using c as a variable name? that's awful, even for code golf! – Giuseppe – 2018-04-20T14:37:21.113

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. – Kirill L. – 2018-04-20T16:19:32.043

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. – Giuseppe – 2018-04-20T16:26:55.750

Oh, I see, sorry about that, will try to avoid setting such "traps" in future. – Kirill L. – 2018-04-20T16:37:29.973

2

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
]

Galen Ivanov

Posted 2018-04-20T02:45:40.970

Reputation: 13 815

1You 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. – Kevin Cruijssen – 2018-04-20T09:54:48.027

@Kevin Cruijssen Thank you, Kevin, it's much better now! – Galen Ivanov – 2018-04-20T10:30:19.713

2

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!

Nit

Posted 2018-04-20T02:45:40.970

Reputation: 2 667

1Nice one. You can replace with J – Oliver – 2018-04-20T20:39:06.587

@Oliver Thanks a lot, I still forget to use the default variables every now and then, that's very handy. – Nit – 2018-04-22T10:29:46.150

2

Perl 5 -p, 37 bytes

#!/usr/bin/perl -p
for$a(a..z){s/$a//&&s/.{@{-}}$/$a$&/}

Try it online!

Ton Hospel

Posted 2018-04-20T02:45:40.970

Reputation: 14 114

1

C (clang), 164 162 bytes

y,n,a,b,c,p,i;f(char*s,l){for(i=0;p=0,++i<123;p<l&&(y=s[p],n=l+~p,a=p+1,b=p,n<p&&(a=n,b=n+1),c=l+~(2*(n<p?n:p)),memmove(s+b,s+a,c),s[n]=y))while(s[p]^i&&p<l)p++;}

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.

Credits

-2 bytes. @Kevin. Thanks

GPS

Posted 2018-04-20T02:45:40.970

Reputation: 341

1You can remove the space at char *s and change i=96 to i=9 to save 2 bytes. – Kevin Cruijssen – 2018-04-20T11:09:26.793

Good catch.. we needn't start from a. Thanks – GPS – 2018-04-20T18:53:26.960

144 bytes – ceilingcat – 2018-11-23T17:23:03.353

1

Perl, 74 70 bytes

84 80 bytes including invocation as unix filter

for$c(a..z){if($p=1+index$_,$c){substr$_,$p-1,1,"";substr$_,-$p,0,$c}}
$ 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}}'
dcba
fyecma
a
bac
ieabhqzugdltkfnvpjxsormycw

Hynek -Pichi- Vychodil

Posted 2018-04-20T02:45:40.970

Reputation: 350

1

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             

nimi

Posted 2018-04-20T02:45:40.970

Reputation: 34 639

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']? – user1472751 – 2018-04-20T18:03:26.087

1@user1472751: ['a'..] is not infinite, because Char belongs to class Bounded. A list with ..] of Bounded values stops at maxBound. Try: print [False ..]. – nimi – 2018-04-20T18:08:18.983

1

SNOBOL4 (CSNOBOL4), 132 128 bytes

	DEFINE('I(I)')
I	U =&LCASE
N	U LEN(1) . K REM . U	:F(RETURN)
	I ARB @S K	:F(N)
	I K =
	I ARB . L RPOS(S) REM . R
	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
END

Giuseppe

Posted 2018-04-20T02:45:40.970

Reputation: 21 077

1

Jelly,  12  11 bytes

W;ṢḟṁUṣ¥jʋ/

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

Try it online!

How?

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"

Jonathan Allan

Posted 2018-04-20T02:45:40.970

Reputation: 67 804

Ok well this one pretty much wrecks everything else... – NL628 – 2018-04-20T18:24:51.157

1Well I think that's what Jelly is for - I half expect Dennis (Jelly's creator) to submit a shorter one! – Jonathan Allan – 2018-04-20T18:26:08.977

Lol that's pretty amazing :P but I can't upvote b/c I used up my daily vote count..rip – NL628 – 2018-04-20T18:26:33.500

1...I think there may be a way to save a byte by use of (filter out) but I have not managed it yet. – Jonathan Allan – 2018-04-20T18:36:39.210

...Beyond my comprehension :O – NL628 – 2018-04-20T18:37:31.617

1looks 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). – Jonathan Allan – 2018-04-20T18:41:11.193

Oh lol okay thanks! :D – NL628 – 2018-04-20T18:50:21.570

1

APL+WIN, 63 bytes

Prompts for input string

l←s[⍋⎕av⍳s←,⎕]⋄⍎∊(⍴s)⍴⊂'s←(n←⌽~s=↑l)\s~↑l⋄((~n)/s)←↑l⋄l←1↓l⋄'⋄s

Explanation:

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

Graham

Posted 2018-04-20T02:45:40.970

Reputation: 3 184