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


21

Я уверен, что большинство, если не все, сталкивались с этим в тот или иной момент:

Приезжая на поиски в Cmabrigde Uinervtisy, он не имеет ничего общего с тем, какой он есть, и который находится на первом месте. Rset может быть очень полезен, и вы можете читать его без изменений. Это слово не только не из-за истерики, но и изредка.

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

  • Затем программа должна случайным образом транспонировать буквы каждого слова длиной 4 или более букв, кроме первой и последней буквы каждого слова.

  • Все остальные форматы должны оставаться неизменными (использование заглавных букв и знаков препинания и т. Д.).

Тестовый текст:

По словам исследователя из Кембриджского университета, не имеет значения, в каком порядке располагаются буквы в слове, важно только, чтобы первая и последняя буквы были в нужном месте. Остальное может быть полным беспорядком, и вы все равно можете прочитать его без проблем. Это потому, что человеческий разум читает не каждую букву отдельно, а слово в целом.

Как обычно, это код-гольф. Самый короткий код выигрывает.


2
Похоже на то, как рандомизировать буквы в слове , хотя в этом случае нужно закодировать только одно слово, тогда как здесь каждое слово в предложении.
Гарет

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

1
Последнее письмо не вписывается rscheearchв ваш образец текста.
Даньеро

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

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

Ответы:


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, я думаю, что нет, это не работает, и я не нашел его ни на одной справочной странице. Спасибо за $&совет :)
Догберт

Вы правы. Я предполагаю, что предположил, что они приняли регулярное выражение perl, как и php;)
primo

3
расскажите мне больше об этом codegolfсценарии
Sparr

1
Спустя много лет, но: нет необходимости создавать новый массив перед shuffle: [*$&.chars]=> $&.chars, сохраняя 3 байта.
Даниеро

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вставить ее в строку.

В любом случае, вот некоторые из вещей, которые я пробовал:

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())
Перестановки!
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: отправить неформатированный вывод на стандартный вывод
  • ''[: подавить форматированный вывод. Это необходимо, потому что в противном случае он выводит только ту часть вывода, которая умещается на терминальной линии, а затем заканчивается на ....

3

Сетчатка , 10 байт

?V`\B\w+\B

Попробуйте онлайн!

Эй, этот старый вызов был сделан для новой Retina!

объяснение

\B\w+\Bсопоставляет группы букв между неограницами, то есть группы букв, которые не начинаются и не заканчивают слово. Поскольку регулярные выражения являются жадными, это будет соответствовать всем буквам слова, кроме первой и последней.

Vявляется «обратной» стадией, которая меняет порядок символов в каждом совпадении регулярного выражения. С ?опцией он шифрует их вместо этого.


Я столкнулся с этим после нахождения другого 10-байтового решения .
FryAmTheEggman

1

APL 107

К сожалению, мой интерпретатор 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

APL, 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``)

Попробуйте онлайн!


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


Вы можете использовать /\B\w+\B/g. (Но для награды обратите внимание, что длина кода не важна. )
Арно

1
@ Arnauld большое спасибо. Поскольку это все еще codegolf, каждый байт считается.
овс

@Arnauld Серьезное правило претендента все еще применяется.
user202729

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 прямо в браузере? Без каких-либо внешних библиотек, компиляторов и т. Д.? Если нет, то это, к сожалению, не считается согласно правилам вознаграждения (нужно решение, которое работает в чистом веб-браузере). Во-вторых, я думаю, что первоначальные правила для Кембриджского Транспонирования немного отличались от показанных здесь (в вопросе OP). Можно ли изменить код так, чтобы он шифровал слова длиной 5+ букв (вместо 4+ букв, как в вопросе OP)?
Трейдер

1
@trejder Все материалы должны соответствовать правилам исходного вопроса. Изменение его таким образом сделает его недействительным.
user202729

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

0

Java, 1557 834 байта Спасибо @JoKing за советы.

Немного опоздал на соревнования. Забыл, что я начал с этой проблемы.

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

Похоже, есть много пробелов, которые вы можете удалить. Вы смотрели на Советы для игры в гольф на Яве ? edit: также у вас, кажется, жестко запрограммирован ввод. Вместо этого вы должны получать информацию от пользователя
Джо Кинг,

@ Шучу ах хорошо. Я приму ввод от пользователя.
Джейден Ли

Мне удалось увеличить это до 650 байт, прежде чем я понял, что это не работает.
Quintec

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