Revuelva palabras mientras conserva sus contornos


44

Esto es mucho más avanzado que Cómo aleatorizar letras en una palabra y la Transposición de Cambridge debido a la regla sobre qué letras pueden intercambiarse con cuáles. Una expresión regular simple no será suficiente aquí.


Es bien sabido que todavía se puede leer un texto mientras se mezclan las entrañas de sus palabras, siempre que sus primeras y últimas letras más sus contornos generales permanezcan constantes. Dado un texto imprimible Ascii + Newline, codifique cada palabra de acuerdo con estas reglas:

  1. La codificación debe ser (pseudo) aleatoria.

  2. Una palabra es una secuencia de los caracteres latinos, de la A a la Z.

  3. Solo las letras iniciales serán mayúsculas.

  4. La primera y la última letra deben permanecer intactas.

  5. Al codificar, solo las letras dentro de uno de los siguientes grupos pueden intercambiar lugares:

    1. acemnorsuvwxz

    2. bdfhkl

    3. gpqy

    4. it

    5. j (permanece en su lugar)

Ejemplo

Srcmable wrods mientras psrrnveieg su oeiltnus

Es bien sabido que todavía se puede leer un txet mientras los inrands de sus wrods se han movido, siempre y cuando su primer y últimas letras más sus ovaerll ontliues raemin no puedan. Dado un patnirlbe Acsii + Nwnliee txet, samrclbe ecah word anoccdirg a estos relus:

  1. Smncrbliag debe ser (pusedo) rondam.

  2. Un wrod es una secuencia de los chreratacs latinos, A thurogh Z.

  3. Solo los comités iniciales serán respetados.

  4. Las letras fisrt y lsat deben permanecer uctoenhud.

  5. Cuando se detalla, solo las letras con uno de los guorps de Fwllnoiog pueden intercambiar plaecs:

    1. aneusvrowxmcz

    2. bhkfdl

    3. gqpy

    4. it

    5. j (se queda en plcae)

Emxaple


tse supone que es más corto que haunque muchas personas no lo escriben así.
Leaky Nun

@LeakyNun Lo sé, pero ¿sugieres eliminarlo tdel grupo 2? O tal vez poner ten un grupo 4 con i?
Adám

Lo último estaría bien.
Leaky Nun

¿Puede el tiempo de ejecución ser teóricamente ilimitado? (como intentos aleatorios hasta que algo esté bien)
Sarge Borsch

1
printable/ patnirlbeno es del todo legible. Creo que el i/ tswap es el culpable. Hmm ... paintrlbeNo, eso tampoco ayudó. Probablemente sea el pr/ paswap, entonces. El esquema se mantiene, pero creo que leí "pr" y "pa" como semánticamente (?) 1 letra. prtnialbeAh, sí. Eso lo hizo. Sin embargo, no estoy seguro de poder ofrecer una solución al algoritmo.
Draco18s

Respuestas:


9

Jalea , 80 74 bytes

-2 bytes moviéndose de czar + vex + mow + suna czar + vexes + unmown(los repetidos esys nno son un problema)
-1 byte usando en Tịlugar de ȦÐf
-1 byte usando en Œle€Øalugar de i@€ØB>⁵
-2 bytes reconfigurando un poco el diseño

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

Un programa completo que toma una lista de caracteres (o una cadena con formato Python), que imprime el resultado de la codificación.

Pruébalo en línea!

Parece una gran cantidad de dificultad para Jelly (¡o eso o me he perdido un truco, que se sabe que sucede!) Esto seguramente será superado por idiomas con una mejor manipulación de cadenas como Retina (sin funcionalidad aleatoria) o 05ab1e .

¿Cómo?

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

En realidad es más difícil de lo que pensaba.
Leaky Nun

@LeakyNun welp me tomó mucho más de 10 minutos lidiar con eso.
Jonathan Allan

1
@JonathanAllan Sí, ha estado allí por años, y probablemente será parte del próximo lanzamiento, porque esto me ha estado molestando muchas veces.
Martin Ender

1
czar + vex + mow + sun
Adám

3
@ Adám búsquedas de diccionario para formar acemnorsuvwxz. Escribiré código comentado en algún momento también.
Jonathan Allan

5

PHP, 278 bytes

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

Pruébalo en línea!

Expandido

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

funciones

array_combine

array_filter

array_keys

ksort

preg_replace_callback

barajar


Consejo: puede usar la configuración "deshabilitar caché de salida" en TIO, en lugar de ejecutar el código varias veces. Lo acabo de ejecutar con el ejemplo - ¡Todo bien!
Jonathan Allan

@ JonathanAllan Gracias por el consejo con el caché. Ya era bastante difícil encontrar una manera de resolver esto
Jörg Hülsermann

5

Pyth , 79 bytes

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

donde está U + 0018.

Pruébalo en línea!

Muestra

Es bien sabido que un texto todavía se puede radar mientras que los mundos de sus mundos han sido seraclbmd, siempre y cuando sus primeras y últimas letras más sus antojitos ontliues rmeain conntsat. Dado un texto, muestre cada acrncdiog de wrod para ver relus:

  1. Scamrlbing debe ser (puesdo) rnadom.

  2. Una palabra es suqencee de los caracteres latinos, A thuorgh Z.

  3. Solo las letras iaitinl serán siempre una mejora.

  4. La primera y la última letra se quedan sin saber.

  5. Cuando srancblimg, solo las letras con uno de los siguientes guorps pueden generar plecas:

    1. amsuvrcnoxewz

    2. bhfkdl

    3. gpqy

    4. it

    5. j (permanece en su lugar)


¿No puedes ahorrar con en \pLlugar de [A-Za-z]?
Adám

@ Adám ¿Qué es \pL?
Leaky Nun

Cualquier personaje con el P ROPIEDAD de ser un L Etter.
Adám

No creo que funcione aquí ...
Leaky Nun

no \wseria suficiente?
Sarge Borsch

5

JavaScript 176 bytes

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

Método:

  1. RegExp itera sobre el centro de cada palabra ( /\B(\w+)\B/g) usando 1st replace fn.

  2. 1st replace fn itera una matriz de RegExp para cada grupo de letras ( /[bdfkhl/g, /[gqpy]/g, etc..).

  3. Cada iteración crea una matriz temporal de caracteres del centro de palabras que aparecen en el grupo de letras actual.

  4. Cada iteración luego usa RegExp del grupo de letras actual para iterar sobre todo el centro de palabras, usando un segundo reemplazo fn.

  5. 2nd reemplaza fn divide aleatoriamente la matriz temporal, elimina un carácter aleatorio y lo devuelve.

Manifestación:

Ejecútelo en JSFiddle: https://jsfiddle.net/CookieJon/bnpznb7r/


Bienvenido a PPCG. Increíble primera respuesta. Sin embargo, creo que necesita \pL(\pL+)\pLmás que \B(\w+)\Bexcluir dígitos y subrayar.
Adám

¡Ah gracias! Debo admitir que regex no es mi bolso (¡Tengo que buscar la referencia CADA vez que lo uso!) Puedo tragarme los 3 caracteres adicionales ... actualizaré mi respuesta en breve, gracias de nuevo. :-)
Bumpy

1
Increíble primera respuesta! :) Algunas mejoras rápidas para que pueda bajar a 155 bytes, incluida la corrección @ Adáms anterior: t => t.replace (/ \ B [az] + \ B / gi, b => ([/ [acemnorsuvwxz ] / g, / [bdfhkl] / ‌ g, / [gpqy] / g, / [it] / g] ‌ .map (d => b = b.replace (‌ d, c => g. empalme (nueva fecha% g.length, 1), g = b.match (d))), b))
Shaggy

@ Shaggy creo que b=>[...].map(...)&&bahorra otro byte. Además, no estoy seguro de que isea ​​necesario.
Neil

Si @ Adám va a ser estrictamente exigente con la definición de su palabra, entonces deberá usar t.replace(/[A-Za-z]([a-z]+)(?=[a-z])/g,(w,b)=>...w[0]+b...)o algo así.
Neil

2

C, 453, 356369 bytes

#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 con comentarios

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

1

Python 3.6, 349 340 bytes

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)

Sangrado con pestañas. La función se nombra A. No utiliza la fuerza bruta, el tiempo de ejecución es determinista, como preguntó OP.


1

Mathematica 232 Bytes

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

La idea básica es permutar los subconjuntos correspondientes a los 4 grupos de caracteres distintos. Probablemente hay margen de mejora.


1

C, 306 282 Bytes

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

Pruébalo en línea

Sin golf:

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

¿Por qué te gustaría hacer 999 swap en una palabra? ¿Sabes que una palabra de un carácter tiene l = -1 y esto posiblemente significa que comienza a hacer 999 intercambios posibles usando 1 + rand ()% -1, así que escribe al azar en 2 giga de memoria ... Pero es posible que vea está mal ...
RosLuP

Desafortunadamente no hay magia con respecto al uso de 999. Es solo 1 byte menos de 1000 :)
Johan du Toit

En gcc parece rand ()% (- 1) return 0 la primera vez que lo probé. por lo que ningún posible intercambio del espacio 2giga al azar ...% de int no es el% de firmar ...
RosLuP

@RosLup, lo siento pero no sigo lo que dices ..
Johan du Toit

1

JavaScript (ES6), 380 327 311 294 Bytes

( 298 282 265 Bytes excluyendo las reglas)

¡Gracias a @Shaggy por los útiles consejos!

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

La función f toma una cadena de cualquier tipo (una sola palabra, varias palabras, varias palabras con signos, lo que interpreta como separación de palabras) y una matriz de una serie de "reglas" de cualquier longitud separadas por comas.

Ese conjunto de reglas, en el caso de su pregunta, sería ["aneusvrowxmcz", "bhkfdl", "gqpy", "it"] "aneusvrowxmcz,bhkfdl,gqpy,it"

Algunas letras no se mezclan aunque podrían hacerlo, ya que usted indicó en su pregunta que las letras "pueden intercambiar espacios". Si lo interpreté mal, puedo cambiar el código para codificar siempre las letras que coinciden con las reglas.

Sé que esta es una cantidad enorme de bytes y no podrá competir con los idiomas de golf, pero quería probar de todos modos, espero que les guste :)

Código no uglificado legible por humanos:

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

1
Las reglas de OP deben incluirse en el recuento de bytes. Por mayo , quise decir tener la oportunidad de hacerlo .
Adám

1
Bienvenido a PPCG :) Definitivamente puedes jugar mucho golf con esto.
Shaggy

1
Iba a intentar jugar esto para ti, pero, dado lo mucho que se puede hacer con él, se me acabó el tiempo, así que te señalaré aquí y aquí para ayudarte a comenzar.
Shaggy

1
Unos indicadores rápidos, sin embargo: 01) Se puede olvidarse de todo el varS an lets. 02) A menos que sea una función recursiva, no es necesario incluir la declaración de variable ( f=) en el recuento de bytes. 03) Use curry cuando una función tiene 2 parámetros (en b=>d=>lugar de (b,d)=>) y llame a su función con f(b)(d). 04) Tienes la ibandera, así que no necesitas incluirla A-Zen tu expresión regular. 05) Puede usar indexOfo searchen una cadena, sin dividirlo en una matriz.
Shaggy

1
¿Cómo la sugerencia 03 guarda caracteres? Lucen iguales para mi.
Steve Bennett,

0

Clojure, 326 322 324 bytes

Actualización 1: reemplazado (map(fn[[k v]]...)...)por(for[[k v]...]...)

Actualización 2: expresión regular fija, usando en \pLlugar de \wetc.

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

Tengo muchas ganas de ver algo más corto. La versión anterior sin golf con algunos ejemplos se ejecuta:

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

Creo que se necesita \pL+y \PL+en lugar de \w+y \W+para excluir dígitos y subrayado.
Adám

0

Perl 6 , 241 195 bytes

Incluye +1 byte para el -pinterruptor de línea de comandos.

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

Sin golf:

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

Creo que necesita (\pL)(\pL+)(\pL)más que (\w)(\w+)(\w)excluir dígitos y subrayar.
Adám

En realidad, \pLincluye muchos caracteres fuera del rango permitido de letras latinas AZ. He actualizado mi código para reflejar los requisitos con mayor precisión.
Sean

Que personajes Recuerde que la entrada está restringida a ASCII + Newlines imprimibles.
Adám

Ah, me perdí eso. aunque \pLse deletrea <:L>en Perl 6.
Sean

0

C #, 438 394 380 374 bytes

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

Ahorre 10 bytes gracias a @ MartinEnder ♦.

Molesto, CaptureCollectionno se implementaIEnumerable<T> y es por eso que .Cast<Capture>()se necesita. Con suerte, puedo combinar la consulta Linq y el foreachbucle.

Estoy seguro de que hay muchas cosas que se pueden jugar al golf, pero me tomó el tiempo suficiente para que funcione ...

Pruébalo en línea!

Versión formateada / completa:

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();
        }
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.