Jak randomizować litery w słowie

55

Według niektórych kontrowersyjnych historii , odrer z wrod deos nie wiele za raednig, tak samo jak frist i lsat lteter macth z oryginalnym wrod.

Więc, dla zabawy, jaka byłaby najkrótsza funkcja do losowego uporządkowania liter w słowie, przy jednoczesnym zachowaniu pierwszej i ostatniej litery?

Oto mój cios w JavaScript. Cała spacja usunięta ma 124 130 znaków.

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

Krótszy JavaScript zawsze mile widziany.


  • Edycja: dodano kontrolę długości. Funkcja nie powinna zawieść w przypadku krótkich słów.
Tomalak
źródło
3
Haskell, 4 znaki: r=id.
Thomas Eding,
2
Tak. Zwraca dokładnie to samo, co dane wejściowe. Z drugiej strony, co robimy z interpunkcją? Czy działamy tylko na słowach składających się wyłącznie z liter?
Thomas Eding,
1
@trinithis nie jest pewien, o czym mówisz, ale idjest funkcją tożsamości. Nadal chciałbym zobaczyć rozwiązanie tego problemu przez Haskell w mniej niż 100 znakach.
Arlen,
3
Czy specyfikacja powinna zostać zaktualizowana, aby wymagać jednolitego podziału wyników? To uniemożliwiłoby 4-znakowe rozwiązanie Haskell. Nie pozwoliłoby to również na przykładowe rozwiązanie JavaScript (tasowanie nie jest jednolite).
Thomas Eding
2
+1 za pierwsze zdanie: w rzeczywistości zajęło mi kilka sekund, aby zdać sobie sprawę z tego, że napisano nieprawidłowo XP
Nate Koppenhaver

Odpowiedzi:

21

Haskell, 4 znaki

Zaproponowana funkcja trinithis faktycznie odpowiada specyfikacji:

s=id

Zwraca ciąg znaków bez zmian, utrzymując w ten sposób pierwszy i ostatni znak na miejscu i dokonując permutacji wszystkich pozostałych znaków.

Jeśli ktoś jest niezadowolony z rozkładu prawdopodobieństwa permutacji, oto rozwiązanie zapewniające lepszy rozkład. Jest to oczywiście o wiele bardziej złożone:

Haskell, 110 120 107 znaków

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

Przykład programu używającego tej funkcji:

main = getLine >>= s >>= putStrLn
Rotsor
źródło
18
„niezadowolony z rozkładu prawdopodobieństwa permutacji” rozśmieszył mnie. :)
Tomalak,
@Rotsor, jak wywołać tę funkcję?
Arlen,
Dodałem przykład do mojego postu.
Rotsor,
fmap((a:t!!i:).tail)
FUZxxl,
3
Pierwsze rozwiązanie należy usunąć, ponieważ nie spełnia kryteriów wyzwania. Opis wyzwania mówi „randomize”. Według meta, random nie zawsze może mieć taki sam wynik .
mbomb007,
19

J, 26 24 23 znaków

r=:{.,({~?~@#)&}.&}:,{:
Eric
źródło
Zgodnie ze wspólnymi zasadami golfa, nie musisz wiązać frazy z nazwą.
FUZxxl,
#?#jest o jeden char krótszy niż?~@#
randomra
15

Ruby, 44 znaki

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

Działa również w przypadku krótkich słów, tzn. Słowa zawierające jeden, dwa lub trzy znaki są zwracane w niezmienionej formie.

Edycja: Użycie pomysłu tablicowego Ventero oszczędza kolejny znak.

Howard
źródło
To właściwie 44 znaki. W końcu znalazłem tę samą odpowiedź, dostrajając własną - teraz po przeczytaniu twojego czuję się jak kopia.
Aleksi Yrttiaho
@ user2316 Oczywiście masz rację. Dziękuję Ci.
Howard
11

Ruby 1.9, 46 znaków

r=->w{w[0]+[*w[1..-2].chars].shuffle*""+w[-1]}
Ventero
źródło
+1 To użycie tablicy-ikon uratowało mi również jeden znak. Świetny pomysł.
Howard
Nie znam ruby ​​- nie działa na moim ruby ​​1.8, więc chyba potrzebuję wersji nigdy? Czy to działa z danymi wejściowymi takimi jak „I”?
użytkownik nieznany
@ użytkownik: Tu jest napis „Ruby 1.9”. ;) - Ventero - Jednym z rozsądnych wymagań, o których zapomniałem wspomnieć, jest to, że nie powinno zawieść dla słów o długości 0 i 1. Przepraszamy.
Tomalak,
11

Golfscript

Jako „funkcja” (o nazwie blok kodu): 20 znaków

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

Podczas działania na najwyższym elemencie stosu: 16 znaków

1/(\)\{;9rand}$\
Ventero
źródło
To nie jest bardzo dobry los, ale prawdopodobnie OK do tego zadania. (Oznacza to, że „będzie wyglądał wystarczająco losowo”.) Mimo to, kosztem dwóch kolejnych znaków, możesz uzyskać znacznie lepszy losowanie, zastępując 9go 9.?.
Ilmari Karonen
To się nie udaje w przypadku słów jednoliterowych, a także nie sądzę, że funkcja powinna mieć możliwość zwracania łańcucha, tablicy ciągów, łańcucha (w przeciwieństwie do pojedynczego łańcucha).
Martin Ender
11

C ++, 79 znaków ( z kontrolą zakresu )

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

C ++, 8165 znaków ( bez sprawdzania zasięgu )

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

Użycie pass by referencji zamiast zwracania wyniku usuwa kolejne 10 znaków z obu rozwiązań.

Pełny program, odczytując ciąg słów i przetasowując je:

#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: nie buduj tego, co już tam jest. Och, a kontrole przelewu dotyczą wusów.

Konrad Rudolph
źródło
Fajnie, std::random_shuffleto dla mnie nowe. btw Myślę, że zapomniałeś #include<string>w swoim pełnym kodzie.
Scott Logan,
1
Coś takiego właśnie miałem na myśli. Niestety w JS nie ma wbudowanego mechanizmu tasowania łańcucha w miejscu.
Tomalak
Nie nadaje się do bardzo krótkich strun.
użytkownik nieznany
To prawda, brakuje Ci kontroli długości (ja też to zrobiłem). Warto również zapoznać się z odpowiedzią BTW @ Arlen .
Tomalak,
1
@userunknown To właśnie miałem na myśli przez „kontrole przepełnienia dotyczą wad”. Ale żeby być uczciwym, to samo zrób prawie wszystkie inne rozwiązania.
Konrad Rudolph
8

Python, 86 znaków

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

A oto przykład użycia:

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

To jest mój pierwszy trening golfowy. Po rozwiązaniu problemu postanowiłem spojrzeć na odpowiedzi i nic dziwnego, że moja odpowiedź nie jest wyjątkowa. To było zabawne: o)

Dokonałem jednej zmiany po spojrzeniu na inne odpowiedzi i zmieniłem moją instrukcję importu na użycie aliasu. Świetny pomysł. ; o)

Ashley Grenon
źródło
A jednak Twoje rozwiązanie jest głosowane przed moim! : p
stoisko
Nie zawodzi na krótkich sznurkach; moja odpowiedź w pythonie wynosiłaby 75 znaków, gdyby zawiodła na krótkich ciągach ( 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 znaków

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

W C nie ma wbudowanej funkcji zamiany ani odtwarzania losowego, więc musiałem to zrobić ręcznie :(

Przykładowy program z 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;
}

EDYCJA : naprawiono błąd, gdy s składa się z mniej niż 3 znaków (dzięki nieznanemu użytkownikowi za zauważenie go!)

Harry K.
źródło
1
W glibc istnieje (była?) Niestandardowa funkcja biblioteki strfry.
Mechaniczny ślimak
zabawne doświadczenie, jeśli go nakarmięchar s[] = "na"; // not anticipated
użytkownik nieznany
@ użytkownik uknown: Właśnie edytowałem kod i naprawiłem go, dziękuję za zauważenie błędu! (Właśnie dodałem> 0 w stanie pętli while, „kosztuje mnie” jeszcze dwa, ale potrzebowałem znaków :))
Harry K.,
1
@Mechanical snail: Myślę, że strfy wciąż jest w Glibc.
Harry K.
7

python, 87 79 75 93 92 znaki (obsługa ciągów o długości 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]

EDYCJA: Początkowo myślał, że powinien dzielić słowa łańcuchowe (co robił przy 128 znakach; teraz przy 87 znakach wymaga). Argh, mój kiepski z czytania ze zrozumieniem.

EDYCJA 2: Zmień z funkcji def na lambda z def, aby zapisać 6 znaków. Zakładając, że próbka jest już zaimportowana do przestrzeni nazw ( from random import sample), może to obniżyć do ~ 60).

EDYCJA 3: „len (w [1: -1])” (12 znaków) do „len (w) -2” (8 znaków) za miłą sugestię gnibblera.

EDYCJA 4: JBernando uratował jeden znak (rozważył from random import *i zobaczył, że jest równoważny - nie uświadomienie sobie, że miejsce import *jest niepotrzebne) .; użytkownik nieznany dodał 19 znaków, w if len(w)<4 elseaby poprawnie obsługiwać ciągi znaków 0 i 1.

EDYCJA 5: Zapisałem kolejny kod na sztuczkę golfową dla boothby'ego. if len(w)<4 elsedo if 4>len(w)else.

dr jimbob
źródło
Jednak pytanie definiowało tylko dane wejściowe jako słowo, a nie ciąg słów. :)
Ben Richards,
1
@ sidran32: Dzięki, mój zły. Właśnie zauważyłem (po ponownym przeczytaniu), a potem zobaczyłem twój komentarz; usunięty - edytowany - i nieskasowany.
dr jimbob
Pomysł - możesz przyciąć 3 znaki, wykonując to .... def f (w): j = w [1: -1]; return w [0] + ''. join (r.sample (j, len (j))) + w [-1]
arrdem
@rmckenzie: Dobry pomysł. Jednak tuż przed tym, jak zobaczyłem twój komentarz, zaraz po tym, jak przyciąłem go do funkcji lambda (oszczędzając 6 znaków), więc nie mogę już wykonać twojej metody definiowania pośrednich zmiennych.
dr jimbob
3
len(w)-2zamiast len(w[1:-1])?
gnibbler
6

C ++, 111 97 znaków

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

Oto pełny program dla tych, którzy chcą go przetestować:

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

Edytować

Uświadomiono sobie, że nie ma potrzeby losowania obu indeksów wymiany, zapisania zmiennej i kilku innych znaków.

Scott Logan
źródło
Doskonały. Większość rozwiązań zawodzi przy bardzo małych wejściach. Nie
użytkownik nieznany
6

php (68 znaków)

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

krótszy (60 znaków)

$r=preg_replace('/(.)(.+)(.)/e','$1.str_shuffle($2).$3',$w);
tobius
źródło
+1 Bardzo miło. :) Właściwie możesz upuścić trim (), aw wyrażeniu regularnym możesz usunąć kotwice i użyć .zamiast \w.
Tomalak,
@Tomalak Sugeruję, aby spróbować przepisać to rozwiązanie w Perlu. Uwzględniając jego sugestie, mam to: use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join('',shuffle split//,$2).$3;}To 87 znaków . Bez wiersza użycia ma 62 znaki .
Ben Richards,
Czy możesz przedstawić wersję demonstracyjną tego działania? Ponieważ nie mogę ...
Steve Robbins,
6

Perl - 96 (lub 71) znaków 84 (lub 59) znaków

To właśnie wymyśliłem w Perlu. Przeszedłem kilka różnych sposobów, aby to zrobić, ale wydawało się to najkrótsze z tego, co do tej pory myślę, przy 97 znakach.

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

Chociaż, jeśli wytniesz linię „use” (co, jak sądzę, jest poprawna, ponieważ inni wykluczyli #include linii w swoich programach C), mogę ją zmniejszyć do 71 znaków :

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

EDYCJA Sugerowano, żebym spróbował wykonać tę metodę implementacji @tobiusa. W ten sposób zredukowałem go do 84 znaków , lub usuwając wiersz użycia , 59 znaków :

use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
Ben Richards
źródło
2
skróciłem twoją wersję do 87:use List::Util 'shuffle';sub r{($b,@w)=split//,$_[0];$e=pop@w;join'',$b,(shuffle@w),$e}
mbx
1
@ sidran32 Czy możesz zaimplementować Perlowi wariant odpowiedzi @tobius , tylko dla porównania?
Tomalak,
@Tomalak Pewnie, wypróbuję to.
Ben Richards,
1
skróciłem twoją wersję wyrażenia regularnego o 3 znaki:use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
mbx
Miły. Jestem zbyt przyzwyczajony do używania stosu nawiasów w celu zachowania przejrzystości. Zły nawyk podczas gry w golfa. : P
Ben Richards,
5

Ruby, 77 75 znaków

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

Moje rozwiązanie Scala w nieco mniej szczegółowym języku. W żadnym wypadku nie jestem ekspertem od Ruby, więc prawdopodobnie jest miejsce na ulepszenia.

Gareth
źródło
Łał. Współpracuje z „I” jako Twoim rozwiązaniem Scala.
użytkownik nieznany
5

Ruby 1.9, 77 48 46 44 znaków

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

Oświadczenie: Dostosowałem to na podstawie odpowiedzi najwyżej ocenionej - później zauważyłem dokładnie taką samą odpowiedź. Możesz sprawdzić historię, którą zachowałem zgodnie z moim oryginalnym pomysłem, ale zmieniłem z ruby ​​1.8 na ruby ​​1.9 w przypadku krótkich lambd i shuffle.

Jeśli dozwolone są puste słowa, to 56 54 znaków

r=->w{w.empty?||w[h=1..-2]=[*w[h].chars].shuffle*"";w}
Aleksi Yrttiaho
źródło
Nikt nie spodziewa się hiszpańskiego „ja”.
użytkownik nieznany
Próbowano również obsługiwać sprawy z 0 lub 1 literami
Aleksi Yrttiaho
5

Python 3, 94 93 91 znaków

Używanie innej techniki. Może także działać w Pythonie 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

... if x[0:-1] else xDaje xjeżeli jego długość wynosi 1 (inaczej byłoby powielany). Funkcja działa w ten sposób dla ciągów o długości 0 i 1.

To sample()pochodzi z https://stackoverflow.com/questions/2668312/shuffle-string-in-python/2668366#2668366 .

Ponieważ jest to jeden wyraz, możemy użyć lambda(eliminuje return, deforaz parę nawiasów).

Edycja: from random import* aby zapisać 1 znak po drugim przesłaniu Pythona.

Ślimak mechaniczny
źródło
Ja wiem, ja tak tak tak późno tutaj, ale może x[0:-1]stać x[:-1]?
Zacharý
4

JavaScript - 118 122 znaków

Krótszy JavaScript - 118 znaków bez spacji. Używa w przybliżeniu tego samego algorytmu co OP, ale z mniejszym łańcuchem. Próbowałem wiele rekurencji i próbowałem wykonać iterację, ale wszystkie one mają tendencję do zapadania się w taki czy inny sposób.

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
źródło
Nie zalicza testu „I”.
użytkownik nieznany
@ Ryan Używanie return z?a+...+z:w;jako domyślnej kontroli długości byłoby w porządku. Ciche założenie było takie, że funkcja otrzyma tylko „poprawne” słowa.
Tomalak,
Dobra uwaga, z wyjątkiem tego, że w zostało zmodyfikowane, więc muszę go użyć aw elsetrójce. Edytowane i do 122 znaków.
Ryan Kinal
@Ryan: Uważam, aże wprowadzanie dwuliterowe byłoby błędne. : - Cholera, następnym razem ostrożniej wyłożę wymagania.
Tomalak,
Właściwie to nie sądzę. zbędzie niezdefiniowany tylko wtedy, gdy słowo ma jedną literę (lub mniej).
Ryan Kinal
4

D, 62 znaki

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

ok, oszukiwałem normalną tablicą znaków zamiast prawdziwego ciągu znaków (który jest niezmiennym char [], więc nie tasuje się w miejscu)

edycja z kontrolą długości wymaga 14 więcej

import std.random;void s(char[] s){if(s.length>1)randomShuffle(s[1..$-1]);}
maniak zapadkowy
źródło
I zwraca co dla danych wejściowych takich jak „ja”?
użytkownik nieznany
Zwrócenie wyniku byłoby sprawiedliwsze (= lepiej porównywalne).
Konrad Rudolph
@ użyj błędu zakresu. @ konrad, który wymagałby return s;i char [] zwrócił typ 11 dodatkowych znaków
maniak ratchet
@ratchet Czy możesz napisać cały program? BTW, nie rozumiem, dlaczego liczysz import std.random;, a nie tylko funkcja.
Arlen,
Zgaduję, że możesz zaoszczędzić 1 bajt, pomijając spację w char[] s(żeby to zrobić char[]s), ale nie używałem D od lat.
Tim Čas
4

php 5.3 (60 znaków)

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

Ulepszony do 56 znaków i nie wymaga już wersji 5.3:

$r=substr_replace($w,str_shuffle(substr($w,1,-1)),1,-1);
migimaru
źródło
+1 fajna alternatywa dla innej odpowiedzi PHP. Nie krótszy, ale brak wyrażenia regularnego to plus.
Tomalak,
Zaktualizowano z krótszym rozwiązaniem, które nie wymaga wersji 5.3
migimaru
Stara wersja jest niepoprawna: zwraca truekrótkie ciągi znaków.
Tytus
3

Perl - 111 znaków (bez użycia funkcji biblioteki)

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}

Zastosowanie :

$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
źródło
3

Pyton

To 90 89 112 znaków python!

Edycja 1: tym razem jako funkcja!

(dzięki gnibbler)

Edycja 2: obsługuje teraz krótkie słowa

(dzięki użytkownik nieznany)

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
źródło
tym mniej, jeśli podążysz za specyfikacją i napiszesz funkcję :)
gnibbler
ach, szkoda
losowa
1
Losowy moduł jest taki jak ja w klubie nocnym ... oboje po prostu tasujemy na miejscu! :)
Andbdrew
Nie działa dla danych wejściowych takich jak „I”; zwraca „II”.
użytkownik nieznany
dzięki! teraz obsługuje krótkie słowa, ale jest nieco dłuższy :)
Andbdrew
3

Scala, 135 139 142 156 znaków

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: usunięto „ciąg” (typ zwrotny można wywnioskować)
-7: usunięte „powrotu” (ostatnie wyrażenie jest wartość powrotna)
-3: uwzględnione s.size-2na
-4: toCharArray->toArray

Gareth
źródło
Współpracuje z „I” i „Verwürfel” bez wymyślnych znaków w języku Python. :) Jednak moje rozwiązanie wykorzystujące „shuffle” jest nieco krótsze.
użytkownik nieznany
@ użytkownik nieznany Dzięki za zmiany :-)
Gareth
3

Python, 86 znaków

Slnicig jest bezpieczny, więc żadne bnouds ckhnceig nie jest neeacrssy. Wkros we wszystkich leghtns.

from random import*
def f(x):x=list(x);t=x[1:-1];shuffle(t);x[1:-1]=t;return''.join(x)
boothby
źródło
3

C ++ 11: - 68 66 znaków

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

pełny 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;
}
Arlen
źródło
Czy kodowanie na stałe w ciągu wejściowym jest legalne?
Thomas Eding,
@trinithis Myślałem, że zajmujemy się tylko samą funkcją. Program pokazuje tylko, jak korzystać z tej funkcji. Niezależnie od tego, nie kodowanie na stałe wejścia nie zrobiłoby różnicy w tym przypadku; po prostu dodajstring s; cin >> s;
Arlen,
3

Ruby 1.9, 43 znaki

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

Nie działa jeszcze dla Ciągów o długości 1 znaku (duplikuje ten znak), a dla pustych Ciągów kończy się niepowodzeniem.

karatedog
źródło
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="")}

Stosowanie:

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"

poniższa funkcja działa ze słowami o długości mniejszej niż 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
źródło
Częścią zadania nie było przesunięcie pierwszej i ostatniej litery.
Tomalak,
@Tomalak naprawione!
Paolo,
Czy to działa ze słowami poniżej 3?
Tomalak,
@Tomalak Teraz powinno być ok! Dzięki za poprawki!
Paolo,
3

Python, 102 znaki

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]

Bez importu! Działa dla słów 1 i wyżej. To jest mój pierwszy wpis w golfa i zainspirował mnie wpis BlueEyedBeast z Shortest code w celu uzyskania niedeterministycznych danych wyjściowych dla pomysłu użycia id (Object) .


Objaśnienie: Tworzy listę liter na podstawie danych wejściowych z wyłączeniem pierwszej i ostatniej i wielokrotnie wyskakuje z tej listy i dołącza się do nowej, aż będzie pusta. Indeks, z którego wyskakuje, to id (7)% len (lista, z której wyskakujemy). Ponieważ id (7) jest adresem pamięci obiektu 7, jest on zasadniczo losowy. Mamy teraz listę losowo zaszyfrowanych liter ze środka oryginalnego tekstu. Wszystko, co teraz robimy, to odpowiednio dołączyć pierwszą i ostatnią literę oryginalnego wyjścia i otrzymaliśmy pożądany wynik: (pierwsza litera) + (zakodowany środek) + (ostatnia litera).

żyrafa
źródło
3

R, 95 92 91 znaków

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

Wykorzystuje leniwą ocenę R do obliczenia a i b jako parametrów funkcji, oszczędzając miejsce z ponownym użyciem później. Również w przeciwieństwie do innych odpowiedzi R działa to dla wszystkich słów o długości> 1 znak. Przykład poniżej:

> f("hippopotamus")
hpuoopaitmps

> f("dog")
dog

> f("az")
az

Edytować: zastąpione unlist()z[[]] Zamieniono [[1]] na el ()

Andrew Haynes
źródło
2

D: 55 znaków

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

pełny 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);
}
Arlen
źródło
Myślę, że tej else sczęści brakuje?
Tomalak,
1
@Tomalak Nie, nie jest, bo nie ma takiej potrzeby. Jeśli łańcuch ma długość 2 lub mniej, to zostawiamy go w spokoju. Również randomShuffle()jest na miejscu.
Arlen
Wow, D jest konkurencyjny. Myślę, że randomShuffle(s[1..$-1])może być s[1..$-1].randomShuffleIIRC (chyba że jest to wersja D starsza niż ten post)
Zacharý
2

Erlang, 188 172 132 znaków

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

Wciąż uczę się Erlanga, więc wszelkie wskazówki dotyczące skrócenia tej wersji są mile widziane.

pełny kod (moduł 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).

Edytować

Wyodrębniono część losową jako osobną funkcję, która nie wymaga już omijania głowy i ogona listy.

Edytuj 2

Zrestrukturyzowano, aby usunąć jeden z fwzorców funkcji, zmieniono funkcję odtwarzania losowego, aby zaakceptować tylko dwa parametry, zmieniono lists:deletena --[], zamieniono lists:reversewywołanie nalists:last

Scott Logan
źródło