55
\$\begingroup\$

According to some controversial story, the odrer of ltteres in a wrod deos not mttaer much for raednig, as lnog as the frist and lsat lteter macth with the orignial wrod.

So, for fun, what would be the shortest function to randomize letter order in a word while keeping the first and the last letter in place?

Here's my stab at it with JavaScript. All whitespace removed it's at 124 130 characters.

function r(w) {
  var l=w.length-1;
  return l<3?w:w[0]+w.slice(1,l).split("").sort(function(){return Math.random()-.5}).join("")+w[l];
}

Shorter JavaScript always welcome.


  • Edit: length check added. Function should not fail for short words.
\$\endgroup\$
  • 3
    \$\begingroup\$ Haskell, 4 characters: r=id. \$\endgroup\$ – Thomas Eding Aug 3 '11 at 20:01
  • 2
    \$\begingroup\$ Yes. It returns the exact same thing as the input. On another note, what do we do about punctuation? Do we only operate on words consisting only of letters? \$\endgroup\$ – Thomas Eding Aug 3 '11 at 20:28
  • 1
    \$\begingroup\$ @trinithis not sure what you talking about, but id is the identity function. I would still like to see Haskell solution to this problem in less than 100 characters. \$\endgroup\$ – Arlen Aug 4 '11 at 7:37
  • 3
    \$\begingroup\$ Should the specification be updated to require a uniform distribution of outcomes? This would disallow the 4 character Haskell solution. It would also disallow your example Javascript solution (shuffling by doing a sort like that is not uniform). \$\endgroup\$ – Thomas Eding Aug 4 '11 at 17:25
  • 2
    \$\begingroup\$ +1 for the first sentence: it actually took me a few seconds to realize it was spelled wrong XP \$\endgroup\$ – Nate Koppenhaver Aug 4 '11 at 18:33

74 Answers 74

2
\$\begingroup\$

PowerShell, 93

filter x{if($_.length-lt3){$_}else{$_[0,-1]-join-join($_[1..($a=$_.Length-2)]|random -c $a)}}

Look, double-jointed code!

\$\endgroup\$
  • \$\begingroup\$ Way too long, sadly. \$\endgroup\$ – Joey Aug 5 '11 at 15:56
  • \$\begingroup\$ You can't beat Golfscript anyway. ;) It's way shorter than my JS solution; Powershell is pretty expressive. \$\endgroup\$ – Tomalak Aug 5 '11 at 16:47
  • \$\begingroup\$ This actually demonstrates plenty of things it doesn't handle well. Usually I aim for at least beating Python :-) \$\endgroup\$ – Joey Aug 6 '11 at 0:10
  • \$\begingroup\$ saved some bytes by making a var on the first call to .Length and not declaring $a, only -5 thanks to all the brackets needed.. filter x{if(($l=$_.length)-lt3){$_}else{$_[0,-1]-join-join($_[1..($l-2)]|random -c $l)}} \$\endgroup\$ – colsw Dec 6 '16 at 15:10
2
\$\begingroup\$

C#, 128

static string r(string w){var t="";while(w.Length>1){int n=new Random().Next(1,w.Length-1);t+=w[n];w=w.Remove(n,1);}return w+t;}
\$\endgroup\$
2
\$\begingroup\$

Scala: 94

def r(w:String)=if(w.size<2)w else w(0)+util.Random.shuffle(w.tail.init.toSeq).mkString+w.last

This is a riff on "user unknowns" answer. Since a String can be implicitly cast to a Seq of chars, we can leverage Seq methods to access the middle and end of the String.

\$\endgroup\$
2
\$\begingroup\$

Groovy, 75

r={w->w.size()<3?w:w[0]+w[1..-2].toList().sort{Math.random()}.join()+w[-1]}

assert r('a') == 'a'
assert r('it') == 'it'
assert r('cap') == 'cap'

for(x in 1..10) {
    def w = r('Honorificabilitudinitatibus')
    println w
    assert w.size()==27 && w[0]=='H' && w[26]=='s'
}
\$\endgroup\$
2
\$\begingroup\$

Q, 38 48

{((:)x),((-1(#:)a)?a:-1_1_x),last x}

Had to change it for words <=3 letters

{$[3<(#)x;((*:)x),((-1*(#:)a)?a:-1_1_x),-1#x;x]}
\$\endgroup\$
  • \$\begingroup\$ You can get three less along the same vein: {$[3<(#)x;(1#x),((-1*(#)a)?a:-1_1_x),-1#x;x]} \$\endgroup\$ – skeevey Mar 20 '12 at 21:03
2
\$\begingroup\$

MATLAB (46 Characters)

f=@(x)[x(1) x(randperm(length(x)-2)+1) x(end)]

Sample Usage:

>> f('elephant')

ans =

eplhnaet

>> f('imawesomebutyousuck')

ans =

iouesutuoeswbamycmk

Works with words size two or greater.

\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog), 34 Charachters

Still trying to golf it a bit more, new to APL. Tips appreciated.

y←(⍴x←⍞)-2⋄x[1],x[1+⍳y][y?y],x[⍴x]

Here is an attempt to explain it, I also simplified it a bit (no charachter improvement, though)

is a statement separator, think of it as a new line.

That leaves us with 2 statements. y←(⍴x←⍞)-2 and x[1],x[1+⍳y][y?y],x[⍴x]

APL works from right to left in statements, but follows parentesis still, so (⍴x←⍞) is executed first. takes charachter input. assigns that to x and gives the length of x. Then the -2 is executed, which subtracts 2 from the length of x. Finally, the length-2 is assigned to y and we move on to the next statement.

x[⍴x] takes the last character of x, think of it as x[x.length] (using the length as the index of the last character).

, is catenate.

So we concatenate the last character of x with x[1+⍳y][y?y] which takes the middle indices of x using 2+⍳y and applies a randomization using [y?y].

⍳y generates 1 2 3 ... y and 1+ turns this into 2 3 4 ... y+1 which are the middle indices of x, for example, this returns bcdef from abcdefg.

[y?y] "deals" y values from 1 to y.

So, x[1+⍳y][y?y] grabs the middle of the word and randomizes it.

Finally, we concatenate the first charachter of x using x[1], to the rest of the string, and that is the output of the program.

Hopefully that was understandable...

\$\endgroup\$
  • 1
    \$\begingroup\$ Oh dear God. (+1) -- Would you care to break it down for somebody who has no concept of APL? \$\endgroup\$ – Tomalak Aug 23 '12 at 5:43
  • \$\begingroup\$ Sure, give me a minute to update it \$\endgroup\$ – MrZander Aug 23 '12 at 5:49
  • \$\begingroup\$ No problem. If you can "golf it down" more do that first. \$\endgroup\$ – Tomalak Aug 23 '12 at 5:52
  • \$\begingroup\$ @Tomalak explained it as best as I could :) \$\endgroup\$ – MrZander Aug 23 '12 at 6:08
2
\$\begingroup\$

J, 25

(]/:0,((2-~#)?1-~#),1-~#)

Example:

      (]/:0,((2-~#)?1-~#),1-~#) 'order'
oedrr
      (]/:0,((2-~#)?1-~#),1-~#) 'order'
oerdr
      (]/:0,((2-~#)?1-~#),1-~#) 'order'
oderr
      (]/:0,((2-~#)?1-~#),1-~#) 'order'
odrer
      (]/:0,((2-~#)?1-~#),1-~#) 'order'
oerdr
      (]/:0,((2-~#)?1-~#),1-~#) 'order'
oerdr
\$\endgroup\$
  • \$\begingroup\$ I can get down to 22 using the random shuffle verb on this page. \$\endgroup\$ – Gareth Aug 23 '12 at 12:02
  • \$\begingroup\$ Actually ignore my last comment, the top answer uses the method I would have used. \$\endgroup\$ – Gareth Aug 23 '12 at 13:00
2
\$\begingroup\$

CJam, 15 bytes

CJam is younger than this challenge, so this submission is not eligible for being accepted. This submission assumes that a "word" contains at least one character (I've requested clarification from the OP).

{(\_W>\W<mr\++}

This defines a block, the equivalent of an unnamed function in CJam.

Test it here.

If full programs (STDIN to STDOUT) are also acceptable, it can be solved in 12 bytes:

l(\_W>\W<mr\

Test it here.

Explanation

(             "Slice off first character and push it on the stack.";
 \            "Swap with remaining string.";
  _W>         "Duplicate and truncate to last character.";
     \W<      "Swap with other copy and slice off last character.";
        mr    "Shuffle.";
          \   "Swap with last character.";
           ++ "Concatenate the three parts back together.";

Note that _W>\W< could in principle be shortened to )\ (which I had originally). However, this fails when the string is empty at that point, i.e. when it originally contained less than 2 characters.

For the full program, we read the input with l first, and we can omit the ++ since the contents of the stack are printed at the end of the program automatically, back to back.

\$\endgroup\$
  • \$\begingroup\$ This is amazing :) \$\endgroup\$ – Tomalak Mar 27 '15 at 16:08
2
\$\begingroup\$

Ruby, 39 characters

->s{a,*b,c=s.chars;[a,*b.shuffle,c]*''}
\$\endgroup\$
  • \$\begingroup\$ You supposed to process each word of the input text separately. \$\endgroup\$ – manatwork Nov 10 '16 at 19:34
  • 2
    \$\begingroup\$ @manatwork The reference solution clearly assumes that the input is a single word. I'm certain that this is what the author intended. \$\endgroup\$ – Lee W Nov 10 '16 at 19:42
  • \$\begingroup\$ Oops. I misread its .split(""). You are right. Sorry. Confused it with Cambridge Transposition. \$\endgroup\$ – manatwork Nov 10 '16 at 20:33
2
\$\begingroup\$

Python 3, 80 chars

This is an improvement on Ashley Grenon's answer. By removing variable assignments and using random.sample instead of random.shuffle, so you don't have to explicitly call list(), I saved 4 characters. This one still fails on strings less than 2 characters.

import random as r
def f(w):return w[0]+''.join(r.sample(w[1:-1],len(w)-2))+w[-1]
\$\endgroup\$
  • \$\begingroup\$ Welcome to Programming Puzzles and Code Golf. This is a great answer; much better than the average first post. If you feel it is required, adding a code breakdown and explanation may improve this answer. \$\endgroup\$ – wizzwizz4 Dec 27 '15 at 11:18
2
\$\begingroup\$

Perl, 41 bytes

40 bytes code + 1 for -n.

$\=chop;s/.//;print"$&",sort{rand 2}/./g

Requires input to be supplied without a newline (echo -n ...) as we use chop to move the last char into $\ (which is appended after all arguments to print) and we sort, applying 0 or 1 (rand 2) to each character. This appears to result in all permutations given enough time. The $& has to be in quotes, as it changes after the /./g is executed, interpolating into a string works around this. Also print has to be used instead of say to utilise $\ :(.

Usage

echo -n 'stringified' | perl -ne '$\=chop;s/.//;print"$&",sort{rand 2}/./g'
sifirgtined

for i in `seq 1 20`; do echo -n 'stringified' | perl -ne '$\=chop;s/.//;print"$&",sort{rand 2}/./g'; echo; done 
segfiiintrd
sitnrigfied
stringified
srtinigfied
sginitrefid
strnigieifd
seriftniigd
sifertniigd
siirtngfied
sintrgieifd
snitrigefid
sfgieinirtd
sigitrnifed
sefiirtingd
sirtnigifed
sifgenritid
srtingiifed
siignrteifd
sefiigtrind
sifneirtigd
\$\endgroup\$
2
\$\begingroup\$

Taxi, 1344 bytes

Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to Chop Suey.Go to Chop Suey:n 1 r 1 l 4 r 1 l.Pickup a passenger going to Post Office.[B]Switch to plan C if no one is waiting.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 3 l.Pickup a passenger going to Narrow Path Park.Pickup a passenger going to Sunny Skies Park.Go to Zoom Zoom:n.Go to Sunny Skies Park:w 2 l.Go to Narrow Path Park:n 1 r 1 r 1 l 1 r.Go to Chop Suey:e 1 r 1 l 1 r.Switch to plan B.[C]Go to Narrow Path Park:n 1 l 1 r 1 l.Switch to plan H if no one is waiting.Pickup a passenger going to Joyless Park.Go to Joyless Park:e 1 r 3 l.Go to Narrow Path Park:w 1 r 3 l.[D]Switch to plan E if no one is waiting.Pickup a passenger going to Cyclone.Go to Cyclone:w 1 l 1 r 2 l.Pickup a passenger going to Firemouth Grill.Pickup a passenger going to Sunny Skies Park.Go to Zoom Zoom:n.Go to Firemouth Grill:w 1 l 2 r 3 r.Go to Sunny Skies Park:w 1 l 1 r 1 r.Go to Narrow Path Park:n 1 r 1 r 1 l 1 r.Switch to plan D.[E]Go to Firemouth Grill:e 1 r 4 r.[F]Switch to plan G if no one is waiting.Pickup a passenger going to Post Office.Go to Fueler Up:e 1 l.Go to Post Office:s 1 r 1 l.Go to Firemouth Grill:n 1 l.Switch to plan F.[G]Go to Joyless Park:e 1 l 3 r.Pickup a passenger going to Post Office.Go to Post Office:w 1 l 1 r 1 l.[H]Go to Post Office:e 1 r 4 r 1 l.

Try it online!

Try it online with linebreaks!

Errors out by having the boss fire me if the string is 1 character, and by being unable to drive in the current direction otherwise. Don't you just love programs that exit uncleanly like that?

Firemouth Grill is one of two destinations in Townsville that offer randomness. It is like any of the three parks in that any number of passengers can be dropped off for later, but they are picked up in a random and unspecified order. This destination alone does the main part of our job, so the only other thing to do is make sure we're only doing this to the characters in the middle.

\$\endgroup\$
  • 1
    \$\begingroup\$ This is amazing :D \$\endgroup\$ – Tomalak Oct 9 '18 at 7:24
2
\$\begingroup\$

Powershell, 81 bytes

Inspired by Joey: I like her double join.

$args|%{($_,($_[0,-1]-join-join($_[1..($a=$_.Length-2)]|random -c 2e9)))[$a-ge2]}

Notable changes:

  1. if else replaced with a Fake ternary operator.
  2. $_.Length is written once.
  3. Other golf to compact the script
  4. The script gets Random for the word length >= 4 only.
  5. random -c $a replaced with random -c 2e9. It need to avoid an exception with word length <= 2. I think the length = 2000000000 is enough for a word.

Test script:

$f = {

$args|%{($_,($_[0,-1]-join-join($_[1..($a=$_.Length-2)]|random -c 2e9)))[$a-ge2]}

}

&$f ""
&$f a
&$f ab
&$f abc
&$f abcd
&$f randomize
&$f reading
&$f Hello
&$f world

Output:

a
ab
abc
acbd
rmaniodze
rniedag
Hlelo
wrlod
\$\endgroup\$
1
\$\begingroup\$

Scala: 112 123

def v(s:String)=if(s.size<4)s else s(0)+util.Random.shuffle(s.substring(1,s.size-1).toList).mkString+s(s.size-1)

Incorporated hints from the comments (length->size (I need this hint every time), mkString without ("")) and size-1, not -2). Thanks.

\$\endgroup\$
  • \$\begingroup\$ I think you can save 6 chars by using .size instead of .length \$\endgroup\$ – Gareth Aug 4 '11 at 8:10
  • \$\begingroup\$ You can also leave the ("") off the mkString call to save 4 more and get down to 112. There's a couple of typos too - the v(0) after the else should be s(0) and s.length-2 in the substring should be s.length-1 otherwise you lose a character in the result. \$\endgroup\$ – Gareth Aug 4 '11 at 9:20
1
\$\begingroup\$

Lua, 173 chars

Does what it needs to do.

function(a)return(a:gsub('(%w)(%w*)(%w)',function(a,b,c)t={}for l in b:gmatch'.'do t[#t+1]=l end while #t>0 do i=math.random(#t)a=a..table.remove(t,i)end return a..c end))end
\$\endgroup\$
1
\$\begingroup\$

Haskell, 195

import Random
import Data.List
r l=fmap(f l.g l)newStdGen
f l n=map snd$head$filter(\l->map fst l==n)$permutations$zip[0..]l
g l=take(n+2).(0:).(++[n+1]).take n.nub.randomRs(1,n)where n=length l-2

Hacked this into existence while Rotsor was making his post. This will cover all possible permutations, and I believe it does so uniformly.

The function r is the function that the user uses.

The algorithm is fairly straightforward. It generates a random list of unique numbers from 1 to n-2. Then it tacks on 0 to the front and n-1 to the end of the list. The take(n+2) is there to handle the case where the input is a single character (or an empty string for that matter). Then it searches for the corresponding permutation and returns that.

The list is generated by generating an infinite list of random numbers from 1 to n-2. Then it picks out the first occurance of each number in that range.

\$\endgroup\$
  • \$\begingroup\$ I've been puzzled why this program always produces the same result until I've realised that one needs to call newStdGen upon each independent call to r. \$\endgroup\$ – Rotsor Aug 4 '11 at 17:52
  • \$\begingroup\$ Run it outside of ghci. Make a main function, such as main = getLine >>= r >>= putStrLn. Then compile it and execute or use runhaskell. This will solve the problem. That or exit ghci every time and restart it after every call to r. \$\endgroup\$ – Thomas Eding Aug 4 '11 at 18:17
  • \$\begingroup\$ I was testing the distribution by doing replicateM 500 $ r "12345", which returned 500 identical results, so running it outside of ghci makes no difference. \$\endgroup\$ – Rotsor Aug 4 '11 at 18:34
  • \$\begingroup\$ Actually I think you should replace getStdGen with newStdGen in your solution, so it behaves in a way most (?) would expect. \$\endgroup\$ – Rotsor Aug 4 '11 at 18:40
  • \$\begingroup\$ I see. Fixed it. Thankfully, the character count is the same :D \$\endgroup\$ – Thomas Eding Aug 4 '11 at 19:11
1
\$\begingroup\$

FSharp, ~207 177

Count includes whitespace since its significant for f#

let f w=
 let r=System.Random()
 let e = Seq.length w
 (w|>Seq.mapi(fun i l->if i=0||i=e-1 then i,l else r.Next(1,e-1),l)|>Seq.sortBy fst|>Seq.map snd|>List.ofSeq).ToString()

Run with:

printfn "%s" (f "apples")
\$\endgroup\$
1
\$\begingroup\$

Java, 194 charcters

String r(String s){String[]c=s.split("");if(c.length>2)java.util.Collections.shuffle(java.util.Arrays.asList(c).subList(2,c.length-1));return(""+java.util.Arrays.asList(c)).replaceAll("\\W","");}

If you can assume java.util.* is imported, then you can shave off a fair amount of characters. Might be able to squeeze in a List variable to save a few more. If the class the r function is implemented in derives from java.util.Arrays, then even more characters can be saved.

\$\endgroup\$
  • \$\begingroup\$ && isn't much shorter than if; try it without asList and without 'replaceAll'. [, L, l, o, a] and [Ljava.lang.String;@addbf1 might be with you. \$\endgroup\$ – user unknown Aug 4 '11 at 4:25
  • \$\begingroup\$ && requires both sides to be boolean expressions, and shuffle has return type void. As for storing the asList into c, the types are incompatable. I could store it in a java.util.List, but that is lengthy right there. \$\endgroup\$ – Thomas Eding Aug 4 '11 at 16:18
  • \$\begingroup\$ @trinithis Yeah I just tried with && and came to the same conclusion. So I deleted my comment. \$\endgroup\$ – Tomalak Aug 4 '11 at 16:37
  • \$\begingroup\$ One can do import static java.util.Arrays.*, which is just another import instead of deriving from java.util.Arrays, which is kind of clumsy. \$\endgroup\$ – Rotsor Aug 5 '11 at 1:06
  • \$\begingroup\$ String r(String s){char[]c=s.toCharArray();if(c.length>2)java.util.Arrays.sort(c,1,c.length-1);return new String(c);} \$\endgroup\$ – Olivier Grégoire Jul 20 '17 at 13:17
1
\$\begingroup\$

Javascript, 202 characters

function r(s){var s=s.split(""),h=[-1],n=s.length-1,t,i;h[-1]=s[0];for(i=0;++i<n;){do{t=Math.random()}while(t in h);h[t]=s[i];h[i]=t;}h.sort();for(i=0;i<n;++i)h[i]=h[h[i]];return n?h.join("")+s[n]:s[0]}

This solution has an unbiased distribution.

Algorithm:

Split input string into an array s. Consider another array h that is doubly used as a dictionary. For each letter in s at index 0 < i < s.length-1, assign a unique random number to h at i. Also map the random number in the range [0, 1) in h to the letter. The first and last letters are handled specially. Before assigning the random numbers as described above, do the analogous thing for the first letter, but hard code the number as -1 (guaranteed to be less than the smallest random number generated, which can be 0). Ignore the last letter for now. Sort h. Map h's random value to the corresponding letter. Join the array into a string and tack on the last letter. Special case for 1 character input, where we return the first character (we still crunch h because the logic is shorter that way).

\$\endgroup\$
  • \$\begingroup\$ for(i=1;i<n;++i) --> for(i=0;++i<n;) ? \$\endgroup\$ – Mechanical snail Aug 4 '11 at 23:09
  • \$\begingroup\$ Nifty (filler.) \$\endgroup\$ – Thomas Eding Aug 4 '11 at 23:50
  • \$\begingroup\$ Why is sorting by Math.random()-.5 biased? \$\endgroup\$ – Tomalak Aug 5 '11 at 4:37
  • \$\begingroup\$ Suppose we have a 5 card deck. Then there are exactly 5! = 120 unique outcomes. If you were to "shuffle" the deck by going through the bottom to the top, swapping the current card with any card in the deck (including itself and including the layer of the deck already shuffled), this would produce 5^5 or 3125 possible outcomes. But 120 does not divide 3125 evenly. Thus by the pigeonhole principle, there exists an outcome that occurs more often than at least one other outcome. Hence the bias. \$\endgroup\$ – Thomas Eding Aug 5 '11 at 17:21
  • \$\begingroup\$ @trinithis, that is an interesting observation! However I think you did not answer the question. Sorting by Math.random() should give uniform distribution if Math.random() generates unique numbers, but in practice it does not. \$\endgroup\$ – Rotsor Aug 6 '11 at 0:48
1
\$\begingroup\$

Perl - 76 chars

Pure Perl implementation that requires no external modules. Also correctly handles one-letter, two-letter word edge cases.

sub r{@a=split//,pop;@a>1?join'',@a[0,(sort{rand()<=>rand}1..$#a-1),$#a]:@a}

Usage

say r('stringified') for 1 .. 20;

# Example output

srfgiietnid
sgfnieiitrd
seiifgrtnid
siigrfeintd
sgiirntiefd
siigerniftd
sifiitgnred
sftrneiiigd
sfieirtngid
sfeitirgnid
sfiertnigid
sigteifrind
sgieftirnid
sieitfrnigd
stnigirfeid
sfietrniigd
siigfrenitd
stefrniiigd
setrfiniigd
sifgtiernid

N.B. I'm not entirely convinced that the letter randomization still renders the word readable in the example above

\$\endgroup\$
1
\$\begingroup\$

Q (42 Characters)

{(x[0]),((neg count 1_-1_x)?1_-1_x),-1#x}

Sample Usage:

q){(x[0]),((neg count 1_-1_x)?1_-1_x),-1#x} "elephant"
"eeahlnpt"
q){(x[0]),((neg count 1_-1_x)?1_-1_x),-1#x} "ant"
"ant"
\$\endgroup\$
  • \$\begingroup\$ Doesn't work for single letter words, need to work on that. \$\endgroup\$ – sinedcm Mar 21 '12 at 17:52
  • \$\begingroup\$ 41 bytes with {$[3<c:(#)x;(x 0),((2-c)?-1_1_x),-1#x;x]}, works with 0, 1, 2 etc length strings too. \$\endgroup\$ – streetster Jun 13 '17 at 15:46
1
\$\begingroup\$

MATLAB, 65 47 characters

r=@(s)s([3-min(end,2):1 randperm(end-2)+1 end])

Works for strings of positive length, but fails on the empty string. Improved by using end as in jazzkingrt's solution.

This use of end can further improve jazzkingrt's solution by substituting end for length(x). However, that solution doesn't handle strings of length one correctly. (I'm not allowed to comment, so I write here instead.)

\$\endgroup\$
1
\$\begingroup\$

Mathematica 98 chars

Not the most economical code but fun to write.

s holds the input sentence (as a string).

Row[StringJoin @@@ (Characters@# /. {f_, m___, e_} :>  
   Flatten@{f, RandomSample@{m}, e} & /@ StringSplit@s), " "]

For example, when `s = "This sentence is fairly easy to read.",

output

\$\endgroup\$
1
\$\begingroup\$

TinyMUSH, 102

&_ me=left(%0,1)[ifelse(eq(strlen(%0),1),,scramble(mid(%0,1,sub(strlen(%0),2)))[right(%0,1)])]
\u(_,X)

Replace "X" with the input word. The user-defined _ attribute uses the built-in scramble() function to scramble letters between the first and last letters.

\$\endgroup\$
1
\$\begingroup\$

Clip, 24

?<lxWx],*R>%Ox{(x)x`(x)x

Here's an effective translation in pseudocode:

x = input by stdin
if len(x) < 2:
  output x
else:
  y = rotate_right(x, 1)
  y.remove_first_occurrence(first(x), last(x))
  # y is now the characters between the first and last of the input.
  shuffle(y)
  output place_at_end(last(x), place_at_beginning(first(x), y))
\$\endgroup\$
  • \$\begingroup\$ esolangs.com does not seem to exist anymore. \$\endgroup\$ – Tomalak Mar 24 '15 at 21:43
  • \$\begingroup\$ @Tomalak Fixed, had a .com instead of .org... \$\endgroup\$ – bcsb1001 Mar 24 '15 at 21:46
1
\$\begingroup\$

Rebol - 63

f: func[s][e: take/last s ajoin trim reduce[take s random s e]]

Ungolfed:

f: func [s] [
    e: take/last s 
    ajoin trim reduce [take s random s e]
]

Usage example:

>> f "1"
== "1"

>> f "12"
== "12"

>> f "123"
== "123"

>> f "1234"
== "1324"


NB. An alternative (but unfortunately not shorter) version would be:

f: func [s] [
    change/part next s random copy/part next s back tail s back tail s
    s
]

With golfing and minor shavings this would come out at 73 chars.

\$\endgroup\$
1
\$\begingroup\$

MATLAB, 48 bytes

function t=f(t)
t(2:end-1)=t(randperm(end-2)+1);

Too bad the spec says 'function', using input() would be 43 bytes. Another version, that will fail slightly on a one-length word (a becomes aa), is 34 bytes:

f=@(t)t([1 randperm(end-2)+1 end])
\$\endgroup\$
1
\$\begingroup\$

Pyth - 11 bytes

Pyth is younger than this challenge so it doesn't count.

pez+hz.SPtz

Gets middle, shuffles it, then adds the rest. Takes I/O from stdout/stdin.

pez+hz      Print First letter of input, something else, and last letter of input
 .S         Shuffle
  P         All but the last
   t        All but the first
    z       The input
\$\endgroup\$
  • \$\begingroup\$ Doesn't work for for 1-letter inputs. \$\endgroup\$ – Jakube Mar 31 '15 at 8:09
1
\$\begingroup\$

JavaScript 132 characters:

function r(w){return w.substr(0,1)+w.substr(1,w.length-2).split('').sort(function(){return Math.random()-.5}).join('')+w.substr(-1)}

You don't need to go through point by point. If provided a function which returns something where Math.round will return a random 0,1,-1, that will be sufficient (because of how sort works).

\$\endgroup\$
  • \$\begingroup\$ That won't keep the first and last letters in place. \$\endgroup\$ – Tomalak Mar 18 '12 at 19:14
  • \$\begingroup\$ @Tomalak Now it will. \$\endgroup\$ – cwallenpoole Mar 20 '12 at 4:16
  • \$\begingroup\$ But it does not work anymore. \$\endgroup\$ – Tomalak Mar 20 '12 at 5:08

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.