Смешайте слова, сохраняя их очертания

44

Это намного сложнее, чем « Как рандомизировать буквы в слове» и « Кембриджская транспозиция» из-за правила о том, какие буквы можно поменять с какими. Простого регулярного выражения здесь будет недостаточно.


Хорошо известно, что текст все еще можно прочитать, пока внутренности его слов зашифрованы, пока их первая и последняя буквы плюс их общие контуры остаются постоянными. Получив печатный текст Ascii + Newline, скремблируйте каждое слово в соответствии с этими правилами:

  1. Скремблирование должно быть (псевдо) случайным.

  2. Слово - это последовательность латинских символов от A до Z.

  3. Только начальные буквы всегда будут заглавными.

  4. Первые и последние буквы должны остаться нетронутыми.

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

    1. acemnorsuvwxz

    2. bdfhkl

    3. gpqy

    4. it

    5. j (остается на месте)

пример

Srcmable wrods в то время как psrrnveieg их oeiltnus

Хорошо известно, что текст все еще может быть прочитан, в то время как внутренности его слов были сняты, пока их первые и последние буквы плюс их ovaerll ontliues raemin не могут сделать. Принимая участие в программе Acsii + Nwnliee, вы можете найти слово anoccdirg для этих людей:

  1. Smncrbliag должен быть (pusedo) rondam.

  2. Wrod - это продолжение латинских chreratacs, A thurogh Z.

  3. Только начальные члены будут выше.

  4. Первые и последние письма должны оставаться уктоэнхудом.

  5. Когда sarnclbimg, только буквы с одним из fwllnoiog guorps могут поменять местами:

    1. aneusvrowxmcz

    2. bhkfdl

    3. gqpy

    4. it

    5. j (остается в отеле)

Emxaple

Адам
источник
tдолжен быть короче, чем hхотя многие люди не пишут это так.
Утренняя монахиня
@ LeakyNun Я знаю, но вы предлагаете удалить tиз группы 2? Или, может быть, положить tв группу 4 с i?
Адам
С последним все будет в порядке.
Утренняя монахиня
может ли среда выполнения быть теоретически неограниченной? (как случайные попытки, пока что-то не так)
Sarge Borsch
1
printable/ patnirlbeне совсем читабельно. Я думаю, что i/ tсвоп виноват. Хм ... paintrlbeНет, это тоже не помогло. Это, вероятно, pr/ paсвоп, то. Контур поддерживает, но я думаю , что я прочитал «PR» и «па» как семантический (?) 1 письмо. prtnialbeО да. Это сделал это. Не уверен, что могу предложить исправление алгоритма.
Draco18s

Ответы:

9

Желе , 80 74 байта

-2 байта, переходя от czar + vex + mow + sunк czar + vexes + unmown(повторяющиеся es и ns не проблема)
-1 байт, используя Tịвместо ȦÐf
-1 байт, Œle€Øaвместо i@€ØB>⁵
-2 байт, немного перенастроив схему

Tị
TẊị⁹ż@œp
e€ç⁸F
W;“HọƊṘ€.`]HɲøƁḤ0ẉlfrøj⁷»Ḳ¤ç/
Ḣ,ṪjÇḟ0
Œle€Øað¬œpÇ€ÑżœpÑ¥

Полная программа, содержащая список символов (или строку в формате Python), которая печатает результат скремблирования.

Попробуйте онлайн!

Кажется, здесь очень много трудностей для Jelly (либо я, либо пропустил уловку, которая, как известно, случается!). Это наверняка будет преодолено языками с лучшими манипуляциями со строками, такими как Retina (без случайной функциональности) или 05ab1e .

Как?

Tị - Link 1, get truthy items: list a
T  - truthy indexes of a
 ị - index into a

TẊị⁹ż@œp - Link 2, selective shuffle: list a, list b
T        - truthy indexes of a (those indexes that may be shuffled in b)
 Ẋ       - random shuffle
   ⁹     - link's right argument, b
  ị      - index into (gets the shuffled values)
      œp - partition b at truthy indexes of a
    ż@   - zip with reversed @rguments (place shuffled values - yields a list of lists)

e€ç⁸F - Link 3, value selective shuffle: list a, list b
e€    - c exists in b? for €ach c in a (1s where b has shuffle-able characters, else 0s)
   ⁸  - link's left argument, a
  ç   - call the last link (2) as a dyad
    F - flatten the result (from the yielded list of lists to one list)

W;“HọƊṘ€.`]HɲøƁḤ0ẉlfrøj⁷»Ḳ¤ç/ - Link 4, perform all shuffles on a word's innards: list x
W                             - wrap x in a list
                          ¤   - nilad followed by link(s) as a nilad:
  “HọƊṘ€.`]HɲøƁḤ0ẉlfrøj⁷»     -   compression of s(bdfhkl)+d( czar)+d(vexes)+d(unmown)+s( gpqy)+d( ti)
                              -     where d() looks up a word in Jelly's dictionary and s() adds a string to the compressed output.
                         Ḳ    -   split on spaces: ["bdfhkl","czarvexesunmown","gpqy","ti"]
                           ç/ - reduce by last link (3) as a dyad (shuffles by each in turn)

Ḣ,ṪjÇḟ0 - Link 5, shuffle a word: list w
Ḣ       - head w (yields the leftmost character and modifies w)
  Ṫ     - tail w (yields the rightmost character and modifies w)
 ,      - pair
        -   Note: head and tail yield 0 when w is empty, so ['a'] -> ["a",0] and [] -> [0,0]
    Ç   - call the last link (4) as a monad (with the modified w)
   j    - join
     ḟ0 - filter discard zeros (thus single or zero letter words pass through unchanged)

Œle€Øað¬œpÇ€ÑżœpÑ¥ - Main link: list s
Œl                 - convert s to lowercase, say t
    Øa             - lowercase alphabet, say a
  e€               - c exists in a? for €ach c in t
      ð            - dyadic chain separation (call that u)
       ¬           - not (vectorises across u), say v
        œp         - partition s at truthy indexes of v (extract words, plus empty lists from within strings of non-alphabetic characters)
          Ç€       - call the last link (5) as a monad for €ach (shuffle their innards)
            Ñ      - call the next link (1) as a monad (only keep the actual words)
                 ¥ - last two links as a dyad:
              œp   -   partition s at truthy indexes of u (get the non-words, plus empty lists from within strings of alphabetic characters)
                Ñ  -   call the next link (1) as a monad (only keep actual non-words)
             ż     - zip together
                   - implicit print
Джонатан Аллан
источник
Это на самом деле сложнее, чем я думал.
Дрянная Монахиня
@LeakyNun, мне понадобилось гораздо больше времени, чтобы разобраться с этим.
Джонатан Аллан
1
@JonathanAllan Да, это было там целую вечность, и, вероятно, будет частью следующего выпуска, потому что это беспокоило меня много раз.
Мартин Эндер
1
czar + vex + mow + sun
адам
3
@ Adám словарь поиска в форме acemnorsuvwxz. Я напишу комментированный код тоже в какой-то момент.
Джонатан Аллан
5

PHP, 278 байт

<?=preg_replace_callback("#\pL\K(\pL+)(?=\pL)#",function($t){preg_match_all("#([^bdf-lpqty])|([bdfhkl])|([gpqy])|([it])|(j)#",$t[0],$p);foreach($p as$v){$k++?$c=array_keys($n=array_filter($v)):$o=[];!$n?:shuffle($n)&&$o+=array_combine($c,$n);}ksort($o);return join($o);},$argn);

Попробуйте онлайн!

расширенный

echo preg_replace_callback("#\pL\K(\pL+)(?=\pL)#" # patter \pL is shorter as [a-z]
,function($t){  # replacement function beginning
  preg_match_all("#([^bdf-lpqty])|([bdfhkl])|([gpqy])|([it])|(j)#",$t[0],$p); # makes groups with the regex. group 0 is the whole substring
  foreach($p as$v){ # loop through groups
    $k++?$c=array_keys($n=array_filter($v)):$o=[]; # group 0 make new empty replacement array in the other case filter the group remove empty values. 
    #You gain an array with the keys as position in the substring and the values
    #store the key array and the values array
    !$n?:shuffle($n)&&$o+=array_combine($c,$n); 
    #if values shuffle the values and make a new array with the keys and the shuffled values and merge the new array to the replacement array
  }
  ksort($o); # sort the replacement array ascending positions 
  return join($o); # return the replacement as string
},$argn);

функции

array_combine

array_filter

array_keys

ksort

preg_replace_callback

шарканье

Йорг Хюльсерманн
источник
Совет: Вы можете использовать параметр «отключить кэш вывода» на TIO, а не запускать код несколько раз. Я просто запустил это на примере - Все хорошо!
Джонатан Аллан
@JonathanAllan Спасибо за подсказку с кешем. Было достаточно сложно найти способ решить эту проблему
Йорг Хюльсерманн
5

Pyth , 79 байт

sm?td++hduuXNhTeTC,f@@GTHUG.S@HGG+-GJ."by❤jã~léܺ"cJ\jPtdedd:jb.z"([A-Za-z]+)"3

где U + 0018.

Попробуйте онлайн!

Образец

Хорошо известно, что текст все еще может быть прочитан, пока ирланды его слов были seraclbmd, до тех пор, пока их первая и последняя буквы плюс их oaervll ontliues rmeain conntsat. Учитывая текст, пожертвуйте каждый ответ на этот вопрос:

  1. Scamrlbing должен быть (puesdo) rnadom.

  2. Слово является преемником латинских chraectars, A thuorgh Z.

  3. Только iaitinl lettres будет когда-либо наверху.

  4. Первый и последний письма остаются без ответа.

  5. Когда srancblimg, только письма с одним из следующих guorps могут включать в себя:

    1. amsuvrcnoxewz

    2. bhfkdl

    3. gpqy

    4. it

    5. j (остается на месте)

Дрянная Монахиня
источник
Вы не можете сохранить с \pLвместо [A-Za-z]?
Адам
@ Adám Что такое \pL?
Утренняя монахиня
Любой символ с р roperty того , чтобы быть л Etter.
Адам
Я не думаю, что это работает здесь ...
Leaky Nun
не \wбудет достаточно?
Сардж Борщ
5

JavaScript 176 байт

t.replace(/\B(\w+)\B/g,b=>{return[/[acemnorsuvwxz]/g,/[bdfhkl]/g,/[gpqy]/g,/[it]/g].forEach(d=>{g=b.match(d),b=b.replace(d,c=>{return g.splice(Math.random()*g.length,1)})}),b})

Метод:

  1. RegExp выполняет итерацию по центру каждого слова ( /\B(\w+)\B/g) с помощью 1-й замены fn.

  2. Первая замена fn повторяет массив RegExp для каждой буквы-группы ( /[bdfkhl/g, /[gqpy]/g, etc..).

  3. Каждая итерация создает временный массив символов центра слов, появляющихся в текущей группе букв.

  4. Затем каждая итерация использует RegExp текущей группы букв для итерации по всему центру слов, используя 2-ю замену fn.

  5. Вторая замена fn случайным образом соединяет временный массив, удаляя случайный символ и возвращая его.

Демо-версия:

Запустите его в JSFiddle: https://jsfiddle.net/CookieJon/bnpznb7r/

неровный
источник
Добро пожаловать в PPCG. Удивительный первый ответ. Тем не менее, я думаю, что вам нужно, \pL(\pL+)\pLа не \B(\w+)\Bисключать цифры и подчеркивание.
Адам
Ах, спасибо! Должен признать, регулярное выражение не моя сумка (я должен искать ссылку КАЖДЫЙ раз, когда я использую его!) Я могу проглотить 3 дополнительных символа ... обновлю свой ответ в ближайшее время, спасибо еще раз. :-)
Неровный
1
Невероятный первый ответ! :) Несколько быстрых улучшений, которые позволят вам сократить размер до 155 байт, включая приведенное выше исправление @ Adáms: t => t.replace (/ \ B [az] + \ B / gi, b => ([/ [acemnorsuvwxz] ] / г, / [bdfhkl] / г, / [gpqy] / г, / [оно] / г] .map (д => Ь = b.replace (д, с => г. сплайсинга (новые Дата% g.length, 1), г = b.match (г))), б))
лохматый
@ Shaggy Я думаю, что b=>[...].map(...)&&bсохраняет еще один байт. Также я не уверен, что ты iнужен.
Нил
Если @ Adám будет очень требователен к определению своего слова, тогда вам нужно будет использовать t.replace(/[A-Za-z]([a-z]+)(?=[a-z])/g,(w,b)=>...w[0]+b...)или что-то подобное.
Нил
2

С, 453, 356, 369 байт.

#define F for
#define M rand()%s+1+q
char a[256],*b=" acemnorsuvwxz\1bdfhkl\1gpqy\1it\1j";g(c,t)char*c,*t;{static int i,j,k,w,v,n,q,s,r;r=-1;if(c&&t){strcpy(c,t);if(!k)F(j=i=k=1;b[i];++i)b[i]-1?(a[b[i]]=j):++j;F(r=i=0;c[i];){F(;isspace(c[i]);++i);F(q=i;!isspace(c[i])&&c[i];++i);F(s=v=i-q-2;--v>0;)if(a[c[j=M]]==a[c[w=M]]&&a[c[j]])n=c[j],c[j]=c[w],c[w]=n;}}return r;}

разворачивать с комментариями

// Input in the arg "t" result in the arg "c"
// NB the memory pointed from c has to be >= memory pointed from t
//    the char is 8 bit
#define F for
#define M rand()%s+1+q
char a[256], *b=" acemnorsuvwxz\1bdfhkl\1gpqy\1it\1j";
   g(c,t)char*c,*t;
   {static int i,j,k,w,v,n,q,s,r;
    r=-1;
    if(c&&t)
      {strcpy(c,t);                         // copy the string in the result space
       if(!k)
         F(j=i=k=1;b[i];++i)
             b[i]-1?(a[b[i]]=j):++j;        // ini [possible because at start k=0]
       F(r=i=0;c[i];)
         {F(;isspace(c[i]);++i);            //skip spaces
                                            // the start q the end+1 i
          F(q=i;!isspace(c[i])&&c[i];++i);  //skip word
          F(s=v=i-q-2;--v>0;)               //loop for swap letters of the same set
            if(a[c[j=M]]==a[c[w=M]]&&a[c[j]])
                n=c[j],c[j]=c[w],c[w]=n;
         }
      }
   return r;
  }


#include <stdio.h>
#define G(x,y) if(x)goto y
main()
{char a[256],r[256];
l1:
 gets(a);// i would know the string lenght<256
 g(r,a);
 printf("%s\n",r);
 G(*a,l1);
}
RosLuP
источник
1

Python 3.6, 349 340 байт

from itertools import *
from random import *
import re
def S(s):
    C=lambda c:len(list(takewhile(lambda x:c not in x,('j','it','gqpy','bhkfdl'))));L=[];B=[[]for i in range(5)]
    for l in s:c=C(l);L+=[c];B[c]+=[l];shuffle(B[c])
    return''.join(B[n].pop()for n in L)
A=lambda t:re.sub('[A-Za-z]{3,}',lambda x:x[0][0]+S(x[0][1:][:-1])+x[0][-1],t)

Отступ с вкладками. Функция названа A. Он не использует грубую силу, время выполнения детерминировано, как спросил OP.

Сардж Борщ
источник
1

Mathematica 232 байта

StringReplace[#,x:Repeated[WordCharacter,{2,∞}]:>""<>(s=StringTake)[x,{i,i}~Table~{i,StringLength@x}/.Flatten[Thread[#->RandomSample@#]&/@(StringPosition[x~s~{2,-2},#]+1&/@Characters@{"acemnorsuvwxz","bdfhkl","gpqy","it","j"})]]]&

Основная идея состоит в том, чтобы переставить подмножества, соответствующие 4 различным группам символов. Вероятно, есть место для улучшения.

Келли Лоудер
источник
1

C 306 282 байта

c,o,d,e,g;l(char*f){char*s[]={"aneusvrowxmcz","bhkfdl","gqpy","it",0},**h,*i,*t;for(i=f;*i;){if(isalpha(*i)){t=i;while(*i&&isalpha(*i))i++;e=i-t-2;for(h=s;*h&&e;*h++){for(c=999;--c;){d=1+rand()%e,o=1+rand()%e;if(strchr(*h,t[d])&&strchr(*h,t[o]))g=t[d],t[d]=t[o],t[o]=g;}}}else++i;}}

Попробуйте онлайн

Ungolfed:

int func(char*p) 
{
    char *groups[] = {"aneusvrowxmcz","bhkfdl","gqpy","it",0}, **g, *s, *t;
    int n,r,i,l,o;

    for (s = p; *s;)
    {
        if (isalpha(*s))
        {
            t = s;
            while (*s && isalpha(*s))
                s++;
            // start scrambling
            l = s - t - 2;
            for(g=groups; *g && l; *g++)
            {
                for(n=999;--n;)
                {
                    i = 1 + rand() % l;
                    r = 1 + rand() % l;
                    if (strchr(*g, t[i]) && strchr(*g, t[r]))
                    {
                        o=t[i];
                        t[i]=t[r];
                        t[r]=o;
                    }
                }
            }
            // end scrambling
        }
        else 
            s++;
    }
}
Йохан дю Туа
источник
Почему вы хотите сделать обмен 999 одним словом? Знаете ли вы, что одно слово одного символа имеет l = -1, и это, возможно, означает, что он начинает делать 999 возможных перестановок, используя 1 + rand ()% -1, поэтому случайная запись в 2 гига памяти ... Но возможно я вижу это неправильно ....
РосЛуП
К сожалению, нет никакого волшебства в использовании 999. Это всего на 1 байт меньше 1000 :)
Johan du Toit
В gcc кажется, что rand ()% (- 1) возвращает 0 первые 2 раза, когда я пытался это сделать. так что нет возможности случайного обмена 2giga space ...% от int не% от unsigned ...
RosLuP
@RosLup, извини, но я не понимаю, что ты говоришь ..
Йохан дю Туа
1

JavaScript (ES6), 380 327 311 294 байта

( 298 282 265 байт без правил)

Спасибо @Shaggy за полезные советы!

((b,d)=>b.replace(/\B[a-z]+\B/gi,f=>(g=>(g.map(j=>(h=d.slice(0,~(rind=d.indexOf(j))?rind:-1),~rind?h.split`,`.length-1:-1)).map((j,k,l,m=[])=>{l.map((n,o)=>n==j?m.push(o):0),sub=m[new Date%(m.length-1)]||k,tmp=g[sub],g[sub]=g[k],g[k]=tmp}),g.join``))([...f])))(s,"aneusvrowxmcz,bhkfdl,gqpy,it");

var f = ((b,d)=>b.replace(/\B[a-z]+\B/gi,f=>(g=>(g.map(j=>(h=d.slice(0,~(rind=d.indexOf(j))?rind:-1),~rind?h.split`,`.length-1:-1)).map((j,k,l,m=[])=>{l.map((n,o)=>n==j?m.push(o):0),sub=m[new Date%(m.length-1)]||k,tmp=g[sub],g[sub]=g[k],g[k]=tmp}),g.join``))([...f])))

var s="Let there be scrambling";
console.log(s);
console.log(f(s,"aneusvrowxmcz,bhkfdl,gqpy,it"))

s="It is well known that a text can still be read while the innards of its words have been scrambled, as long as their first and last letters plus their overall outlines remain constant. Given a printable Ascii+Newline text, scramble each word according to these rules";
console.log(s);
console.log(f(s,"aneusvrowxmcz,bhkfdl,gqpy,it"))

Функция f принимает строку любого вида (одно слово, несколько слов, несколько слов со знаками в ней - которые она интерпретирует как разбивающие слова) и массив строк «правил» любой длины, разделенных запятыми.

Этот набор правил, в случае вашего вопроса, будет ["aneusvrowxmcz", "bhkfdl", "gqpy", "it"] "aneusvrowxmcz,bhkfdl,gqpy,it"

Некоторые буквы не смешиваются, даже если бы они могли, поскольку вы указали в своем вопросе, что буквы «могут поменяться местами». Если я неверно истолковал это, я могу изменить код, чтобы всегда перемешивать буквы, которые соответствуют правилам.

Я знаю, что это огромное количество байтов, и оно не сможет конкурировать с языками игры в гольф, но я все равно хотел попробовать, надеюсь, вам понравится :)

Читаемый человеком неуглифицированный код:

((txt,rules)=>txt.replace(/\B[a-z]+\B/gi,wo=>((w=>(w.map(c=>(h=rules.slice(0, ~(rind=rules.indexOf(c))?rind:-1),~rind?(h.split`,`.length-1):-1)).map((e,i,arr,a=[])=>{
    arr.map((x,i)=>(x==e)?a.push(i):0),
    sub=a[new Date%(a.length-1)]||i,
    tmp=w[sub],
    w[sub]=w[i],
    w[i]=tmp
}),w.join``))([...wo]))))(str, "aneusvrowxmcz,bhkfdl,gqpy,it")
Hankrecords
источник
1
Правила OP должны быть включены в число байтов. К маю , я имел в виду есть шанс .
Адам
1
Добро пожаловать в PPCG :) Вы можете определенно много играть в гольф .
Лохматый
1
Я собирался попробовать сыграть в эту игру для вас, но, учитывая, как много можно с этим сделать, у меня не хватило времени, поэтому вместо этого я укажу вам здесь и здесь, чтобы помочь вам начать.
Лохматый
1
Несколько быстрых указателей, хотя: 01) Избавьтесь от всех varS letс. 02) Если это не рекурсивная функция, нет необходимости включать объявление переменной ( f=) в ваш счетчик байтов. 03) Используйте каррирование, когда функция имеет 2 параметра ( b=>d=>вместо (b,d)=>) и вызывайте вашу функцию с помощью f(b)(d). 04) У вас есть iфлаг, поэтому нет необходимости включать его A-Zв регулярное выражение. 05) Вы можете использовать indexOfили searchстроку, не разбивая ее на массив.
Лохматый
1
Как предложение 03 спасает персонажей? Они выглядят одинаково для меня.
Стив Беннет
0

Clojure, 326 322 324 байта

Обновление 1: заменено (map(fn[[k v]]...)...)на(for[[k v]...]...)

Обновление 2: исправлено регулярное выражение, \pLвместо использования \wи т. Д.

#(let[G(zipmap"bdfhklgpqyitj""0000001111223")](apply str(flatten(interleave(for[v(re-seq #"\pL+"%)w[(rest(butlast v))]W[(into{}(for[[k v](group-by G w)][k(shuffle v)]))]R[(rest(reductions(fn[r i](merge-with + r{(G i)1})){}w))]][(first v)(map(fn[c r](nth(W(G c))(-(r(G c))1)))w R)(if(second v)(last v))])(re-seq #"\PL+"%)))))

Я с нетерпением жду, чтобы увидеть что-то короче. Более ранняя версия с несколькими примерами запускается:

(def f #(let[G(zipmap"bdfhklgpqyitj""0000001111223")] ; Create groups, the longest "acemnorsuvwxz" goes to an implicit group nil
          (apply str(flatten(interleave
                              (for[v (re-seq #"\w+"%)                                          ; Iterate over words
                                   w [(rest(butlast v))]                                       ; This holds the middle part
                                   W [(into{}(map(fn[[k v]][k(shuffle v)])(group-by G w)))]    ; Create shuffled groups
                                   R [(rest(reductions(fn[r i](merge-with + r{(G i)1})){}w))]] ; Calculate cumulative sum of group items, used to look-up nth value from shuffled values
                               [(first v)                                     ; First character
                                (map(fn[g r](nth(W g)(-(r g)1)))(map G w)R)   ; Shuffled middle part
                                (if(>(count v)1)(last v))])                   ; Last character, unless the word is just a single character
                              (re-seq #"\W+"%)))))) ; Interleave with spaces, commas, newline etc.

(f "It is well known that a text can still be read while the innards of its words have been scrambled, as long as their first and last letters plus their overall outlines remain constant.\n")
;  "It is well known that a txet can sitll be read wlihe the irnands of its wrods hvae been seacmlbrd, as lnog as their fisrt and lsat letters plus their oavrell ontlieus rmaein cnontast.\n"
;  "It is well kwonn that a text can sitll be raed wlihe the innards of its wrods hvae been seramlbcd, as long as their fisrt and lsat lettres plus their oravell ouiltnes rmeain cnsatont.\n"
;  "It is well konwn that a text can still be read while the iarnnds of its words have been sraemlbcd, as lnog as their first and lsat lrttees plus their oaevrll ontlieus remain canntsot.\n"
NikoNyrh
источник
Я думаю , что вам нужно , \pL+и \PL+вместо того , \w+и \W+исключить цифры и подчеркивания.
Адам
0

Perl 6 , 241 195 байт

Включает +1 байт для -pпереключателя командной строки.

s:g/(<:L>)(<:L>+)(<:L>)/{$0}{[~]
$1.comb.pairs.classify({first
.value~~*,:k,/<[bdfhkl]>/,/<[gpqy]>/,/<[it]>/,/j/,!0}).values.map({$_».key
»=>«$_».value.pick(*)})».List.flat.sort».value}$2/;

Ungolfed:

s:g/(<:L>)(<:L>+)(<:L>)/{$0}{
    [~]
    $1.comb
    .pairs
    .classify({
        first .value ~~ *, :k,
            /<[bdfhkl]>/,
            /<[gpqy]>/,
            /<[it]>/,
            /j/,
            !0
    })
    .values
    .map({ $_».key »=>« $_».value.pick(*) })
    ».List
    .flat
    .sort
    ».value
}$2/;
Шон
источник
Я думаю, что вам нужно, (\pL)(\pL+)(\pL)а не (\w)(\w+)(\w)исключать цифры и подчеркивание.
Адам
На самом деле \pLвключает в себя много символов за пределами допустимого диапазона латинских букв AZ. Я обновил свой код для более точного отражения требований.
Шон
Какие персонажи? Помните, что ввод ограничен печатными ASCII + символами новой строки.
Адам
Ах, я пропустил это. \pLзаписано <:L>в Perl 6, хотя
Шон
0

C #, 438 394 380 374 байта

namespace System.Text.RegularExpressions{using Linq;s=>Regex.Replace(s,@"\p{L}(([gpqy])|(i|t)|(j)|([bdf-l])|([a-z]))*?[a-z]?\b",m=>{var a=m.Value.ToArray();for(int i=1,j;++i<7;){var c=m.Groups[i].Captures;var n=c.Cast<Capture>().Select(p=>p.Index-m.Index).ToList();foreach(Capture p in c){a[j=n[new Random().Next(n.Count)]]=p.Value[0];n.Remove(j);}}return new string(a);});}

Сохраните 10 байтов благодаря @ MartinEnder ♦.

Досадно, CaptureCollectionне реализуется,IEnumerable<T> и поэтому .Cast<Capture>()это необходимо. Надеюсь, я могу объединить запрос Linq и foreachцикл, хотя.

Я уверен, что есть много чего можно сыграть в гольф, но мне потребовалось достаточно много времени, чтобы заставить его работать ...

Попробуйте онлайн!

Отформатированная / Полная версия:

namespace System.Text.RegularExpressions
{
    using Linq;

    class P
    {
        static void Main()
        {
            Func<string, string> f = s =>
                Regex.Replace(s, @"\p{L}(([gpqy])|(i|t)|(j)|([bdf-l])|([a-z]))*?[a-z]?\b", m =>
                {
                    var a = m.Value.ToArray();

                    for (int i = 1, j; ++i < 7;)
                    {
                        var c = m.Groups[i].Captures;

                        var n = c.Cast<Capture>().Select(p => p.Index - m.Index).ToList();

                        foreach(Capture p in c)
                        {
                            a[j = n[new Random().Next(n.Count)]] = p.Value[0];
                            n.Remove(j);
                        }
                    }

                    return new string(a);
                });

            Console.WriteLine(f("Scramble words while preserving their outlines"));
            Console.ReadLine();
        }
    }
}
TheLethalCoder
источник