Как рандомизировать буквы в слове

55

Согласно некоторой противоречивой истории , запах слов в мире не так уж и велик для Рэднига, так же, как и у первого, и другого, с оригинальным языком.

Итак, для интереса, что было бы самой короткой функцией для рандомизации буквенного порядка в слове при сохранении первой и последней буквы на месте?

Вот мой удар с помощью JavaScript. Все пробелы удалены - это 124 130 символов.

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 всегда приветствуется.


  • Изменить: добавлена ​​проверка длины. Функция не должна выходить из строя для коротких слов.
Томалак
источник
3
Haskell, 4 -х символов: r=id.
Томас Эдинг
2
Да. Он возвращает то же самое, что и входные данные. С другой стороны, что мы делаем с пунктуацией? Разве мы оперируем только словами, состоящими только из букв?
Томас Эдинг
1
@trinithis не уверен, о чем ты говоришь, но idэто функция идентичности. Я все еще хотел бы, чтобы Haskell решил эту проблему менее чем за 100 символов.
Арлен
3
Должна ли спецификация быть обновлена, чтобы требовать равномерного распределения результатов? Это запретило бы 4-х символьное решение на Haskell. Это также запретило бы ваше примерное решение Javascript (перетасовывание, выполняя подобную сортировку, не является равномерной).
Томас Эдинг
2
+1 за первое предложение: мне потребовалось несколько секунд, чтобы понять, что это было написано неправильно XP
Нейт Коппенхавер

Ответы:

21

Хаскель, 4 персонажа

Предложенная функция trinithis фактически соответствует спецификации:

s=id

Он возвращает строку без изменений, сохраняя, таким образом, первый и последний символы и делая перестановку всех остальных символов.

Если кто-то недоволен распределением вероятностей перестановок, вот решение, дающее лучшее распределение. Это, очевидно, намного сложнее:

Haskell, 110 120 107 символов

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

Пример программы, использующей эту функцию:

main = getLine >>= s >>= putStrLn
Rotsor
источник
18
«Недовольный распределением вероятностей перестановок» заставил меня смеяться. :)
Томалак
@ Rotsor как ты называешь эту функцию?
Арлен
Я добавил пример в свой пост.
Ротсор
fmap((a:t!!i:).tail)
FUZxxl
3
Первое решение должно быть удалено, так как оно не соответствует критериям задачи. Описание вызова говорит «рандомизировать». Согласно мета, случайный не всегда может иметь одинаковый результат .
mbomb007
19

J, 26 24 23 символа

r=:{.,({~?~@#)&}.&}:,{:
Эрик
источник
Согласно общепринятым правилам игры в гольф, вам не нужно связывать фразу с именем.
FUZxxl
#?#на один символ короче?~@#
randomra
15

Рубин, 44 символа

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

Работает также для коротких слов, т.е. слова с одним, двумя или тремя символами возвращаются без изменений.

Изменить: Использование идеи массива-сплат Ventero сохраняет еще один символ.

Говард
источник
Это на самом деле 44 символа. В конце концов я пришел к тому же самому ответу путем точной настройки своего собственного - теперь я чувствую себя подражателем после прочтения вашего.
Алекси Ирттиахо
@ user2316 Конечно, ты прав. Спасибо.
Говард
11

Ruby 1.9, 46 символов

r=->w{w[0]+[*w[1..-2].chars].shuffle*""+w[-1]}
Ventero
источник
+1 Это использование массива-сплата спасло меня и один символ. Отличная идея.
Говард
Я не знаю ruby ​​- он терпит неудачу на моем ruby1.8, так что я думаю, что мне нужна никогда не версия? Это работает с вводом как «я»?
пользователь неизвестен
@user: Там написано "Ruby 1.9". ;) - Ventero - Одно из разумных требований, о которых я забыл упомянуть, заключается в том, что оно не должно нарушаться при длинах слов 0 и 1. Извините.
Томалак
11

Golfscript

В качестве «функции» (названной кодовым блоком): 20 символов

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

При работе с самым верхним элементом в стеке: 16 символов

1/(\)\{;9rand}$\
Ventero
источник
Это не очень хорошая случайность, но, вероятно, хорошо для этой задачи. (То есть, он будет «выглядеть достаточно случайным».) Тем не менее, за счет еще двух символов, вы могли бы получить намного лучшую случайность, заменив 9на 9.?.
Ильмари Каронен
Это не подходит для однобуквенных слов, и я также не думаю, что функция должна позволять возвращать строку, массив строк, строку (в отличие от одной строки).
Мартин Эндер
11

C ++, 79 символов ( с проверкой диапазона )

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

C ++, 8165 символов ( без проверки диапазона )

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

Использование передачи по ссылке вместо возврата результата сбрасывает еще 10 символов из любого решения.

Полная программа, читающая цепочку слов и перетасовывающая их

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

Мораль: не строить то, что уже есть. Да, и проверки переполнения для wusses.

Конрад Рудольф
источник
Хорошо std::random_shuffle, это новый для меня. Кстати, я думаю, что вы забыли #include<string>в своем полном коде.
Скотт Логан
1
Нечто подобное я и имел в виду изначально. К сожалению, в JS нет встроенной функции для перестановки строк.
Томалак
Не подходит для очень коротких строк.
пользователь неизвестен
Это правда, вы пропустили проверку длины (я тоже сделал). Кстати , ответ Арлена тоже стоит посмотреть.
Томалак
1
@userunknown Вот что я имел в виду под «проверками переполнения для целей». Но, если быть честным, то же самое можно сказать и о других решениях.
Конрад Рудольф
8

Python, 86 символов

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

И вот пример использования этого:

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

Это мой первый опыт игры в гольф. После решения проблемы я решил посмотреть на ответы, и неудивительно, что мой ответ не уникален. Это было весело, хотя: о)

Я сделал одно изменение после просмотра других ответов, и это изменило мою инструкцию импорта, чтобы использовать псевдоним. Отличная идея. ; О)

Эшли Гренон
источник
И все же, ваше решение проголосовало впереди моего! : p
boothby
Терпит неудачу на коротких последовательностях; мой Python ответ будет 75 символов, если он не удастся на короткие строки ( from random import*\nf=lambda w:w[0]+''.join(sample(w[1:-1]),len(w)-2)+w[-1]).
р джимбоб
7

C (K & R) - 88 86 87 символов

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

В C нет встроенной функции swap или shuffle, поэтому мне пришлось делать это вручную :(

Пример программы с 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;
}

РЕДАКТИРОВАТЬ : исправлена ​​ошибка, когда s состоит из менее чем 3 символов (спасибо, пользователь-неизвестно, что заметил это!)

Гарри К.
источник
1
В glibc есть (была?) Нестандартная библиотечная функция strfry.
Механическая улитка
забавный опыт, если я буду его кормитьchar s[] = "na"; // not anticipated
пользователь неизвестен
@ user uknown: я только что отредактировал код и исправил его, спасибо за замечание ошибки! (Я просто добавил> 0 в состоянии цикла while, «стоило мне» еще двух, но необходимых символов :))
Harry K.
1
@ Механическая улитка: я думаю, что strfy все еще в glibc.
Гарри К.
7

python, 87 79 75 93 92 символа (обработка строк длиной 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]

РЕДАКТИРОВАТЬ: Первоначально думал, что он должен был разделить строковые слова (что он сделал в 128 символов; теперь в 87 символов делает требование). Ох, мой плохой в понимании чтения.

РЕДАКТИРОВАТЬ 2: изменить с def на лямбда-функцию с def, чтобы сохранить 6 символов. Если предположить, что sample уже импортирован в пространство имен ( from random import sample), это может привести к снижению до ~ 60).

РЕДАКТИРОВАТЬ 3: от «len (w [1: -1])» (12 символов) до «len (w) -2» (8 символов) в соответствии с хорошим предложением гнибблера.

РЕДАКТИРОВАТЬ 4: JBernando сохранил один символ (считал from random import *и видел, что это было эквивалентно - не понимая пространство в import *ненужном) .; неизвестный пользователь добавил 19 символов w if len(w)<4 elseдля правильной обработки строк 0 и 1.

РЕДАКТИРОВАТЬ 5: Сохранено еще один символ в коде игры в гольф Бобби. if len(w)<4 elseк if 4>len(w)else.

доктор джимбоб
источник
Тем не менее, вопрос определял вход только как слово, а не как цепочку слов. :)
Бен Ричардс
1
@ sidran32: Спасибо, мой плохой. Я только что заметил (после перечитывания), а затем увидел ваш комментарий; удалено - отредактировано - и восстановлено.
р джимбоб
Идея - вы можете обрезать 3 символа, выполнив это .... def f (w): j = w [1: -1]; return w [0] + ''. join (r.sample (j, len (j))) + w [-1]
arrdem
@rmckenzie: Хорошая идея. Однако, прямо перед тем, как я увидел ваш комментарий сразу после того, как я обрезал его до лямбда-функции (сохраняя 6 символов), поэтому я больше не могу использовать ваш метод определения промежуточных переменных.
р джимбоб
3
len(w)-2вместо len(w[1:-1])?
gnibbler
6

C ++, 111 97 символов

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

Вот полная программа для тех, кто хочет ее протестировать:

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

редактировать

Понял, что нет необходимости случайным образом менять индексы подкачки, сохранить переменную и еще несколько символов.

Скотт Логан
источник
Отлично. Большинство решений терпят неудачу при очень маленьком входе. Твой нет.
пользователь неизвестен
6

php (68 символов)

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

короче (60 символов)

$r=preg_replace('/(.)(.+)(.)/e','$1.str_shuffle($2).$3',$w);
tobius
источник
+1 Очень мило. :) Вы можете отказаться от trim (), а в регулярном выражении вы можете удалить якоря и использовать .вместо \w.
Томалак
@Tomalak Предложено Я пытаюсь переписать это решение на Perl. Включая его предложения, я получил это: use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join('',shuffle split//,$2).$3;}это 87 символов . Без использования строки, это 62 символа .
Бен Ричардс
Можете ли вы предоставить демо этой работы? Потому что я не могу ...
Стив Роббинс
6

Perl - 96 (или 71) символов 84 (или 59) символов

Это то, что я придумал в Perl. Прошло несколько разных способов сделать это, но это казалось самым коротким из того, что я могу себе представить, до 97 символов.

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

Хотя, если вы вырежете строку «use» (которую я считаю верной, поскольку другие исключают строки #include в своих программах на C), я могу сократить ее до 71 символа :

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

РЕДАКТИРОВАТЬ Было предложено, чтобы я попытался сделать это, реализуя метод @tobius '. Таким образом, я получил его до 84 символов или, удалив строку использования , 59 символов :

use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
Бен Ричардс
источник
2
сократил вашу версию до 87:use List::Util 'shuffle';sub r{($b,@w)=split//,$_[0];$e=pop@w;join'',$b,(shuffle@w),$e}
mbx
1
@ sidran32 Можете ли вы реализовать Perl вариант ответа @tobius , просто для сравнения?
Томалак
@ Томалак Конечно, я попробую.
Бен Ричардс
1
сократил вашу версию регулярного выражения на 3 символа:use List::Util 'shuffle';sub r{$_[0]=~m/(.)(.+)(.)/;$1.join'',shuffle split//,$2.$3}
mbx
Приятно. Я слишком привык использовать кучу помощи скобок для ясности. Плохая привычка при игре в гольф. : P
Бен Ричардс
5

Рубин, 77 75 знаков

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

Мое решение Scala на чуть менее многословном языке. Я ни в коем случае не эксперт по Ruby, так что, вероятно, есть возможности для улучшения.

Gareth
источник
Ух ты. Работает с «Я», как ваше решение для Scala.
пользователь неизвестен
5

Ruby 1,9, 77 48 46 44 символов

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

Отказ от ответственности: я настроил это на основе ответа с наивысшим рейтингом - позже заметил тот же самый ответ. Вы можете проверить историю, в которой я придерживался своей первоначальной идеи, но изменил с ruby ​​1.8 на ruby ​​1.9 для коротких лямбд и shuffle.

Если пустые слова разрешены, тогда 56 54 символов

r=->w{w.empty?||w[h=1..-2]=[*w[h].chars].shuffle*"";w}
Алекси Ирттиахо
источник
Никто не ожидает испанского «я».
пользователь неизвестен
Попытка обработать дела также с 0 или 1
буквой
5

Python 3, 94 93 91 символов

Используя другую технику. Может также работать в 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

... if x[0:-1] else xДает , xесли его длина равна 1 ( в противном случае он будет дублироваться). Таким образом, функция работает для строк длиной 0 и 1.

Это sample()с https://stackoverflow.com/questions/2668312/shuffle-string-in-python/2668366#2668366 .

Так как это одно выражение, мы можем использовать lambda(исключая return, defи пару скобок).

Редактировать: from random import* чтобы сохранить 1 символ, после другой подачи Python.

Механическая улитка
источник
Я знаю, что я так опоздал, но может x[0:-1]стать x[:-1]?
Захарий
4

JavaScript - 118 122 символов

Короче JavaScript - 118 символов без пробелов. Использует примерно тот же алгоритм, что и OP, но с меньшей цепочкой. Я пробовал много рекурсии, и я пробовал некоторую итерацию, но все они имеют тенденцию увязать в той или иной мере.

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 Использование return z?a+...+z:w;в качестве неявной проверки длины будет в порядке. Предполагалось, что функция получит только «правильные» слова.
Томалак
Хороший вопрос, за исключением того, что w был изменен, поэтому я должен использовать aв elseтроичной. Отредактировано и до 122 символов.
Райан Кинал
@ Райан: Я считаю, aчто было бы неправильно для двухбуквенного ввода. Черт возьми, в следующий раз я выложу требования более тщательно.
Томалак
Я не думаю, что это будет на самом деле. zбудет только неопределенным, если слово будет одной буквой (или меньше).
Райан Кинал
4

D, 62 символа

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

ладно, я обманул с помощью обычного массива char вместо реальной строки (которая является неизменяемой char [], поэтому не нужно тасовать на месте)

редактировать с проверкой длины требуется еще 14

import std.random;void s(char[] s){if(s.length>1)randomShuffle(s[1..$-1]);}
чокнутый урод
источник
И это возвращает то, что для входа как «я»?
пользователь неизвестен
Было бы честнее (лучше сопоставимо) вернуть результат.
Конрад Рудольф
@user ошибка диапазона. @ konrad, который потребует, return s;и char [] вернет тип 11 больше символов
ratchet freak
@ratchet Не могли бы вы опубликовать всю программу, пожалуйста? Кстати, я не понимаю, почему вы считаете import std.random;, а не только функция.
Арлен
Я предполагаю, что вы могли бы сэкономить 1 байт, используя пропуск char[] s(чтобы сделать это char[]s), но я годами не использовал D.
Тим Час
4

php 5.3 (60 символов)

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

Улучшено до 56 символов и больше не требует версии 5.3:

$r=substr_replace($w,str_shuffle(substr($w,1,-1)),1,-1);
migimaru
источник
+1 хорошая альтернатива другому ответу PHP. Не короче, но без регулярных выражений это плюс.
Томалак
Обновленный с более коротким решением, которое не требует версии 5.3
migimaru
Старая версия не верна: возвращается trueдля коротких строк.
Титус
3

Perl - 111 символов (без использования библиотечной функции)

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}

Использование :

$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
источник
3

питон

Это 90 89 112 символов Python!

Редактировать 1: как функция на этот раз!

(спасибо, Гнибблер)

Редактировать 2: теперь обрабатывает короткие слова

(спасибо, пользователь неизвестен)

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
источник
еще меньше, если вы будете следовать спецификации и написать функцию :)
gnibbler
ах, жалкая перестановка не работает на струнах
gnibbler
1
Случайный модуль похож на меня в ночном клубе ... мы оба просто перемешиваем! :)
Andbdrew
Не работает для ввода, как «Я»; вернуть 'II'.
пользователь неизвестен
Спасибо! теперь он обрабатывает короткие слова, но немного длиннее :)
Andbdrew
3

Scala, 135 139 142 156 символов

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: удалено «: строка» (тип возвращаемого значения может быть выведен)
-7: удалено «возвращение» (последнее выражение является возвращаемым значением)
-3: s.size-2вычеркнуто из
-4: toCharArray->toArray

Gareth
источник
Работает с 'I' и 'Verwürfel' без причудливых символов Python. :) Однако мое решение с использованием 'shuffle' немного короче.
пользователь неизвестен
@ пользователь неизвестен Спасибо за правки :-)
Гарет
3

Питон, 86 символов

Slnicig безопасен, так что нет ничего страшного. Wkros на всех длинах.

from random import*
def f(x):x=list(x);t=x[1:-1];shuffle(t);x[1:-1]=t;return''.join(x)
Бутби
источник
3

C ++ 11: - 68 66 символов

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

полная программа:

#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;
}
Арлен
источник
Правильно ли жесткое кодирование во входной строке?
Томас Эдинг
@trinithis Я думал, что нас интересует только сама функция. Программа показывает только, как использовать функцию. В любом случае, несложное кодирование ввода не будет иметь значения в этом случае; просто добавьstring s; cin >> s;
Арлен
3

Ruby 1.9, 43 символа

г = ш [0] + [* ш [1 ..- 2] .chars] .shuffle.join + W [-1]

Пока не работает для строк длиной 1 символ (дублирует этот символ) и завершается ошибкой для пустой строки.

karatedog
источник
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="")}

Использование:

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"

нижеследующая функция работает со словами длиной менее 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
источник
Часть задачи не состояла в том, чтобы переместить первые и последние буквы.
Томалак
@ Томалак исправлен!
Paolo
Работает ли это со словами ниже 3?
Томалак
@ Томалак Теперь все должно быть хорошо! Спасибо за исправления!
Paolo
3

Python, 102 символа

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]

Нет импорта! Работает для слов 1 символа и выше. Это моя первая запись о гольфе, и я был вдохновлен записью BlueEyedBeast из кратчайшего кода, чтобы создать недетерминированный вывод для идеи использования id (Object) .


Объяснение: Он создает список букв из входных данных, исключая первое и последнее, и многократно появляется из этого списка и добавляет новый, пока он не будет пустым. Индекс, из которого он появляется, - это id (7)% len (список, из которого мы выскакиваем). Поскольку id (7) является адресом памяти объекта 7, он является по существу случайным. Итак, теперь у нас есть список случайно зашифрованных букв из центра исходного ввода. Все, что мы делаем сейчас, это добавляем первые и последние буквы исходного вывода соответственно, и мы получаем желаемый результат: (первая буква) + (скремблированная середина) + (последняя буква).

жирафа
источник
3

Р, 95 92 91 персонаж

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

Использует ленивую оценку R для вычисления a и b как параметров функции, экономя место с последующим повторным использованием. Также в отличие от другого ответа R это работает для всех слов> 1 символ длиной. Пример ниже:

> f("hippopotamus")
hpuoopaitmps

> f("dog")
dog

> f("az")
az

Редактировать: Заменено unlist()на[[]] Заменено [[1]] на el ()

Эндрю Хейнс
источник
2

D: 55 символов

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

полная программа:

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);
}
Арлен
источник
Я думаю, что else sчасть отсутствует?
Томалак
1
@ Томалак Нет, это не так, потому что в этом нет необходимости. Если строка имеет длину 2 или менее, то мы оставляем ее в покое. Кроме того, randomShuffle()на месте.
Арлен
Ух ты, будь конкурентоспособным. Я думаю, что randomShuffle(s[1..$-1])может быть s[1..$-1].randomShuffleIIRC (если это не в версии D старше, чем этот пост)
Zacharý
2

Эрланг, 188 172 132 символа

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

Я все еще изучаю Erlang, поэтому любые советы по сокращению это приветствуются.

полный код (модуль 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).

редактировать

Вытащил перемешанную часть как отдельную функцию, которая больше не требует, чтобы заголовок и хвост списка передавались.

Редактировать 2

Реструктурирован, чтобы удалить один из fшаблонов функций, изменил функцию shuffle, чтобы принимать только два параметра, изменил lists:deleteдля --[], обменял lists:reverseвызов наlists:last

Скотт Логан
источник