Transposição de Cambridge

21

Tenho certeza de que a maioria, se não todos, já se deparou com isso em algum momento ou outro:

De acordo com uma pesquisa na Cmabrigde Uinervtisy, não é possível ver o que há em um artigo, o que é mais importante é o primeiro e o último a ser encontrado. O rset pode ser muito simples e você pode usá-lo com um pouco de porbelm. Isso ocorre porque o homem não pode ser perseguido por istlef, mas sim como um mundo inteiro.

  • Crie um programa que insira qualquer quantidade de texto. Para fins de teste, use a versão sem codificação do texto acima, encontrada abaixo.

  • O programa deve então transpor aleatoriamente as letras de cada palavra com um comprimento de 4 ou mais letras, exceto a primeira e a última letra de cada palavra.

  • Todas as outras formatações devem permanecer as mesmas (maiúsculas e pontuação, etc.).

Texto de teste:

Segundo um pesquisador da Universidade de Cambridge, não importa em que ordem as letras de uma palavra são, a única coisa importante é que a primeira e a última letra estejam no lugar certo. O resto pode ser uma bagunça total e você ainda pode lê-lo sem problemas. Isso ocorre porque a mente humana não lê cada letra sozinha, mas a palavra como um todo.

Como sempre, este é um código de golfe. O menor código vence.

jdstankosky
fonte
2
Semelhante a Como aleatorizar letras em uma palavra , embora apenas uma palavra precise ser embaralhada, enquanto aqui está toda palavra em uma frase.
Gareth
Concordo. As perguntas são semelhantes o suficiente para que soluções para um problema possam ser usadas quase diretamente para o outro.
Primo
11
A última letra não está correta no rscheearchtexto de exemplo.
Daniero 20/12/12
10
Eu ficaria mais impressionado com um programa que fez o inverso (ou seja, a entrada é o texto embaralhado).
Lister
11
A posição do apóstrofo deve don'tpermanecer na mesma posição? A especificação diz, All other formatting must remain the same (capitalization and punctuation, etc.).mas não tenho certeza de como isso funciona aqui ...
Gaffi 20/03

Respostas:

9

Ruby - 50 48 caracteres, mais o -pparâmetro da linha de comando.

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

Obrigado @primo por -2 char.

Teste

➜  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
fonte
11
Ruby não suporta \Kasserção look-behind de largura zero? Além disso, o agrupamento mais interno é desnecessário, usando em $&vez de $1.
Primo
@ primo, acho que não, ele não funciona, e nem o encontrei em nenhuma página de referência. Obrigado pela $&dica :)
Dogbert
Você está certo. Eu acho que assumi que eles pegaram o perl regex diretamente, como o php faz;)
primo
3
conte-me mais sobre esse codegolfscript
Sparr 02/02
11
Muitos anos depois, mas: Não há necessidade de criar uma nova matriz antes do shuffle: [*$&.chars]=> $&.chars, economizando 3 bytes.
Daniero 17/07/19
5

Python, 118

Python é terrivelmente estranho para coisas 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,

Bônus

Tentei outras coisas que achei inteligentes, mas você precisa importar todo tipo de coisa e muitos métodos não têm valores de retorno, mas precisam ser chamados separadamente como sua própria declaração. O pior é quando você precisa converter a string em uma lista e depoisjoin voltar a ser uma seqüência de caracteres.

Enfim, aqui estão algumas das coisas que eu tentei:

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())
Permutações!
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]])),
Você não pode embaralhar uma partição de uma lista diretamente e shuffleretornar None, sim!
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
fonte
4

PHP 84 bytes

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

Usando um regex para capturar palavras com pelo menos 4 3 letras e embaralhar os caracteres internos. Esse código também pode manipular a entrada com várias linhas.

Se apenas uma linha de entrada for necessária (como no exemplo), isso poderá ser reduzido para 68 bytes

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

Há apenas uma letra no meio, por isso não importa se você a embaralha.

primo
fonte
3

J (48)

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

Explicação:

  • 1!:1[3: leia todas as entradas do stdin
  • rxapply: aplique a função fornecida às partes da entrada que correspondem à regex
  • ({~?~@#): um trem de verbos que embaralha sua entrada: #conta o comprimento, isso é aplicado aos dois lados da ?atribuição de N números distintos de 0 a N e, em {seguida , seleciona os elementos nesses índices da matriz de entrada.
  • ('\w(\w+)\w';,1): use essa regex, mas use apenas o valor do primeiro grupo
  • [1!:2&4: envia saída não formatada para stdout
  • ''[: suprime a saída formatada. Isso é necessário porque, caso contrário, ele somente envia a parte da saída que cabe em uma linha de terminal e termina com ....
marinus
fonte
3

Retina , 10 bytes

?V`\B\w+\B

Experimente online!

Ei, esse velho desafio foi feito para a nova Retina!

Explicação

\B\w+\Bcorresponde a grupos de letras entre não-limites, ou seja, grupos de letras que não começam nem terminam uma palavra. Como as expressões regulares são gananciosas, isso corresponderá a todas as letras de uma palavra, exceto a primeira e a última.

Vé o estágio "reverso", que reverte a ordem dos caracteres em cada correspondência da regex. Com a ?opção, embaralha-os em seu lugar.

Leo
fonte
Eu me deparei com isso depois de encontrar outra solução de 10 bytes .
FryAmTheEggman 27/10
1

APL 107

Infelizmente, meu intérprete de APL não suporta regexs, então aqui está uma versão inicial onde o texto a ser codificado é armazenado na variável 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]

Essencialmente, o código divide o texto em palavras com base apenas nas letras do alfabeto e depois nas letras entre a primeira e a última letra dessas palavras. Essas letras são embaralhadas e toda a cadeia de caracteres remontada.

Graham
fonte
1

APL, 58 49

Acredito que isso funcione no IBM APL2 (não tenho IBM APL)

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

Caso contrário, no Dyalog APL, adicione à frente:

 ⎕ML←3⋄

que adiciona 6 caracteres


Isso pressupõe que os únicos caracteres que não sejam palavras são espaço, vírgula e ponto.

TwiNight
fonte
Ainda golfable, mas eu não tenho símbolos APL no 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 (maior):

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 os métodos alteram o valor da variável passada para o Sub. ie

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

irá produzir algo como isto:

"Tihs is a tset."

Além disso, isso aleatoriamente a pontuação da metade da palavra, portanto, isso pode não se encaixar na especificação 100%.

Gaffi
fonte
1

APL NARS 172 chars

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 função g () tem entrada como uma string; tem saída como uma sequência. Eu adiciono o comando de entrada porque não sei como inserir \ 'em uma seqüência de caracteres citada. 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
fonte
1

PHP 7.1, não competindo, 80 bytes

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

recebe entrada dos argumentos da linha de comando. Corra com -nr. (obviamente falhará na pontuação)

Titus
fonte
1

PHP, 94 + 1 bytes

+1 para -Rsinalizador

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

Entrada do tubo através php -nR '<code>'.

Nota: preg_replace_callbackchegou ao PHP na versão 4.0.5; encerramentos foram introduzidos no php 5.3;
portanto, isso requer PHP 5.3 ou posterior.

Infelizmente, a correspondência é sempre enviada como uma matriz, mesmo que não haja subpadrões,
portanto , não posso usar apenas str_shufflecomo retorno de chamada, o que economizaria 29 bytes.

Titus
fonte
1

JavaScript, 76 67 bytes

graças a Arnauld por -9 bytes.

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

Experimente 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
ovs
fonte
Você pode usar /\B\w+\B/g. (Mas, para a recompensa, observe que o tamanho do código não é importante. )
Arnauld
11
@ Arnauld muito obrigado. Como ainda é um codegolf, cada byte conta.
ovs 5/08/19
@Arnauld A regra de candidato sério ainda se aplica.
user202729
11
@trejder Adicionei uma explicação que deve ajudá-lo a modificar o código para suas necessidades. Em sua forma atual, o código deve funcionar bem na maioria dos navegadores. Se você deseja usar isso em código real, provavelmente deve alterar a maneira como embaralha os caracteres para um algoritmo uniforme.
ovs
0

R, 179

Usando a função que escrevi para as letras aleatórias em um problema de palavra :

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

Solução:

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
fonte
0

Pitão, 23 bytes

jdm?gld4++hd.<Ptd1eddcz

Não competir porque Pyth foi criado depois que este desafio foi lançado.

Experimente online

Downgoat
fonte
0

Japonês , 32 bytes

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

Experimente online!

Bejofo
fonte
Posso executar o Japt diretamente em um navegador? Sem bibliotecas externas, compiladores, etc.? Caso contrário, infelizmente isso não conta de acordo com as regras de recompensa (precisa de uma solução que funcione em um navegador puro). Segunda coisa, como acho que as regras originais para a transposição de Cambridge eram um pouco diferentes das mostradas aqui (na pergunta do OP). É possível modificar seu código para embaralhar palavras com mais de 5 letras (em vez de mais de 4 letras, como na pergunta do OP)?
Trejder
11
@trejder Todos os envios devem estar de acordo com as regras da pergunta original. Modificá-lo assim tornaria inválido.
user202729
11
@trejder Japt não pode ser executado diretamente em um navegador sem um compilador. Em segundo lugar, se você substituir o 4 no código por 5, ele deverá embaralhar apenas palavras com mais de 5 letras.
Bejofo 7/08/18
0

Java, 1557 834 bytes Obrigado por @JoKing para obter dicas.

Um pouco tarde para a competição. Esqueci que eu tinha começado com este problema.

Golfe

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

Não-golfe

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
fonte
Parece que há muito espaço em branco que você pode remover. Você já deu uma olhada em Dicas para jogar golfe em Java ? edit: também, você parece ter a entrada codificada. Você deve tomar a entrada do usuário em vez
Jo rei
@ JoKing ah ok. Vou receber a entrada do usuário.
Jaden Lee
Eu consegui jogar isso até 650 bytes antes de perceber que não funciona.
Quintec
@Quintec, você quer dizer que meu código não funciona?
Jaden Lee
0

Sidef , 89 85 bytes

Bloco (chamado anônimo):

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

Saída, quando usado como { ... }('..'):

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

Um pouco não-destruído

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