FizzBuzz 리버스 솔버


32

개요 : 일반화 된 FizzBuzz 프로그램의 출력이 주어지면 프로그램에 사용 된 요인 및 단어 목록을 반환합니다.

도전 설명

사용할 요소 및 단어 목록과 시작 숫자를 입력으로받는 일반화 된 FizzBuzz 프로그램을 상상해보십시오. 예를 들어이 프로그램의 입력이

3 2,Ninja 5,Bear 7,Monkey

이 프로그램은에서 번호를 인쇄 할 3100로 나누어 번호를 대체 2Ninja, 숫자로 나눌 5Bear,와 숫자로 나누어 7과 함께 Monkey. 더 그 용어의 하나보다 다음 나눌 번호는 프로그램 같은 것들을 인쇄, 단어를 연결할 것 NinjaBear또는 BearMonkey또는 NinjaMonkey또는 NinjaBearMonkey. 해당 입력의 출력은 다음과 같습니다.

3
Ninja
Bear
Ninja
Monkey
Ninja
9
NinjaBear
11
Ninja
13
NinjaMonkey
Bear
Ninja
17
Ninja
19
NinjaBear
Monkey
Ninja
23
Ninja
Bear
Ninja
27
NinjaMonkey
29
NinjaBear
31
Ninja
33
Ninja
BearMonkey
Ninja
37
Ninja
39
NinjaBear
41
NinjaMonkey
43
Ninja
Bear
Ninja
47
Ninja
Monkey
NinjaBear
51
Ninja
53
Ninja
Bear
NinjaMonkey
57
Ninja
59
NinjaBear
61
Ninja
Monkey
Ninja
Bear
Ninja
67
Ninja
69
NinjaBearMonkey
71
Ninja
73
Ninja
Bear
Ninja
Monkey
Ninja
79
NinjaBear
81
Ninja
83
NinjaMonkey
Bear
Ninja
87
Ninja
89
NinjaBear
Monkey
Ninja
93
Ninja
Bear
Ninja
97
NinjaMonkey
99
NinjaBear

프로그램이 단어를 결합해야 할 때마다 항상 가장 낮은 수에서 가장 높은 수로 이동 합니다. 따라서 MonkeyBear원숭이가 곰보다 숫자가 많기 때문에 다음과 같이 인쇄되지 않습니다 .

프로그램이 취해야 출력 으로서 일반화 FizzBuzz 프로그램의 입력출력 입력 일반화 FizzBuzz 프로그램에 제공한다. 다시 말해, 일반화 된 FizzBuzz 프로그램에 대한 "역 프로그램"을 작성하십시오. 예를 들어, 위의 코드 블록을 입력으로 지정하면 프로그램이 출력되어야합니다 3 2,Ninja 5,Bear, 7,Monkey.

단어가 항상 따라야 할 몇 가지 규칙이 있습니다.

  • 입력에서 요인과 단어가 무엇인지 정확하게 말할 수 있습니다.
  • 각 단어는 대문자로 시작하며 다른 대문자 나 숫자를 포함하지 않습니다.
  • 각 요소는 고유합니다.

샘플 입력 및 출력

입력:

Calvins
7
Hobbies
9
10
11
Calvins
13
14
15
Hobbies
17
Calvins
19
20
21
22
23
CalvinsHobbies
25
26
27
28
29
Calvins
31
Hobbies
33
34
35
Calvins
37
38
39
Hobbies
41
Calvins
43
44
45
46
47
CalvinsHobbies
49
50
51
52
53
Calvins
55
Hobbies
57
58
59
Calvins
61
62
63
Hobbies
65
Calvins
67
68
69
70
71
CalvinsHobbies
73
74
75
76
77
Calvins
79
Hobbies
81
82
83
Calvins
85
86
87
Hobbies
89
Calvins
91
92
93
94
95
CalvinsHobbies
97
98
99
100

산출:

6 6,Calvins 8,Hobbies

입력:

FryEggman
7
Am
Fry
The
11
FryAmEggman
13
14
FryThe
Am
17
FryEggman
19
AmThe
Fry
22
23
FryAmEggman
The
26
Fry
Am
29
FryTheEggman
31
Am
Fry
34
The
FryAmEggman
37
38
Fry
AmThe
41
FryEggman
43
Am
FryThe
46
47
FryAmEggman
49
The
Fry
Am
53
FryEggman
The
Am
Fry
58
59
FryAmTheEggman
61
62
Fry
Am
The
FryEggman
67
Am
Fry
The
71
FryAmEggman
73
74
FryThe
Am
77
FryEggman
79
AmThe
Fry
82
83
FryAmEggman
The
86
Fry
Am
89
FryTheEggman
91
Am
Fry
94
The
FryAmEggman
97
98
Fry
AmThe

산출:

6 3,Fry 4,Am 5,The 6,Eggman

입력:

DeliciousTartApplePie
DeliciousCreamPancakeStrawberry
DeliciousProfiterole
DeliciousCream
DeliciousPancake
DeliciousCreamStrawberryTart

산출:

95 1,Delicious 2,Cream 3,Pancake 4,Strawberry 5,Tart 19,Apple 95,Pie 97,Profiterole

여기 에서 입력을 생성하는 데 사용한 코드를 얻을 수 있습니다 .


목록이 항상 정확히 100까지 올라 갑니까?
Dennis

@Dennis 그렇습니다. 상한은 항상 100입니다.
absinthe

15
당신의 모범 중 하나가되어 영광입니다.
NinjaBearMonkey

이 :) 샌드 박스에 원래보다 당신의 도전의 더 나은 버전
베타 붕괴

1
@ NinjaBearMonkey 많은 단어가 포함 된 이름을 선택하면 더 좋은 예가되었다고 가정합니다. 저도 @Pyrrha를 포함시켜 주셔서 감사합니다! :)
FryAmTheEggman

답변:


10

Pyth, 73 바이트

jd+J-101lK.zjL\,Sm,_-F>2+_Jf}d@KTUKd{smtcdf-@dTGUdf>T\:K

그것은 확실히 힘든 일이었습니다. @ MartinBüttner의 예제와 반복 요소 없음 예제의 모든 것을 포함하여 모든 주요 사례를 다루었다고 생각합니다.

NinjaBearMonkey , 맛있는

높은 수준에서 프로그램은 먼저 알파벳 문자를 대문자로 잘라내어 모든 단어를 찾습니다.

그런 다음 행이 각 문자열이 행에 나타나는지 여부에 매핑되며 가능한 각 요소가 동일한 순서를 생성하는지 테스트합니다. 만약 그렇다면, 해당 인자는 gobal list에 추가되며, 인자가 이미 존재하는지 확인합니다. 아직 존재하지 않으면 계수가 사용됩니다. 문자열은 입력에서 처음 나타나는 순서대로 정렬되며, 동일한 행에서 한 번만 나타나는 문자열의 순서를 명확하게합니다.

그 후, 그것은 단지 포맷팅과 인쇄입니다.


5

스칼라, 350 자

(s:String)⇒{def g(a:Int,b:Int):Int=if(b==0)a.abs else g(b,a%b);val(j,q)=(s.lines:\100→Map.empty[String,Int]){case(l,(n,m))⇒if(l(0).isDigit)(n-1,m)else(n-1,m++(Seq(Seq(l(0)))/:l.tail){case(x,c)⇒if(c.isUpper)Seq(c)+:x else (x(0):+c)+:x.tail}.map{t⇒val w=t.mkString;w→g(m.getOrElse(w,n),n)})};s"${j+1}"+q.map{case(k,v)=>s" $v,$k"}.toSeq.sorted.mkString}

이기는 것이 아니라 좋은 질문입니다.

테스트 결과 :

scala> (s:String)⇒{def g(a:Int,b:Int):Int=if(b==0)a.abs else g(b,a%b);val(j,q)=(s.lines:\100→Map.empty[String,Int]){case(l,(n,m))⇒if(l(0).isDigit)(n-1,m)else(n-1,m++(Seq(Seq(l(0)))/:l.tail){case(x,c)⇒if(c.isUpper)Seq(c)+:x else (x(0):+c)+:x.tail}.map{t⇒val w=t.mkString;w→g(m.getOrElse(w,n),n)})};s"${j+1}"+q.map{case(k,v)=>s" $v,$k"}.toSeq.sorted.mkString}
res0: String => String = <function1>

scala> res0("""DeliciousTartApplePie
     | DeliciousCreamPancakeStrawberry
     | DeliciousProfiterole
     | DeliciousCream
     | DeliciousPancake
     | DeliciousCreamStrawberryTart""")
res1: String = 95 1,Delicious 2,Cream 3,Pancake 4,Strawberry 5,Tart 95,Apple 95,Pie 97,Profiterole

scala> res0("""FryEggman
     | 7
     | Am
     | Fry
     | The
     | 11
     | FryAmEggman
     | 13
     | 14
     | FryThe
     | Am
     | 17
     | FryEggman
     | 19
     | AmThe
     | Fry
     | 22
     | 23
     | FryAmEggman
     | The
     | 26
     | Fry
     | Am
     | 29
     | FryTheEggman
     | 31
     | Am
     | Fry
     | 34
     | The
     | FryAmEggman
     | 37
     | 38
     | Fry
     | AmThe
     | 41
     | FryEggman
     | 43
     | Am
     | FryThe
     | 46
     | 47
     | FryAmEggman
     | 49
     | The
     | Fry
     | Am
     | 53
     | FryEggman
     | The
     | Am
     | Fry
     | 58
     | 59
     | FryAmTheEggman
     | 61
     | 62
     | Fry
     | Am
     | The
     | FryEggman
     | 67
     | Am
     | Fry
     | The
     | 71
     | FryAmEggman
     | 73
     | 74
     | FryThe
     | Am
     | 77
     | FryEggman
     | 79
     | AmThe
     | Fry
     | 82
     | 83
     | FryAmEggman
     | The
     | 86
     | Fry
     | Am
     | 89
     | FryTheEggman
     | 91
     | Am
     | Fry
     | 94
     | The
     | FryAmEggman
     | 97
     | 98
     | Fry
     | AmThe""")
res2: String = 6 3,Fry 4,Am 5,The 6,Eggman

4

파이썬 2, 366 340 331 바이트

이 프로그램은 stdin을 통해 입력을받습니다.

새로운 접근 방식:

줄의 끝으로부터의 거리를 기준으로 한 단어의 요인 만 계산합니다. 예를 들어 (마지막 샘플에서) : DeliciousTartApplePie파이는 다음과 같이 계산되며 [95,19,5,1][0]애플은 다음과 같습니다 [95,19,5,1][1].

import sys
import re
d=[(i,re.findall('[A-Z][a-z]*',l)[::-1])for i,l in enumerate(sys.stdin)]
e=101-len(d)
print e," ".join(`x`+','+`y`[1:-1]for x,y in sorted({next((j-i for j,t in d if j>i and w in t),[x for x in range(i+e,0,-1)if(i+e)%x==0][d[i][1].index(w)]):w for w,i in{w:i for i,l in d[::-1]for w in l}.items()}.iteritems()))

오래된 접근법 :

import sys
import re
l=[(i,re.findall('[A-Z][a-z]*',l))for i,l in enumerate(sys.stdin)]
e=101-len(l)
d={}
for i,s in l:
 for w in s[::-1]:
  if w not in d.values():
   d[next((j-i for j,t in l[i+1:]if w in t),next(m for m in range(i+e,0,-1)if(i+e)%m==0and m not in d))]=w 
print e," ".join(`x`+','+`y`[1:-1]for x,y in sorted(d.iteritems()))

용법:

python FizzBuzzReverseSolver.py < Sample1.txt

설명 (오래된 접근법) :

  • 일반적으로 프로그램은 줄 번호 목록과 단어 목록 (예 : [(0, []), (1, ['Ninja']), (2, ['Bear']), ...].
  • 모든 줄의 각 단어에 대해 (줄 끝에서 시작) :
    • 다음에 나오는 단어를 찾아 사전 정의 된 사전에 차이와 단어를 삽입하십시오.
    • 찾을 수없는 경우 사전에없는 행 번호 (자체 포함)의 가장 큰 요소를 삽입하고 단어를 사전에 삽입하십시오.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.