| Bytes | Lang | Time | Link |
|---|---|---|---|
| 070 | AWK | 241107T185547Z | xrs |
| 012 | Uiua | 241013T202132Z | nyxbird |
| 069 | Zsh +coreutils | 230218T044723Z | roblogic |
| 132 | Go | 230131T141621Z | bigyihsu |
| 010 | Thunno 2 j | 230608T185141Z | The Thon |
| 071 | C gcc | 230307T165925Z | evanstar |
| 081 | JavaScript | 230201T022845Z | EzioMerc |
| 026 | GolfScript | 230217T161326Z | emirps |
| 018 | J | 230201T033122Z | Jonah |
| 027 | APL | 220715T172237Z | Vadim Tu |
| 022 | K ngn/k | 220309T210410Z | coltim |
| 018 | Pyth | 220308T201600Z | sinvec |
| 005 | Vyxal | 220202T225516Z | emanresu |
| nan | Haskell | 110804T163158Z | Rotsor |
| 125 | JavaScript | 110803T145359Z | Ryan Kin |
| 092 | Python | 110803T170750Z | dr jimbo |
| 011 | 05AB1E | 181010T121827Z | Kevin Cr |
| 098 | Javascript | 181010T114344Z | Spitemas |
| 093 | JavaScript | 181010T065048Z | guest271 |
| 081 | Powershell | 181009T095101Z | mazzy |
| 104 | APLNARS | 181009T092706Z | user5898 |
| 102 | JavaScript | 181009T072945Z | guest271 |
| 1344 | Taxi | 181009T061512Z | JosiahRy |
| 073 | Python 3 | 180718T024521Z | JathOsh |
| 079 | R | 180717T164846Z | JayCe |
| 019 | ><> | 180409T074734Z | Jo King |
| 054 | PHP 7.1 | 180409T044527Z | Titus |
| 041 | Perl | 161213T123719Z | Dom Hast |
| nan | R | 170613T130203Z | Andrew H |
| 080 | Python 3 | 151227T064559Z | dzil123 |
| 152 | C# w/Linq 152 nonwhitespace chars. | 110803T193810Z | KeithS |
| 151 | VBA | 120319T213306Z | Gaffi |
| 040 | ><> | 161208T155400Z | redstarc |
| 091 | Coffeescript 91 Bytes | 161206T134538Z | NeRoboto |
| 102 | Python | 161207T031118Z | giraffe |
| 132 | JavaScript | 111116T090622Z | cwallenp |
| 039 | Ruby | 161110T192633Z | Lee W |
| 011 | Pyth | 150330T225436Z | Maltysen |
| 048 | MATLAB | 150330T094445Z | Sanchise |
| 015 | CJam | 150327T153313Z | Martin E |
| 063 | Rebol | 150326T173227Z | draegtun |
| 024 | Clip | 150324T211635Z | bcsb1001 |
| 102 | TinyMUSH | 141101T231802Z | Muqo |
| 098 | Mathematica | 120823T123355Z | DavidC |
| 025 | J | 120823T112223Z | defhlt |
| 034 | APL Dyalog | 120823T052445Z | MrZander |
| 047 | MATLAB | 120321T104331Z | Pontus v |
| 046 | MATLAB 46 Characters | 120410T031630Z | jazzking |
| 042 | Q 42 Characters | 120321T172717Z | sinedcm |
| 048 | Q | 120320T094209Z | tmartin |
| nan | R | 120318T190017Z | Paolo |
| 075 | Groovy | 111116T072217Z | Armand |
| 094 | Scala | 111114T142839Z | bkuder |
| 128 | C# | 110921T154533Z | Luis SaT |
| 076 | Perl | 110917T075813Z | Zaid |
| 076 | Python | 110909T183833Z | Donald W |
| 093 | PowerShell | 110805T092217Z | Joey |
| 091 | Python 3 | 110804T185731Z | Mechanic |
| 132 | Erlang | 110804T160539Z | Scott Lo |
| 202 | Javascript | 110804T223916Z | Thomas E |
| 194 | Java | 110803T210530Z | Thomas E |
| 066 | C++11 | 110804T053741Z | Arlen |
| 055 | D | 110804T210327Z | Arlen |
| 177 | FSharp | 110803T205553Z | sideproj |
| 086 | Python | 110804T201117Z | boothby |
| 195 | Haskell | 110804T170822Z | Thomas E |
| 109 | Python 103 96 90 88 85 | 110803T162926Z | arrdem |
| 059 | Perl 84 or | 110803T170713Z | Ben Rich |
| 060 | php 5.3 | 110804T172723Z | migimaru |
| 135 | Scala | 110803T130850Z | Gareth |
| 068 | php | 110803T182256Z | tobius |
| 173 | Lua | 110804T135133Z | jpjacobs |
| 062 | D | 110803T161228Z | ratchet |
| nan | 110803T195101Z | Andbdrew | |
| 079 | C++ | 110803T154143Z | Konrad R |
| 044 | Ruby | 110803T163415Z | Howard |
| nan | 110804T032256Z | user unk | |
| 044 | Ruby 1.9 | 110803T131022Z | Aleksi Y |
| nan | C K&R 88 | 110803T200722Z | Harry K. |
| 111 | Perl | 110803T183136Z | mbx |
| 023 | J | 110803T152501Z | Eric |
| 046 | Ruby 1.9 | 110803T145021Z | Ventero |
| 075 | Ruby | 110803T140954Z | Gareth |
| 097 | C++ | 110803T124348Z | Scott Lo |
AWK, -F '' 70 bytes
{srand();for(i=1;i++<NF-1;)b[rand()]=$i;for(a in b)s=s b[a]}$0=$1 s$NF
To test:
awk -F '' '{srand();for(i=1;i++<NF-1;)b[rand()]=$i;for(a in b)s=s b[a]}$0=$1 s $NF' <<< "controversial"
{srand(); # seed random
for(i=1;i++<NF-1;) # only inside letters
b[rand()]=$i; # random location in array
for(a in b)s=s b[a]} # iterate through array
$0=$1 s$NF # output
Uiua, 12 bytes
⍣⍜(↘1↘¯1)°⍆∘
⍣⍜(↘1↘¯1)°⍆∘
⍜(↘1↘¯1) # under dropping the first and last:
°⍆ # shuffle
⍣ ∘ # catch errors with identity
⍜ under performs a transformation, calls a function, and then undoes the transformation. ↘ dropping from an empty array would error on inputs of length 1, so we have to catch the error.
Zsh +coreutils, 69 bytes
for n;printf $n[1]`fold -1<<<${n:1:-1}|shuf|rs -g0`${n:$#n-1:$#n-1}\
Try it online!
73bytes
78bytes
85bytes
92bytes
Incidentally, the Zsh documentation mixes up the descriptions of flags. F splits, f joins.
Go, 154 132 bytes
import."math/rand"
func f(S string)(e string){k:=S[1:len(S)-1]
for _,i:=range Perm(len(k)){e+=k[i:i+1]}
return S[:1]+e+S[len(S)-1:]}
- -22 bytes from
rand.Perm, using string slices, and named return.
Thunno 2 j, 10 bytes
Dḣ?Ṫsḣµr$h
Explanation
Dḣ?Ṫsḣµr$h # Implicit input
D # Duplicate the input
ḣ # Pop one copy and check if it's length is more than 1
? # If that's true:
Ṫ # Remove the last character and push it separately
s # Swap so the last character is below the rest of the string
ḣ # Discard the first character from this string
µr # Randomly shuffle the string
$h # Push the first character of the input again
# Implicit output of joined stack
C (gcc), 71 bytes
Look mom, I beat python!
f(s,d)char*s;{for(;s[2];)if(d=rand()%~-strlen(++s))*s^=s[d]^=*s^=s[d];}
JavaScript, 81 bytes
s=>s.length<4?s:s[0]+[...s.slice(1,-1)].sort(_=>Math.random()>.5).join``+s.at(-1)
Try it:
f=s=>s.length<4?s:s[0]+[...s.slice(1,-1)].sort(_=>Math.random()>.5).join``+s.at(-1)
;[
'',
'1',
'12',
'123',
'1234',
'12345',
'123456',
'1234567',
'12345678',
'123456789',
].forEach(s=>console.log(f(s)))
JavaScript, 4 bytes
s=>s
It is funny but in real the chance to randomly sort the symbols position in string and get the same string is equal to get the another string. And this is not depend on how many times we will randomize the symbols in string. It may seem like something unreal, but that's the way it is :)
To understand it more easy way imagine that we must generate a number by generating random digits. Let's say we have to get a number of length n. We have 10 digits, so in each position the chance of any digit is \$\frac{1}{10}\$ so the total chance to get the any number with length of n is \$(\frac{1}{10})^n\$. So the chance to get the number 8888888888888888...8888 randomly is the same as the chance to get 9872346897621449...0467. It is important to understand that the probability of the next digit is independent of the previous generated digit
J, 18 bytes
({~>:,~0,1+?~)_2+#
Constructs random indexes for the interior, prepends 0, appends n-1, then uses all those to index into the input.
APL, 27 bytes
{3≥⍴⍵:⍵⋄⍵[⍋0,(?⍨2-⍨⍴⍵),⍴⍵]}
K (ngn/k), 22 bytes
{,/0N?'(0 1,1|#1_x)_x}
hat-tip ovf from the array programming discord / matrix for this answer!
Takes a single word to shuffle/randomize.
(...)_xcutx(the input) on the indices from(...), returning a three-item list containing the first element, the middle element(s), and the last element(0 1,1|#1_x)generate a three-item list equivalent to[0, 1, max(1, len(x)-1)]. taking the max with 1 ensures single-character strings (e.g.,"a") are handled as well.
0N?'shuffleeach slice; this is a no-op on empty and one-character strings,/flatten the shuffled slices into a single string and (implicitly) return it
Vyxal, 5 bytes
ÞẇṖ℅j
Þẇ # Push (first+last, rest)
Ṗ℅ # Shuffle (rest)
j # Join (first+last) by (rest)
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
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;
}
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.
05AB1E, 12 11 bytes
g≠ićs¨.rIθJ
Try it online or verify some more inputs.
Fun 12 11 bytes alternative:
g͸1.ø£€.rJ
Try it online or verify some more inputs.
Both version also work for strings with less than 3 characters. The first one could be just ćs¨.rIθJ (8 bytes), but then it doesn't work for single-character strings ("a" becomes "aa").
Explanation:
g # Take the length of the (implicit) input
# i.e. "howaboutthis" → 12
# i.e. "a" → 1
≠i # If this length is not 1:
# i.e. 12 → 1 (truthy)
# i.e. 1 → 0 (falsey)
ć # Extract the head of the (implicit) input
# i.e. "howaboutthis" → "owaboutthis" and "h"
s # Swap so the list (minus head) is at the top of the stack again
¨ # Remove the last character
# i.e. "owaboutthis" → "owaboutthi"
.r # Randomly shuffle the characters
# i.e. "owaboutthi" → "oohbtwtiua"
Iθ # Take the last character of the input
# i.e. "howaboutthis" → "s"
J # Join the values on the stack together (and output implicitly)
# i.e. "h", "oohbtwtiua", "s" → "hoohbtwtiuas"
# (Implicit else)
# (Output the input as is implicitly)
# i.e. "a"
g # Take the length of the (implicit) input
# i.e. "howaboutthis" → 12
# i.e. "a" → 1
Í # Subtract 2
# i.e. 12 → 10
# i.e. 1 → -1
¸ # Wrap it into a list
# i.e. 10 → [10]
# i.e. -1 → [-1]
1.ø # Surround it with 1s
# i.e. [10] → [1,10,1]
# i.e. [-1] → [1,-1,1]
£ # Split the (implicit) input into parts of that size
# i.e. "howaboutthis" and [1,10,1] → ["h","owaboutthi","s"]
# i.e. "a" and [1,-1,1] → ["a","",""]
€ # Map each value to:
.r # Randomly shuffle the characters
# i.e. ["h","owaboutthi","s"] → ["h","oohbtwtiua","s"]
# i.e. ["a","",""] → ["a","",""]
J # Join the values in the list together (and output implicitly)
# i.e. ["h","oohbtwtiua","s"] → "hoohbtwtiuas"
# i.e. ["a","",""] → "a"
Javascript 98 bytes
a=>{c=l=a.length-1;for(b=[a[0]];--c;)d=Math.random()*99|0,b[d]?c++:b[d]=a[c];return b.join``+a[l]}
This assigns each letter other than the first and last to a random array index, and then joins the array into a string. 99 can be changed to 9e9 to work on (much!) longer words at the cost of a byte, but then join takes almost a minute. Besides, there aren't many words that even approach 100 characters.
Because of that, this is 12 bytes shorter (86 bytes) and works almost every time:
a=>{c=l=a.length-1;for(b=[a[0]];--c;)b[Math.random()*9e9|0]=a[c];return b.join``+a[l]}
JavaScript, 93 bytes
(_,[a,[...b],c,d=b.sort(_=>Math.random()-.5).join``]=_.match(/(^.)|[^\1]+(?=.$)|.$/g))=>a+d+c
Using .match() with regular expression /(^.)|[^\1]+(?=.$)|.$/g to match first character, one or more characters that at not the first character followed by one character and end of string, and character followed by end of string and .sort() approach used at the question.
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:
if elsereplaced with a Fake ternary operator.$_.Lengthis written once.- Other golf to compact the script
- The script gets
Randomfor the word length >= 4 only. random -c $areplaced withrandom -c 2e9. It need to avoid an exception with word length <= 2. I think the length =2000000000is 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
APL(NARS), 52 chars, 104 bytes
∇r←s w;x
r←,w⋄→0×⍳3≥⍴w⋄r←(↑w),x[?⍨⍴x←¯1↓1↓w],¯1↑w
∇
This 'solution' is based to the fact that 3?3 return a random permutation of 1 2 3;
6?6 a random permutation of 1 2 3 4 5 6 ecc n?n a random permutation of 1 2 .. n
so if B is a string B[(⍴B)?⍴B] would be a string random permutation of B.
The function 's' has to have as input one string and return one string or ''.
If someone see some error, please to say, thank you.
test:
⎕fmt s¨'' 'w' 'my' 'the' 'this' 'this' 'this'
┌7────────────────────────────────────────────┐
│┌0┐ ┌1─┐ ┌2──┐ ┌3───┐ ┌4────┐ ┌4────┐ ┌4────┐│
││ │ │ w│ │ my│ │ the│ │ tihs│ │ this│ │ this││
│└¯┘ └──┘ └───┘ └────┘ └─────┘ └─────┘ └─────┘2
└∊────────────────────────────────────────────┘
s¨'random' 'random' 'random' 'random'
rdonam rodanm raodnm rodnam
s 'permutation'
ptaemutroin
JavaScript, 102 bytes
(_,a=[..._].slice(1,-1))=>_.replace(/./g,(m,i)=>(l=a.length,!i||!l?m:a.splice(~~(Math.random()*l),1)))
Using spread syntax and .slice() create array from input string beginning at index 1 through -1, .splice() elements from array within .replace() callback function, return string.
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 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.
Python 3, 75 73 bytes
Thanks to @WW for saving me 2 bytes
lambda x:x[0]+''.join(sample(x[1:-1],len(x)-2))+x[-1]
from random import*
R, 93 79 bytes
function(x,l=nchar(x))"if"(l<4,x,intToUtf8(utf8ToInt(x)[c(1,sample(l-2)+1,l)]))
Wroks for any ipnut szie dwon to zero, by frsit ckciheng the lgnteh of the sintrg and rneturing it if nchar(x)<4
-14 bytes thanks to Giuseppe!
PHP 7.1, 54 bytes
If the word has less than 4 letters, don´t shuffle:
$r=$w[3]?$w[0].str_shuffle(substr($w,1,-1)).$w[-1]:$w;
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
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 Replaced [[1]] with el()unlist() with [[]]
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]
C# w/Linq - 152 non-whitespace chars.
It's terrible compared to other languages on char count, but elegant:
public string Shuf(string i)
{
return new String(i.Take(1)
.Concat(i.Skip(1).Take(i.Length-2).OrderBy(x=>Guid.NewGuid()))
.Concat(new[]{i.Last()})
.ToArray());
}
VBA, 128 177 151 chars
I know this is an older puzzle, but I wanted to add my two cents from
Sub o(s)
n=Left(s,1)
p=Len(s)-1
s=Right(s,p)
For i=1 To p-1
p=p-1
r=Int(p*Rnd()+1)
n=n & Mid(s,r,1)
s=Left(s,r-1) & Right(s,p-r+1)
Next
s=n & s
End Sub
Example Usage:
a = "According"
o a ' a is assigned by the passing of the reference to the 'o' sub.
a = "to"
o a ' see above...
a = "some"
o a
a = "controversial"
o a
a = "story"
o a
I was actually happily surprised to see it fare as well as it did against some of the other, more typical CG languages. After improving, this is still not the shortest, but I was happy to do it.
Coffee-script: 76 91 Bytes
f=(a)->a.length>1&&a[0]+(a.split('')[1..-2].sort ()->.5-Math.random()).join('')+a[-1..]||a
Wow, I like this language already.
Python, 102 characters
def f(x):t=list(x)[1:-1];k='';exec'k+=t.pop(id(7)%len(t));'*len(t);return[x[0],x[0]+k+x[-1]][len(x)>1]
No imports! Works for words 1 character and above. This is my first golf entry and I was inspired by BlueEyedBeast's entry from Shortest code to produce non-deterministic output for the idea of using id(Object).
Explanation: It makes a list of letters from the input excluding the first and last, and repeatedly pops from this list and appends to a new one until empty. The index it pops from is id(7) % len(list we're popping from). Since id(7) is the memory address of the object 7, it is essentially random. So now we have a list of randomly scrambled letters from the center of the original input. All we do now is append the first and last letters of the original output accordingly and we got the output we want: (first letter)+(scrambled middle)+(last letter).
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).
Ruby, 39 characters
->s{a,*b,c=s.chars;[a,*b.shuffle,c]*''}
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
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])
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.
If full programs (STDIN to STDOUT) are also acceptable, it can be solved in 12 bytes:
l(\_W>\W<mr\
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.
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.
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))
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.
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.",

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
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...
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.)
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.
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"
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]}
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"
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'
}
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.
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;}
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
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]
PowerShell, 93
filter x{if($_.length-lt3){$_}else{$_[0,-1]-join-join($_[1..($a=$_.Length-2)]|random -c $a)}}
Look, double-jointed code!
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.
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 ffunction patterns, changed the shuffle function to accept only two parameters, changed lists:delete for --[], swapped a lists:reverse call for a lists:last
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).
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.
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;
}
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);
}
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")
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)
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.
Python - 103 96 90 88 85 109 characters
import random as r
def s(x):
if len(x)>3:y=list(x[1:-1]);r.shuffle(y);return x[0]+''.join(y)+x[-1]
return x
props to @dr jimbob for the "import as" bit and for catching my non-conformance with the spec. props also to @user unknown for getting the spec clarified.
Edit: updated to conform to short-words spec.
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}
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);
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
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);
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
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]);}
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]
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.
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.
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.
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}
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! )
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}
$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}
J, 26 24 23 characters
r=:{.,({~?~@#)&}.&}:,{:
Ruby 1.9, 46 characters
r=->w{w[0]+[*w[1..-2].chars].shuffle*""+w[-1]}
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.
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.