Transposisi Cambridge

21

Saya yakin sebagian besar, jika tidak semua, dari Anda telah menemukan ini di beberapa titik:

Sehubungan dengan penelitian di Cmabrigde Uinervtisy, ia tidak dapat berubah dalam waktu dekat dengan yang lain, yang lebih awal dan lebih baik berada di rghit pclae. Rets dapat menjadi toatl mses dan Anda dapat melihat itu hanya dengan porbelm. Ini adalah karena dewa-dewa hnamn mnid tidak dibagikan oleh istlef, tetapi lebih sebagai wlohe.

  • Buat program yang memasukkan sejumlah teks. Untuk tujuan pengujian, gunakan versi teks di atas yang tidak diacak, ditemukan di bawah.

  • Program kemudian harus secara acak mengubah huruf setiap kata dengan panjang 4 huruf atau lebih, kecuali huruf pertama dan terakhir dari setiap kata.

  • Semua pemformatan lain harus tetap sama (huruf besar dan tanda baca, dll.).

Teks pengujian:

Menurut seorang peneliti di Universitas Cambridge, tidak masalah bagaimana urutan huruf dalam sebuah kata, satu-satunya hal yang penting adalah bahwa huruf pertama dan terakhir berada di tempat yang tepat. Selebihnya bisa berantakan total dan Anda masih bisa membacanya tanpa masalah. Ini karena pikiran manusia tidak membaca setiap huruf dengan sendirinya tetapi kata secara keseluruhan.

Seperti biasa, ini adalah kode-golf. Kode terpendek menang.

jdstankosky
sumber
2
Mirip dengan Cara mengacak huruf dalam sebuah kata , meskipun dalam satu kata itu hanya satu kata perlu diacak sedangkan di sini itu setiap kata dalam sebuah kalimat.
Gareth
Saya setuju. Pertanyaannya cukup mirip sehingga solusi untuk satu masalah dapat digunakan hampir secara langsung untuk yang lain.
Primo
1
Huruf terakhir tidak tepat dalam rscheearchteks sampel Anda.
daniero
10
Saya akan lebih terkesan dengan program yang melakukan sebaliknya (yaitu input adalah teks yang diacak).
Mr Lister
1
Haruskah posisi apostrof don'ttetap berada di posisi yang sama? Spesifikasinya mengatakan All other formatting must remain the same (capitalization and punctuation, etc.).tetapi saya tidak yakin bagaimana cara kerjanya di sini ...
Gaffi

Jawaban:

9

Ruby - 50 48 karakter, plus-p parameter baris perintah.

gsub(/(?<=\w)\w+(?=\w)/){[*$&.chars].shuffle*''}

Terima kasih @rimo untuk -2 char.

Uji

➜  codegolf git:(master) ruby -p 9261-cambridge-transposition.rb < 9261.in
Acdrcinog to a racreseher at Cagribmde Ursvetniiy, it dsoen't mttaer in waht odrer the leertts in a word are, the olny ionarpmtt tnhig is that the fsirt and last letetr be at the rghit pcale. The rset can be a taotl mses and you can slitl raed it wthiuot perlbom. Tihs is buaecse the hmuan mind does not raed ervey lteetr by ietlsf but the word as a wlhoe.
Dogbert
sumber
1
Ruby tidak mendukung \Kuntuk pernyataan selebar nol lebar? Juga, pengelompokan terdalam tidak perlu, menggunakan $&bukan $1.
primo
@ primo, saya pikir tidak, itu tidak berfungsi, dan saya belum menemukannya di halaman referensi. Terima kasih untuk$& tipnya :)
Dogbert
Kamu benar. Saya kira saya berasumsi mereka telah mengambil perl regex secara langsung, seperti php;)
primo
3
ceritakan lebih banyak tentang ini codegolf skrip
Sparr
1
Bertahun-tahun kemudian, tetapi: Tidak perlu membuat array baru sebelum shuffle: [*$&.chars] => $&.chars, menghemat 3 byte.
daniero
5

Python, 118

Python sangat canggung untuk hal-hal seperti ini!

from random import*
for w in raw_input().split():l=len(w)-2;print l>0and w[0]+''.join((sample(w[1:-1],l)))+w[-1]or w,

Bonus

Saya mencoba beberapa hal lain yang saya pikir akan pintar, tetapi Anda harus mengimpor segala macam hal, dan banyak metode tidak memiliki nilai pengembalian, tetapi perlu dipanggil secara terpisah sebagai pernyataannya sendiri. Yang terburuk adalah ketika Anda perlu mengubah string ke daftar dan kemudian joinmemasukkannya kembali ke string.

Bagaimanapun, berikut adalah beberapa hal yang saya coba:

Regex!
import re,random
def f(x):a,b,c=x.group(1,2,3);return a+''.join(random.sample(b,len(b)))+c
print re.sub('(\w)(\w+)(\w)',f,raw_input())
Permutasi!
import itertools as i,random as r
for w in raw_input().split():print''.join(r.choice([x for x in i.permutations(w)if w[0]+w[-1]==x[0]+x[-1]])),
Anda tidak dapat mengocok partisi daftar secara langsung dan shufflekembaliNone , yay!
from random import*
for w in raw_input().split():
 w=list(w)
 if len(w)>3:v=w[1:-1];shuffle(v);w[1:-1]=v
 print ''.join(w),
daniero
sumber
4

PHP 84 byte

<?for(;$s=fgets(STDIN);)echo preg_filter('/\w\K\w+(?=\w)/e','str_shuffle("\0")',$s);

Menggunakan regex untuk menangkap kata yang setidaknya 4 panjangnya 3 huruf , dan mengocok karakter dalam. Kode ini dapat menangani input dengan banyak baris juga.

Jika hanya satu jalur input yang diperlukan (seperti pada contoh), ini dapat dikurangi menjadi 68 byte

<?=preg_filter('/\w\K\w+(?=\w)/e','str_shuffle("\0")',fgets(STDIN));

Hanya ada satu huruf di tengah, jadi tidak masalah jika kamu mengocoknya.

primo
sumber
3

J (48)

''[1!:2&4('\w(\w+)\w';,1)({~?~@#)rxapply 1!:1[3

Penjelasan:

  • 1!:1[3: baca semua input dari stdin
  • rxapply: menerapkan fungsi yang diberikan ke bagian input yang cocok dengan regex
  • ({~?~@#): kereta kata kerja yang mengocok inputnya: #menghitung panjangnya, ini diterapkan pada kedua sisi untuk ?memberikan N angka yang berbeda dari 0 hingga N, {lalu memilih elemen pada indeks tersebut dari array input.
  • ('\w(\w+)\w';,1): gunakan regex itu tetapi hanya gunakan nilai dari grup pertama
  • [1!:2&4: kirim keluaran yang belum diformat ke stdout
  • ''[: menekan output yang diformat. Hal ini diperlukan karena jika tidak, hanya output bagian dari output yang sesuai pada jalur terminal dan kemudian berakhir dengan ....
marinus
sumber
3

Retina , 10 byte

?V`\B\w+\B

Cobalah online!

Hei, tantangan lama ini dibuat untuk Retina baru!

Penjelasan

\B\w+\Bcocok dengan kelompok huruf antara non-batas, yaitu kelompok huruf yang tidak memulai atau mengakhiri kata. Karena regex serakah, ini akan cocok dengan semua huruf kata kecuali yang pertama dan yang terakhir.

Vadalah tahap "terbalik", yang membalik urutan karakter di setiap pertandingan regex. Dengan ?opsi itu malah mengacak mereka.

Leo
sumber
Saya kebetulan menemukan ini setelah menemukan solusi 10-byte lain .
FryAmTheEggman
1

APL 107

Sayangnya penerjemah APL saya tidak mendukung regex jadi di sini adalah versi rumah digulung di mana teks yang akan diacak disimpan dalam variabel t:

⎕av[((~z)\(∊y)[∊(+\0,¯1↓n)+¨n?¨n←⍴¨y←(~z←×(~x)+(x>¯1↓0,x)+x>1↓(x←~53≤(∊(⊂⍳26)+¨65 97)⍳v←⎕av⍳,t),0)⊂v])+z×v]

Pada dasarnya kode mempartisi teks menjadi kata-kata berdasarkan huruf-huruf alfabet saja dan kemudian menjadi huruf-huruf antara huruf pertama dan terakhir dari kata-kata itu. Huruf-huruf ini kemudian diacak dan seluruh rangkaian karakter disusun kembali.

Graham
sumber
1

APL, 58 49

Saya percaya ini bekerja di IBM APL2 (Saya tidak punya IBM APL)

({⍵[⌽∪t,⌽∪1,?⍨t←⍴⍵]}¨x⊂⍨~b),.,x⊂⍨b←' ,.'∊⍨x←⍞,' '

Jika tidak, maka di Dyalog APL, tambahkan ke depan:

 ⎕ML←3⋄

yang menambahkan 6 karakter


Ini mengasumsikan satu-satunya karakter non-kata adalah spasi, koma, dan titik.

TwiNight
sumber
Masih bisa golf, tapi saya tidak punya simbol APL di iPhone ...
TwiNight
1

VBA, 351 373 /409

Sub v(g)
m=1:Z=Split(g," "):j=UBound(Z)
For u=0 To j
t=Z(u):w=Len(t):l=Right(t,1):If Not l Like"[A-Za-z]" Then w=w-1:t=Left(t,w):e=l Else e=""
If w>3 Then
n=Left(t,1):p=w-1:s=Right(t,p):f=Right(t,1)
For p=1 To p-1
q=w-p:r=Int((q-1)*Rnd())+1:n=n & Mid(s,r,1):s=Left(s,r-1) & Right(s,q-r)
Next
Else
n=t:f=""
End If
d=d & n & f & e & " "
Next
g=d
End Sub

Metode Alternatif (lebih besar):

Sub v(g)
m=1:Z=Split(g," "):j=UBound(Z)
For u=0 To j
t=Split(StrConv(Z(u),64),Chr(0)):w=UBound(t)-1:l=Asc(t(w)):If l<64 Or (l>90 And l<97) Or l>122 Then e=t(w):w=w-1 Else e=""
If w>3 Then
n=t(0):p=w-1:s=""
For i=-p To -1
s=t(-i) & s
Next
f=t(w)
For p=1 To p-1
r=Int((w-p)*Rnd())+1:n=n & Mid(s,r,1):s=Left(s,r-1) & Right(s,w-p-r)
Next
n=n & s
Else
n=Z(u):f="":e=""
End If
d=d & n & f & e & " "
Next
g=d
End Sub

Kedua metode ini mengubah nilai variabel yang diteruskan ke Sub. yaitu

Sub Test()
strTestString = "This is a test."
v strTestString
Debug.Print strTestString
End Sub

akan menampilkan sesuatu seperti ini:

"Tihs is a tset."

Juga, ini tidak mengacak tanda baca tengah kata, jadi ini mungkin tidak sesuai dengan spesifikasi 100%.

Gaffi
sumber
1

APL NARS 172 karakter

r←g x;i;s;d;k
s←⎕AV[98..123]∪⎕A
i←1⋄v←''⋄r←''⋄k←⍴x
A:d←''⋄→C×⍳i>k⋄d←x[i]⋄→C×⍳∼d∊s⋄v←v,d⋄i+←1⋄→A
C:v←{t←¯2+⍴r←⍵⋄t≤1:r⋄r[1+t?t]←⍵[1+⍳t]⋄r}v
r←∊r,v,d
v←''⋄i+←1⋄→A×⍳i≤k
g x←⍞

13 + 17 + 18 + 44 + 41 + 8 + 17 + 5 + 9 = 172; Fungsi ini g () memiliki input sebagai string; memiliki output sebagai string. Saya menambahkan perintah input karena saya tidak tahu bagaimana memasukkan \ 'dalam string yang dikutip. Berkomentar

∇r←g x;i;s;d;k
   ⍝ words are element of  a-zA-Z separed from all other
   s←⎕AV[98..123]∪⎕A ⍝a-zA-Z ascii ⎕IO = 1
   i←1⋄v←''⋄r←''⋄k←⍴x
A:   d←''⋄→C×⍳i>k⋄d←x[i]⋄→C×⍳∼d∊s⋄v←v,d⋄i+←1⋄→A
C:      v←{t←¯2+⍴r←⍵⋄t≤1:r⋄r[1+t?t]←⍵[1+⍳t]⋄r}v
        r←∊r,v,d
        v←''⋄i+←1⋄→A×⍳i≤k
∇

hasil

g x←⍞
According to a researcher at Cambridge University, it doesn't matter in what order the letters in a word are, the only important thing is that the first and last letter be at the right place. The rest can be a total mess and you can still read it without problem. This is because the human mind does not read every letter by itself but the word as a whole.
  Androiccg to a rhraeecser at Cgirbdmae Uirevtsiny, it deson't mtetar in waht oderr the ltrtees in a wrod are, the olny intro
  apmt tinhg is taht the frsit and lsat lteter be at the rghit pacle. The rset can be a ttaol mses and you can siltl rae
  d it wtuhoit poeblrm. Tihs is bcsauee the hmaun mnid deos not raed eervy lteter by isletf but the wrod as a wolhe.
RosLuP
sumber
1

PHP 7.1, tidak bersaing, 80 byte

for(;$w=$argv[++$i];)echo$w[3]?$w[0].str_shuffle(substr($w,1,-1)).$w[-1]:$w," ";

mengambil input dari argumen baris perintah. Jalankan dengan -nr. (jelas akan gagal pada tanda baca)

Titus
sumber
1

PHP, 94 +1 byte

+1 untuk -Rbendera

<?=preg_replace_callback("/(?<=\w)\w+(?=\w)/",function($m){return str_shuffle($m[0]);},$argn);

Masukan pipa melalui php -nR '<code>'.

Catatan: preg_replace_callbackdatang ke PHP dalam 4.0.5; penutupan diperkenalkan di php 5.3;
jadi ini membutuhkan PHP 5.3 atau yang lebih baru.

Sayangnya, pertandingan selalu dikirim sebagai array, bahkan jika tidak ada sub pola,
jadi saya tidak bisa hanya menggunakan str_shufflepanggilan balik, yang akan menghemat 29 byte.

Titus
sumber
1

JavaScript, 76 67 byte

terima kasih kepada Arnauld untuk -9 byte.

t=>t.replace(/\B\w+\B/g,m=>[...m].sort(_=>Math.random()-.5).join``)

Cobalah online!


Tidak disatukan

t =>                  // function with a single argument
     t.replace(       // Replace ...
         /\B\w+\B/g,  // every match of the regex
         m => ...     // with the return value of the replacement function
     )

/       /g            // Match all occurences of
   \w+                // 1 or more word chars ...
 \B   \B              // ... that aren't on the beginning or end of the word

m =>                  // Replacement function
     [...m]           // convert matched string to a list of chars
       .sort(_ => Math.random()-.5) // sort with a random comparision function
       .join``        // join the list into a single string
ovs
sumber
Anda bisa menggunakannya /\B\w+\B/g. (Tapi untuk hadiahnya, perhatikan bahwa panjang kode tidak penting. )
Arnauld
1
@Arnauld terima kasih banyak. Karena ini masih codegolf, setiap byte penting.
Ovs
@Arnauld Aturan pesaing serius masih berlaku.
user202729
1
@trejder Saya menambahkan penjelasan yang akan membantu Anda mengubah kode untuk kebutuhan Anda. Dalam bentuknya yang sekarang, kode harus berjalan dengan baik di sebagian besar browser. Jika Anda ingin menggunakan ini dalam kode nyata, Anda mungkin harus mengubah cara mengocok karakter ke algoritma yang seragam.
Ovs
0

R, 179

Menggunakan fungsi yang saya tulis untuk huruf acak dalam masalah kata :

Memasukkan:

s <- "According to a researcher at Cambridge University, it doesn't matter in what order the letters in a word are, the only important thing is that the first and last letter be at the right place. The rest can be a total mess and you can still read it without problem. This is because the human mind does not read every letter by itself but the word as a whole."

Larutan:

f=function(w){l=length;s=strsplit(w,"")[[1]];ifelse(l(s)<3,w,paste(c(s[1],sample(s[2:(l(s)-1)]),s[l(s)]),collapse=""))}
g=Vectorize(f)
paste(g(strsplit(s," ")[[1]]), collapse=" ")

Hasil:

[1] "Arioccdng to a reehaecrsr at Cabrgimde Uveirisnyt, it des'not mttear in waht odrer the lttrees in a wrod are, the olny inpotmart thnig is that the fsrit and lsat letetr be at the right palce. The rset can be a toatl mses and you can stlil raed it wutioht pmrlebo. This is bsuceae the hmuan mnid deos not read ervey lteetr by iesltf but the word as a wleho."
Paolo
sumber
0

Pyth, 23 byte

jdm?gld4++hd.<Ptd1eddcz

Non-bersaing karena Pyth dibuat setelah tantangan ini diposting.

Cobalah online

Downgoat
sumber
0

Japt , 32 byte

m@Xl ¨4?Xg0 +Xs1J ö(x) +XgJ:X}" 

Cobalah online!

Bejofo
sumber
Bisakah saya menjalankan Japt langsung di browser? Tanpa perpustakaan eksternal, kompiler dll? Jika tidak maka ini sayangnya tidak dihitung sesuai aturan hadiah (butuh solusi yang bekerja di browser web murni). Hal kedua, karena saya pikir aturan asli untuk Cambridge Transposition sedikit berbeda dari yang ditunjukkan di sini (dalam pertanyaan OP). Apakah mungkin untuk mengubah kode Anda untuk mengacak kata-kata yang panjangnya 5+ huruf (alih-alih panjangnya 4+ huruf, seperti dalam pertanyaan OP)?
trejder
1
@trejder Semua kiriman harus sesuai dengan aturan dalam pertanyaan awal. Memodifikasi seperti ini akan membuatnya tidak valid.
user202729
1
@trejder Japt tidak dapat berjalan langsung di browser tanpa kompiler. Kedua, jika Anda mengganti 4 dalam kode dengan 5, maka kata itu seharusnya hanya terdiri dari 5+ huruf.
Bejofo
0

Java, 1557 834 byte Berkat @ JoKing untuk tip.

Agak terlambat untuk kompetisi. Lupa bahwa saya sudah mulai dengan masalah ini.

Golf

import java.util.*;public class s{ public static void main(String[] args){ Scanner s=new Scanner(System.in);String a=s.next();String[] q=a.split("\\s+");for (int i=0;i<q.length;i++) { q[i]=q[i].replaceAll("[^\\w]", ""); }String f="";for (String z:q) { f+=scramble(z);f+=" "; }System.out.print(f); }private static String scramble(String w){if(w.length()==1||w.length()==2){return w;}char[]l=w.toCharArray();char q=l[w.length()-1];String e=Character.toString(l[0]);char[]n=new char[l.length-2];for(int i=0;i<l.length-2;i++){n[i]=l[i+1];}HashMap<Integer,Character>s=new HashMap<>();int c=1;for(char p:n){s.put(c,p);c++;}HashMap<Integer,Integer>o=new HashMap<>();Random z=new Random();for(int i=0;i<w.length()-2;i++){int m=z.nextInt(n.length);while(o.getOrDefault(m,0) == 1){m=z.nextInt(n.length);}e+=s.get(m+1);o.put(m,1);}return e+=q;}}

Non-golf

import java.util.HashMap;
import java.util.Random;

public class SentenceTransposition {
    public static void main(String[] args) {
        String input = "According to a researcher at Cambridge University, it doesn't matter in what order the letters in a word are, the only important thing is that the first and last letter be at the right place. The rest can be a total mess and you can still read it without problem. This is because the human mind does not read every letter by itself but the word as a whole.";
        String[] words = input.split("\\s+");
        for (int i = 0; i < words.length; i++) {
            words[i] = words[i].replaceAll("[^\\w]", "");
        }
        String finalsentence = "";
        for (String word : words) {
            finalsentence += scramble(word);
            finalsentence += " ";
        }
        System.out.println(finalsentence);
    }

    private static String scramble(String word) {
        if (word.length() == 1 || word.length() == 2) {
            return word;
        }
        char[] letters = word.toCharArray();
        char lletter = letters[word.length()-1];
        String endword = Character.toString(letters[0]);
        char[] nletters = new char[letters.length-2];
        for (int i = 0; i < letters.length-2; i++) {
            nletters[i] = letters[i+1];
        }
        HashMap<Integer, Character> set = new HashMap<>();
        int count = 1;
        for (char nletter : nletters) {
            set.put(count, nletter);
            count++;
        }
        HashMap<Integer, Integer> chosen = new HashMap<>();
        Random random = new Random();
        for (int i = 0; i < word.length()-2; i++) {
            int cur = random.nextInt(nletters.length);
            while (chosen.getOrDefault(cur,0) == 1) {
                cur = random.nextInt(nletters.length);
            }
            endword += set.get(cur+1);
            chosen.put(cur, 1);
        }
        return endword += lletter;
    }
}
Jaden Lee
sumber
Sepertinya ada banyak ruang kosong yang bisa Anda hapus. Pernahkah Anda melihat Tips untuk bermain golf di Jawa ? sunting: juga, Anda sepertinya memiliki input kode-keras. Anda seharusnya mengambil input dari pengguna
Jo King
@ Bersenang-senang ah ok. Saya akan mengambil input dari pengguna.
Jaden Lee
Saya berhasil menurunkan ini ke 650 byte sebelum menyadari bahwa itu tidak berhasil.
Quintec
@ Quintec maksud Anda bahwa kode saya tidak berfungsi?
Jaden Lee
0

Sidef , 89 85 byte

Blokir (panggilan anonim):

{.words.map{[_[0],(_.len-1?([_[1..^(_.len-1)]].shuffle...,_[1]):'')].join}.join(' ')}

Output, ketika digunakan seperti { ... }('..'):

 I hvae nveer not ocne in my life slleepd nhedatarnel crtreolcy
 I have never not once in my lfie sepelld naetadenrhl ccrtloery

Agak tidak serigala

.words.map{
  [
    .first,
    (_.len-1
      ? (  [ _[1..^(_.len-1)] ].shuffle..., .last )
      : '')
  ].join
}.join(' ')
kucing
sumber