Transposición de Cambridge

21

Estoy seguro de que la mayoría, si no todos, se han encontrado con esto en algún momento:

En busca de una investigación en Cmabrigde Uinervtisy, no se pierde nada en lo que se refiere a las letras en un mundo, lo único que debe saber es la primera y la última letra. El primer conjunto puede ser una tarea completa y usted puede evaluarlo por completo. Tihs es bcuseae the huamn mnid deos, no crió ervey lteter por istlef, sino el mundo como un wlohe.

  • Cree un programa que ingrese cualquier cantidad de texto. Para fines de prueba, use la versión sin codificar del texto anterior, que se encuentra a continuación.

  • El programa debe transponer aleatoriamente las letras de cada palabra con una longitud de 4 o más letras, excepto la primera y la última letra de cada palabra.

  • El resto del formato debe permanecer igual (mayúsculas y puntuación, etc.).

Texto de prueba:

Según un investigador de la Universidad de Cambridge, no importa en qué orden estén las letras de una palabra, lo único importante es que la primera y la última letra estén en el lugar correcto. El resto puede ser un desastre total y aún puede leerlo sin problemas. Esto se debe a que la mente humana no lee todas las letras por sí misma, sino la palabra en su conjunto.

Como de costumbre, este es un código de golf. El código más corto gana.

jdstankosky
fuente
2
Similar a Cómo aleatorizar letras en una palabra , aunque en esa solo se necesita codificar una sola palabra, mientras que aquí están todas las palabras en una oración.
Gareth
Estoy de acuerdo. Las preguntas son lo suficientemente similares como para que las soluciones para un problema puedan usarse casi directamente para el otro.
primo
1
La última letra no está rscheearchen su texto de muestra.
daniero
10
Estaría más impresionado con un programa que hizo lo contrario (es decir, la entrada es el texto codificado).
Sr. Lister
1
¿Debe la posición del apóstrofe don'tpermanecer en la misma posición? La especificación dice All other formatting must remain the same (capitalization and punctuation, etc.).pero no estoy seguro de cómo funciona aquí ...
Gaffi

Respuestas:

9

Ruby - 50 48 caracteres, más -pparámetro de línea de comando.

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

Gracias @primo por -2 char.

Prueba

➜  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
fuente
1
¿Ruby no es compatible \Kcon la aserción retrospectiva de ancho cero? Además, la agrupación más interna es innecesaria, utilizando en $&lugar de $1.
primo
@primo, creo que no, no funciona, y tampoco lo he encontrado en ninguna página de referencia. Gracias por el $&consejo :)
Dogbert
Tienes razón. Supongo que supuse que habían tomado perl regex directamente, como lo hace php;)
primo
3
cuéntame más sobre este codegolfscript
Sparr
1
Muchos años después, pero: No es necesario crear una nueva matriz antes de la combinación aleatoria: [*$&.chars]=> $&.chars, ahorrando 3 bytes.
daniero
5

Python, 118

¡Python es terriblemente incómodo para cosas como esta!

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,

Prima

Intenté algunas otras cosas que pensé que serían inteligentes, pero tienes que importar todo tipo de cosas, y muchos métodos no tienen valores de retorno, pero deben llamarse por separado como su propia declaración. Lo peor es cuando necesita convertir la cadena en una lista y luego joinvolver a convertirla en una cadena.

De todos modos, estas son algunas de las cosas que probé:

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())
Permutaciones!
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]])),
No puede barajar una partición de una lista directamente y shuffleregresa None, ¡sí!
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
fuente
4

PHP 84 bytes

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

Usando una expresión regular para capturar palabras que tienen al menos 4 3 letras de largo , y barajando los caracteres internos. Este código también puede manejar la entrada con varias líneas.

Si solo se requiere una línea de entrada (como en el ejemplo), esto se puede reducir a 68 bytes

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

Solo hay una letra en el medio, por lo que no importa si la barajas.

primo
fuente
3

J (48)

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

Explicación:

  • 1!:1[3: lee todas las entradas de stdin
  • rxapply: aplica la función dada a las partes de la entrada que coinciden con la expresión regular
  • ({~?~@#): un tren de verbos que baraja su entrada: #cuenta la longitud, esto se aplica a ambos lados de ?dar N números distintos de 0 a N, {luego selecciona los elementos en esos índices de la matriz de entrada.
  • ('\w(\w+)\w';,1): usa esa expresión regular pero solo usa el valor del primer grupo
  • [1!:2&4: envía salida sin formato a stdout
  • ''[: suprime la salida formateada. Esto es necesario porque de lo contrario solo genera esa parte de la salida que se ajusta a una línea de terminal y luego termina con ....
marinus
fuente
3

Retina , 10 bytes

?V`\B\w+\B

Pruébalo en línea!

¡Hola, este viejo desafío se hizo para la nueva Retina!

Explicación

\B\w+\Bhace coincidir grupos de letras entre no límites, es decir, grupos de letras que no comienzan o terminan una palabra. Como las expresiones regulares son codiciosas, esto coincidirá con todas las letras de una palabra, excepto la primera y la última.

Ves la etapa "inversa", que invierte el orden de los caracteres en cada coincidencia de la expresión regular. Con la ?opción, los revuelve en su lugar.

León
fuente
Sucedí esto después de encontrar otra solución de 10 bytes .
FryAmTheEggman
1

APL 107

Lamentablemente, mi intérprete APL no admite expresiones regulares, así que aquí hay una versión casera donde el texto que se va a codificar se almacena en la variable 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]

Esencialmente, el código divide el texto en palabras basadas únicamente en las letras del alfabeto y luego en las letras entre la primera y la última letra de esas palabras. Estas letras se mezclan y se vuelve a ensamblar toda la cadena de caracteres.

Graham
fuente
1

APL, 58 49

Creo que esto funciona en IBM APL2 (no tengo IBM APL)

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

Si no, entonces en Dyalog APL, agregue al frente:

 ⎕ML←3⋄

que agrega 6 caracteres


Esto supone que los únicos caracteres que no son palabras son espacio, coma y punto.

TwiNight
fuente
Todavía golfable, pero no tengo símbolos APL en 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

Método alternativo (más 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

Ambos métodos cambian el valor de la variable pasada a Sub. es decir

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

generará algo como esto:

"Tihs is a tset."

Además, esto aleatoriza la puntuación de mitad de palabra, por lo que puede no ajustarse al 100% de la especificación.

Gaffi
fuente
1

APL NARS 172 caracteres

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; Esta función g () tiene entrada como una cadena; tiene salida como una cadena. Agrego el comando de entrada porque no sé cómo insertar \ 'en una cadena entre comillas. Comentado

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

resultado

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
fuente
1

PHP 7.1, no compite, 80 bytes

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

toma datos de los argumentos de la línea de comandos. Corre con -nr. (obviamente fallará en la puntuación)

Titus
fuente
1

PHP, 94 + 1 bytes

+1 para -Rbandera

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

Entrada de tubería a través php -nR '<code>'.

Nota: preg_replace_callbackllegó a PHP en 4.0.5; los cierres se introdujeron en php 5.3;
entonces esto requiere PHP 5.3 o posterior.

Desafortunadamente, la coincidencia siempre se envía como una matriz, incluso si no hay subpatrones,
por lo tanto , no puedo usarla str_shufflecomo devolución de llamada, lo que ahorraría 29 bytes.

Titus
fuente
1

JavaScript, 76 67 bytes

Gracias a Arnauld por -9 bytes.

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

Pruébalo en línea!


Sin golf

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
fuente
Tenga en cuenta que " barajar haciendo una ordenación como esa no es uniforme "
usuario202729
Puedes usar /\B\w+\B/g. (Pero para la recompensa, tenga en cuenta que la longitud del código no es importante. )
Arnauld
1
@Arnauld muchas gracias. Como esto sigue siendo codegolf, cada byte cuenta.
ovs
@Arnauld Todavía se aplica la regla de contendiente serio.
user202729
1
@trejder Agregué una explicación que debería ayudarte a modificar el código según tus necesidades. En su forma actual, el código debería funcionar bien en la mayoría de los navegadores. Si desea usar esto en código real, probablemente debería cambiar la forma en que baraja los caracteres a un algoritmo uniforme.
ovs
0

R, 179

Usando la función que escribí para aleatorizar letras en un problema de palabras :

Entrada:

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

Solución:

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

Resultado:

[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
fuente
0

Pyth, 23 bytes

jdm?gld4++hd.<Ptd1eddcz

No compite porque Pyth se creó después de que se publicó este desafío.

Pruébalo en línea

Downgoat
fuente
0

Japt , 32 bytes

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

Pruébalo en línea!

Bejofo
fuente
¿Puedo ejecutar Japt directamente en un navegador? ¿Sin bibliotecas externas, compiladores, etc.? Si no, entonces desafortunadamente esto no cuenta según las reglas de recompensa (necesita una solución que funcione en un navegador web puro). En segundo lugar, como creo que las reglas originales para Cambridge Transposition fueron un poco diferentes a las mostradas aquí (en la pregunta OP). ¿Es posible modificar su código para codificar palabras de más de 5 letras (en lugar de más de 4 letras, como en la pregunta de OP)?
trejder
1
@trejder Todos los envíos deben cumplir con las reglas de la pregunta original. Modificarlo de esta manera lo invalidaría.
user202729
1
@trejder Japt no puede ejecutarse directamente en un navegador sin un compilador. En segundo lugar, si reemplaza el 4 en el código con 5, entonces solo debería codificar palabras de más de 5 letras.
Bejofo
0

Java, 1557 834 bytes Gracias a @JoKing por sus consejos.

Un poco tarde para la competencia. Olvidé que había comenzado con este 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;}}

No 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
fuente
Parece que hay mucho espacio en blanco que puedes eliminar. ¿Has echado un vistazo a Consejos para jugar al golf en Java ? editar: también, parece que la entrada está codificada. En su lugar, deberías recibir información del usuario
Jo King,
@JoKing ah ok. Tomaré aportes del usuario.
Jaden Lee
Logré reducir esto a 650 bytes antes de darme cuenta de que no funciona.
Quintec
@Quintec, ¿quieres decir que mi código no funciona?
Jaden Lee
0

Sidef , 89 85 bytes

Bloque (invocable anónimo):

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

Salida, cuando se usa como { ... }('..'):

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

Algo no golfista

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