ケンブリッジ転置


21

すべてではないにしても、ほとんどの人が何らかの点でこれ出くわしたと思います。

Cmabrigde UinervtisyのrscheearchへのAoccdrnig、それはwrodのltteersがwordでmttaerであるとは思わない、olny iprmoetnt tihngはrhtit pclaeであります。rsetはtoatl msesである可能性があり、あなたはそれをwouthit porbelmに座っていることができます。Tihsはbcuseaeであり、istlefがervey lteterを支持したのではなく、wloheとしてwrodを食べました。

  • 任意の量のテキストを入力するプログラムを作成します。テストのために、上記のテキストのスクランブルされていないバージョンを使用してください。

  • 次に、プログラムは、各単語の最初と最後の文字を除いて、4文字以上の長さの各単語の文字をランダムに転置する必要があります。

  • 他のすべてのフォーマットは同じままにする必要があります(大文字と句読点など)。

テストテキスト:

ケンブリッジ大学の研究者によると、単語の文字がどのような順序であるかは関係ありません。唯一重要なことは、最初と最後の文字が正しい場所にあることです。残りは完全に混乱する可能性がありますが、問題なく読むことができます。これは、人間の心がすべての文字を読むのではなく、単語全体を読むからです。

いつものように、これはコードゴルフです。最短のコードが優先されます。


2
単語内の文字をランダム化する方法と似ていますが、ここでは1つの単語だけをスクランブルする必要がありますが、ここでは文中のすべての単語です。
ガレス

同意する。質問はよく似ているため、ある問題の解決策を他の問題にほぼ直接使用できます。
primo

1
rscheearchサンプルテキストの最後の文字は正しくありません。
daniero

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*''}

-2文字をありがとう@primo。

テスト

➜  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

@primo、私はそうは思わない、それは機能せず、どのリファレンスページでも見つけられなかった。$&ヒントをお
寄せ

あなたが正しい。私は彼らがPHPのようにperl正規表現を直接取ったと仮定したと思います;)
primo

3
これについての詳細を教えcodegolfスクリプト
SPARR

1
数年後、しかし:shuffle:[*$&.chars]=>の前に新しい配列を作成する必要はありません$&.chars。3バイトを節約します。
daniero

5

Python、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文字の長さの単語をキャプチャ†し、内部文字をシャッフルします。このコードは、複数行の入力も処理できます。

入力の1行のみが必要な場合(例のように)、これを68バイトに減らすことができます。

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

中央に1文字しかないので、シャッフルしても問題ありません。


3

J(48)

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

説明:

  • 1!:1[3:stdinからすべての入力を読み取ります
  • rxapply:指定された関数を、正規表現に一致する入力の部分に適用します
  • ({~?~@#):入力をシャッフルする動詞列:#長さをカウントします。これは?、0からNまでのN個の異なる番号を与える両側に適用さ{れ、入力配列からそれらのインデックスの要素を選択します。
  • ('\w(\w+)\w';,1):その正規表現を使用しますが、最初のグループの値のみを使用します
  • [1!:2&4:フォーマットされていない出力をstdoutに送信します
  • ''[:フォーマットされた出力を抑制します。これが必要なのは、そうでない場合は、出力の中で端末行に収まる部分のみを出力し、で終わるため...です。

3

網膜、10バイト

?V`\B\w+\B

オンラインでお試しください!

ねえ、この古い挑戦は新しい網膜のために作られました!

説明

\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文字を追加します


これは、単語以外の文字のみがスペース、コンマ、およびピリオドであることを前提としています。


それでもgolfable、私は... iPhone上のAPL記号を持っていない
TwiNight

1

VBA、351373 /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_callbackPHPは4.0.5で導入されました。クロージャーはphp 5.3で導入されました。
そのため、PHP 5.3以降が必要です。

残念ながら、サブパターンがない場合でも、一致は常に配列として送信されるため、29バイトを節約する
だけstr_shuffleのコールバックとして使用することはできません。


1

JavaScript、76 67バイト

-9バイトのArnauldに感謝します。

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どうもありがとう。これはまだcodegolfなので、すべてのバイトがカウントされます。
-ovs

@Arnauld重大な競合者ルールは引き続き適用されます。
user202729

1
@trejder必要に応じてコードを変更するのに役立つ説明を追加しました。現在の形式では、コードはほとんどのブラウザーで適切に実行されるはずです。これを実際のコードで使用する場合は、おそらく、文字をシャッフルする方法を統一アルゴリズムに変更する必要があります。
-ovs

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をブラウザーで直接実行できますか?外部ライブラリ、コンパイラなどはありませんか?そうでない場合、残念ながら、これは報奨金規則としてカウントされません(純粋なWebブラウザーで機能するソリューションが必要です)。第二に、ケンブリッジ転置の元のルールはここで示したものとは少し異なっていたと思います(OPの質問で)。コードを変更して、5文字以上の単語をスクランブルすることは可能ですか(OPの質問のように4文字以上の長さの代わりに)?
トレジェ

1
@trejderすべての提出物は、元の質問の規則に準拠する必要があります。このように変更すると、無効になります。
user202729

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

削除できる空白はたくさんあるようです。あなたは見たことがあり、Javaでゴルフのヒントを?編集:また、入力がハードコードされているようです。代わりにユーザーからの入力を取得する必要があります
ジョーキング

@JoKingああ大丈夫。ユーザーからの入力を受け取ります。
ジェイデンリー

うまくいかないことに気づく前に、なんとかこれを650バイトまでゴルフすることができました。
クインテック

@Quintec私のコードが機能しないということですか?
ジェイデンリー

0

Sidef89 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(' ')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.