Cómo aleatorizar letras en una palabra

55

De acuerdo con alguna historia controvertida , el que odia a los personajes en un mundo no se enamora mucho de la educación, como el hombre y el hombre que se relacionan con el mundo original.

Entonces, por diversión, ¿cuál sería la función más corta para aleatorizar el orden de las letras en una palabra mientras se mantiene la primera y la última letra en su lugar?

Aquí está mi puñalada con JavaScript. Todo el espacio en blanco eliminado está en 124 130 caracteres.

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];
}

Un JavaScript más corto siempre es bienvenido.


  • Editar: verificación de longitud añadida. La función no debe fallar para palabras cortas.
Tomalak
fuente
3
Haskell, 4 caracteres: r=id.
Thomas Eding
2
Si. Devuelve exactamente lo mismo que la entrada. En otra nota, ¿qué hacemos con la puntuación? ¿Operamos solo con palabras que consisten solo en letras?
Thomas Eding
1
@trinithis no está seguro de lo que estás hablando, pero ides la función de identidad. Todavía me gustaría ver la solución de Haskell a este problema en menos de 100 caracteres.
Arlen
3
¿Debería actualizarse la especificación para requerir una distribución uniforme de resultados? Esto no permitiría la solución Haskell de 4 caracteres. También rechazaría su solución Javascript de ejemplo (barajar haciendo un tipo como ese no es uniforme).
Thomas Eding
2
+1 para la primera oración: en realidad me tomó unos segundos darme cuenta de que estaba mal escrito XP
Nate Koppenhaver

Respuestas:

21

Haskell, 4 personajes

La función trinithis propuesta en realidad coincide con la especificación:

s=id

Devuelve la cadena sin cambios, manteniendo así el primer y último carácter en su lugar y haciendo una permutación de todos los demás caracteres.

Si alguien no está satisfecho con la distribución de probabilidad de las permutaciones, aquí hay una solución que produce una mejor distribución. Obviamente es mucho más complejo:

Haskell 110 120 107 caracteres

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

Un ejemplo de un programa que usa esta función:

main = getLine >>= s >>= putStrLn
Rotsor
fuente
18
"Insatisfecho con la distribución de probabilidad de las permutaciones" me hizo reír. :)
Tomalak
@Rotsor, ¿cómo se llama esa función?
Arlen
He añadido un ejemplo a mi publicación.
Rotsor
fmap((a:t!!i:).tail)
FUZxxl
3
La primera solución debe eliminarse ya que no se ajusta a los criterios de desafío. La descripción del desafío dice "aleatorizar". Según el meta, aleatorio no siempre puede tener la misma salida .
mbomb007
19

J, 26 24 23 caracteres

r=:{.,({~?~@#)&}.&}:,{:
Eric
fuente
De acuerdo con las reglas comunes de golf de código, no tiene que vincular la frase a un nombre.
FUZxxl
#?#es un char más corto que?~@#
randomra
15

Ruby, 44 caracteres.

r=->w{w[h=1..-2]=[*w[h].chars].shuffle*"";w}

Funciona también para palabras cortas, es decir, las palabras con uno, dos o tres caracteres se devuelven sin modificaciones.

Editar: Usar la idea de matriz-splat de Ventero ahorra otro personaje.

Howard
fuente
Eso es en realidad 44 personajes. Finalmente se me ocurrió exactamente la misma respuesta ajustando la mía, ahora me siento como un imitador después de leer la suya.
Aleksi Yrttiaho
@ user2316 Por supuesto que tienes razón. Gracias.
Howard
11

Ruby 1.9, 46 caracteres

r=->w{w[0]+[*w[1..-2].chars].shuffle*""+w[-1]}
Ventero
fuente
+1 Este uso de array-splat también me salvó un personaje. Gran idea.
Howard
No sé ruby: falla en mi ruby1.8, así que supongo que necesito una versión nunca. ¿Funciona con entradas como 'I'?
usuario desconocido el
@usuario: Dice "Ruby 1.9" allí mismo. ;) - Ventero - Uno de los requisitos sensibles que olvidé mencionar es que no debe fallar para las longitudes de palabra 0 y 1. Lo siento.
Tomalak
11

Golfscript

Como una "función" (llamada codeblock): 20 caracteres

{1/(\)\{;9rand}$\}:r

Cuando se opera en el elemento superior de la pila: 16 caracteres

1/(\)\{;9rand}$\
Ventero
fuente
Esa no es una muy buena combinación, pero probablemente esté bien para esta tarea. (Es decir, "se verá lo suficientemente aleatorio"). Aún así, a costa de dos caracteres más, podría obtener una mezcla mucho mejor al reemplazar 9con 9.?.
Ilmari Karonen
Esto falla para las palabras de una sola letra, y tampoco creo que se deba permitir que la función devuelva una cadena, una matriz de cadenas, una cadena (en oposición a una sola cadena).
Martin Ender
11

C ++, 79 caracteres ( con verificación de rango )

string f(string s){if(s.size()>3)random_shuffle(&s[1],&s.end()[-1]);return s;}

C ++, 8165 caracteres ( sin verificación de rango )

string f(string s){random_shuffle(&s[1],&s.end()[-1]);return s;}

El uso de pasar por referencia en lugar de devolver el resultado elimina otros 10 caracteres de cualquiera de las soluciones.

Programa completo, leyendo una cadena de palabras y barajando convirtiéndolas:

#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;
}

Moral: no construyas lo que ya está allí. Ah, y los controles de desbordamiento son para wusses.

Konrad Rudolph
fuente
Bien, std::random_shuffleeso es nuevo para mí. por cierto creo que te olvidaste #include<string>en tu código completo.
Scott Logan
1
Algo así es lo que tenía en mente originalmente. Desafortunadamente, no hay una función integrada para mezclar una cadena en el lugar en JS.
Tomalak
Falla para cadenas muy cortas.
Usuario desconocido el
Eso es cierto, te estás perdiendo una verificación de longitud (también lo hice). Por cierto, la respuesta de @ Arlen también merece una mirada.
Tomalak
1
@userunknown Eso es lo que quise decir con "comprobaciones de desbordamiento para wusses". Pero para ser justos, también lo hacen casi todas las demás soluciones.
Konrad Rudolph el
8

Python, 86 caracteres

import random as r
def f(w):t=list(w[1:-1]);r.shuffle(t);return w[0]+''.join(t)+w[-1]

Y aquí hay un ejemplo de uso:

for x in ["ashley", "awesome", "apples"]:
    print f(x)

Este es mi primer código de ejercicio de golf. Después de resolver el problema, decidí mirar las respuestas y no sorprende que la respuesta mía no sea única. Sin embargo, esto fue divertido: o)

Realicé un cambio después de mirar las otras respuestas y estaba cambiando mi declaración de importación para usar un alias. Gran idea. ; o)

Ashley Grenon
fuente
Y, sin embargo, su solución se vota antes que la mía. : p
boothby
Falla en cadenas cortas; mi respuesta de Python sería de 75 caracteres si fallara en cadenas cortas ( from random import*\nf=lambda w:w[0]+''.join(sample(w[1:-1]),len(w)-2)+w[-1]).
dr jimbob
7

C (K&R) - 88 86 87 caracteres

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

No hay una función integrada de intercambio o aleatorio en C, así que tuve que hacerlo manualmente :(

Programa de muestra con 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;
}

EDITAR : se corrigió el error cuando s consta de menos de 3 caracteres (¡gracias a un usuario desconocido por notarlo!)

Harry K.
fuente
1
En glibc, hay (was?) Una función de biblioteca no estándar strfry.
Caracol mecánico
experiencia divertida, si lo alimento conchar s[] = "na"; // not anticipated
usuario desconocido
@user uknown: acabo de editar el código y lo arreglé, ¡gracias por notar el error! (Acabo de agregar> 0 en la condición del ciclo while, "me costó" dos más, pero necesitaba caracteres :))
Harry K.
1
@Caracol mecánico: creo que strfy todavía está en glibc.
Harry K.
7

pitón, 87 79 75 93 92 caracteres (manejo de cadenas de longitud 0,1)

from random import*
f=lambda w:w if 4>len(w)else w[0]+''.join(sample(w[1:-1],len(w)-2))+w[-1]

EDITAR: Originalmente pensé que se suponía que debía dividir las palabras de cadena (lo que hizo en 128 caracteres; ahora en 87 caracteres sí se requiere). Argh, mi mala comprensión de lectura.

EDIT 2: Cambiar de def a la función lambda de def para guardar 6 caracteres. Suponiendo que la muestra ya se haya importado al espacio de nombres ( from random import sample) podría reducir esto a ~ 60).

EDITAR 3: "len (w [1: -1])" (12 caracteres) a "len (w) -2" (8 caracteres) según la sugerencia de gnibbler.

EDITAR 4: JBernando guardó un personaje (lo consideró from random import *y vio que era equivalente, sin darse cuenta de que el espacio import *es innecesario) .; El usuario desconocido agregó 19 caracteres w if len(w)<4 elsepara manejar las cadenas de caracteres 0 y 1 correctamente.

EDITAR 5: Guardado otro char por truco de golf de código de cabina. if len(w)<4 elsea if 4>len(w)else.

dr jimbob
fuente
Sin embargo, la pregunta solo definió la entrada como una palabra, no como una cadena de palabras. :)
Ben Richards
1
@ sidran32: Gracias, mi mal. Me acabo de dar cuenta (al releer) y luego vi tu comentario; eliminado - editado - y sin borrar.
dr jimbob
Idea: puede recortar 3 caracteres haciendo esto ... def f (w): j = w [1: -1]; return w [0] + ''. join (r.sample (j, len (j))) + w [-1]
arrdem
@rmckenzie: Buena idea. Sin embargo, justo antes de ver su comentario justo después de recortarlo a la función lambda (guardar 6 caracteres), ya no puedo hacer su método para definir vars intermedios.
dr jimbob
3
len(w)-2en lugar de len(w[1:-1])?
gnibbler
6

C ++, 111 97 caracteres

std::string f(std::string s){for(int i=s.size()-1;i>1;std::swap(s[rand()%i+1],s[--i]));return s;}

Aquí hay un programa completo para aquellos que deseen probarlo:

#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;
}

Editar

Se dio cuenta de que no es necesario aleatorizar ambos índices de intercambio, guardó una variable y algunos caracteres más.

Scott Logan
fuente
Excelente. La mayoría de las soluciones fallan en entradas muy pequeñas. Tuyo no.
Usuario desconocido el
6

php (68 caracteres)

$r=preg_replace('/^(\w)(\w+)(\w)$/e','$1.str_shuffle($2).$3',trim($w));

más corto (60 caracteres)

$r=preg_replace('/(.)(.+)(.)/e','$1.str_shuffle($2).$3',$w);
tobius
fuente
+1 Muy bien. :) Podría soltar el trim (), en realidad, y en la expresión regular puede eliminar los anclajes y usarlos en .lugar de \w.
Tomalak
@Tomalak Sugerido Intento reescribir esta solución en Perl. Incluyendo sus sugerencias, obtuve esto: use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join('',shuffle split//,$2).$3;}son 87 caracteres . Sin la línea de uso, son 62 caracteres .
Ben Richards
¿Puede proporcionar una demostración de este trabajo? Porque no puedo ...
Steve Robbins
6

Perl - 96 (o 71) caracteres 84 (o 59) caracteres

Esto es lo que se me ocurrió en Perl. Pasé por varias formas diferentes de hacerlo, pero esto parecía más corto de lo que puedo pensar hasta ahora, con 97 caracteres.

use List::Util 'shuffle';sub r{($b,@w)=split//,$_[0];$e=pop(@w);return$b.join('',shuffle@w).$e;}

Sin embargo, si corta la línea de 'uso' (que supongo que es válida, ya que otros excluyeron #incluir líneas en sus programas en C), puedo reducirla a 71 caracteres :

sub r{($b,@w)=split//,$_[0];$e=pop(@w);return$b.join('',shuffle@w).$e;}

EDITAR Se sugirió que intente hacer esto implementando el método @tobius. De esta forma lo reduje a 84 caracteres , o quitando la línea de uso , 59 caracteres :

use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
Ben Richards
fuente
2
acortó su versión a 87:use List::Util 'shuffle';sub r{($b,@w)=split//,$_[0];$e=pop@w;join'',$b,(shuffle@w),$e}
mbx
1
@ sidran32 ¿Puede implementar Perl una variante de la respuesta de @tobius , solo para comparar?
Tomalak
@Tomalak Claro, lo probaré.
Ben Richards
1
acortó su versión de use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
expresiones regulares
Agradable. Estoy demasiado acostumbrado a usar una gran cantidad de paréntesis para mayor claridad. Mal hábito al jugar al golf. : P
Ben Richards
5

Ruby, 77 75 caracteres

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

Mi solución Scala en un lenguaje un poco menos detallado. No soy un experto en Ruby de ninguna manera, por lo que probablemente haya margen de mejora.

Gareth
fuente
Guau. Funciona con 'I', como su solución scala.
Usuario desconocido el
5

Ruby 1.9, 77 48 46 44 caracteres

r=->w{w[h=1..-2]=[*w[h].chars].shuffle*"";w}

Descargo de responsabilidad: Ajusté esto en función de la respuesta mejor clasificada, noté la misma respuesta más adelante. Puede consultar el historial que he mantenido fiel a mi idea original pero que cambié de ruby ​​1.8 a ruby ​​1.9 para lambdas cortas yshuffle .

Si se permiten palabras vacías, 56 54 caracteres

r=->w{w.empty?||w[h=1..-2]=[*w[h].chars].shuffle*"";w}
Aleksi Yrttiaho
fuente
Nadie espera el español 'yo'.
usuario desconocido el
Intento de manejar casos con 0 o 1 letras también
Aleksi Yrttiaho
5

Pitón 3, 94 93 91 caracteres

Usando una técnica diferente. También podría funcionar en 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

El ... if x[0:-1] else xdax si su longitud es 1 (de lo contrario se duplicaría). La función funciona para cadenas de longitud 0 y 1.

El sample()es de https://stackoverflow.com/questions/2668312/shuffle-string-in-python/2668366#2668366 .

Ya que es una expresión, se puede utilizar una lambda(eliminando return, defy un par de paréntesis).

Editar: from random import* para guardar 1 carácter, después del otro envío de Python.

Caracol mecánico
fuente
Yo que soy tan tan tan tarde aquí, pero puedo x[0:-1]llegar a ser x[:-1]?
Zacharý
4

JavaScript - 118 caracteres

JavaScript más corto: 118 caracteres sin espacios en blanco. Utiliza aproximadamente el mismo algoritmo que el OP, pero con menos encadenamiento. Intenté muchas recursiones e intenté algunas iteraciones, pero todas tienden a atascarse de una forma u otra.

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;
}
Ryan Kinal
fuente
No pasa la prueba 'I-test.
usuario desconocido el
@Ryan Usar return z?a+...+z:w;como una verificación de longitud implícita estaría en orden. La suposición silenciosa era que la función recibiría solo palabras "válidas".
Tomalak
Buen punto, excepto que w ha sido modificado, así que tengo que usarlo aen el elsedel ternario. Editado, y hasta 122 caracteres.
Ryan Kinal
@ Ryan: creo aque sería incorrecto para la entrada de dos letras. : - \ Maldita sea la próxima vez voy a delinear los requisitos con más cuidado.
Tomalak
No creo que lo haga, en realidad. zsolo estará indefinido si la palabra es una letra (o menos).
Ryan Kinal
4

D, 62 caracteres

import std.random;void s(char[] s){randomShuffle(s[1..$-1]);}

Está bien, hice trampa con una matriz de caracteres normal en lugar de una cadena real (que es un carácter inmutable char [], por lo que no hay barajado in situ)

editar con una verificación de longitud requiere 14 más

import std.random;void s(char[] s){if(s.length>1)randomShuffle(s[1..$-1]);}
monstruo de trinquete
fuente
¿Y devuelve qué para una entrada como 'I'?
usuario desconocido el
Sería más justo (= mejor comparable) devolver el resultado.
Konrad Rudolph el
@user un error de rango. @ Konrad que requeriría return s;y char [] Tipo de retorno 11 caracteres más
monstruo de trinquete
@ratchet ¿Podría publicar todo el programa, por favor? Por cierto, no entiendo por qué estás contando import std.random;, y no solo la función.
Arlen
Supongo que podría ahorrar 1 byte al omitir el espacio en char[] s(para hacerlo char[]s), pero no he usado D en años.
Tim Čas
4

php 5.3 (60 caracteres)

$r=!$w[2]?:$w[0].str_shuffle(substr($w,1,-1)).substr($w,-1);

Mejorado a 56 caracteres y ya no requiere la versión 5.3:

$r=substr_replace($w,str_shuffle(substr($w,1,-1)),1,-1);
migimaru
fuente
+1 buena alternativa a la otra respuesta PHP. No es más corto, pero no regex es una ventaja.
Tomalak
Actualizado con una solución más corta que no requiere la versión 5.3
migimaru
La versión anterior no es correcta: devuelve truecadenas cortas.
Tito
3

Perl - 111 caracteres (sin usar ninguna función de biblioteca)

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}

Uso :

$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}
mbx
fuente
3

Pitón

¡Son 90 89 112 caracteres de python!

Edición 1: ¡como una función esta vez!

(gracias gnibbler)

Edición 2: ahora maneja palabras cortas

(gracias usuario desconocido)

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]
Andbdrew
fuente
aún menos si sigues las especificaciones y escribes una función :)
gnibbler
ah, piedad shuffle no funciona en cadenas
gnibbler
1
El módulo aleatorio es como yo en un club nocturno ... ¡los dos simplemente barajamos en su lugar! :)
Andbdrew
No funciona para entradas como 'I'; volver 'II'.
usuario desconocido el
¡Gracias! ahora maneja palabras cortas, pero es un poco más largo :)
Andbdrew
3

Scala, 135 139 142 156 caracteres

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: eliminado ': String' (tipo de retorno puede inferir)
-7: eliminado 'retorno' (última expresión es el valor de retorno)
-3: factorizado s.size-2cabo
-4: toCharArray->toArray

Gareth
fuente
Funciona con 'I' y 'Verwürfel' sin personajes elegantes de Python. :) Sin embargo, mi solución usando 'shuffle' es un poco más corta.
Usuario desconocido el
@user unknown Gracias por las ediciones :-)
Gareth
3

Python, 86 caracteres

Slnicig es seguro, por lo que no hay ningún ckhnceig cercano. Wkros en todas las longitudes.

from random import*
def f(x):x=list(x);t=x[1:-1];shuffle(t);x[1:-1]=t;return''.join(x)
boothby
fuente
3

C ++ 11: - 68 66 caracteres

auto f=[&](){if(s.size()>2)random_shuffle(s.begin()+1,s.end()-1);};

programa completo:

#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;
}
Arlen
fuente
¿Es legal la codificación en la cadena de entrada?
Thomas Eding
@trinithis Pensé que solo nos preocupaba la función en sí. El programa solo muestra cómo usar la función. De todos modos, no codificar la entrada de manera rígida no haría una diferencia en este caso; solo agreguestring s; cin >> s;
Arlen
3

Ruby 1.9, 43 caracteres

r = w [0] + [* w [1 ..- 2] .chars] .shuffle.join + w [-1]

Todavía no funciona para cadenas de 1 carácter (duplica ese carácter) y falla para una cadena vacía.

karatedog
fuente
3

Python - 76 caracteres

import random as r
def f(w):m=list(w)[1:-1];r.shuffle(m);return w[0]+''.join(m)+w[-1]
Donald Wilson
fuente
El script de usuario de George pone esto en 85 caracteres.
dmckee
3

R, 104 (126)

f=function(w){s=strsplit(w,"")[[1]];paste(c(s[1],sample(s[2:(length(s)-1)]),s[length(s)]),collapse="")}

Uso:

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"

La siguiente función funciona con palabras con una longitud inferior a 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"
Paolo
fuente
Parte de la tarea era no mover la primera y la última letra.
Tomalak
@Tomalak arreglado!
Paolo
¿Funciona con palabras de menos de 3?
Tomalak
@Tomalak ¡Ahora debería estar bien! Gracias por las correcciones!
Paolo
3

Python, 102 caracteres

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]

¡Sin importaciones! Funciona para palabras de 1 carácter y superiores. Esta es mi primera entrada de golf y me inspiró la entrada de BlueEyedBeast del código más corto para producir una salida no determinista para la idea de usar id (Object) .


Explicación: hace una lista de letras de la entrada, excluyendo la primera y la última, y ​​aparece repetidamente en esta lista y se agrega a una nueva hasta que esté vacía. El índice del que aparece es id (7)% len (lista de la que estamos emergiendo). Como id (7) es la dirección de memoria del objeto 7, es esencialmente aleatorio. Así que ahora tenemos una lista de letras aleatorizadas desde el centro de la entrada original. Todo lo que hacemos ahora es agregar la primera y la última letra del resultado original en consecuencia y obtenemos el resultado que queremos: (primera letra) + (codificado en el medio) + (última letra).

jirafa
fuente
3

R 95 92 91 caracteres

f=function(w,a=el(strsplit(w,'')),b=length(a))cat(a[1],sample(a[c(1,b)],b-2),a[b],sep="")

Utiliza la evaluación perezosa de R para calcular ayb como parámetros de función, ahorrando espacio con la reutilización posterior. También, a diferencia de otras respuestas R, esto funciona para todas las palabras> 1 carácter largo. Ejemplo a continuación:

> f("hippopotamus")
hpuoopaitmps

> f("dog")
dog

> f("az")
az

Editar: Reemplazado unlist()con[[]] Reemplazado [[1]] con el ()

Andrew Haynes
fuente
2

D: 55 caracteres

void f(T)(T s){if(s.length>2)randomShuffle(s[1..$-1]);};

programa completo:

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);
}
Arlen
fuente
Creo que else sfalta la parte?
Tomalak
1
@Tomalak No, no lo es, porque no es necesario. Si la cadena tiene una longitud de 2 o menos, entonces la dejamos sola. Además, randomShuffle()está en su lugar.
Arlen
Wow, D siendo competitivo. Creo que randomShuffle(s[1..$-1])puede ser s[1..$-1].randomShuffleIIRC (a menos que esté en una versión D anterior a esta publicación)
Zacharý
2

Erlang, 188 172 132 caracteres

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

Todavía estoy aprendiendo Erlang, por lo que agradezco cualquier consejo para hacer esto más corto.

código completo (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).

Editar

Tomó la parte aleatoria como una función separada que ya no requiere que se pasen el encabezado y la cola de la lista.

Editar 2

Reestructurado para eliminar uno de los fpatrones de función, cambió la función aleatoria para aceptar solo dos parámetros, cambió lists:deletepor --[], cambió una lists:reversellamada por unlists:last

Scott Logan
fuente