원래 번호 (II)


18

이 문제는 본질적으로 동일하다 이 하나 하나 개의 차이 : 지금 어디 문자열의 문자를 임의 재생하도록 허용된다.

대본

요한은 중요한 숫자를 가지고 있으며 다른 사람들이 그것을보고 싶어하지 않습니다.

그는 다음 단계를 사용하여 번호를 암호화하기로 결정했습니다.

그의 수는 항상 비 감소 순서입니다 (예. "1123")

그는 각 숫자를 영어 단어로 변환했습니다. (예. "123" -> "ONETWOTHREE")

그런 다음 글자를 무작위로 재 배열하십시오. (예. "ONETWOTHREE" -> "EEWOOHRNTET")

요한은 자신의 수가 안전하다고 느꼈습니다. 실제로 이러한 암호화는 쉽게 해독 할 수 있습니다.


직무

암호화 된 문자열이 주어지면 작업은 암호를 해독하고 원래 숫자를 반환하는 것입니다.


규칙

  • 이것은 코드 골프이므로 바이트 단위의 최단 답변이 이깁니다.
  • 입력 문자열이 항상 유효하다고 가정 할 수 있습니다
  • 입력 문자열은 대문자 만 포함합니다
  • 원래 숫자는 항상 오름차순으로 정렬됩니다
  • 숫자를 문자열 또는 정수 형식으로 반환 할 수 있습니다
  • 글자는 전체 문자열이 아닌 한 단어 사이에서만 섞입니다. 문자열의 어느 곳에서나 문자를 섞을 수 있습니다.
  • 숫자는 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 좋은 생각입니다! 추가되었습니다.
Cristian Lupascu

"ZERO"가없는 이유는 무엇입니까?
RosLuP

@RosLuP 존은 제로 선도 제로 싫어 ...
크리스티안 루 파스

답변:


9

파이썬 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를 산출하고 약간의 레저 스위트 Larry -esque가되기 위해)로 작업합시다!

먼저 c=map(input().count,"OWHUFXSGIQ")입력을 받아 각각의 숫자를 센다 OWHUFXSGIQ-이들은 각각의 숫자에 오름차순으로 나타나는 문자 들이며, 2,4,6,8은 "자신의"문자 ( WUXG)를 가진 여분의 문자와 Q함께 0을 추가한다 끝까지 결과 목록의 길이를 고르게하십시오. 예를 들어 :

[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 씩 늘리고 인덱스를 두 배로 사용할 수 있습니다.
9에 대한 조정에는 가장 많은 작업이 필요하기 때문에 인덱스 8에 위치하므로 시작할 수 있습니다 i=4. 문자열은 "71735539994"다음 인덱스 준다 j(우리가 사용해 제로 포함될 아홉째 인덱스 확보 한 각 단계에서 제거하는 값을 "Q"생성 할 때를 c); c[i*2]-=c[int(j)]각 조정 행하는 i=-~i%5이동 i(다음 인덱스 -~i이다 -(-1-i)또는 i+1저장 괄호 (i+1)%5)를 유지i*2의 범위 내에서 c.
따라서, 우리는 먼저 인덱스 번호를 감산 j=7인덱스 것과 i*2=8( "I"의 수로부터 계산의 "G"의 수를 감산 "에이트"는 (S)의 (올바른) 숫자로 다운 카운트 "아홉"조정 "I"도 있습니다). 그런 다음 "ONE"에 대한 인덱스 를 참조 하여 i=0( -~4%5 = (4+1)%5 = 0) 로 이동 하고 "W"와 "TWO"를 입력 i*2 = 0하여 인덱스 j=1에서 찾은 값을 빼고 "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)어떤 숫자지지합니다 의해 여기에 우리 만 보여 많은 반복 (새로운 문자열 문자열 객체 (문자열로 문제의 숫자 문자)의 표현과 곱하여 문자열을 가져옵니다 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']: 조금 설명해 주시면 문자열 생성 방법을 이해하는 데 어려움을 겪고 있습니다.
Cyril Gandon

1
@CyrilGandon : 공백으로 구분 된 단어의 대문자 압축 문자열을 구분합니다. Z의미 Z합니다. 다른 모든 2 기호 쌍은 05AB1E 사전 의 압축 단어를 나타냅니다 . 예를 들어로 €µ번역합니다 ONE.
Emigna

좋아, 사전에 포함 된 문자열을 어떻게 압축합니까? 쌍의 유니 코드 값이 있습니까?
Cyril Gandon

1
@ CyrilGandon : 당신은 dict ( hello의 경우 2420)에서 단어의 줄 번호를 취하고 1을 뺍니다 2419. 우리가 필요로하는 기호 는 문서 뒤에 24그리고 그 뒤에있는 기호입니다 . 우리의 경우이다 하고 그렇게 될 것이다1924=Ÿ19=™HELLO‘Ÿ™‘
Emigna

1
Adnan이 작성한 압축기도 대부분의 경우에 사용할 수 있습니다. 링크가 약간 길지만 05AB1E 대화방 에서 찾을 수 있습니다 . 더 궁금한 점이 있는지 물어봐도 좋은 곳입니다.)
Emigna

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. 이것은 일부 단어는 모두 같은 문자로 겹쳐 있다는 사실에 난이도가 도착 FIVESEVEN사용 V. 로 식별 FIVE하면 이 문제를 해결할 수 있습니다 F(.*)V.


1
@RickHitchcock 수정되었습니다. 8 로의 전환에 대한 재귀가 제대로 작동하지 않았습니다
fireflame241

1
@RickHitchcock. 그들 모두의 재귀를 수정했습니다.
fireflame241241

이전 또는 이전 대체물을 제외 GH하고 NO는 짜증나고 인접 해 있습니다 .81
Neil

아마도 효과 }`GH 8가있을 것입니다 8- }문자를 다시 정렬하여 나머지 GH함께 배치합니다 .
Neil

@ 네일 좋은 생각. 나는 또한 그것을 할 수 있었다NO -> 1 있었는데 편리했습니다.
fireflame241241

5

코 틀린 1.1 , 359 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-목록으로 축소
  • -4-불필요한 브래킷 제거
  • 0-논리 추가
  • -2-kevin-cruijssen 덕분에 빈 문자열 재사용

1
방금 비슷한 접근법을 사용하여 Java 8 답변 (127 바이트) 과 정확하게 관련되어 있음을 알았습니다 . ;)하지만 하나의 질문 : 당신은 변경할 수 없습니다 var s=""return sr=""return r입력 문자열, 그 시점에서 더 이상 필요하지 재사용하여? 나는 전에 Kotlin에서 프로그래밍 한 적이 없으므로 여기서 말도 안되는 소리 일 수 있습니다. ; p
Kevin Cruijssen


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#

온라인으로 사용해보십시오!

Jonathan Allan 에게 -1 감사합니다 .


7 자보다 큰 일부 입력의 경우 시간이 초과됩니다 (예 : NINEFIVE, THREEFIVE). 버그입니까, 아니면 코드가 비효율적입니까?
Cristian Lupascu

@ w0lf 후자 ( Œ!"순열"을 의미)
Outgolfer Erik

"!"대신 "AA"를 사용하여 바이트를 저장하십시오....“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»...
Jonathan Allan

@JonathanAllan oh AA는 단어인가요?
Outgolfer Erik

짧은 사전의 첫 단어입니다.
Jonathan Allan

3

자바 8, 248234 바이트

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

자바 (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 .
  • 그런 다음 두 개의 일치하는 문자가 모두 나타납니다.이 문자는 위의 네 가지 중 하나와도 일치하므로 개수에서 뺄 수 있습니다. F=5; H=3 합니다.
  • 그런 다음 다시 같은 작업을 수행 V=7 (빼기)F=5 ) .
  • 그런 다음 남은 세 개의 일치하는 문자 모두에 대해 동일합니다. O=1; N=9 .
    • 그러나 N에 두 개의 어커런스가 있으므로 의 모든 어커런스마다 NINE추가 작업을 수행해야 했기 때문에 대신 두 개의 이전 일치 항목을 빼서 대신 사용 했습니다.-1NI=9

코드 설명 :

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
젠장, 목록에 추가하고 정렬하는 것이 더 짧을 것이라고 생각했을 것입니다. 잘 했어!
Olivier Grégoire

1
글쎄, 결국, 나는 너를 능가 했지만 많이는 아니었다.)
Olivier Grégoire


1

파이썬 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

파이썬 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())

온라인으로 사용해보십시오!

연결된 도전을 읽은 후 이것이 Draco18s의 ES6 솔루션을 기반으로하는 mdahmoune의 Python 솔루션 에 대한 변형이라는 것을 알았지 만 적어도 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)

ungolfed 코멘트 결과

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.