[Question]
  [
According to some [controversial story](http://www.mrc-cbu.cam.ac.uk/people/matt.davis/Cmabrigde/), 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.
  
[Answer]
# Haskell, ~~110~~ ~~120~~ 107 characters
```
import Random
s l=randomRIO(1,length l-2)>>=g.($l).splitAt
g(a:b,c:d)=fmap(a:).s$c:b++d
g(a,b)=return$a++b
```
An example of a program using this function:
```
main = getLine >>= s >>= putStrLn
```
[Answer]
## J, 26 24 23 characters
```
r=:{.,({~?~@#)&}.&}:,{:
```
[Answer]
### Ruby, 44 characters
```
r=->w{w[h=1..-2]=[*w[h].chars].shuffle*"";w}
```
Works also for short words, i.e. words with one, two or three characters are returned unaltered.
*Edit:* Using the array-splat idea of Ventero saves another char.
[Answer]
## Ruby 1.9, 46 characters
```
r=->w{w[0]+[*w[1..-2].chars].shuffle*""+w[-1]}
```
[Answer]
## C++, 79 characters (*with range check*)
```
string f(string s){if(s.size()>3)random_shuffle(&s[1],&s.end()[-1]);return s;}
```
## C++, ~~81~~ 65 characters (*without range check*)
```
string f(string s){random_shuffle(&s[1],&s.end()[-1]);return s;}
```
Using pass by reference instead of returning the result shaves off another 10 characters from either solution.
Full program, reading a string of words and shuffling converting them:
```
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <ctime>
#include <string>
using namespace std;    
string f(string s){if(s.size()>3)random_shuffle(&s[1],&s.end()[-1]);return s;}
int main() {
    std::srand(std::time(0));
    std::string s;
    while(std::cin >> s)
        std::cout << f(s) << " ";
    std::cout << std::endl;
}
```
Morale: don’t build what’s already there. ~~Oh, and overflow checks are for wusses.~~
[Answer]
# **C (K&R) - 88 ~~86~~ ~~87~~ chars**
```
r(char*s){int m,j,l=strlen(s)-2,i=l;while(--i>0){j=rand()%l+1;m=s[j];s[j]=s[1];s[1]=m;}}
```
There's no build-in swap or shuffle function in C, so I had to do it manually :(
Sample Program with Ungolfed r():
```
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
// -----------------------------------------------------------------------
r( char *s )
{
    int m, j, l=strlen(s)-2, i=l;
    while (--i>0)
    {
        j = rand() % l + 1;
        m = s[j];
        s[j] = s[1];
        s[1] = m;
    }
}
// -----------------------------------------------------------------------
int main()
{
    char s[] = "anticipated";
    srand( time(0) );
    r( s );
    puts( s );
    return 0;
}
```
**EDIT**: fixed the bug when s consists of less than 3 chars (thanks to user-uknown for noticing it! )
[Answer]
## Python, ~~87~~ ~~79~~ ~~75~~ ~~93~~ 92 chars
```
from random import*
f=lambda w:w if 4>len(w)else w[0]+''.join(sample(w[1:-1],len(w)-2))+w[-1]
```
EDIT: Originally thought it was supposed to split string words (which it did at 128 chars; now at 87 chars does requirement). Argh, my bad at reading comprehension.
EDIT 2: Change from def to lambda function from def to save 6 chars. Assuming sample is already imported to the namespace (`from random import sample`) could bring this down to ~60).
EDIT 3: "len(w[1:-1])" (12 chars) to "len(w)-2" (8 chars) per gnibbler's nice suggestion.
EDIT 4: JBernando saved one char (had considered `from random import *` and saw it was equivalent -- not realizing the space in `import *` is unnecessary).; user unknown added 19 chars `w if len(w)<4 else` to handle 0 and 1 char strings correctly.
EDIT 5: Saved another char per boothby's code golf trick. `if len(w)<4 else` to `if 4>len(w)else`.
[Answer]
# C++, 111 97 chars
```
std::string f(std::string s){for(int i=s.size()-1;i>1;std::swap(s[rand()%i+1],s[--i]));return s;}
```
Here is a full program for those who wish to test it:
```
#include<string>
#include<iostream>
std::string f(std::string s){for(int i=s.size()-1;i>1;std::swap(s[rand()%i+1],s[--i]));return s;}
int main(){
    for(int i = 0; i<100; ++i)
    std::cout<<f("letters")<<std::endl;
}
```
# Edit
Realised there is no need to random both swap indexes, saved a variable and a few more characters.
[Answer]
# php (68 characters)
```
$r=preg_replace('/^(\w)(\w+)(\w)$/e','$1.str_shuffle($2).$3',trim($w));
```
# shorter (60 characters)
```
$r=preg_replace('/(.)(.+)(.)/e','$1.str_shuffle($2).$3',$w);
```
[Answer]
## Perl - 96 (or 71) characters 84 (or 59) characters
This is what I came up with in Perl. Went through a few different ways to do it but this seemed shortest from what I can think of so far, at 97 characters.
```
use List::Util 'shuffle';sub r{($b,@w)=split//,$_[0];$e=pop(@w);return$b.join('',shuffle@w).$e;}
```
Though, if you cut out the 'use' line (which I guess is valid, since others excluded #include lines in their C programs) I can cut it down further to **71 characters**:
```
sub r{($b,@w)=split//,$_[0];$e=pop(@w);return$b.join('',shuffle@w).$e;}
```
**EDIT**
It was suggested that I try doing this implementing @tobius' method. This way I got it down to **84 characters**, or by removing the *use* line, **59 characters**:
```
use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
```
[Answer]
## Ruby, 77 75 characters
```
def r(s);f=s.size-2;1.upto(f){|i|x=rand(f)+1;t=s[i];s[i]=s[x];s[x]=t};s;end
```
My Scala solution in a slightly less verbose language. I'm not a Ruby expert by any means, so there's probably room for improvement.
[Answer]
**Ruby 1.9, 77 48 46 44 chars**
```
r=->w{w[h=1..-2]=[*w[h].chars].shuffle*"";w}
```
Disclaimer: I tuned this based on the highest ranked answer - noticed the exact same answer later on. You can check the history that I have kept true to my original idea but changed from ruby 1.8 to ruby 1.9 for short lambdas and `shuffle`. 
If empty words are allowed then 56 54 chars
```
r=->w{w.empty?||w[h=1..-2]=[*w[h].chars].shuffle*"";w}
```
[Answer]
# Python 3, ~~94~~ ~~93~~ 91 characters
Using a different technique. Might also work in Python 2.
```
from random import*
s=lambda x:x[0]+''.join(sample(x[1:-1],len(x)-2))+x[-1]if x[0:-1]else x
```
The `... if x[0:-1] else x` gives `x` if its length is 1 (otherwise it would be duplicated). The function thereby works for strings of length 0 and 1.
The `sample()` is from <https://stackoverflow.com/questions/2668312/shuffle-string-in-python/2668366#2668366>.
Since it's one expression, we can use a `lambda` (eliminating `return`, `def`, and a pair of parentheses).
**Edit:** `from random import*` to save 1 character, after the other Python submission.
[Answer]
## D, 62 chars
```
import std.random;void s(char[] s){randomShuffle(s[1..$-1]);}
```
okay I cheated with a normal char array instead of a real string (which is immutable char[] so no in-place shuffling)
**edit** with a length check it requires 14 more
```
import std.random;void s(char[] s){if(s.length>1)randomShuffle(s[1..$-1]);}
```
[Answer]
## php 5.3 (60 chars)
```
$r=!$w[2]?:$w[0].str_shuffle(substr($w,1,-1)).substr($w,-1);
```
**Improved to 56 chars and no longer requires version 5.3:**
```
$r=substr_replace($w,str_shuffle(substr($w,1,-1)),1,-1);
```
[Answer]
**Python, 86 chars**
Slnicig is safe, so no bnouds ckhnceig is neeacrssy. Wkros on all
leghtns.
```
from random import*
def f(x):x=list(x);t=x[1:-1];shuffle(t);x[1:-1]=t;return''.join(x)
```
[Answer]
# JavaScript - 118 122 125 chars
Uses approximately the same algorithm as the OP, but with less chaining. I tried a lot of recursion, and I tried some iteration, but they all tend to get bogged down in some way or another.
```
function s(w){w=w.split('');var a=w.shift(),z=w.pop();return z?a+(w.sort(function(){return Math.random()-.5}).join(''))+z:a;}
```
Ungolfed:
```
function s(w)
{
    w = w.split('');
    var a = w.shift(),
        z = w.pop();
    return z?a + (w.sort(function() { return Math.random() - .5}).join('')) + z:a;
}
```
[Answer]
**Perl - 111 characters (without using any library function)**
```
sub r{($f,@w)=split//,shift;$l=pop@w;while(@w){if(rand(9)>1){push@w,shift@w}else{push@t,pop@w}}join'',$f,@t,$l}
```
[Usage](http://ideone.com/XUEie): 
```
$in="randomizethis";
$out = &r($in);
print "\nout: $out";
sub r{($f,@w)=split//,shift;$l=pop@w;while(@w){if(rand(9)>1){push@w,shift@w}else{push@t,pop@w}}join'',$f,@t,$l}
```
[Answer]
# Python
It's 90 89 112 characters of python!
## Edit 1: as a function this time!
 (thanks gnibbler)
## Edit 2: now handles short words
 (thanks user unknown)
```
import random as r
def q(s):
 a=list(s)
 b=a[1:-1]
 r.shuffle(b)
 if len(s)<4:
  return s
 return a[0]+''.join(b)+a[-1]
```
[Answer]
## Scala, 135 139 142 156 characters
```
def r(s:String)={var(x,o,t,f)=(0,s.toArray,' ',s.size-2)
for(i<-1 to f){t=o(i)
x=util.Random.nextInt(f)+1
o(i)=o(x)
o(x)=t}
o.mkString}
```
-7: removed ':String' (return type can be inferred)  
-7: removed 'return ' (last expression is the return value)  
-3: factored `s.size-2` out  
-4: `toCharArray` -> `toArray`
[Answer]
# C++11: - 68 66 chars
```
auto f=[&](){if(s.size()>2)random_shuffle(s.begin()+1,s.end()-1);};
```
full program:
```
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(int argc, char* argv[]){
  string s = "SomestrinG";
  auto f=[&](){if(s.size()>2)random_shuffle(s.begin()+1,s.end()-1);};
  f();
  cout << s << endl;
  return 0;
}
```
[Answer]
# Python - 76 characters
```
import random as r
def f(w):m=list(w)[1:-1];r.shuffle(m);return w[0]+''.join(m)+w[-1]
```
[Answer]
## R, 104 (126)
```
f=function(w){s=strsplit(w,"")[[1]];paste(c(s[1],sample(s[2:(length(s)-1)]),s[length(s)]),collapse="")}
```
Usage:
```
for (i in 1:10) print(f("parola"))
[1] "plraoa"
[1] "prolaa"
[1] "praola"
[1] "parloa"
[1] "plaora"
[1] "palroa"
[1] "porlaa"
[1] "ploraa"
[1] "porlaa"
[1] "ploraa"
```
the below function works with words with length less than 3:
```
f=function(w){s=strsplit(w,"")[[1]];ifelse(length(s)<3,w,paste(c(s[1],sample(s[2:(length(s)-1)]),s[length(s)]),collapse=""))}
f("pl")
[1] "pl"
f("a")
[1] "a"
```
[Answer]
# R, ~~95~~ ~~92~~ 91 characters
```
f=function(w,a=el(strsplit(w,'')),b=length(a))cat(a[1],sample(a[c(1,b)],b-2),a[b],sep="")
```
Makes use of R's lazy evaluation to compute a and b as function parameters, saving space with re-use later on. Also unlike other R answer this works for all words >1 char long.
Example below:
```
> f("hippopotamus")
hpuoopaitmps
> f("dog")
dog
> f("az")
az
```
Edit:  ~~Replaced `unlist()` with `[[]]`~~  Replaced [[1]] with el()
[Answer]
# D: 55 characters
```
void f(T)(T s){if(s.length>2)randomShuffle(s[1..$-1]);};
```
full program:
```
import std.stdio, std.random, std.conv;
void f(T)(T s){if(s.length>2)randomShuffle(s[1..$-1]);};
void main(){
  char[] s = to!(char[])("SomestrinG");
  f(s);
  writeln(s);
}
```
[Answer]
# Erlang, 188 172 132 chars
```
f([H|C=[_|_]])->T=[lists:last(C)],[H|s(C--T,T)];f(X)->X. s([],N)->N;s(D,N)->E=[lists:nth(random:uniform(length(D)),D)],s(D--E,E++N).
```
I'm still learning Erlang so any tips on making this shorter are appreciated.
full code(string\_shuffle module):
```
-module(string_shuffle).
-export([f/1]).
f([H|C=[_|_]])->
    T=[lists:last(C)],
    [H|s(C--T,T)];f(X)->X.
f(X)->X.
s([],N)->N;
s(D,N)->
    E=[lists:nth(random:uniform(length(D)),D)],
    s(D--E,E++N).
```
## Edit
Took the shuffle part out as a seperate function which no longer requires the head and tail of the list to be passed around.
## Edit 2
Restructured to remove one of the `f`function patterns, changed the shuffle function to accept only two parameters, changed `lists:delete` for `--[]`, swapped a `lists:reverse` call for a `lists:last`
[Answer]
## PowerShell, 93
```
filter x{if($_.length-lt3){$_}else{$_[0,-1]-join-join($_[1..($a=$_.Length-2)]|random -c $a)}}
```
Look, double-join~~t~~ed code!
[Answer]
# 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;}
```
[Answer]
## 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.
[Answer]
# 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'
}
```
]