Como randomizar letras em uma palavra

55

De acordo com uma história controversa , o odioso dos últimos em um artigo não é muito importante para o futuro, tanto quanto o primeiro e o último, com o texto original.

Então, por diversão, qual seria a função mais curta para randomizar a ordem das letras em uma palavra, mantendo a primeira e a última letra no lugar?

Aqui está minha facada com JavaScript. Todo o espaço em branco removido está em 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];
}

JavaScript mais curto sempre bem-vindo.


  • Editar: verificação de comprimento adicionada. A função não deve falhar em palavras curtas.
Tomalak
fonte
3
Haskell, 4 caracteres: r=id.
Thomas Eding
2
Sim. Retorna exatamente a mesma coisa que a entrada. Em outra nota, o que fazemos sobre pontuação? Operamos apenas com palavras que consistem apenas em letras?
Thomas Eding
11
@ trinith não tem certeza do que está falando, mas idé a função de identidade. Eu ainda gostaria de ver a solução Haskell para esse problema em menos de 100 caracteres.
Arlen
3
A especificação deve ser atualizada para exigir uma distribuição uniforme dos resultados? Isso não permitiria a solução Haskell de 4 caracteres. Também impediria o seu exemplo de solução Javascript (embaralhar fazendo uma classificação como essa não é uniforme).
Thomas Eding
2
+1 na primeira frase: na verdade, levei alguns segundos para perceber que estava escrito XP errado
Nate Koppenhaver

Respostas:

21

Haskell, 4 caracteres

A função trinithis proposta realmente corresponde à especificação:

s=id

Ele retorna a string inalterada, mantendo assim o primeiro e o último caracteres no lugar e fazendo uma permutação de todos os outros caracteres.

Se alguém está insatisfeito com a distribuição de probabilidade das permutações, aqui está uma solução que produz uma melhor distribuição. É obviamente muito mais complexo:

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

Um exemplo de um programa usando esta função:

main = getLine >>= s >>= putStrLn
Rotsor
fonte
18
"insatisfeito com a distribuição de probabilidade das permutações" me fez rir. :)
Tomalak
@ Rotsor como você chama essa função?
Arlen
Adicionei um exemplo ao meu post.
Rotsor 4/08/11
fmap((a:t!!i:).tail)
FUZxxl
3
A primeira solução deve ser removida, pois não se encaixa nos critérios de desafio. A descrição do desafio diz "randomize". De acordo com a meta, o aleatório nem sempre pode ter a mesma saída .
Mbomb007
19

J, 26 24 23 caracteres

r=:{.,({~?~@#)&}.&}:,{:
Eric
fonte
De acordo com as regras comuns de código de golfe, você não precisa vincular a frase a um nome.
FUZxxl
#?#é um caractere menor que?~@#
randomra 15/02
15

Ruby, 44 caracteres

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

Funciona também para palavras curtas, ou seja, palavras com um, dois ou três caracteres são retornadas inalteradas.

Edit: Usar a idéia de array-splat do Ventero salva outro caracter.

Howard
fonte
Na verdade, são 44 caracteres. Acabei encontrando exatamente a mesma resposta ajustando a minha - agora me sinto como uma cópia depois de ler a sua.
Aleksi Yrttiaho
@ user2316 Claro que você está certo. Obrigado.
Howard
11

Ruby 1.9, 46 caracteres

r=->w{w[0]+[*w[1..-2].chars].shuffle*""+w[-1]}
Ventero
fonte
+1 Este uso de array-splat me salvou também de um caractere. Boa ideia.
Howard Howard
Não conheço ruby ​​- ele falha no meu ruby1.8, então acho que preciso de uma versão nunca? Funciona com entradas como 'I'?
usuário desconhecido
@ usuário: Ele diz "Ruby 1.9" ali. ;) - Ventero - Um dos requisitos sensatos que esqueci de mencionar é que não deve falhar nos comprimentos de palavra 0 e 1. Desculpe.
Tomalak
11

Golfscript

Como uma "função" (chamada codeblock): 20 caracteres

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

Ao operar no elemento superior da pilha: 16 caracteres

1/(\)\{;9rand}$\
Ventero
fonte
Isso não é muito bom, mas provavelmente está OK para esta tarefa. (Ou seja, "parecerá bastante aleatório".) Ainda assim, ao custo de mais dois caracteres, você poderá obter uma mudança muito melhor substituindo 9por 9.?.
Ilmari Karonen
Isso falha nas palavras de uma letra e também não acho que a função deva retornar string, array de strings, string (em oposição a uma única string).
Martin Ender
11

C ++, 79 caracteres ( com verificação de intervalo )

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

C ++, 8165 caracteres ( sem verificação de alcance )

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

O uso de passagem por referência em vez de retornar o resultado reduz outros 10 caracteres de qualquer solução.

Programa completo, lendo uma sequência de palavras e convertendo-as aleatoriamente:

#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: não construa o que já está lá. Ah, e as verificações de transbordamento são para covardes.

Konrad Rudolph
fonte
Legal, std::random_shuffleisso é novo para mim. btw eu acho que você esqueceu #include<string>no seu código completo.
Scott Logan
11
Algo assim é o que eu tinha em mente originalmente. Infelizmente, não existe um interno para embaralhar uma sequência no JS.
Tomalak
Falha em seqüências de caracteres muito curtas.
usuário desconhecido
É verdade, você está perdendo uma verificação de comprimento (eu também fiz). A resposta da BTW @ Arlen também merece uma olhada.
amigos estão
11
@userunknown Isso é o que eu quis dizer com "cheques excedentes são para covardes". Mas para ser justo, o mesmo acontece com quase todas as outras soluções.
Konrad Rudolph
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]

E aqui está um exemplo de como usá-lo:

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

Este é o meu primeiro exercício de golfe com código. Depois de resolver o problema, decidi procurar as respostas e não é surpresa que a minha resposta não seja única. Isso foi divertido: o)

Fiz uma alteração depois de examinar as outras respostas e estava alterando minha declaração de importação para usar um alias. Boa ideia. ; o)

Ashley Grenon
fonte
E, no entanto, sua solução é votada antes da minha! : p
Boothby
Falha em seqüências curtas; minha resposta em python seria de 75 caracteres se falhasse em strings curtas ( 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;}}

Não há nenhuma função de troca ou reprodução aleatória incorporada em C, então eu tive que fazer isso manualmente :(

Programa de exemplo com 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 : corrigido o bug quando s consiste em menos de 3 caracteres (obrigado ao usuário-conhecido por notá-lo!)

Harry K.
fonte
11
Na glibc, existe (houve?) Uma função de biblioteca não-padrão strfry.
Caracol mecânico
experiência engraçada, se eu alimentá-lo comchar s[] = "na"; // not anticipated
usuário desconhecido
@ usuário desconhecido: Acabei de editar o código e corrigi-lo, obrigado por perceber o bug! (Eu só acrescentou> 0 na condição do loop while, "me custando" mais dois, mas necessário, caracteres :))
Harry K.
11
@ Caracol mecânico: Acho que o strfy ainda está na glibc.
Harry K.
7

python, 87 79 75 93 92 caracteres (manipulação de cadeias de comprimento 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]

Edição: Originalmente pensado que era para dividir palavras de seqüência de caracteres (o que fez em 128 caracteres; agora em 87 caracteres requer). Argh, meu mau entendimento de leitura.

EDIT 2: Altere da função def para lambda de def para salvar 6 caracteres. Supondo que a amostra já esteja importada para o espaço para nome ( from random import sample) pode reduzir para ~ 60).

EDIT 3: "len (w [1: -1])" (12 caracteres) a "len (w) -2" (8 caracteres) por sugestão agradável do gnibbler.

EDIT 4: JBernando salvou um caractere (considerou from random import *e viu que era equivalente - não perceber que o espaço import *é desnecessário) .; usuário desconhecido adicionou 19 caracteres w if len(w)<4 elsepara manipular as seqüências de caracteres 0 e 1 corretamente.

EDIÇÃO 5: Salva outro caractere por truque de golfe do código do boothby. if len(w)<4 elsepara if 4>len(w)else.

dr jimbob
fonte
No entanto, a pergunta definiu apenas a entrada como uma palavra, não como uma sequência de palavras. :)
Ben Richards
11
@ sidran32: Obrigado, meu mal. Acabei de perceber (ao reler) e depois vi seu comentário; excluído - editado - e desmarcado.
dr jimbob
Idéia - você pode cortar três caracteres fazendo isso ... def f (w): j = w [1: -1]; return w [0] + ''. join (r.sample (j, len (j))) + w [-1]
arrdem
@rmckenzie: Boa ideia. No entanto, logo antes de ver o seu comentário logo após o aparar na função lambda (economizando 6 caracteres), não posso mais executar seu método de definição de vars intermediários.
precisa saber é o seguinte
3
len(w)-2em vez de len(w[1:-1])?
N
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;}

Aqui está um programa completo para quem deseja testá-lo:

#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

Percebeu que não há necessidade de selecionar aleatoriamente os dois índices de swap, salvou uma variável e mais alguns caracteres.

Scott Logan
fonte
Excelente. A maioria das soluções falha com entradas muito pequenas. O seu não.
usuário desconhecido
6

php (68 caracteres)

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

mais curto (60 caracteres)

$r=preg_replace('/(.)(.+)(.)/e','$1.str_shuffle($2).$3',$w);
tobius
fonte
+1 Muito bom. :) Você pode soltar o trim (), na verdade, e no regex você pode remover as âncoras e usá-las em .vez de \w.
Tomalak
@Tomalak Suggested Tente reescrever esta solução em Perl. Incluindo as sugestões dele, recebi o seguinte: use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join('',shuffle split//,$2).$3;}são 87 caracteres . Sem a linha de uso, são 62 caracteres .
Ben Richards
Você pode fornecer uma demonstração desse trabalho? Porque eu não posso ...
Steve Robbins
6

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

Foi isso que eu criei no Perl. Passamos por algumas maneiras diferentes de fazer isso, mas isso parecia mais curto do que eu posso pensar até agora, com 97 caracteres.

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

No entanto, se você cortar a linha 'use' (que eu acho que é válida, já que outras pessoas excluíram #incluir linhas em seus programas em C), eu posso reduzi-la para 71 caracteres :

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

EDIT Foi sugerido que eu tentasse fazer isso implementando o método @tobius '. Dessa maneira, reduzi para 84 caracteres ou, removendo a linha de uso , 59 caracteres :

use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
Ben Richards
fonte
2
encurtou sua versão para 87: #use List::Util 'shuffle';sub r{($b,@w)=split//,$_[0];$e=pop@w;join'',$b,(shuffle@w),$e}
mbx
11
@ sidran32 Você pode implementar no Perl uma variante da resposta do @tobius , apenas para comparação?
quer
@ Tomlak Claro, eu vou experimentar.
Ben Richards
11
reduziu sua versão do regex em 3 caracteres:use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
mbx
Agradável. Estou muito acostumado a usar uma grande quantidade de parênteses para maior clareza. Mau hábito ao jogar golfe. : 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

Minha solução Scala em uma linguagem um pouco menos detalhada. Eu não sou especialista em Ruby, por isso, provavelmente há espaço para melhorias.

Gareth
fonte
Uau. Funciona com 'I' como sua solução scala.
usuário desconhecido
5

Ruby 1.9, 77 48 46 44 caracteres

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

Disclaimer: Eu ajustei isso com base na resposta mais alta classificada - notei a mesma resposta mais tarde. Você pode verificar a história que eu mantive fiel à minha idéia original, mas mudei de ruby ​​1.8 para ruby ​​1.9 para lambdas curtas e shuffle.

Se palavras vazias forem permitidas, 56 54 caracteres

r=->w{w.empty?||w[h=1..-2]=[*w[h].chars].shuffle*"";w}
Aleksi Yrttiaho
fonte
Ninguém espera o 'eu' espanhol.
usuário desconhecido
Tentativa de lidar com casos com 0 ou 1 letras bem
Aleksi Yrttiaho
5

Python 3, 94 93 91 caracteres

Usando uma técnica diferente. Também pode funcionar em 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

O ... if x[0:-1] else xxse seu comprimento é 1 (caso contrário, seria duplicado). A função funciona assim para cadeias de comprimento 0 e 1.

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

Desde que é uma expressão, podemos usar uma lambda(eliminando return, defe um par de parênteses).

Editar: from random import* para salvar um caractere, após o outro envio do Python.

Caracol mecânico
fonte
Eu sei que estou tão tarde aqui, mas pode x[0:-1]se tornar x[:-1]?
Zachary
4

JavaScript - 118 122 caracteres

JavaScript mais curto - 118 caracteres sem espaço em branco. Usa aproximadamente o mesmo algoritmo que o OP, mas com menos encadeamento. Tentei muita recursão e tentei algumas iterações, mas todas elas tendem a ficar atoladas de uma maneira ou de outra.

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
fonte
Não passa no teste 'eu'.
usuário desconhecido
@ Ryan Usando return z?a+...+z:w;como uma verificação implícita de comprimento estaria em ordem. A suposição silenciosa era de que a função receberia apenas palavras "válidas".
amigos estão
Bom ponto, exceto que w foi modificado, então eu tenho que usar ano elseternário. Editado e até 122 caracteres.
Ryan Kinal
@ Ryan: Eu acredito aque seria errado para a entrada de duas letras. : - \ Droga da próxima vez vou alinhar os requisitos com mais cuidado.
quer
Eu não acho que seria, na verdade. zserá indefinido apenas se a palavra for uma letra (ou menos).
Ryan Kinal
4

D, 62 caracteres

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

ok, eu trapacei com uma matriz de caracteres normal em vez de uma string real (que é um caracter imutável [], portanto, não é necessário arrastar no local)

editar com uma verificação de comprimento, requer mais 14

import std.random;void s(char[] s){if(s.length>1)randomShuffle(s[1..$-1]);}
catraca arrepiante
fonte
E retorna o que para uma entrada como 'I'?
usuário desconhecido
Seria mais justo (= melhor comparável) retornar o resultado.
Konrad Rudolph
@user um erro de intervalo. @ Konrad que exigiria return s;e char [] tipo de retorno mais 11 caracteres
aberração catraca
@ratchet Poderia postar o programa inteiro, por favor? BTW, eu não entendo por que você está contando import std.random;, e não apenas a função.
Arlen
Suponho que você poderia economizar 1 byte, omitindo o espaço char[] s(para torná-lo char[]s), mas eu não uso D há anos.
Tim Čas 12/12/19
4

php 5.3 (60 caracteres)

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

Aprimorado para 56 caracteres e não requer mais a versão 5.3:

$r=substr_replace($w,str_shuffle(substr($w,1,-1)),1,-1);
migimaru
fonte
Uma boa alternativa para a outra resposta PHP. Não é mais curto, mas nenhum regex é uma vantagem.
Tomalak
Atualizado com uma solução mais curta que não requer a versão 5.3
migimaru
A versão antiga não está correta: retorna truepara cadeias curtas.
Titus
3

Perl - 111 caracteres (sem usar nenhuma função da 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
fonte
3

Pitão

São 90 89 112 caracteres de python!

Edit 1: desta vez em função!

(obrigado gnibbler)

Edição 2: agora lida com palavras curtas

(obrigado usuário desconhecido)

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
fonte
ainda menos se você seguir a especificação e escrever uma função :)
gnibbler
ah, pena shuffle não funciona em cordas
gnibbler
11
O módulo aleatório é como eu em uma boate ... nós dois meio que nos misturamos no lugar! :)
Andbdrew
Não funciona para entradas como 'I'; retornar 'II'.
usuário desconhecido
obrigado! que agora lida com palavras curtas, mas é um pouco mais :)
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: removido ': String' (tipo de retorno pode ser inferida)
-7: removido 'retorno' (última expressão é o valor de retorno)
-3: consignado s.size-2fora
-4: toCharArray->toArray

Gareth
fonte
Funciona com 'I' e 'Verwürfel' sem caracteres sofisticados em Python. :) No entanto, minha solução usando 'shuffle' é um pouco menor.
usuário desconhecido
@user unknown Obrigado pelas edições :-)
Gareth
3

Python, 86 caracteres

Slnicig é seguro, portanto, nenhum bnouds ckhnceig é neeacrssy. Wkros em todas as leghtns.

from random import*
def f(x):x=list(x);t=x[1:-1];shuffle(t);x[1:-1]=t;return''.join(x)
boothby
fonte
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
fonte
A codificação embutida na string de entrada é legal?
Thomas Eding
@ trinithis Eu pensei que estávamos preocupados apenas com a função em si. O programa mostra apenas como usar a função. Independentemente disso, a codificação incorreta da entrada não faria diferença nesse caso; basta adicionarstring s; cin >> s;
Arlen
3

Ruby 1.9, 43 caracteres

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

Ainda não funciona para Strings de 1 caractere (duplica esse caractere) e falha para String vazia.

karatedog
fonte
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
fonte
O script de usuário de George coloca isso em 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"

a função abaixo funciona com palavras com comprimento menor que 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
fonte
Parte da tarefa não era mover a primeira e a última letras.
18712 Tomalak
@Tomalak fixed!
Paolo
Funciona com palavras com menos de 3?
precisa
@Tomalak Agora deve ficar tudo bem! Obrigado pelas correções!
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]

Sem importações! Funciona para palavras com 1 caractere e acima. Esta é minha primeira entrada no golfe e fui inspirado pela entrada da BlueEyedBeast no código Shortest para produzir uma saída não determinística para a idéia de usar o id (Object) .


Explicação: Faz uma lista de letras da entrada, excluindo a primeira e a última, e aparece repetidamente nesta lista e anexa a uma nova até ficar vazia. O índice do qual ele aparece é id (7)% len (lista da qual estamos saindo). Como id (7) é o endereço de memória do objeto 7, é essencialmente aleatório. Portanto, agora temos uma lista de letras embaralhadas aleatoriamente no centro da entrada original. Tudo o que fazemos agora é anexar a primeira e a última letra da saída original de acordo e obtemos a saída que queremos: (primeira letra) + (meio embaralhado) + (última letra).

girafa
fonte
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 a avaliação lenta de R para calcular aeb como parâmetros de função, economizando espaço com reutilização posteriormente. Diferentemente de outras respostas R, isso funciona para todas as palavras com> 1 caractere. Exemplo abaixo:

> f("hippopotamus")
hpuoopaitmps

> f("dog")
dog

> f("az")
az

Editar: Substituído unlist()por[[]] Substituído [[1]] por el ()

Andrew Haynes
fonte
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
fonte
Eu acho que a else sparte está faltando?
amigos estão
11
@Tomalak Não, não é, porque não há necessidade disso. Se a string tiver um comprimento igual ou inferior a 2, então a deixamos em paz. Além disso, randomShuffle()está no local.
quer
U, D sendo competitivo. Eu acho que randomShuffle(s[1..$-1])pode ser s[1..$-1].randomShuffleIIRC (a menos que esteja em uma versão D mais velho do que este post)
Zachary
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).

Eu ainda estou aprendendo Erlang, então todas as dicas para torná-lo mais curto são apreciadas.

código completo (módulo string_shuffle):

-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

Retirou a parte aleatória como uma função separada, que não exige mais que o cabeçalho e o final da lista sejam passados.

Editar 2

Reestruturado para remover um dos fpadrões de função, alterou a função aleatória para aceitar apenas dois parâmetros, alterados lists:deletepor --[], trocou uma lists:reversechamada por umlists:last

Scott Logan
fonte