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...
Can we assume that the word is not empty? – Martin Ender – 2015-03-27T16:31:23.040
Throughout the other answers valid results for edge cases ("short input") were required. The empty string qualifies as an edge case, so I'd say no. – Tomalak – 2015-03-27T17:03:46.427
Is there any reason this isn't just as simple as using a built in shuffle function? – Cyoce – 2015-12-27T07:56:30.947
@ThomasEding shuffling arbitrarily long strings uniformly would require that the random number generator has arbitrarily many bits in its state, so
id
is a good compromise. – Angs – 2016-11-10T19:10:05.8073Haskell, 4 characters:
r=id
. – Thomas Eding – 2011-08-03T20:01:53.710@trinithis Huh? – Tomalak – 2011-08-03T20:11:09.793
The randomizing function always returns the same (AHEM) random outcome. (
id x = x
is a built in function. For Haskellers out there, I still thinkid
should be able to be written point-free style:id=
) – Thomas Eding – 2011-08-03T20:14:10.440@trinithis I'm afraid I know nothing about Haskell. ;) Does that keep the first and last letters in place? – Tomalak – 2011-08-03T20:24:35.447
2Yes. 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? – Thomas Eding – 2011-08-03T20:28:38.617
@trinithis Yeah I assumed the function would only be fed with valid input, i.e. one word. ;) – Tomalak – 2011-08-03T20:33:36.793
1@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. – Arlen – 2011-08-04T07:37:12.460To clarify the spec: is it required that the function takes an argument and returns the result or are other solutions acceptable? For instance, in C++ it’s much shorter not to bother with arguments and return type and just mutate some global state. – Konrad Rudolph – 2011-08-04T10:51:08.640
3Should 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). – Thomas Eding – 2011-08-04T17:25:24.497
1I would like to clarify that by uniform, we should treat the problem as if each character was unique. That is, duplicate letters will 'apparently' skew the distribution, but in actuality, it doesn't, because we are really working on the problem of permuting [1, 2, ..., n] while keeping 1 and n in the same spot. – Thomas Eding – 2011-08-04T17:49:52.073
2+1 for the first sentence: it actually took me a few seconds to realize it was spelled wrong XP – Nate Koppenhaver – 2011-08-04T18:33:09.900