元の番号(II)


18

この課題は基本的にこれと同じですが、文字列のどこでも文字をシャッフルできるようになりました。

シナリオ

ジョンには重要な数があり、他の人に見られたくない。

彼は、次の手順を使用して番号を暗号化することにしました。

彼の番号は常に非減少列である(すなわち。"1123"

彼は各桁を英語の単語に変換しました。(つまり"123" -> "ONETWOTHREE"

そして、文字をランダムに並べ替えます。(つまり"ONETWOTHREE" -> "EEWOOHRNTET"

ジョンはそうすることで彼の番号が安全であると感じました。実際、このような暗号化は簡単に解読できます:(


仕事

暗号化された文字列sが与えられたら、あなたの仕事はそれを解読して元の番号を返すことです。


ルール

  • これはコードゴルフであるため、バイト単位の最短回答が優先されます
  • 入力文字列は常に有効であると仮定できます
  • 入力文字列には大文字のみが含まれています
  • 元の番号は常に昇順で配置されます
  • 文字列または整数形式で数値を返すことができます
  • 文字は、文字列全体ではなく、1つの単語間でのみシャッフルされます。文字は、文字列のどこでもシャッフルできます。
  • 数字は1から9までです(ONEからNINE

可能なスクランブルされていない文字列

以下は、数字から文字列に変換された直後の文字列のリストです。

 1 -> ONE 
 2 -> TWO
 3 -> THREE
 4 -> FOUR
 5 -> FIVE
 6 -> SIX
 7 -> SEVEN
 8 -> EIGHT
 9 -> NINE

"NEO" -> 1

"NWEOOT" -> 12

"TOEERWNEHOT" -> 123

"IHNEVGENNEISTE" -> 789

"WEETVTRFSVUHNEEFRHIXEOINSNIEGTOONIEE" -> 123456789

"EWHEWROETOTTON" -> 1223

"ONEWESTV" -> 27 (ETHproductionsに感謝!)


7
推奨されるテストケース:次のようなもの"ONEWESTV" -> 27(実際には表示されない数字を含む)
-ETHproductions

@ETHproductions素晴らしいアイデア!追加されました。
クリスティアンルパスク

「ゼロ」がないのはなぜですか?
RosLuP

@RosLuPジョンは...先頭のゼロを嫌い
クリスティアンLupascu

回答:


9

Python 2、123バイト

c=map(input().count,"OWHUFXSGIQ")
i=4
for j in"71735539994":c[i*2]-=c[int(j)];i=-~i%5
s=""
for n in c:i+=1;s+=`i`*n
print s

引用された入力を取り、Johnの番号を出力する完全なプログラム。

オンラインでお試しください!またはテストスイートを見る

どうやって?

例「NEONSEXTOWNII」で作業してみましょう(1269を生成し、Leisure Suite Larry -esqueになります!)

最初c=map(input().count,"OWHUFXSGIQ")に入力を取得し、それぞれの数をカウントしますOWHUFXSGIQ-これらは昇順で各数に現れる文字で、2,4,6、および8には「独自の」文字(WUXG)に加えてQ、ゼロを追加する追加の文字があります最後に結果のリストの長さを均等にします。例:

[2,1,0,0,0,1,1,0,2,0] <- c
 O W H U F X S G I Q  <- is the counts of these letters
 1 2 3 4 5 6 7 8 9 0  <- which "relate to" these digits in John's number
   2   4   6   8   0  <- these will be correct as the letters are unique to their words

1、3、5、7、および9のエントリは、他の文字の豊富さを修正するために調整する必要があります。これは次のループで実行されます。

i=4
for j in"71735539994":c[i*2]-=c[int(j)];i=-~i%5

調整するエントリは代替エントリ(1,3,5,7,9,1,3,5、...)であるため、各ステップでインデックス変数に2を追加し、10を法として留まることができます。複数回トラバースする必要がある場合の範囲(これを行います)。いくつかのバイトを節約するために、1ずつ増やし、5を法として、2倍のインデックスを使用できます。
9の調整には最も多くの作業が必要なので、そこから開始しi=4ます。インデックス8にあるため、から開始します。文字列"71735539994"は、j各段階で削除する値のインデックス、を提供します(ここで"Q"、作成時に使用することで9番目のインデックスにゼロが含まれることを確認しましたc)。c[i*2]-=c[int(j)]各個別調整と実行i=-~i%5移動i(次のインデックスに-~iある-(-1-i)またはi+1保存括弧(i+1)%5)を維持i*2の範囲内c
したがって、最初にindexの数j=7からindex i*2=8の数を減算し、「I」の数から「G」の数を引いて、「正しい」数の「正しい」数で「NINE」のカウントダウンを調整します( 「I」もあります)。次にi=0-~4%5 = (4+1)%5 = 0)に進みi*2 = 0、「ONE」のインデックスを参照し、j=1「W」をカウントし、「TWO」をカウントするエントリのインデックスで見つかった値を減算し、「O」のカウントを調整します。ループの終わりまでに、修正されたカウントが得られます。

[1,1,0,0,0,1,0,0,1,0] <- c   (for 1223333448 it would be: [1,2,4,2,0,0,0,1,0,0])
 1 2 3 4 5 6 7 8 9 0

残っているのは、c現在何を表しているのかを印刷すること1269です()。iがに戻った0ため、ループの開始時にインクリメントし、数字として使用します。

s=""
for n in c:i+=1;s+=`i`*n
print s

バックティック、`i`、Python2はの省略表現されているrepr(i)(ここでは、我々はのみが表示オブジェクト(文字列として、当該桁の文字)の文字列表現を取得していると数のcreatsで多くのリピートの新しい文字列を文字列を乗算n=0回す`i`と言うから発言権を維持回すと、それはまた、より大きな正の整数のために働く、そうなっ例えば。)"5"""n=1"6""6""3"*4"3333"


8

05AB1E、31バイト

[{‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#NSèJ{Q#

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

説明

[                                   # start loop
 {                                  # sort input
  ‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#            # push the list ['Z','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']
                        N           # push the current iteration counter
                         S          # split to list of digits
                          è         # index into the list with each
                           J{       # join to string and sort
                             Q#     # if the strings are equal, exit loop
                                    # implicitly print iteration counter

大量の入力に対しては非常に非効率的です。


‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# # push the list ['Z','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']:少し説明してもらえますか。文字列を生成する方法を理解するのに苦労しています。
シリルガンドン

1
@CyrilGandon:スペースで区切られた単語の大文字の圧縮文字列を区切ります。Zを意味しZます。他のすべての2シンボルペアは、05AB1Eの辞書から圧縮された単語を示します。したがって、たとえばとして€µ翻訳されONEます。
エミグナ

ニース、辞書に含まれる文字列をどのように圧縮しますか?ペアのユニコード値を持つ何か?
シリルガンドン

1
@CyrilGandon:辞書の単語の行番号(helloの場合は 2420 )を取得し、1を引きます。これにより、が得られ2419ます。私たちが必要とするシンボルが続いている記号である2419してドキュメント。私たちの場合、これは24=Ÿandであり19=™、そうHELLOなります‘Ÿ™‘
Emigna

1
ほとんどの場合に使用できるAdnanによって作成されたコンプレッサーもあります。リンクは少し長いですが、05AB1Eチャットルームで見つけることができます。それは、さらに質問があるかどうかを尋ねるのに良い場所です:)
エミグナ

8

網膜112 97バイト

O`.
}`GH
8
X
6
H
3
+`F(.*)O(.*)U
4$1$2
+`O(.*)W
2$1
+`F(.*)V
5$1
+`N(.*)V
7$1
}`NO
1
NN
9
T`L
O`.

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

@Neilのおかげで-12バイト

転置でのL文字クラスの使用による-3バイト

使い方

基本的に、これは文字が特定の番号名でのみ使用されるという事実に依存しています。たとえば、SIXが含まれる唯一の名前Xです。これは、both FIVESEVENusing など、一部の単語が文字で重複しているという事実により複雑になりますV。これは、識別することによって補正することができFIVEF(.*)V


1
@RickHitchcock修正済み。8への変換の再帰が正しく機能していませんでした
-fireflame241

1
@RickHitchcock。それらすべての再帰を修正しました。
-fireflame241

うるさくGHおよびNO以前のを除いて、隣接するだろう8か、1以前の置換から...
ニール

おそらく}`GH 8のために働くだろう8- }文字は、このように、残りの配置、再ソートする原因となるGH一緒に。
ニール

@ニールいいアイデア。私もそれを行うことができましたNO -> 1。これは便利でした。
fireflame241

5

Kotlin 1.1359の 352 331 327 325バイト

提出

fun r(r:String):String{var s=""
val f=r.split(s).groupingBy{it}.eachCount()
val c=Array(10,{0})
c[8]=f["G"]?:0
c[6]=f["X"]?:0
c[4]=f["U"]?:0
c[2]=f["W"]?:0
c[1]=(f["O"]?:0)-c[2]-c[4]
c[3]=(f["R"]?:0)-c[4]
c[7]=(f["S"]?:0)-c[6]
c[5]=(f["V"]?:0)-c[7]
c[9]=((f["N"]?:0)-c[1]-c[7])/2
for(i in 1..9)for(x in 1..c[i])s+=i
return s}

Kotlin 1.1がサポートされていないため、TryItOnlineでは機能しません

テスト

fun r(r:String):String{
val f=r.split("").groupingBy{it}.eachCount()
val c=Array(10,{0})
c[8]=f["G"]?:0
c[6]=f["X"]?:0
c[4]=f["U"]?:0
c[2]=f["W"]?:0
c[1]=(f["O"]?:0)-c[2]-c[4]
c[3]=(f["R"]?:0)-c[4]
c[7]=(f["S"]?:0)-c[6]
c[5]=(f["V"]?:0)-c[7]
c[9]=((f["N"]?:0)-c[1]-c[7])/2
var s=""
for(i in 1..9)for(x in 1..c[i])s+=i
return s}

data class TestData(val input: String, val output: String)

fun main(vararg args:String) {
    val items = listOf(
    TestData("NEO" , "1"),
    TestData("NWEOOT" , "12"),
    TestData("TOEERWNEHOT" , "123"),
    TestData("IHNEVGENNEISTE" , "789"),
    TestData("WEETVTRFSVUHNEEFRHIXEOINSNIEGTOONIEE" , "123456789"),
    TestData("EWHEWROETOTTON" , "1223")
    )
    for (item in items) {
        val out = r(item.input)
        if (out != item.output) {
            throw AssertionError("Bad result: $item : $out")
        }
    }
}

論理

ベビーベッドシート

上記のシートを使用して、各文字を解決する最も簡単な方法を見つけました

  • 緑=単独で解決
  • 青=解決するには緑が必要
  • オレンジ=解決するにはブルーが必要
  • 赤=解くにはオレンジが必要

編集

  • -7-w0lfによる空白の変更
  • -21-listOfを配列に縮小
  • -4-不要なブラケットを削除
  • 0-ロジックを追加
  • -2-kevin-cruijssenによる空の文字列の再利用

1
同様のアプローチを使用して、Java 8の回答(127バイト)でがあなたと完全に結びついていることに気付きました。;)しかし、一つの質問:あなたが変更することはできませんvar s=""return sr=""してreturn r、入力文字列、その時点で、あなたはもはや必要性を再利用することで?私は以前にKotlinでプログラミングしたことがないので、ここでナンセンスな話をするかもしれません。; p
ケビンクルーッセン

1
残念ながらない> 話し合います。kotlinlang.org
t

1
ああ、もちろんそれは可能性でした。パラメータはfinalデフォルトです。うーん、あなたはゴルフのことができるかもしれないもうひとつ:場所var s=""メソッドの最初のものとして、そして置き換えるval f=r.split("").val f=r.split(s).。繰り返しますが、うまくいくかどうかはわかりません。あまりにも悪いTIOは、そうでない場合、私は自分自身が...愚かな音を作る前に、これらの提案を自分自身をしようとするだろう、まだバージョン1.1をサポートしていません
ケビンCruijssen

4

ゼリー、37バイト

1ðDị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»ŒuḲ¤ẎŒ!ċð1#

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

-1 ジョナサン・アランに感謝します。


これは、7文字(例:NINEFIVETHREEFIVE)を超える入力ではタイムアウトします。それはバグですか、それともコードは非効率ですか?
クリスティアンルパスク

後者の@ w0lf(Œ!「順列」を意味します)
エリックアウトゴルファー

「AA」を使用して、バイトの保存ではなく、「!」:...“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»...
ジョナサン・アラン

@JonathanAllanああ、AAは言葉ですか?
エリックアウトゴルファー

はい、短い辞書の最初の単語です。
ジョナサンアラン

3

Java 8、248 234バイト

s->{int x=0,a[]=new int[10];for(String t:"2WO;4UORF;6XSI;8GI;5FI;7S;3R;1O;9I".split(";"))for(;s.indexOf(t.charAt(1))>=0;a[t.charAt(0)-48]++)for(String z:t.split(""))s=s.replaceFirst(z,"");for(s="";x++<9;)for(;a[x]-->0;)s+=x;return s;}

コードの説明:

s->{
    // Array to count how often which number appears
    int a[]=new int[10];
    // The first character behind the number serves the identification
    // the other characters get removed to identify the other numbers later
    for(String t:"2WO;4UORF;6XSI;8GI;5FI;7S;3R;1O;9I".split(";"))
        // Check if the string contains the id 
        for(;s.indexOf(t.charAt(1))>=0;a[t.charAt(0)-48]++)
            // Remove the relevant charcters
            for(String z:t.split(""))
                s=s.replaceFirst(z,"");
    // Clear the string to write the output
    s="";
    // write the numbers sequential into the output 
    for(int x=0;x++<9;)
        for(;a[x]-->0;)
            s+=x;
    return s;
}

-14オリビエ・グレゴワールに感謝



2

Java 8、346 345 344 336 327バイト

s->{int g=c(s+=" ","G"),u=c(s,"U"),w=c(s,"W"),x=c(s,"X"),f=c(s,"F")-u,h=c(s,"H")-g,v=c(s,"V")-f,o=c(s,"O")-u-w,i=c(s,"I")-f-x-g;return d(s=d(s=d(s=d(s=d(s=d(s=d(s=d(s=d("",o,1),w,2),h,3),u,4),f,5),x,6),v,7),g,8),n,9);}int c(String...s){return~-s[0].split(s[1]).length;}String d(String s,int i,int n){for(;i-->0;s+=n);return s;}

ここで試してみてください。

一般的な説明:

私はアルファベットの各文字の出現を見てきました:

E 13357789
F 45
G 8
H 38
I 5689
N 1799
O 124
R 34
S 67
T 238
U 4
V 57
W 2
X 6
  • 最初に、単一一致文字の出現をすべてカウントしましたG=8; U=4; W=2; X=6
  • 次に、上記の4つのうちの1つにも一致する2つの一致する文字のすべての出現数をカウントから減算できますF=5; H=3
  • それからV=7(を引くことでF=5)同じことを繰り返しました。
  • 次に、残った3つの一致文字すべてに同じ:O=1; N=9
    • しかし、Nに2つのオカレンスNINEがある-1ため、のすべてのオカレンスに対して追加を行う必要があったためNI=9代わりに使用しました(2つではなく3つの以前の一致を減算する)。

コードの説明:

s->{                    // Method with String as parameter and return-type
  int g=c(s+=" ","G"),  //  Amount of 8s (and append a space to `s` first, for the .split)
      u=c(s,"U"),       //  Amount of 4s
      w=c(s,"W"),       //  Amount of 2s
      x=c(s,"X"),       //  Amount of 6s
      f=c(s,"F")-u,     //  Amount of 5s
      h=c(s,"H")-g,     //  Amount of 3s
      v=c(s,"V")-f,     //  Amount of 7s
      o=c(s,"O")-u-w,   //  Amount of 1s
      i=c(s,"I")-f-x-g; //  Amount of 9s
  return d(             //  Return the result by:
   s=d(
    s=d(
     s=d(
      s=d(
       s=d(
        s=d(
         s=d(
          s=d("",       //   Making the input String `s` empty, since we no longer need it
                 o,1),  //   Append all 1s to `s`
         w,2),          //   Append all 2s to `s`
        h,3),           //   Append all 3s to `s`
       u,4),            //   Append all 4s to `s`
      f,5),             //   Append all 5s to `s`
     x,6),              //   Append all 6s to `s`
    v,7),               //   Append all 7s to `s`
   g,8),                //   Append all 8s to `s`
  i,9);                 //   And then returning `s` + all 9s
}                       // End of method

int c(String...s){  // Separate method with String-varargs parameter and int return-type
                    //  `s[0]` is the input-String
                    //  `s[1]` is the character to check
  return~-s[0].split(s[1]).length;
                    //  Return the amount of times the character occurs in the String
}                   // End of separated method (1)

String d(String s,int i,int n){
               // Separate method with String and two int parameters and String return-type
  for(;i-->0;  //  Loop from the first integer-input down to 0
      s+=n     //   And append the input-String with the second input-integer
  );           //  End of loop
  return s;    //  Return the resulting String
}              // End of separated method (2)

1
くそー、リストに追加してから並べ替えるのはもっと短くなると思っていただろう(そうではない)。よくやった!
オリビエグレゴワール

1
まあ、最終的に、私はあなたをアウトゴルフしましたが、それほどではありません;)
オリビエグレゴワール


1

Python 3、225バイト

def f(s):
	r=[]
	for i,w in zip([2,4,6,8,3,5,7,1,9],["WTO","UFOR","XSI","GEIHT","HTREE","FIVE","VSEEN","ONE","NINE"]):
		while s.count(w[0]):
			r+=[i]
			for l in w:s="".join(s.split(l,1))
	return "".join(sorted(map(str,r)))

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

簡単:最初に特定の文字で識別される数字を削除します。


1

Python 3、125バイト

lambda s:''.join(min(w)*(2*sum(map(s.count,w[:2]))-sum(map(s.count,w)))for w in"O1WU W2 H3G U4 F5U X6 S7X G8 IUFXG9".split())

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

リンクの挑戦を読んだ後、私は、これは上のバリエーションで実現mdahmouneのPythonのソリューションに基づいて、それ自体で、Draco18sのES6ソリューション、ちょっと、少なくとも私たちは、2つのバイトオフgolfed。

そのソリューションのように、特定の文字の出現回数の線形結合を介して答えを計算します。最初の2文字を追加し、その後すべてを減算する単語として線形結合を記述することにより、線形結合を簡単にエンコードします。最初の2文字を埋め込むために文字が必要になる場合があります。これを使用して、出力したい数字(入力では発生しないため、アルゴリズムに影響を与えません)を非表示にしminます。



1

公理、351バイト

s:="GXUWRFVIONETHS";e:EqTable(CHAR,INT):=table();v:=[8,6,4,2,3,5,7,9,1];z:=[k for k in 1..46|prime?(k)];F(x,y)==>for i in 1..#x repeat y;F(z,e.(s.i):=z.i);t:=[1787026,2451,16445,5957,16036207,130169,20372239,495349,20677];h(a)==(r:=1;F(a,r:=r*e.(a.i));j:=[];F(v,while r rem z.i=0 repeat(r:=r quo t.i;j:=cons(v.i,j)));j:=sort j;k:=0;F(j,k:=k*10+j.i);k)

コメントなしの結果

s:="GXUWRFVIONETHS" -- tutte le lettere di ONE..NINE in ordine di importanza 
e:EqTable(Character,Integer):=table()
v:=[8,6,4,2,3,5,7,9,1]              -- numeri da controllare in quell'ordine di apparizione di v
z:=[k for k in 1..46|prime?(k)]     -- 14 numeri primi da associare a s
F(x,y)==>for i in 1..#x repeat y 
F(z,e.(s.i):=z.i)                   -- riempie la tavola associando numeri primi alle lettere "GXUW..."
t:=[1787026,2451,16445,5957,16036207,130169,20372239,495349,20677]  -- prodotto di numeri primi 1787026 dovrebbe essere HEIGHT
h(a)==
     r:=1 ;F(a,r:=r*e.(a.i))        -- calcola il numero associato alla stringa a
     j:=[];F(v,while r rem z.i=0 repeat(r:=r quo t.i;j:=cons(v.i,j)));j:=sort j  -- leva il nome dei numeri che man mano trova, aggiunge a j
     k:=0 ;F(j,k:=k*10+j.i)         -- costruisce il numero decimale k, da j vettore ordinato
     k                              -- ritorna tale numero k
------------------------------------------------------
(8) -> h("IHNEVGENNEISTE")
   (8)  789
                                                    Type: PositiveInteger
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.