Perebutan kata-kata sambil mempertahankan garis besarnya

44

Ini jauh lebih maju daripada Cara mengacak huruf dalam sebuah kata dan Cambridge Transposition karena aturan tentang huruf mana yang dapat ditukar dengan yang mana. Regex sederhana tidak akan cukup di sini.


Sudah diketahui bahwa teks masih dapat dibaca sementara bagian dalam kata-katanya telah diacak, selama huruf pertama dan terakhir ditambah keseluruhan garis besarnya tetap konstan. Diberikan teks Ascii + Newline yang dapat dicetak, aduk setiap kata sesuai aturan berikut:

  1. Perebutan harus (pseudo) acak.

  2. Kata adalah urutan karakter Latin, A hingga Z.

  3. Hanya huruf awal yang akan menjadi huruf besar.

  4. Huruf pertama dan terakhir harus tetap tidak tersentuh.

  5. Saat berebut, hanya surat dalam salah satu grup berikut yang dapat bertukar tempat:

    1. acemnorsuvwxz

    2. bdfhkl

    3. gpqy

    4. it

    5. j (tetap di tempat)

Contoh

Srcmable wrods sambil psrrnveieg oeiltnus mereka

Sudah diketahui bahwa sebuah txet masih dapat dibaca sementara inrand dari wrodnya telah diacak, selama huruf terakhir dan huruf terakhir mereka ditambah huruf mereka sendiri dan raemin tidak dapat menulis. Diberi hak paten Acsii + Nwnliee txet, samrclbe ecah word anoccdirg untuk relus ini:

  1. Smncrbliag harus (pusedo) rondam.

  2. Wrod adalah seqencue dari chreratacs Latin, A thurogh Z.

  3. Hanya lrtte awal yang akan lebih dulu.

  4. Hak fiskal dan lsat harus tetap uctoenhud.

  5. Saat sarnclbimg, hanya huruf dengan salah satu pengatur fwllnoiog yang dapat menggabungkan plaecs:

    1. aneusvrowxmcz

    2. bhkfdl

    3. gqpy

    4. it

    5. j (tetap di plcae)

Emxaple

Adm
sumber
tseharusnya lebih pendek daripada hmeskipun banyak orang tidak menulisnya.
Leaky Nun
@ LeakyNun saya tahu, tetapi apakah Anda menyarankan untuk menghapus tdari grup 2? Atau mungkin menempatkan tdalam grup 4 dengan i?
Adám
Yang terakhir akan baik-baik saja.
Leaky Nun
dapatkah runtime secara teoritis tidak dibatasi? (seperti percobaan acak sampai ada sesuatu yang benar)
Sarge Borsch
1
printableSaya patnirlbetidak bisa dibaca. Saya pikir i/ tswap yang harus disalahkan. Hmm ... paintrlbeTidak juga tidak membantu. Mungkin itu adalah pr/ paswap. Garis besarnya dipertahankan, tetapi saya pikir saya membaca "pr" dan "pa" secara semantik (?) 1 huruf. prtnialbeAh iya. Itu berhasil. Tidak yakin saya bisa menawarkan perbaikan pada algoritme.
Draco18s

Jawaban:

9

Jelly , 80 74 byte

-2 byte dengan pindah dari czar + vex + mow + sunke czar + vexes + unmown(berulang edan ns bukan masalah)
-1 byte menggunakan Tịdaripada ȦÐf
-1 byte menggunakan Œle€Øadaripada i@€ØB>⁵
-2 byte dengan mengkonfigurasi ulang tata letak sedikit

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

Program lengkap yang mengambil daftar karakter (atau string berformat Python), yang mencetak hasil pengacakan.

Cobalah online!

Sejumlah besar kesulitan untuk Jelly di sini tampaknya (baik itu atau saya telah melewatkan trik, yang telah diketahui terjadi!) Ini pasti akan dikalahkan oleh bahasa dengan manipulasi string yang lebih baik seperti Retina (tanpa fungsi acak) atau 05ab1e .

Bagaimana?

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
sumber
Ini sebenarnya lebih sulit daripada yang saya kira.
Leaky Nun
@ LeakyNun, aku butuh waktu lebih lama dari 10 menit untuk bergulat dengannya.
Jonathan Allan
1
@ JonathanAllan Ya, sudah ada di sana selama berabad-abad, dan mungkin akan menjadi bagian dari rilis berikutnya, karena ini telah menggangguku berkali-kali.
Martin Ender
1
czar + vex + mow + sun
Adám
3
@ Adám lookup kamus untuk membentuk acemnorsuvwxz. Saya akan menulis kode komentar di beberapa titik juga.
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);

Cobalah online!

Diperluas

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

fungsi

array_combine

array_filter

array_keys

ksort

preg_replace_callback

mengocok

Jörg Hülsermann
sumber
Tip: Anda bisa menggunakan pengaturan "disable cache output" pada TIO, daripada menjalankan kode beberapa kali. Saya hanya menjalankannya dengan contoh - Semua baik!
Jonathan Allan
@ JonathanAllan Terima kasih atas tipnya dengan cache. Cukup sulit untuk menemukan cara untuk menyelesaikan ini
Jörg Hülsermann
5

Pyth , 79 byte

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

dimana U + 0018

Cobalah online!

Sampel

Sudah diketahui bahwa sebuah teks masih dapat ditingkatkan sementara iringan dari wrodnya telah seraclbmd, selama lettres pertama dan terakhir mereka ditambah ontliues mereka sendiri ontliues rmeain conntsat. Diberikan teks, sacmrble setiap wrod acrncdiog untuk thsee relus:

  1. Scamrlbing harus (puesdo) rnadom.

  2. Sebuah kata adalah suqencee dari chraectars Latin, A thuorgh Z.

  3. Hanya saja iaitinl lettres yang akan menjadi uppaersce.

  4. Lettres pertama dan terakhir msut tetap diunduh.

  5. Saat srancblimg, hanya lettres wiihtn salah satu dari pengikutnya follnwiog yang dapat mengikutsertakan plecas:

    1. amsuvrcnoxewz

    2. bhfkdl

    3. gpqy

    4. it

    5. j (tetap di tempat)

Biarawati Bocor
sumber
Tidak bisakah Anda menabung dengan \pLbukan [A-Za-z]?
Adám
@ Adám Apa itu \pL?
Leaky Nun
Setiap karakter dengan p Real Property menjadi L Etter.
Adám
Saya tidak berpikir itu bekerja di sini ...
Leaky Nun
tidak \wakan cukup?
Sarge Borsch
5

JavaScript 176 byte

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

Metode:

  1. RegExp mengulangi bagian tengah setiap kata ( /\B(\w+)\B/g) menggunakan ganti 1st fn.

  2. Pengganti pertama fn mengulangi array RegExp untuk setiap grup surat ( /[bdfkhl/g, /[gqpy]/g, etc..).

  3. Setiap iterasi membangun array temp dari karakter pusat kata yang muncul di grup surat saat ini.

  4. Setiap iterasi kemudian menggunakan RegExp grup surat saat ini untuk beralih di seluruh pusat kata, menggunakan fn ganti kedua.

  5. Pengganti kedua fn menyambung secara acak array temp, menghapus karakter acak dan mengembalikannya.

Demo:

Jalankan di JSFiddle: https://jsfiddle.net/CookieJon/bnpznb7r/

Bergelombang
sumber
Selamat datang di PPCG. Jawaban pertama yang luar biasa. Namun, saya pikir Anda perlu \pL(\pL+)\pLdaripada \B(\w+)\Bmengecualikan angka dan garis bawah.
Adám
Ah terima kasih! Harus mengakui regex bukan tas saya (saya harus mencari referensi SETIAP kali saya menggunakannya!) Saya dapat menelan 3 karakter tambahan ... akan memperbarui jawaban saya segera terima kasih lagi. :-)
Bumpy
1
Jawaban pertama yang luar biasa! :) Beberapa perbaikan cepat untuk menurunkan Anda ke 155 byte, termasuk @ Adáms koreksi di atas: t => t.replace (/ \ B [az] + \ B / gi, b => ([/ [acemnorsuvwxz ] / g, / [bdfhkl] / ‌ g, / [gpqy] / g, / [it] / g] map .map (d => b = b.letakkan kembali (‌ d, c => g. sambatan (Tanggal baru% g.length, 1), g = b.match (d))), b))
Shaggy
@ Shaggy Saya pikir b=>[...].map(...)&&bmenyimpan byte lain. Saya juga tidak yakin Anda iperlu.
Neil
Jika @ Adám akan sangat pilih-pilih dengan definisi kata-katanya maka Anda harus menggunakan t.replace(/[A-Za-z]([a-z]+)(?=[a-z])/g,(w,b)=>...w[0]+b...)atau semacamnya.
Neil
2

C, 453, 356 369 byte

#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 dengan komentar

// 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
sumber
1

Python 3.6, 349 340 byte

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)

Diindentasi dengan tab. Fungsi ini dinamai A. Itu tidak menggunakan kekuatan kasar, runtime bersifat deterministik, seperti yang diminta OP.

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

Ide dasarnya adalah untuk mengubah urutan himpunan bagian yang sesuai dengan 4 grup karakter yang berbeda. Mungkin ruang untuk perbaikan.

Kelly Lowder
sumber
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;}}

Cobalah online

Tidak Disatukan:

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
sumber
Mengapa Anda ingin melakukan 999 swap dalam satu kata? Apakah Anda tahu bahwa satu kata dari satu karakter memiliki l = -1 dan ini mungkin berarti bahwa ia mulai melakukan 999 kemungkinan swap menggunakan 1 + rand ()% -1 jadi tulis acak dalam memori 2 giga ... Tetapi mungkin saya melihat salah ....
RosLuP
Sayangnya tidak ada keajaiban tentang penggunaan 999. Hanya 1 byte kurang dari 1000 :)
Johan du Toit
Dalam gcc tampaknya rand ()% (- 1) mengembalikan 0 2 kali pertama saya mencobanya. jadi mungkin tidak ada swap ruang 2giga acak ...% int bukan% dari unsigned ...
RosLuP
@ RosLup, saya minta maaf tapi saya tidak mengikuti apa yang Anda katakan ..
Johan du Toit
1

JavaScript (ES6), 380 327 311 294 Bytes

( 298 282 265 Bytes tidak termasuk aturan)

Terima kasih kepada @Shaggy untuk tips yang bermanfaat!

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

Fungsi f mengambil string apa pun (kata tunggal, banyak kata, banyak kata dengan tanda di dalamnya - yang diartikan sebagai pemecah kata) dan larik string "aturan" dengan panjang apa pun yang dipisahkan oleh koma.

Array aturan itu, dalam kasus pertanyaan Anda, adalah ["aneusvrowxmcz", "bhkfdl", "gqpy", "it"] "aneusvrowxmcz,bhkfdl,gqpy,it"

Beberapa huruf tidak tercampur meskipun mereka bisa, karena Anda menyatakan dalam pertanyaan Anda bahwa huruf "mungkin bertukar ruang". Jika saya salah mengartikannya, saya dapat mengubah kode untuk selalu berebut huruf yang sesuai dengan aturan.

Saya tahu ini adalah jumlah byte yang sangat besar dan tidak akan dapat bersaing dengan bahasa golf, tetapi saya tetap ingin mencobanya, semoga Anda menyukainya :)

Kode tidak terbaca yang dapat dibaca manusia:

((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")
Terima kasih
sumber
1
Aturan OP harus dimasukkan dalam hitungan byte. Dengan Mei , maksudku punya kesempatan untuk .
Adám
1
Selamat datang di PPCG :) Anda pasti bisa bermain golf banyak ini.
Shaggy
1
Saya akan mencoba untuk bermain golf ini untuk Anda, tetapi, mengingat berapa banyak yang bisa dilakukan dengan itu, saya kehabisan waktu jadi saya akan mengarahkan Anda di sini dan di sini untuk membantu Anda memulai.
Shaggy
1
Beberapa petunjuk singkat: 01) Singkirkan semua vars dan lets. 02) Kecuali itu adalah fungsi rekursif, tidak perlu menyertakan deklarasi variabel ( f=) dalam jumlah byte Anda. 03) Gunakan currying ketika suatu fungsi memiliki 2 parameter ( b=>d=>bukan (b,d)=>) dan panggil fungsi Anda dengan f(b)(d). 04) Anda memiliki ibendera sehingga tidak perlu disertakan A-Zdalam regex Anda. 05) Anda bisa menggunakan indexOfatau menggunakan searchstring, tanpa membaginya menjadi sebuah array.
Shaggy
1
Bagaimana saran 03 menyimpan karakter? Mereka terlihat sama bagi saya.
Steve Bennett
0

Clojure, 326 322 324 byte

Pembaruan 1: diganti (map(fn[[k v]]...)...)dengan(for[[k v]...]...)

Pembaruan 2: memperbaiki regex, menggunakan \pLalih-alih \wdll.

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

Saya tak sabar untuk melihat sesuatu yang lebih pendek. Versi ungolfed sebelumnya dengan beberapa contoh berjalan:

(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
sumber
Saya pikir Anda perlu \pL+dan \PL+bukan \w+dan \W+untuk mengecualikan angka dan garis bawah.
Adm
0

Perl 6 , 241 195 byte

Termasuk +1 byte untuk -psakelar baris perintah.

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

Tidak Disatukan:

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
sumber
Saya pikir Anda perlu (\pL)(\pL+)(\pL)daripada (\w)(\w+)(\w)mengecualikan angka dan garis bawah.
Adm
Sebenarnya \pLtermasuk banyak karakter di luar rentang yang diizinkan huruf latin AZ. Saya telah memperbarui kode saya untuk mencerminkan persyaratan dengan lebih akurat.
Sean
Karakter yang mana? Ingatlah bahwa input dibatasi untuk ASCII + Newlines yang dapat dicetak.
Adám
Ah, aku merindukan itu. \pLdieja <:L>dalam Perl 6 sekalipun.
Sean
0

C #, 438 394 380 374 byte

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

Hemat 10 byte berkat @ MartinEnder ♦.

Yang menjengkelkan, CaptureCollectiontidak diterapkanIEnumerable<T> dan itu sebabnya .Cast<Capture>()diperlukan. Semoga, saya bisa menggabungkan permintaan Linq dan foreachloop.

Saya yakin ada banyak yang bisa bermain golf tetapi butuh waktu cukup lama hanya untuk membuatnya bekerja ...

Cobalah online!

Versi yang diformat / Lengkap:

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
sumber