Кембриджська транспозиція


21

Я впевнений, що більшість із них, якщо не всі, натрапили на це в той чи інший момент:

Aoccdrnig до пошукового пошуку у Cmabrigde Uinervtisy, він не перетворюється в тому, що це є в wrod, але olny iprmoetnt цихng - це frist, а lsat ltteer знаходиться у rghit pclae. Rset може бути тотс-мсес, і ви можете сидіти, якби це було з порбелем. Tihs є bcuseae huamn mnid deos не raed ervey lteter by istlef, а wrod як wlohe.

  • Створіть програму, яка вводить будь-яку кількість тексту. Для тестування використовуйте нешифровану версію вищевказаного тексту, яку ви знайдете нижче.

  • Потім програма повинна випадковим чином перекладати літери кожного слова довжиною 4 або більше літер, крім першої та останньої літери кожного слова.

  • Усі інші формати повинні залишатися однаковими (з великої літери та пунктуації тощо).

Текст тестування:

За словами дослідника Кембриджського університету, не важливо, в якому порядку знаходяться літери в слові, єдине важливе - це те, що перша і остання літера знаходяться в потрібному місці. Решта може бути загальним безладом, і ви все одно можете прочитати це без проблем. Це тому, що людський розум читає не кожну букву сам по собі, а слово в цілому.

Як завжди, це код-гольф. Найкоротший код виграє.


2
Подібно до Як рандомізувати букви в слові , хоча в цьому одному лише одному слові потрібно зашифрувати, тоді як тут це кожне слово в реченні.
Гарет

Я згоден. Питання досить схожі, що рішення однієї проблеми можна використовувати майже безпосередньо для іншої.
примо

1
Останній лист не є правильним rscheearchу вашому прикладі тексту.
daniero

10
Мене більше вразить програма, яка зробила реверс (тобто введення - це скремтований текст).
Містер Лістер

1
Чи повинна позиція апострофа don'tзалишатися в тому ж самому положенні? Специфікація каже, All other formatting must remain the same (capitalization and punctuation, etc.).але я не впевнений, як це відбувається тут ...
Гаффі

Відповіді:


9

Ruby - 50 48 символів плюс -pпараметр командного рядка.

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

Дякую @primo за -2 чару.

Тест

➜  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 не підтримує \Kзастереження нульової ширини? Крім того, найпотужніше групування непотрібне, використовуючи $&замість $1.
примо

@primo, я думаю, що це не працює, і я не знайшов його на жодній довідковій сторінці. Дякую за $&пораду :)
Dogbert

Ти правий. Напевно, я припускав, що вони взяли прямий регекс прямо, як це робить php;)
примі

3
розкажи мені більше про цей codegolfсценарій
Спарр

1
Через багато років, але: Не потрібно створювати новий масив перед перетасуванням: [*$&.chars]=> $&.chars, зберігаючи 3 байти.
daniero

5

Пітона, 118

Python жахливо незручний для таких речей!

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,

Бонус

Я спробував деякі інші речі, які я вважав розумними, але вам доведеться імпортувати всілякі речі, і багато методів не мають повернених значень, але їх потрібно викликати окремо як власне твердження. Найгірше, коли потрібно перетворити рядок у список, а потім joinзнову повернути його до рядка.

У кожному разі, ось що я спробував:

Регекс!
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())
Перестановки!
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]])),
Ви не можете безпосередньо перетасувати розділ списку і shuffleповертається None, так!
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 байти

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

Використовуючи регулярний вираз для зйомки слів, довжиною щонайменше 4 3 літери , і переміщення внутрішніх символів. Цей код також може обробляти введення в декількох рядках.

Якщо потрібен лише один рядок введення (як у прикладі), це може бути зменшено до 68 байт

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

В середині є лише одна літера, тож не має значення, чи перетасуєте її.


3

J (48)

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

Пояснення:

  • 1!:1[3: читати всі дані зі stdin
  • rxapply: застосувати задану функцію до частин вводу, які відповідають регулярному вираженню
  • ({~?~@#): дієслівний потяг, який зміщує свій вхід: #підраховує довжину, це застосовується до обох сторін? даючи N чітких чисел від 0 до N, {а потім вибирає елементи в цих індексах з вхідного масиву.
  • ('\w(\w+)\w';,1): використовувати цей регулярний вираз, але використовувати лише значення з першої групи
  • [1!:2&4: надіслати неформатований вихід до stdout
  • ''[: придушити відформатований вихід. Це необхідно, тому що в іншому випадку він видає лише ту частину виводу, яка вписується в термінальну лінію, а потім закінчується ....

3

Сітківка , 10 байт

?V`\B\w+\B

Спробуйте в Інтернеті!

Гей, цей старий виклик був зроблений для нової Retina!

Пояснення

\B\w+\Bвідповідає групам букв між немежами, тобто групами літер, які не починаються і не закінчуються словом. Оскільки регулярні вирази жадібні, це відповідає всім літерам слова, крім першої та останньої.

V- це "зворотний" етап, який змінює порядок символів у кожній відповідності регулярного вираження. З ?опцією він замість них перебирає.


Я трапився через це, знайшовши ще 10-байтне рішення .
FryAmTheEggman

1

107 APL

На жаль, мій перекладач APL не підтримує регулярні вирази, тому ось домашня версія, де текст, який потрібно скремлювати, зберігається у змінній 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]

По суті код розбиває текст на слова, засновані лише на букви алфавіту, а потім на літери між першою та останньою літерами цих слів. Потім ці листи зашифровуються, а весь рядок символів знову збирається.


1

АПЛ, 58 49

Я вважаю, що це працює в IBM APL2 (у мене немає IBM APL)

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

Якщо ні, то в Dyalog APL додайте на фронт:

 ⎕ML←3⋄

що додає 6 символів


Це передбачає, що єдиними несловними символами є пробіл, кома та період.


Ще пограбає, але у мене немає символів APL на 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

Черговий (більший) метод:

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

Обидва ці способи змінюють значення змінної, переданої на Sub. тобто

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

виведе щось подібне:

"Tihs is a tset."

Крім того, це рандомізує розділові знаки середнього слова, тому це може не відповідати специфікації на 100%.


1

APL NARS 172 символів

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; Ця функція g () має введення як рядок; має вихід у вигляді рядка. Я додаю команду введення, тому що я не знаю, як вставити \ 'у цитований рядок. Прокоментував

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

результат

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, не конкуруючи, 80 байт

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

приймає дані з аргументів командного рядка. Бігайте з -nr. (явно не вдасться в пунктуації)


1

PHP, 94 + 1 байт

+1 для -Rпрапора

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

Вхід труби наскрізь php -nR '<code>'.

Примітка: preg_replace_callbackприйшов до PHP в 4.0.5; закриття були введені в php 5.3;
тому для цього потрібно PHP 5.3 або пізнішої версії.

На жаль, відповідність завжди надсилається як масив, навіть якщо немає підшаблонів,
тому я не можу просто використовувати str_shuffleяк зворотний виклик, який би заощадив 29 байт.


1

JavaScript, 76 67 байт

завдяки Арнольду за -9 байт.

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

Спробуйте в Інтернеті!


Безумовно

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


Можна використовувати /\B\w+\B/g. (Але для баунті зауважте, що довжина коду не важлива. )
Арнольд,

1
@Arnauld велике спасибі Оскільки це все ще кодогольф, кожен байт рахується.
ов

@Arnauld Серйозне правило претендента все ще діє.
користувач202729

1
@trejder Я додав пояснення, яке повинно допомогти вам змінити код для ваших потреб. У своєму нинішньому вигляді код повинен працювати добре в більшості браузерів. Якщо ви хочете використовувати це в реальному коді, вам, мабуть, слід змінити спосіб переміщення символів на єдиний алгоритм.
ов

0

R, 179

Використовуючи функцію, яку я написав для рандомізованих літер у задачі слова :

Вхід:

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

Рішення:

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

Результат:

[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

Japt , 32 байти

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

Спробуйте в Інтернеті!


Чи можна запускати Japt безпосередньо в браузері? Без зовнішніх бібліотек, компіляторів тощо? Якщо ні, то це, на жаль, не враховується за правилами баунті (потрібне рішення, яке працює в чистому веб-браузері). По-друге, як я думаю, оригінальні правила для Кембриджської транспозиції були дещо іншими, ніж показано тут (у питанні про ОП). Чи можна змінити свій код, щоб скремлювати слова завдовжки 5+ літер (замість довгих 4 літер, як у питанні ОП)?
трейдер

1
@trejder Усі матеріали повинні відповідати правилам оригінального питання. Змінивши його таким чином, це зробить його недійсним.
користувач202729

1
@trejder Japt не може працювати безпосередньо у браузері без компілятора. По-друге, якщо ви заміните 4 у коді на 5, тоді він повинен лише зашифрувати 5 літер довгими словами.
Бежофо

0

Java, 1557 834 байти Завдяки @JoKing за поради.

Трохи запізнився на змагання. Забув, що я починав цю проблему.

Гольф

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

Не гольф

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

Схоже, є багато пробілів, які ви можете видалити. Ви переглядали поради щодо гольфу на Яві ? редагувати: також у вас, здається, є вхід жорстко закодований. Натомість ви повинні брати дані від користувача
Jo King

@JoKing ах гаразд. Я візьму дані від користувача.
Яден Лі

Мені вдалося переграти це поле до 650 байт, перш ніж зрозуміти, що це не працює.
Квінтек

@Quintec ти маєш на увазі, що мій код не працює?
Яден Лі

0

Сидеф , 89 85 байт

Блок (анонімний дзвінок):

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

Вихід при використанні { ... }('..'):

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

Дещо незворушний

.words.map{
  [
    .first,
    (_.len-1
      ? (  [ _[1..^(_.len-1)] ].shuffle..., .last )
      : '')
  ].join
}.join(' ')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.