Transposition de Cambridge

21

Je suis sûr que la plupart d'entre vous, sinon tous, sont tombés sur cela à un moment ou à un autre:

Après une recherche à Cmabrigde Uinervtisy, il ne faut pas mttaer dans waht oredr les ltteers dans un wrod sont, l'olny iprmoetnt tihng est taht the frist et lsat ltteer être au rghit pclae. Le rset peut être un mse toatl et vous pouvez le sitall raed wouthit porbelm. Tihs est bcuseae les deos huamn mnid pas raed ervey lteter par istlef, mais le wrod comme un wlohe.

  • Créez un programme qui saisit n'importe quelle quantité de texte. À des fins de test, utilisez la version non brouillée du texte ci-dessus, que vous trouverez ci-dessous.

  • Le programme doit ensuite transposer au hasard les lettres de chaque mot d'une longueur de 4 lettres ou plus, à l'exception de la première et de la dernière lettre de chaque mot.

  • Tous les autres formats doivent rester les mêmes (majuscules et ponctuation, etc.).

Test du texte:

Selon un chercheur de l'Université de Cambridge, peu importe l'ordre dans lequel les lettres d'un mot sont, la seule chose importante est que la première et la dernière lettre soient au bon endroit. Le reste peut être un gâchis total et vous pouvez toujours le lire sans problème. C'est parce que l'esprit humain ne lit pas chaque lettre seule mais le mot dans son ensemble.

Comme d'habitude, c'est un code-golf. Le code le plus court gagne.

jdstankosky
la source
2
Semblable à Comment randomiser des lettres dans un mot , bien que dans celui-ci, un seul mot doive être brouillé alors qu'ici, c'est chaque mot dans une phrase.
Gareth
Je suis d'accord. Les questions sont suffisamment similaires pour que les solutions d'un problème puissent être utilisées presque directement pour l'autre.
primo
1
La dernière lettre n'est pas rscheearchdans votre exemple de texte.
daniero
10
Je serais plus impressionné par un programme qui a fait l'inverse (c'est-à-dire que l'entrée est le texte brouillé).
M. Lister
1
La position de l'apostrophe doit-elle don'trester dans la même position? La spécification dit All other formatting must remain the same (capitalization and punctuation, etc.).mais je ne sais pas comment cela fonctionne ici ...
Gaffi

Réponses:

9

Ruby - 50 48 caractères, plus le -pparamètre de ligne de commande.

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

Merci @primo pour -2 caractères.

Tester

➜  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
la source
1
Ruby ne prend pas en charge l' \Kassertion de recherche de largeur nulle? En outre, le regroupement le plus interne est inutile, en utilisant $&au lieu de $1.
primo
@primo, je ne pense pas, cela ne fonctionne pas, et je ne l'ai pas non plus trouvé dans une page de référence. Merci pour le $&pourboire :)
Dogbert
Tu as raison. Je suppose que j'ai supposé qu'ils avaient pris regex perl directement, comme le fait php;)
primo
3
m'en dire plus sur ce codegolfscript
Sparr
1
De nombreuses années plus tard, mais: Il n'est pas nécessaire de créer un nouveau tableau avant le shuffle: [*$&.chars]=> $&.chars, économisant 3 octets.
daniero
5

Python, 118

Python est terriblement maladroit pour des choses comme ça!

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,

Prime

J'ai essayé d'autres choses que je pensais être intelligentes, mais vous devez importer toutes sortes de choses, et beaucoup de méthodes n'ont pas de valeurs de retour, mais doivent être appelées séparément comme sa propre instruction. Le pire est lorsque vous devez convertir la chaîne en liste, puis la reconvertir en joinchaîne.

Quoi qu'il en soit, voici quelques-unes des choses que j'ai essayées:

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())
Permutations!
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]])),
Vous ne pouvez pas mélanger directement une partition d'une liste et shuffleretourne 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),
daniero
la source
4

PHP 84 octets

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

Utiliser une expression régulière pour capturer des mots d'au moins 4 3 lettres et mélanger les caractères intérieurs. Ce code peut également gérer l'entrée avec plusieurs lignes.

Si une seule ligne d'entrée est requise (comme dans l'exemple), elle peut être réduite à 68 octets

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

Il n'y a qu'une seule lettre au milieu, donc peu importe si vous la mélangez.

primo
la source
3

J (48)

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

Explication:

  • 1!:1[3: lire toutes les entrées de stdin
  • rxapply: applique la fonction donnée aux parties de l'entrée qui correspondent à l'expression régulière
  • ({~?~@#): un train de verbes qui mélange son entrée: #compte la longueur, ceci est appliqué aux deux côtés pour ?donner N nombres distincts de 0 à N, {puis sélectionne les éléments à ces indices dans le tableau d'entrée.
  • ('\w(\w+)\w';,1): utilisez cette expression régulière, mais utilisez uniquement la valeur du premier groupe
  • [1!:2&4: envoyer une sortie non formatée à stdout
  • ''[: supprime la sortie formatée. Ceci est nécessaire car sinon il ne sort que la partie de la sortie qui tient sur une ligne de terminal et se termine ensuite par ....
marinus
la source
3

Rétine , 10 octets

?V`\B\w+\B

Essayez-le en ligne!

Hé, ce vieux défi a été fait pour la nouvelle Retina!

Explication

\B\w+\Bfait correspondre des groupes de lettres entre des non-frontières, c'est-à-dire des groupes de lettres qui ne commencent ni ne terminent un mot. Étant donné que les expressions régulières sont gourmandes, cela correspondra à toutes les lettres d'un mot, sauf la première et la dernière.

Vest l'étape "inverse", qui inverse l'ordre des caractères dans chaque correspondance de l'expression régulière. Avec l' ?option, il les brouille à la place.

Leo
la source
Je suis tombé sur cela après avoir trouvé une autre solution de 10 octets .
FryAmTheEggman
1

APL 107

Malheureusement, mon interprète APL ne prend pas en charge les expressions régulières, voici donc une version roulée à la maison où le texte à brouiller est stocké dans 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]

Essentiellement, le code partitionne le texte en mots basés uniquement sur les lettres de l'alphabet, puis en lettres entre la première et la dernière lettre de ces mots. Ces lettres sont ensuite brouillées et la chaîne de caractères entière réassemblée.

Graham
la source
1

APL, 58 49

Je crois que cela fonctionne dans IBM APL2 (je n'ai pas IBM APL)

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

Sinon, puis dans Dyalog APL, ajoutez à l'avant:

 ⎕ML←3⋄

ce qui ajoute 6 caractères


Cela suppose que les seuls caractères autres que des mots sont l'espace, la virgule et le point.

TwiNight
la source
Toujours jouable au golf, mais je n'ai pas de symboles APL sur 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éthode alternative (plus 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

Ces deux méthodes modifient la valeur de la variable transmise à Sub. c'est à dire

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

produira quelque chose comme ceci:

"Tihs is a tset."

De plus, cela ponctue la ponctuation au milieu du mot, ce qui peut ne pas correspondre à 100% à la spécification.

Gaffi
la source
1

APL NARS 172 caractères

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; Cette fonction g () a une entrée sous forme de chaîne; a une sortie sous forme de chaîne. J'ajoute la commande d'entrée car je ne sais pas comment insérer \ 'dans une chaîne entre guillemets. Commenté

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

résultat

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
la source
1

PHP 7.1, non concurrent, 80 octets

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

prend l'entrée des arguments de la ligne de commande. Courez avec -nr. (échouera évidemment à la ponctuation)

Titus
la source
1

PHP, 94 + 1 octets

+1 pour le -Rdrapeau

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

Entrée de tuyau à travers php -nR '<code>'.

Remarque: preg_replace_callbackest venu à PHP en 4.0.5; des fermetures ont été introduites dans php 5.3;
cela nécessite donc PHP 5.3 ou une version ultérieure.

Malheureusement, la correspondance est toujours envoyée sous forme de tableau, même s'il n'y a pas de sous-modèles,
donc je ne peux pas simplement l'utiliser str_shufflecomme rappel, ce qui économiserait 29 octets.

Titus
la source
1

JavaScript, 76 67 octets

merci à Arnauld pour -9 octets.

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

Essayez-le en ligne!


Non 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
la source
Vous pouvez utiliser /\B\w+\B/g. (Mais pour la prime, notez que la longueur du code n'est pas importante. )
Arnauld
1
@Arnauld merci beaucoup. Comme il s'agit toujours de codegolf, chaque octet compte.
ovs
La règle @Arnauld Serious contender s'applique toujours.
user202729
1
@trejder J'ai ajouté une explication qui devrait vous aider à modifier le code selon vos besoins. Dans sa forme actuelle, le code devrait bien fonctionner dans la plupart des navigateurs. Si vous souhaitez l'utiliser dans du code réel, vous devriez probablement changer la façon dont il mélange les caractères en un algorithme uniforme.
ovs
0

R, 179

En utilisant la fonction que j'ai écrite pour les lettres aléatoires dans un problème de mot :

Contribution:

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

Solution:

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

Résultat:

[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
la source
0

Pyth, 23 octets

jdm?gld4++hd.<Ptd1eddcz

Non concurrent car Pyth a été créé après la publication de ce défi.

Essayez-le en ligne

Downgoat
la source
0

Japt , 32 octets

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

Essayez-le en ligne!

Bejofo
la source
Puis-je exécuter Japt directement dans un navigateur? Sans bibliothèques externes, compilateurs, etc.? Sinon, cela ne compte malheureusement pas selon les règles de prime (besoin d'une solution qui fonctionne dans un navigateur Web pur). Deuxième chose, car je pense que les règles d'origine pour Cambridge Transposition étaient un peu différentes de celles présentées ici (en question OP). Est-il possible de modifier votre code pour brouiller les mots de plus de 5 lettres (au lieu de 4+ lettres, comme dans la question OP)?
trejder
1
@trejder Toutes les soumissions doivent être conformes aux règles de la question d'origine. Le modifier comme ceci le rendrait invalide.
user202729
1
@trejder Japt ne peut pas s'exécuter directement dans un navigateur sans compilateur. Deuxièmement, si vous remplacez le 4 du code par 5, il ne devrait brouiller que les mots longs de 5+ lettres.
Bejofo
0

Java, 1557 834 octets Merci à @JoKing pour des conseils.

Un peu tard pour la compétition. J'ai oublié que j'avais commencé sur ce problème.

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
la source
Il semble qu'il y ait beaucoup d'espace à supprimer. Avez-vous regardé les astuces pour jouer au golf à Java ? edit: vous semblez aussi avoir l'entrée codée en dur. Vous devriez plutôt recevoir les commentaires de l'utilisateur
Jo King
@JoKing ah ok. Je prendrai la contribution de l'utilisateur.
Jaden Lee
J'ai réussi à faire un golf à 650 octets avant de réaliser que cela ne fonctionne pas.
Quintec
@Quintec voulez-vous dire que mon code ne fonctionne pas?
Jaden Lee
0

Sidef , 89 85 octets

Bloquer (appelable anonyme):

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

Sortie, lorsqu'elle est utilisée comme { ... }('..'):

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

Assez peu golfé

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