FizzBuzz Reverse Solver

32

Synopsis: Geben Sie bei der Ausgabe eines verallgemeinerten FizzBuzz-Programms die Liste der für das Programm verwendeten Faktoren und Wörter zurück.

Herausforderungsbeschreibung

Stellen Sie sich ein verallgemeinertes FizzBuzz-Programm vor, das als Eingabe eine Liste der zu verwendenden Faktoren und Wörter sowie die Zahl, bei der begonnen werden soll, verwendet. Zum Beispiel, wenn die Eingabe dieses Programms war

3 2,Ninja 5,Bear 7,Monkey

Die Programmnummern drucken würden aus 3zu 100, Zahlen ersetzt teilbar durch 2mit Ninja, Zahlen teilbar durch 5mit Bearund Zahlen teilbar durch 7mit Monkey. Für Zahlen, die dann mehr als einen dieser Ausdrücke teilbar sind, verkettet das Programm die Wörter und druckt Dinge wie NinjaBearoder BearMonkeyoder NinjaMonkeyoder NinjaBearMonkey. Hier ist die Ausgabe dieser Eingabe:

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

Beachten Sie, dass das Programm immer dann, wenn es Wörter zusammenfügen muss, von der niedrigsten zur höchsten Zahl wechselt . So wird so etwas nicht ausgedruckt MonkeyBear(da Monkey eine höhere Zahl als Bear ist).

Ihr Programm soll im nehmen Ausgabe des verallgemeinerten FizzBuzz Programms als Eingang und Ausgang den Eingang zu dem verallgemeinerten FizzBuzz Programm gegeben. Mit anderen Worten, schreiben Sie ein "umgekehrtes Programm" für das verallgemeinerte FizzBuzz-Programm. Wenn Sie beispielsweise den obigen Codeblock als Eingabe angeben, sollte Ihr Programm eine Ausgabe durchführen 3 2,Ninja 5,Bear, 7,Monkey.

Es gibt einige Regeln, denen die Wörter immer folgen:

  • Es ist immer möglich, genau zu sagen, welche Faktoren und Wörter von der Eingabe stammen.
  • Jedes Wort beginnt mit einem Großbuchstaben und enthält keine anderen Großbuchstaben oder Ziffern.
  • Jeder Faktor ist einzigartig.

Sample Ein- und Ausgänge

Eingang:

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

Ausgabe:

6 6,Calvins 8,Hobbies

Eingang:

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

Ausgabe:

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

Eingang:

DeliciousTartApplePie
DeliciousCreamPancakeStrawberry
DeliciousProfiterole
DeliciousCream
DeliciousPancake
DeliciousCreamStrawberryTart

Ausgabe:

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

Den Code, mit dem ich die Eingaben generiert habe, erhalten Sie hier .

Absinth
quelle
Steigt die Liste immer auf genau 100?
Dennis
@Dennis Ja, die Obergrenze ist immer 100.
Absinth
15
Es ist nur eine Ehre, in einem Ihrer Beispiele zu sein.
NinjaBearMonkey
Dies ist eine viel bessere Version Ihrer Herausforderung als ursprünglich in der Sandbox :)
Beta Decay
1
@ NinjaBearMonkey Ich nehme an, die Auswahl von Namen mit vielen Wörtern hat uns zu besseren Beispielen gemacht. Danke, dass du mich auch mit einbezogen hast @Pyrrha! :)
FryAmTheEggman

Antworten:

10

Pyth, 73 Bytes

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

Das war mit Sicherheit eine schwierige Frage. Ich denke, ich habe alle Randfälle behandelt, einschließlich aller Aspekte in @ MartinBüttners Beispiel und dem Beispiel ohne Wiederholungsfaktoren.

NinjaBearMonkey , Köstlichkeit

Auf der hohen Ebene findet das Programm zuerst alle Wörter, indem es die alphabetischen Zeichenfolgen in Großbuchstaben zerlegt.

Anschließend werden die Zeilen darauf abgebildet, ob jede Zeichenfolge in der Zeile angezeigt wird oder nicht, und jeder mögliche Faktor wird geprüft, um festzustellen, ob er dieselbe Reihenfolge ergibt. Ist dies der Fall, wird der Faktor zu einer globalen Liste hinzugefügt, in der überprüft wird, ob der Faktor bereits vorhanden war. Wenn es noch nicht vorhanden war, wird der Faktor verwendet. Die Zeichenfolgen werden nach dem ersten Auftreten in der Eingabe sortiert, wodurch die Reihenfolge der Zeichenfolgen, die jeweils nur einmal in derselben Zeile vorkommen, eindeutig wird.

Danach wird nur noch formatiert und gedruckt.

isaacg
quelle
5

Scala, 350 Zeichen

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

nicht gewinnen ... aber schöne frage.

getestete Ergebnisse:

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
quelle
4

Python 2, 366 340 331 Bytes

Dieses Programm empfängt Eingaben über stdin.

Neuer Ansatz:

Berechnen Sie den Faktor nur der Wörter eines Vorkommens anhand des Abstands vom Zeilenende. Zum Beispiel (aus der letzten Probe): DeliciousTartApplePiePie ist berechnen als: [95,19,5,1][0]und Apple ist: [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()))

Alter Ansatz:

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

Verwendung:

python FizzBuzzReverseSolver.py < Sample1.txt

Erklärung (des alten Ansatzes):

  • Im Allgemeinen erstellt das Programm eine Liste mit Zeilennummern und Wörtern (z [(0, []), (1, ['Ninja']), (2, ['Bear']), ...]. B.
  • Für jedes Wort in jeder Zeile (ab dem Ende der Zeile):
    • Suchen Sie das nächste Vorkommen des Wortes und fügen Sie die Differenz und das Wort in ein vordefiniertes Wörterbuch ein.
    • Wenn es nicht gefunden wird, geben Sie den größten Faktor der Zeilennummer (einschließlich der Zeilennummer selbst) ein, der noch nicht im Wörterbuch vorhanden ist, sowie das Wort zum Wörterbuch.
Die Krypta
quelle