Trasposizione di Cambridge


21

Sono sicuro che la maggior parte, se non tutti, di voi si sono imbattuti in questo in un punto o nell'altro:

In occasione di una ricerca presso Cmabrigde Uinervtisy, non è in alcun modo in grado di resistere agli altri in un mondo, l'olmo iprmoetnt tihng è il primo e il momento è alla destra. L'rset può essere un toatl ms e puoi farlo alzare da solo. Tihs è perché il huamn mnid deos non ha raccolto Ervey lteter da istlef, ma il wrod come un wlohe.

  • Crea un programma che inserisca qualsiasi quantità di testo. A scopo di test, utilizzare la versione non decodificata del testo sopra riportato, disponibile di seguito.

  • Il programma deve quindi trasporre casualmente le lettere di ogni parola con una lunghezza di 4 o più lettere, tranne la prima e l'ultima lettera di ogni parola.

  • Tutte le altre formattazioni devono rimanere invariate (maiuscole e punteggiatura, ecc.).

Testo di prova:

Secondo un ricercatore dell'Università di Cambridge, non importa in quale ordine siano le lettere in una parola, l'unica cosa importante è che la prima e l'ultima lettera siano nel posto giusto. Il resto può essere un disastro totale e puoi ancora leggerlo senza problemi. Questo perché la mente umana non legge ogni lettera da sola ma la parola nel suo insieme.

Come al solito, questo è un codice-golf. Il codice più corto vince.


2
Simile a Come randomizzare le lettere in una parola , sebbene in quella solo una singola parola debba essere confusa mentre qui ci sono tutte le parole in una frase.
Gareth,

Sono d'accordo. Le domande sono abbastanza simili che le soluzioni per un problema possono essere utilizzate quasi direttamente per l'altro.
primo

1
L'ultima lettera non è rscheearchnel testo di esempio.
daniero,

10
Sarei più colpito da un programma che ha fatto il contrario (ovvero l'input è il testo criptato).
Lister,

1
La posizione dell'apostrofo deve don'trimanere nella stessa posizione? Le specifiche dicono All other formatting must remain the same (capitalization and punctuation, etc.).ma non sono sicuro di come funzioni qui ...
Gaffi,

Risposte:


9

Rubino - 50 48 caratteri, più -pparametro della riga di comando.

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

Grazie @primo per -2 caratteri.

Test

➜  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.

1
Ruby non supporta l' \Kasserzione look-behind a larghezza zero? Inoltre, il raggruppamento più interno non è necessario, usando $&invece di $1.
primo

@primo, penso di no, non funziona e non l'ho trovato in nessuna pagina di riferimento. Grazie per la $&punta :)
Dogbert,

Hai ragione. Immagino di aver supposto che avessero preso direttamente il perge regex, come fa php;)
primo

3
dimmi di più su questa codegolfsceneggiatura
Sparr il

1
Molti anni dopo, ma: Non è necessario creare un nuovo array prima dello shuffle: [*$&.chars]=> $&.chars, salvando 3 byte.
daniero,

5

Python, 118

Python è terribilmente imbarazzante per cose come questa!

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,

indennità

Ho provato alcune altre cose che pensavo fossero intelligenti, ma devi importare ogni sorta di cose, e molti metodi non hanno valori di ritorno, ma devono essere chiamati separatamente come propria dichiarazione. Il peggio è quando è necessario convertire la stringa in un elenco e quindi joinreinserirla in una stringa.

Ad ogni modo, ecco alcune delle cose che ho provato:

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())
Permutazioni!
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]])),
Non puoi mescolare direttamente una partizione di un elenco e shuffletornare None, 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),

4

PHP 84 byte

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

Usare una regex per catturare parole lunghe almeno 4 3 lettere e mescolare i caratteri interni. Questo codice può gestire anche l'input con più righe.

Se è richiesta una sola riga di input (come nell'esempio), questa può essere ridotta a 68 byte

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

C'è solo una lettera nel mezzo, quindi non importa se la mescoli.


3

J (48)

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

Spiegazione:

  • 1!:1[3: leggi tutti gli input da stdin
  • rxapply: applica la funzione data alle porzioni dell'input che corrispondono alla regex
  • ({~?~@#): un treno di verbi che mescola il suo input: #conta la lunghezza, questo viene applicato ad entrambi i lati ?dando N numeri distinti da 0 a N, {quindi seleziona gli elementi in quegli indici dalla matrice di input.
  • ('\w(\w+)\w';,1): usa quel regex ma usa solo il valore del primo gruppo
  • [1!:2&4: invia output non formattato a stdout
  • ''[: elimina l'output formattato. Ciò è necessario perché altrimenti emette solo quella parte dell'uscita che si adatta su una linea terminale e quindi termina con ....

3

Retina , 10 byte

?V`\B\w+\B

Provalo online!

Ehi, questa vecchia sfida è stata fatta per la nuova Retina!

Spiegazione

\B\w+\Bfa corrispondere gruppi di lettere tra non confini, ovvero gruppi di lettere che non iniziano né finiscono una parola. Poiché le regex sono avide, questo corrisponderà a tutte le lettere di una parola tranne la prima e l'ultima.

Vè la fase "inversa", che inverte l'ordine dei personaggi in ogni partita della regex. Con l' ?opzione invece li rimescola.


Mi sono imbattuto in questo dopo aver trovato un'altra soluzione da 10 byte .
FryAmTheEggman,

1

107 APL

Sfortunatamente il mio interprete APL non supporta regexs, quindi ecco una versione home roll in cui il testo da mescolare è memorizzato nella variabile 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]

In sostanza, il codice suddivide il testo in parole basandosi solo sulle lettere dell'alfabeto e quindi nelle lettere tra la prima e l'ultima lettera di quelle parole. Queste lettere vengono quindi rimescolate e l'intera stringa di caratteri riassemblata.


1

APL, 58 49

Credo che funzioni in IBM APL2 (non ho IBM APL)

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

In caso contrario, quindi in Dyalog APL, aggiungi in primo piano:

 ⎕ML←3⋄

che aggiunge 6 caratteri


Ciò presuppone che i soli caratteri non di parole siano spazio, virgola e punto.


Ancora giocabile a golf, ma non ho simboli APL su 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

Metodo alternativo (più grande):

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

Entrambi questi metodi cambiano il valore della variabile passata a Sub. vale a dire

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

produrrà qualcosa del genere:

"Tihs is a tset."

Inoltre, questo rende casuale la punteggiatura a metà parola, quindi potrebbe non adattarsi al 100% delle specifiche.


1

APL NARS 172 caratteri

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←⍞

+ 17 + 13 + 18 + 44 + 41 + 17 + 8 + 5 9 = 172; Questa funzione g () ha input come stringa; ha un output come stringa. Aggiungo il comando di input perché non so come inserire \ 'in una stringa tra virgolette. Commentate

∇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
∇

risultato

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.

1

PHP 7.1, non in competizione, 80 byte

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

accetta input dagli argomenti della riga di comando. Corri con -nr. (ovviamente fallirà alla punteggiatura)


1

PHP, 94 + 1 byte

+1 per la -Rbandiera

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

Ingresso del tubo attraverso php -nR '<code>'.

Nota: preg_replace_callbackarrivato a PHP in 4.0.5; chiusure sono state introdotte in php 5.3;
quindi questo richiede PHP 5.3 o successivo.

Sfortunatamente, la corrispondenza viene sempre inviata come un array, anche se non ci sono sottotitoli,
quindi non posso usare solo str_shufflecome callback, che risparmierebbe 29 byte.


1

JavaScript, 76 67 byte

grazie ad Arnauld per -9 byte.

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

Provalo online!


Ungolfed

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


È possibile utilizzare /\B\w+\B/g. (Ma per la generosità, notalo lunghezza del codice non è importante. )
Arnauld

1
@Arnauld grazie mille. Dato che questo è ancora codegolf, ogni byte conta.
Ovs

@Arnauld Si applica ancora la regola del concorrente serio.
user202729

1
@trejder Ho aggiunto una spiegazione che dovrebbe aiutarti a modificare il codice in base alle tue esigenze. Nella sua forma attuale il codice dovrebbe funzionare bene nella maggior parte dei browser. Se vuoi usarlo in codice reale, dovresti probabilmente cambiare il modo in cui mescola i caratteri in un algoritmo uniforme.
ovs

0

R, 179

Usando la funzione che ho scritto per le lettere casuali in un problema di parola :

Ingresso:

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

Soluzione:

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

Risultato:

[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."

0

Pyth, 23 byte

jdm?gld4++hd.<Ptd1eddcz

Non competitiva perché Pyth è stato realizzato dopo che questa sfida è stata pubblicata.

Provalo online


0

Japt , 32 byte

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

Provalo online!


Posso eseguire Japt direttamente in un browser? Senza librerie esterne, compilatori ecc.? In caso contrario, sfortunatamente questo non conta secondo le regole di ricompensa (è necessaria una soluzione che funzioni nel browser Web puro). In secondo luogo, poiché penso che le regole originali per la trasposizione di Cambridge fossero un po 'diverse da quelle mostrate qui (nella domanda di OP). È possibile modificare il codice per mescolare le parole di almeno 5 lettere (anziché di 4+ lettere, come nella domanda di OP)?
trejder,

1
@trejder Tutti gli invii devono essere conformi alle regole della domanda originale. Modificarlo in questo modo lo renderebbe non valido.
user202729

1
@trejder Japt non può essere eseguito direttamente in un browser senza un compilatore. In secondo luogo, se si sostituisce il 4 nel codice con 5, si dovrebbe solo mescolare parole lunghe più di 5 lettere.
Bejofo,

0

Java, 1557 834 byte Grazie a @JoKing per i suggerimenti.

Un po 'in ritardo per la competizione. Ho dimenticato che avevo iniziato con questo problema.

golfed

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-golfed

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

Sembra che ci sia un sacco di spazio bianco che puoi rimuovere. Hai dato un'occhiata a Suggerimenti per giocare a golf in Java ? modifica: inoltre, sembra che l'input sia codificato. Dovresti invece ricevere input dall'utente
Jo King,

@JoKing ah ok. Prenderò input dall'utente.
Jaden Lee,

Sono riuscito a golf fino a 650 byte prima di rendermi conto che non funziona.
Quintec,

@Quintec vuoi dire che il mio codice non funziona?
Jaden Lee,

0

Sidef , 89 85 byte

Blocco (richiamabile anonimo):

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

Output, se utilizzato come { ... }('..'):

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

Abbastanza ungolfed

.words.map{
  [
    .first,
    (_.len-1
      ? (  [ _[1..^(_.len-1)] ].shuffle..., .last )
      : '')
  ].join
}.join(' ')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.