FizzBuzz Reverse Solver

32

Streszczenie: Biorąc pod uwagę wyniki uogólnionego programu FizzBuzz, zwróć listę czynników i słów użytych dla programu.

Opis wyzwania

Wyobraź sobie uogólniony program FizzBuzz, który pobiera jako listę listę czynników i słów do użycia oraz liczbę na początek. Na przykład, jeśli wejście tego programu było

3 2,Ninja 5,Bear 7,Monkey

Program będzie wydrukować numery od 3celu 100, zastępując liczb podzielnych przez 2się Ninja, liczb podzielnych przez 5się Bear, a liczba podzielna przez 7z Monkey. W przypadku liczb, które są podzielne, niż więcej niż jeden z tych terminów, program połączy słowa, drukując rzeczy takie jak NinjaBearlub BearMonkeylub NinjaMonkeylub NinjaBearMonkey. Oto wynik tego wejścia:

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

Pamiętaj, że ilekroć program musi łączyć słowa ze sobą, zawsze przechodzi od najniższej liczby do najwyższej liczby . Więc nie wydrukuje czegoś takiego MonkeyBear(ponieważ Monkey jest wyższą liczbą niż Bear).

Twój program powinien podjąć w wyjściu z uogólnioną programu FizzBuzz jako wejście i wyjście na wejście podany do uogólnionego programu FizzBuzz. Innymi słowy, napisz „program wsteczny” dla uogólnionego programu FizzBuzz. Na przykład, biorąc pod uwagę powyższy blok kodu jako dane wejściowe, twój program powinien wypisać dane 3 2,Ninja 5,Bear, 7,Monkey.

Istnieją pewne zasady, których słowa zawsze będą przestrzegać:

  • Zawsze będzie można dokładnie powiedzieć, jakie czynniki i słowa pochodzą z danych wejściowych.
  • Każde słowo rozpocznie się wielką literą i nie będzie zawierać żadnych innych wielkich liter ani cyfr.
  • Każdy czynnik jest wyjątkowy.

Przykładowe wejścia i wyjścia

Wkład:

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

Wydajność:

6 6,Calvins 8,Hobbies

Wkład:

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

Wydajność:

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

Wkład:

DeliciousTartApplePie
DeliciousCreamPancakeStrawberry
DeliciousProfiterole
DeliciousCream
DeliciousPancake
DeliciousCreamStrawberryTart

Wydajność:

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

Możesz pobrać kod, którego użyłem do wygenerowania danych wejściowych tutaj .

Absynt
źródło
Czy lista zawsze sięga dokładnie 100?
Dennis,
@Dennis Tak, górna granica wynosi zawsze 100.
absynt
15
To zaszczyt być jednym z twoich przykładów.
NinjaBearMonkey
To jest o wiele lepsza wersja twojego wyzwania niż pierwotnie w piaskownicy :)
Beta Decay
1
@NinjaBearMonkey Podejrzewam, że wybieranie nazw zawierających wiele słów uczyniło nas lepszymi przykładami. Dziękuję za uwzględnienie mnie również @Pyrrha! :)
FryAmTheEggman

Odpowiedzi:

10

Pyth, 73 bajty

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

To było z pewnością trudne. Myślę, że omówiłem wszystkie najważniejsze przypadki, w tym wszystko w przykładzie @ MartinBüttner i przykład braku powtarzania czynników.

NinjaBearMonkey , Deliciousness

Na wysokim poziomie program najpierw znajduje wszystkie słowa, dzieląc ciągi alfabetyczne na wielkie litery.

Następnie wiersze są odwzorowywane na to, czy każdy ciąg pojawia się w wierszu, i każdy możliwy czynnik jest testowany, aby sprawdzić, czy daje to to samo uporządkowanie. Jeśli tak, czynnik jest dodawany do listy gobal, która sprawdza, czy czynnik był już obecny. Jeśli nie był jeszcze obecny, używany jest współczynnik. Ciągi są uporządkowane według pierwszego pojawienia się na wejściu, co niejednoznacznie porządkuje ciągi, które pojawiają się tylko raz w tym samym wierszu.

Potem to tylko formatowanie i drukowanie.

isaacg
źródło
5

Scala, 350 znaków

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

nie wygrywa ... ale miłe pytanie.

przetestowane wyniki:

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
Gilad Hoch
źródło
4

Python 2, 366 340 331 bajtów

Ten program odbiera dane wejściowe przez standardowe wejście.

Nowe podejście:

Oblicz współczynnik tylko jednego słowa wystąpienia według odległości od końca linii. Na przykład (z ostatniej próby): DeliciousTartApplePiePie jest obliczyć jako: [95,19,5,1][0]a Apple jest: [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()))

Stare podejście:

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()))

Stosowanie:

python FizzBuzzReverseSolver.py < Sample1.txt

Objaśnienie (starego podejścia):

  • Zasadniczo program tworzy listę numerów wierszy i listę słów (np [(0, []), (1, ['Ninja']), (2, ['Bear']), ...].
  • Dla każdego słowa w każdym wierszu (zaczynając od końca wiersza):
    • Znajdź następne wystąpienie słowa i wstaw różnicę i słowo do predefiniowanego słownika.
    • Jeśli nie zostanie znaleziony, wstaw największy czynnik numeru wiersza (łącznie z nim), który już nie istnieje w słowniku i słowo do słownika.
TheCrypt
źródło