Wymieszaj słowa, zachowując ich kontury

44

Jest to o wiele bardziej zaawansowane niż Jak losowo wybierać litery w słowie i Cambridge Transposition z powodu reguły o tym, które litery mogą być zamieniane z którymi. Proste wyrażenie regularne nie wystarczy tutaj.


Powszechnie wiadomo, że tekst można nadal czytać, podczas gdy wnętrze jego słów jest zakodowane, o ile ich pierwsza i ostatnia litera oraz ich ogólny zarys pozostają niezmienne. Biorąc pod uwagę tekst Ascii + Newline do wydrukowania, zmieszaj każde słowo zgodnie z następującymi zasadami:

  1. Mieszanie musi być (pseudo) losowe.

  2. Słowo to ciąg znaków łacińskich od A do Z.

  3. Tylko początkowe litery będą zawsze wielkie.

  4. Pierwsza i ostatnia litera muszą pozostać nietknięte.

  5. Podczas szyfrowania tylko litery z jednej z następujących grup mogą wymieniać się miejscami:

    1. acemnorsuvwxz

    2. bdfhkl

    3. gpqy

    4. it

    5. j (zostaje na miejscu)

Przykład

Srcmable wyszedł, a psrrnveieg ich oeiltnus

Powszechnie wiadomo, że txet można nadal czytać, podczas gdy rozszyfrowywane są jego produkty, o ile ich fisrt i ostatnie litery oraz ich ovaerll ontliues raemin nie są w stanie. Biorąc pod uwagę patnirlbe Acsii + Nwnliee txet, samrclbe ecah słowo anoccdirg do tych relus:

  1. Smncrbliag musi być (pusedo) rondam.

  2. Wrod jest sekwencją łacińskich chrerataków, A thurogh Z.

  3. Tylko pierwsze inicjały będą dostępne.

  4. Lettres fisrt i lsat muszą pozostać uctoenhud.

  5. Kiedy sarnclbimg, tylko litery z jednym z guwps fwllnoiog mogą ecxhange tablice:

    1. aneusvrowxmcz

    2. bhkfdl

    3. gqpy

    4. it

    5. j (zostaje w pokoju)

Emxaple

Adám
źródło
tma być krótszy niż hchoć wiele osób tego nie pisze.
Leaky Nun
@LeakyNun Wiem, ale czy sugerujesz usunięcie tz grupy 2? A może tw grupie 4 i?
Adám
To drugie byłoby w porządku.
Leaky Nun
czy środowisko wykonawcze może być teoretycznie nieograniczone? (jak losowe próby, aż coś będzie dobrze)
Sarge Borsch
1
printable/ patnirlbenie jest całkiem czytelny. Myślę, że winą jest i/ tswap. Hmm ... paintrlbeNie, to też nie pomogło. Zatem prawdopodobnie jest to pr/ paswap. Zarys utrzymuje, ale myślę, że czytam „Pr” i „PA” jako semantycznie (?) 1 list. prtnialbeO tak. To zrobiło to. Nie jestem jednak pewien, czy mogę zaoferować poprawkę do algorytmu.
Draco18s,

Odpowiedzi:

9

Galaretka , 80 74 bajtów

-2 bajty, przechodząc z czar + vex + mow + sundo czar + vexes + unmown(powtarzane esi nnie stanowią problemu)
-1 bajt przy użyciu Tịzamiast ȦÐf
-1 bajtu, Œle€Øazamiast i@€ØB>⁵
-2 bajtów przez nieco zmienioną konfigurację układu

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

Pełny program pobierający listę znaków (lub ciąg sformatowany w języku Python), który drukuje wynik mieszania.

Wypróbuj online!

Wydaje się, że tutaj istnieje ogromna trudność dla Jelly (albo to, albo nie trafiłem sztuczki, o której wiadomo, że się zdarza!) Na pewno zostaną pokonane przez języki z lepszą manipulacją ciągami, takie jak Retina (brak losowej funkcjonalności) lub 05ab1e .

W jaki sposób?

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
Jonathan Allan
źródło
To jest naprawdę trudniejsze niż myślałem.
Leaky Nun
@LeakyNun welp zajęło mi więcej niż 10 minut, aby się z tym zmagać.
Jonathan Allan
1
@JonathanAllan Tak, był tam od wieków i prawdopodobnie będzie częścią kolejnego wydania, ponieważ to mnie wkurza wiele razy.
Martin Ender
1
czar + vex + mow + sun
Adám
3
@ Wyszukiwanie słowników w formularzu Adám acemnorsuvwxz. W pewnym momencie też napiszę skomentowany kod.
Jonathan Allan
5

PHP, 278 bajtów

<?=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);

Wypróbuj online!

Rozszerzony

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

Funkcje

array_combine

filtr_tablicowy

tablice_kluczy

ksort

preg_replace_callback

człapać

Jörg Hülsermann
źródło
Wskazówka: Możesz użyć ustawienia „wyłącz wyjściową pamięć podręczną” w TIO zamiast uruchamiać kod kilka razy. Właśnie uruchomiłem z przykładem - Wszystko dobrze!
Jonathan Allan
@JonathanAllan Dziękuję za podpowiedź z pamięcią podręczną. Trudno było znaleźć rozwiązanie tego problemu
Jörg Hülsermann
5

Pyth , 79 bajtów

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

gdzie jest U + 0018.

Wypróbuj online!

Próba

Dobrze wiadomo, że tekst można jeszcze usunąć, podczas gdy jego nazwy są seraclbmd, o ile ich pierwsza i ostatnia litera plus ich oaervll ontliues rmeain conntsat. Biorąc pod uwagę tekst, poświęcić każdego wrod acrncdiog, aby zobaczyć relus:

  1. Scamrlbing musi być (puesdo) rnadom.

  2. Słowo jest suqencee łacińskich chraectars, A thuorgh Z.

  3. Tylko iaitinl lettres będzie zawsze uppaersce.

  4. Pierwsza i ostatnia litera pozostają nierozłączone.

  5. Kiedy srancblimg, tylko litery wiihtn jednego z guorpsów follnwiog mogą enxhcage plecas:

    1. amsuvrcnoxewz

    2. bhfkdl

    3. gpqy

    4. it

    5. j (zostaje na miejscu)

Leaky Nun
źródło
Nie możesz oszczędzić \pLzamiast [A-Za-z]?
Adám
@ Adám Co to jest \pL?
Leaky Nun
Każda postać z p roperty bycia L etter.
Adám
Nie sądzę, żeby tu
działało
nie \wwystarczy?
Sarge Barszcz
5

JavaScript 176 bajtów

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

Metoda:

  1. RegExp iteruje po środku każdego słowa ( /\B(\w+)\B/g), używając 1. zastępowania fn.

  2. 1st replace fn iteruje tablicę RegExp dla każdej litery-grupy ( /[bdfkhl/g, /[gqpy]/g, etc..).

  3. Każda iteracja tworzy tablicę temp znaków w centrum słów pojawiających się w bieżącej grupie liter.

  4. Każda iteracja używa następnie RegExp bieżącej grupy liter do iteracji po całym centrum słów, używając drugiej zamiany fn.

  5. 2. zastąp fn losowo splata tablicę temp, usuwając losowy znak i zwracając go.

Próbny:

Uruchom go w JSFiddle: https://jsfiddle.net/CookieJon/bnpznb7r/

Wyboisty
źródło
Witamy w PPCG. Niesamowita pierwsza odpowiedź. Myślę jednak, że musisz \pL(\pL+)\pLraczej niż \B(\w+)\Bwykluczać cyfry i podkreślenia.
Adám
Ach, dzięki! Muszę przyznać, że regex nie jest moją torbą (muszę szukać referencji za każdym razem, gdy jej używam!) Mogę połknąć 3 dodatkowe znaki ... zaktualizuję moją odpowiedź wkrótce dzięki. :-)
Wyboisty
1
Niesamowita pierwsza odpowiedź! :) Kilka szybkich ulepszeń, które pozwolą Ci obniżyć do 155 bajtów, w tym powyższa poprawka @ Adáms: t => t.replace (/ \ B [az] + \ B / gi, b => ([/ [acemnorsuvwxz ] / g, / [bdfhkl] / ‌ g, / [gpqy] / g, / [it] / g] ‌ .map (d => b = b.replace (‌ d, c => g. splot (nowa data% g. długość, 1), g = b.match (d))), b))
Shaggy
@Shaggy Myślę, że b=>[...].map(...)&&bzapisuje kolejny bajt. Nie jestem też pewien, czy twoje ijest konieczne.
Neil
Jeśli @ Adám będzie ściśle wybredny ze swoją definicją słowa, będziesz musiał go użyć t.replace(/[A-Za-z]([a-z]+)(?=[a-z])/g,(w,b)=>...w[0]+b...).
Neil
2

C, 453, 356 369 bajtów

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

Ungolf z komentarzami

// 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
źródło
1

Python 3.6, 349 340 bajtów

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)

Wcięte za pomocą zakładek. Funkcja nosi nazwę A. Nie używa brutalnej siły, czas działania jest deterministyczny, jak poprosił OP.

Barszcz Sarge
źródło
1

Mathematica 232 bajty

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"})]]]&

Podstawową ideą jest permutacja podzbiorów odpowiadających 4 odrębnym grupom znaków. Prawdopodobnie pole do poprawy.

Kelly Lowder
źródło
1

C, 306 282 bajtów

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

Wypróbuj online

Nie golfowany:

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++;
    }
}
Johan du Toit
źródło
Dlaczego chciałbyś dokonać wymiany 999 jednym słowem? Czy wiesz, że jedno słowo jednego znaku ma l = -1 i to prawdopodobnie oznacza, że ​​zaczyna robić 999 możliwych zamian za pomocą 1 + rand ()% -1, więc losowo pisz w 2 giga pamięci ... Ale możliwe, widzę to źle ....
RosLuP
Niestety użycie 999 nie ma magii. To tylko 1 bajt mniej niż 1000 :)
Johan du Toit
W gcc wydaje się, że rand ()% (- 1) zwraca 0 za pierwszym razem, gdy go wypróbowałem. więc możliwe brak zamiany losowej przestrzeni 2giga ...% int nie jest% bez znaku ...
RosLuP
@RosLup, przepraszam, ale nie podążam za tym, co mówisz ..
Johan du Toit
1

JavaScript (ES6), 380 327 311 294 bajtów

( 298 282 265 bajtów z wyłączeniem reguł)

Dzięki @Shaggy za przydatne wskazówki!

((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"))

Funkcja f przyjmuje ciąg dowolnego rodzaju (pojedyncze słowo, wiele słów, wiele słów ze znakami - co interpretuje jako podział na słowa), a tablica ciąg „reguł” o dowolnej długości oddzielonych przecinkami.

Taki zestaw reguł byłby w przypadku twojego pytania ["aneusvrowxmcz", "bhkfdl", "gqpy", "it"] "aneusvrowxmcz,bhkfdl,gqpy,it"

Niektóre litery nie mieszają się, nawet jeśli mogłyby, ponieważ w swoim pytaniu stwierdziłeś, że litery „mogą wymieniać spacje”. Jeśli źle go zinterpretowałem, mogę zmienić kod, aby zawsze mieszał litery zgodne z regułami.

Wiem, że to ogromna ilość bajtów i nie będzie w stanie konkurować z językami golfa, ale i tak chciałem spróbować, mam nadzieję, że ci się spodoba :)

Kod nieglikalny czytelny dla człowieka:

((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
źródło
1
Reguły OP muszą być uwzględnione w liczbie bajtów. Przez maja , chciałem mieć szansę .
Adám
1
Witamy w PPCG :) Zdecydowanie możesz z tego dużo grać w golfa .
Kudłaty
1
Chciałem spróbować zagrać w golfa dla ciebie, ale biorąc pod uwagę, jak wiele można z tym zrobić, zabrakło mi czasu, więc zamiast tego wskażę ci tutaj i tutaj, aby pomóc Ci zacząć.
Kudłaty
1
Kilka szybkich wskazówek, choć: 01) Pozbądź się wszystkich vars e lets. 02) O ile nie jest to funkcja rekurencyjna, nie trzeba dołączać deklaracji zmiennej ( f=) do liczby bajtów. 03) Użyj curry, gdy funkcja ma 2 parametry ( b=>d=>zamiast (b,d)=>) i wywołaj swoją funkcję za pomocą f(b)(d). 04) Masz iflagę, więc nie musisz uwzględniać A-Zw wyrażeniu regularnym. 05) Możesz użyć indexOflub searchna łańcuchu, bez dzielenia go na tablicę.
Kudłaty
1
W jaki sposób sugestia 03 ratuje postacie? Wyglądają tak samo dla mnie.
Steve Bennett
0

Clojure, 326 322 324 bajty

Aktualizacja 1: zastąpiona (map(fn[[k v]]...)...)przez(for[[k v]...]...)

Aktualizacja 2: naprawiono wyrażenia regularne, używając \pLzamiast \witp.

#(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+"%)))))

Nie mogę się doczekać, aby zobaczyć coś krótszego. Wcześniejsza wersja bez golfa z kilkoma przykładowymi uruchomieniami:

(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
źródło
Myślę, że trzeba \pL+i \PL+zamiast \w+i \W+wykluczyć cyfry i podkreślenia.
Adám
0

Perl 6 , 241 195 bajtów

Zawiera +1 bajt dla -pprzełącznika wiersza poleceń.

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

Nie golfowany:

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/;
Sean
źródło
Myślę, że musisz (\pL)(\pL+)(\pL)raczej niż (\w)(\w+)(\w)wykluczać cyfry i podkreślenia.
Adám
W rzeczywistości \pLzawiera wiele znaków spoza dozwolonego zakresu liter łacińskich AZ. Zaktualizowałem swój kod, aby dokładniej odzwierciedlał wymagania.
Sean
Które postacie? Pamiętaj, że dane wejściowe są ograniczone do ASCII + Newlines do wydruku.
Adám
Ach, tęskniłem za tym. \pLjest napisane <:L>w Perlu 6.
Sean
0

C #, 438 394 380 374 bajtów

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

Zaoszczędź 10 bajtów dzięki @ MartinEnder ♦.

Irytujące, CaptureCollectionnie wdrażaIEnumerable<T> i dlatego .Cast<Capture>()jest potrzebny. Mam nadzieję, że mogę połączyć zapytanie Linq i foreachpętlę.

Jestem pewien, że jest wiele rzeczy do gry w golfa, ale zajęło mi to wystarczająco dużo czasu, aby uruchomić to ...

Wypróbuj online!

Sformatowana / Pełna wersja:

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