Comment randomiser des lettres dans un mot

55

Selon une histoire controversée , le titre de rapporteur dans une lettre ne serait pas très utile au raid, comme le premier et le dernier journaliste avec le mot original.

Donc, pour le plaisir, quelle serait la fonction la plus courte pour randomiser l’ordre des lettres dans un mot tout en maintenant la première et la dernière lettre en place?

Voici mon coup de couteau avec JavaScript. Tous les espaces sont supprimés: 124 130 caractères.

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 plus court toujours la bienvenue.


  • Edit: vérification de la longueur ajoutée. La fonction ne devrait pas échouer pour les mots courts.
Tomalak
la source
3
Haskell, 4 caractères: r=id.
Thomas Eding
2
Oui. Il retourne exactement la même chose que l'entrée. Sur une autre note, que faisons-nous de la ponctuation? Est-ce que nous n'opérons que des mots composés uniquement de lettres?
Thomas Eding
1
@trinithis ne sait pas de quoi vous parlez, mais idc'est la fonction identité. J'aimerais toujours voir la solution Haskell à ce problème en moins de 100 caractères.
Arlen
3
La spécification devrait-elle être mise à jour pour exiger une distribution uniforme des résultats? Cela interdirait la solution Haskell à 4 caractères. Cela exclurait également votre exemple de solution Javascript (mélanger en faisant une sorte comme si ce n’était pas uniforme).
Thomas Eding
2
+1 pour la première phrase: il m'a fallu quelques secondes pour me rendre compte qu'il était mal orthographié XP
Nate Koppenhaver

Réponses:

21

Haskell, 4 personnages

La fonction trinithis proposée correspond effectivement à la spécification:

s=id

Il retourne la chaîne inchangée, gardant ainsi les premier et dernier caractères en place et permettant une permutation de tous les autres caractères.

Si quelqu'un n'est pas satisfait de la distribution de probabilité des permutations, voici une solution permettant d'obtenir une meilleure distribution. C'est évidemment beaucoup plus complexe:

Haskell, 110 120 107 caractères

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 exemple de programme utilisant cette fonction:

main = getLine >>= s >>= putStrLn
Rotsor
la source
18
"insatisfait de la distribution de probabilité des permutations" m'a fait rire. :)
Tomalak
@Rotsor comment appelez-vous cette fonction?
Arlen
J'ai ajouté un exemple à mon message.
Rotsor
fmap((a:t!!i:).tail)
FUZxxl
3
La première solution doit être supprimée car elle ne correspond pas au critère de challenge. La description du défi dit "randomize". Selon la méta, random ne peut pas toujours avoir le même résultat .
mbomb007
19

J, 26 24 23 caractères

r=:{.,({~?~@#)&}.&}:,{:
Eric
la source
Selon les règles de golf courantes, il n'est pas nécessaire de lier la phrase à un nom.
FUZxxl
#?#est un caractère plus court que?~@#
randomra
15

Ruby, 44 personnages

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

Fonctionne également pour les mots courts, c’est-à-dire que les mots contenant un, deux ou trois caractères sont renvoyés sans modification.

Edit: Utiliser l’idée de array-splat de Ventero enregistre un autre caractère.

Howard
la source
C'est en fait 44 caractères. J'ai finalement trouvé exactement la même réponse en ajustant la mienne - maintenant, je me sens comme un imitateur après avoir lu le vôtre.
Aleksi Yrttiaho
@ user2316 Bien sûr, vous avez raison. Je vous remercie.
Howard
11

Ruby 1.9, 46 caractères

r=->w{w[0]+[*w[1..-2].chars].shuffle*""+w[-1]}
Ventero
la source
+1 Cette utilisation de array-splat m'a sauvé aussi un caractère. Bonne idée.
Howard
Je ne connais pas ruby ​​- il échoue sur mon ruby1.8, alors je suppose que j'ai besoin d'une version Never? Est-ce que cela fonctionne avec une entrée comme "I"?
utilisateur inconnu
@user: Il est écrit "Ruby 1.9". ;) - Ventero - L’une des exigences sensibles que j’ai oublié de mentionner est qu’il ne devrait pas échouer pour les longueurs de mot 0 et 1. Désolé.
Tomalak
11

Golfscript

En tant que "fonction" (nommé codeblock): 20 caractères

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

En opérant sur le premier élément de la pile: 16 caractères

1/(\)\{;9rand}$\
Ventero
la source
Ce n'est pas un très bon shuffle, mais probablement OK pour cette tâche. (C'est, ça va « l' air assez aléatoire ».) Pourtant, au prix de deux caractères, vous pourriez obtenir un bien meilleur en remplaçant Shuffle 9avec 9.?.
Ilmari Karonen
Cela échoue pour les mots d'une seule lettre, et je ne pense pas non plus que la fonction devrait être autorisée à renvoyer une chaîne, un tableau de chaînes, une chaîne (par opposition à une chaîne unique).
Martin Ender
11

C ++, 79 caractères ( avec contrôle de plage )

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

C ++, 8165 caractères ( sans vérification de la plage )

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

Utiliser passe par référence au lieu de renvoyer le résultat supprime 10 autres caractères de l'une ou l'autre solution.

Programme complet, lisant une chaîne de mots et les mélangeant en les convertissant:

#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: ne construisez pas ce qui existe déjà. Oh, et les contrôles de débordement sont pour des wusses.

Konrad Rudolph
la source
Nice, std::random_shufflec'est un nouveau pour moi. BTW je pense que vous avez oublié #include<string>dans votre code complet.
Scott Logan
1
Quelque chose comme ça est ce que j'avais à l'esprit à l'origine. Malheureusement, il n’existe pas de fonction intégrée permettant de mélanger une chaîne sur place dans JS.
Tomalak
Échec pour les très courtes chaînes.
utilisateur inconnu
C'est vrai, vous manquez un chèque de longueur (moi aussi). La réponse de BTW @ Arlen vaut également le détour.
Tomalak
1
@userunknown C'est ce que je voulais dire par «les contrôles de débordement sont pour les virus». Mais pour être juste, il en va de même pour presque toutes les autres solutions.
Konrad Rudolph
8

Python, 86 caractères

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

Et voici un exemple d'utilisation:

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

Ceci est mon premier exercice de golf de code. Après avoir résolu le problème, j'ai décidé d'examiner les réponses et il n'est pas surprenant que ma réponse ne soit pas unique. C'était amusant cependant: o)

J'ai fait un changement après avoir examiné les autres réponses et cela modifiait mon instruction d'importation pour utiliser un alias. Bonne idée. ; o)

Ashley Grenon
la source
Et pourtant, votre solution est votée avant la mienne! : p
stand by le
Échec sur les cordes courtes; ma réponse en python serait de 75 caractères si elle échouait avec des chaînes courtes ( 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 caractères

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

Il n'y a pas de fonction swap ou shuffle intégrée en C, je devais donc le faire manuellement :(

Exemple de programme avec 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 : correction du bug quand s est composé de moins de 3 caractères (merci à l'utilisateur de l'avoir remarqué!)

Harry K.
la source
1
Dans la glibc, il existe (existait?) Une fonction de bibliothèque non standard strfry.
Escargot mécanique
expérience amusante, si je le nourris avecchar s[] = "na"; // not anticipated
utilisateur inconnu
@ utilisateur inconnu: Je viens de modifier le code et de le corriger, merci d'avoir remarqué le bogue! (Je viens d'ajouter> 0 dans l'état de la boucle while, "me coûtant" deux de plus, mais nécessaire, les caractères :))
Harry K.
1
@ Escargot mécanique: Je pense que strfy est toujours dans la glibc.
Harry K.
7

python, 87 79 75 93 92 caractères (manipulation de chaînes de longueur 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]

EDIT: À l’origine, on pensait qu’il était supposé diviser les mots de chaîne (ce qui était le cas pour 128 caractères; maintenant, l’exigence de 87 caractères). Argh, ma mauvaise compréhension en lecture.

EDIT 2: Change de def en fonction lambda de def pour sauvegarder 6 caractères. En supposant qu'un échantillon est déjà importé dans l'espace de noms ( from random import sample), cela pourrait ramener le nombre à ~ 60).

EDIT 3: "len (w [1: -1])" (12 caractères) à "len (w) -2" (8 caractères) par suggestion agréable du gnibbler.

EDIT 4: JBernando a sauvegardé un caractère (il avait considéré from random import *et vu que c’était équivalent - ne pas se rendre compte que la place en import *était inutile) .; utilisateur inconnu a ajouté 19 caractères w if len(w)<4 elsepour gérer correctement les chaînes de caractères 0 et 1.

EDIT 5: enregistré un autre personnage par tour de golf code astuce. if len(w)<4 elseà if 4>len(w)else.

dr jimbob
la source
Cependant, la question définissait uniquement l'entrée en tant que mot, pas une chaîne de mots. :)
Ben Richards
1
@ sidran32: Merci, mon mauvais. Je venais de remarquer (en relisant) et puis vu votre commentaire; supprimé - édité - et non supprimé.
dr jimbob
Idée - vous pouvez supprimer 3 caractères en procédant de la sorte .... def f (w): j = w [1: -1]; return w [0] + ''. join (r.sample (j, len (j))) + w [-1]
arrdem
@ rmckenzie: bonne idée. Cependant, juste avant d'avoir vu votre commentaire juste après l'avoir ajusté à la fonction lambda (enregistrement de 6 caractères), je ne peux plus utiliser votre méthode de définition des vars intermédiaires.
dr jimbob
3
len(w)-2au lieu de len(w[1:-1])?
Gnibbler
6

C ++, 111 97 caractères

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

Voici un programme complet pour ceux qui souhaitent le tester:

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

Modifier

Réalisé, il n’est pas nécessaire d’aléatoire des deux index de swap, d’une variable enregistrée et de quelques caractères supplémentaires.

Scott Logan
la source
Excellent. La plupart des solutions échouent avec une très petite entrée. À toi pas.
utilisateur inconnu
6

php (68 caractères)

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

plus court (60 caractères)

$r=preg_replace('/(.)(.+)(.)/e','$1.str_shuffle($2).$3',$w);
tobius
la source
+1 très bien. :) Vous pouvez laisser tomber le trim (), en fait, et dans la regex, vous pouvez enlever les ancres et utiliser à la .place de \w.
Tomalak
@Tomalak a suggéré d'essayer de réécrire cette solution en Perl. Y compris ses suggestions, je suis arrivé ceci: use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join('',shuffle split//,$2).$3;}Voilà 87 caractères . Sans la ligne d'utilisation, c'est 62 caractères .
Ben Richards
Pouvez-vous fournir une démonstration de ce travail? Parce que je ne peux pas ...
Steve Robbins Le
6

Perl - 96 (ou 71 caractères) 84 (ou 59 caractères)

C’est ce que j’ai trouvé en Perl. Je suis passé par différentes manières de le faire, mais cela semblait le plus court de ce que je peux penser à ce jour, à 97 personnages.

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

Cependant, si vous supprimez la ligne 'use' (ce qui, je suppose, est valide, car d'autres personnes ont exclu les lignes #include dans leurs programmes C), je peux la réduire davantage à 71 caractères :

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

EDIT Il a été suggéré que j'essaie de faire ceci en implémentant la méthode de @tobius. De cette façon, je l'ai réduit à 84 caractères , ou en supprimant la ligne d' utilisation , 59 caractères :

use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
Ben Richards
la source
2
réduit votre version à 87:use List::Util 'shuffle';sub r{($b,@w)=split//,$_[0];$e=pop@w;join'',$b,(shuffle@w),$e}
mbx
1
@ sidran32 Pouvez-vous implémenter Perl une variante de la réponse de @tobius , juste pour comparer?
Tomalak
@Tomalak Bien sûr, je vais l'essayer.
Ben Richards
1
raccourci votre version regex de 3 caractères:use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
mbx
Agréable. Je suis trop habitué à utiliser beaucoup de parenthèses pour plus de clarté. Mauvaise habitude au golf. : P
Ben Richards
5

Ruby, 77 75 caractères

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

Ma solution Scala dans une langue légèrement moins commentée. Je ne suis absolument pas un expert de Ruby, alors il y a probablement place à amélioration.

Gareth
la source
Sensationnel. Fonctionne avec «je» comme solution de scala.
utilisateur inconnu
5

Ruby 1.9, 77 48 46 44 caractères

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

Avertissement: J'ai réglé ceci en fonction de la réponse la mieux classée - j'ai remarqué la même réponse plus tard. Vous pouvez vérifier l’historique que j’ai gardé fidèle à mon idée d’origine, mais qui est passé de ruby ​​1.8 à ruby ​​1.9 pour les lambdas courts et shuffle.

Si les mots vides sont autorisés, alors 56 54 caractères

r=->w{w.empty?||w[h=1..-2]=[*w[h].chars].shuffle*"";w}
Aleksi Yrttiaho
la source
Personne n'attend le 'je' espagnol.
utilisateur inconnu
A tenté de traiter les cas avec 0 ou 1 lettres aussi
Aleksi Yrttiaho
5

Python 3, 94 93 91 caractères

Utiliser une technique différente. Peut aussi fonctionner 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

Le ... if x[0:-1] else xdonne xsi sa longueur est 1 (sinon, il serait dupliqué). La fonction fonctionne donc pour les chaînes de longueur 0 et 1.

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

Comme il est une expression, on peut utiliser un lambda(éliminant return, defet une paire de parenthèses).

Éditer: from random import* pour sauvegarder un caractère après l'autre soumission Python.

Escargot mécanique
la source
Je sais que je suis si tard, mais que je peux x[0:-1]devenir x[:-1]?
Zacharý
4

JavaScript - 118 122 caractères

JavaScript plus court - 118 caractères sans espace. Utilise approximativement le même algorithme que l'OP, mais avec moins de chaînage. J'ai essayé beaucoup de récursion, et j'ai essayé quelques itérations, mais ils ont tous tendance à s'enliser d'une manière ou d'une autre.

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
la source
Ne réussit pas le 'I'-test.
utilisateur inconnu
@Ryan return z?a+...+z:w;Une vérification de longueur implicite serait utile. L'hypothèse silencieuse était que la fonction ne recevrait que des mots "valides".
Tomalak
Bon point, sauf que w a été modifié, je dois donc l'utiliser adans elsele ternaire. Édité et jusqu'à 122 caractères.
Ryan Kinal
@Ryan: Je pense que ce aserait faux pour une saisie de deux lettres. : - \ Zut la prochaine fois que je vais préciser les exigences.
Tomalak
Je ne pense pas que ce serait le cas. zne sera indéfini que si le mot est une lettre (ou moins).
Ryan Kinal
4

D, 62 caractères

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

d'accord j'ai triché avec un tableau de caractères normal au lieu d'une chaîne réelle (qui est un caractère immuable [], donc pas de brassage sur place)

éditer avec une vérification de longueur, il en faut 14 de plus

import std.random;void s(char[] s){if(s.length>1)randomShuffle(s[1..$-1]);}
monstre à cliquet
la source
Et ça retourne quoi pour une entrée comme 'je'?
utilisateur inconnu
Il serait plus juste (= mieux comparable) de renvoyer le résultat.
Konrad Rudolph
@user une erreur de plage. @ Konrad qui aurait besoin return s;et char [] renvoyer le type 11 plus de caractères
freak freak
@ratchet Pourriez-vous publier le programme complet, s'il vous plaît? BTW, je ne comprends pas pourquoi vous comptez import std.random;, et pas seulement la fonction.
Arlen
J'imagine que vous pourriez économiser 1 octet en omettant l'espace char[] s(pour le faire char[]s), mais je n'ai pas utilisé D depuis des années.
Tim Čas
4

php 5.3 (60 caractères)

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

Amélioré à 56 caractères et ne nécessite plus la version 5.3:

$r=substr_replace($w,str_shuffle(substr($w,1,-1)),1,-1);
migimaru
la source
+1 bonne alternative à l'autre réponse PHP. Pas plus court, mais pas de regex est un plus.
Tomalak
Mise à jour avec une solution plus courte ne nécessitant pas la version 5.3
migimaru
L'ancienne version n'est pas correcte: retourne truepour les chaînes courtes.
Titus
3

Perl - 111 caractères (sans utiliser aucune fonction de bibliothèque)

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}

Utilisation :

$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
la source
3

Python

C'est 90 89 112 caractères de python!

Edit 1: comme une fonction cette fois!

(merci gnibbler)

Edit 2: gère maintenant les mots courts

(merci utilisateur inconnu)

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
la source
encore moins si vous suivez les spécifications et écrivez une fonction :)
gnibbler
ah, pitié shuffle ne fonctionne pas sur les chaînes
gnibbler
1
Le module aléatoire est comme moi dans une boîte de nuit ... on mélange tous les deux à la place! :)
Andbdrew
Ne fonctionne pas pour une entrée comme "je"; retourne 'II'.
utilisateur inconnu
Merci! il gère maintenant les mots courts, mais est un peu plus long :)
Andbdrew
3

Scala, 135 139 142 156 caractères

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: enlevé ': String' (le type de retour peut être inféré)
-7: enlevé 'retour' (la dernière expression est la valeur de retour)
-3: factored s.size-2out
-4: toCharArray->toArray

Gareth
la source
Fonctionne avec 'I' et 'Verwürfel' sans caractères Python sophistiqués. :) Cependant, ma solution utilisant 'shuffle' est un peu plus courte.
utilisateur inconnu
@user unknown Merci pour les modifications :-)
Gareth
3

Python, 86 caractères

Slnicig est sûr, donc pas de problème, ckhnceig n’est nécessaire. Wkros à tous points de vue.

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

C ++ 11: - 68 66 caractères

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

programme complet:

#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
la source
Le codage en dur dans la chaîne d'entrée est-il légal?
Thomas Eding
@trinithis Je pensais que nous ne nous intéressions qu'à la fonction elle-même. Le programme montre seulement comment utiliser la fonction. Quoi qu’il en soit, le fait de ne pas coder en dur l’entrée ne ferait aucune différence dans ce cas; il suffit d'ajouterstring s; cin >> s;
Arlen
3

Ruby 1.9, 43 caractères

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

Ne fonctionne pas encore pour les chaînes de 1 caractère (duplique ce caractère) et échoue pour les chaînes vides.

karatedog
la source
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="")}

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"

la fonction ci-dessous fonctionne avec des mots de longueur inférieure à 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
la source
Une partie de la tâche consistait à ne pas déplacer les première et dernière lettres.
Tomalak
@Tomalak réparé!
Paolo
Est-ce que ça marche avec des mots de moins de 3?
Tomalak
@Tomalak Maintenant ça devrait aller! Merci pour les corrections!
Paolo
3

Python, 102 caractères

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]

Aucune importation! Fonctionne pour les mots 1 caractère et plus. C’est ma première participation au golf et j’ai été inspiré par l’entrée de Blueesty Code dans Shortest pour produire une sortie non déterministe sur l’idée d’utiliser id (Object) .


Explanation: Il crée une liste de lettres à partir de l'entrée, en excluant les première et dernière, puis disparaît de manière répétée dans cette liste et en ajoute une nouvelle jusqu'à ce qu'elle soit vide. L'index dont il provient est id (7)% len (la liste d'où nous venons). Puisque id (7) est l'adresse mémoire de l'objet 7, il est essentiellement aléatoire. Nous avons maintenant une liste de lettres brouillées de manière aléatoire à partir du centre de l’entrée initiale. Tout ce que nous faisons maintenant est d’ajouter les première et dernière lettres de la sortie originale en conséquence et nous obtenons la sortie souhaitée: (première lettre) + (brouillé au milieu) + (dernière lettre).

girafe
la source
3

R, 95 92 91 caractères

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

Utilise l’évaluation paresseuse de R pour calculer a et b en tant que paramètres de fonction, économisant ainsi de la place lors de la réutilisation ultérieure. De plus, contrairement aux autres réponses R, cela fonctionne pour tous les mots> 1 caractère. Exemple ci-dessous:

> f("hippopotamus")
hpuoopaitmps

> f("dog")
dog

> f("az")
az

Modifier: Remplacé unlist()par[[]] Remplacé [[1]] par el ()

Andrew Haynes
la source
2

D: 55 caractères

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

programme complet:

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
la source
Je pense que la else spartie est manquante?
Tomalak
1
@Tomalak Non, ce n'est pas le cas, car il n'est pas nécessaire. Si la chaîne a une longueur inférieure ou égale à 2, nous la laissons seule. En outre, randomShuffle()est en place.
Arlen
Wow, D être compétitif. Je pense que randomShuffle(s[1..$-1])peut être s[1..$-1].randomShuffleIIRC (à moins que ce soit dans une version D plus ancienne que ce post)
Zacharý
2

Erlang, 188 172 132 caractères

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

J'apprends toujours Erlang, donc tous les conseils pour raccourcir cette étape sont appréciés.

code complet (module 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).

Modifier

La partie aléatoire a été retirée en tant que fonction distincte qui n'exige plus que la tête et la queue de la liste soient diffusées.

Modifier 2

Restructuré pour supprimer l'un des fmodèles de fonction, modification de la fonction de lecture aléatoire afin qu'elle n'accepte que deux paramètres, modification lists:deletede --[], échange d'un lists:reverseappel contre unlists:last

Scott Logan
la source