FizzBuzz Reverse Solver

32

Sinopsis: Mengingat hasil dari program FizzBuzz yang digeneralisasi, kembalikan daftar faktor dan kata-kata yang digunakan untuk program tersebut.

Deskripsi Tantangan

Bayangkan program FizzBuzz umum yang memasukkan sebagai input daftar faktor dan kata-kata untuk digunakan dan nomor untuk memulai. Misalnya, jika input dari program ini adalah

3 2,Ninja 5,Bear 7,Monkey

Program akan mencetak angka dari 3ke 100, mengganti angka yang dapat dibagi 2dengan Ninja, angka yang dapat dibagi 5dengan Bear, dan angka yang dapat dibagi 7dengan Monkey. Untuk angka yang dapat dibagi lebih dari satu istilah, program akan menggabungkan kata-kata, mencetak hal-hal seperti NinjaBearatau BearMonkeyatau NinjaMonkeyatau NinjaBearMonkey. Inilah output dari input itu:

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

Perhatikan bahwa setiap kali program perlu menggabungkan kata-kata, itu selalu berubah dari angka terendah ke angka tertinggi . Jadi itu tidak akan mencetak sesuatu seperti MonkeyBear(karena Monyet adalah angka yang lebih tinggi daripada Beruang).

Program Anda harus mengambil dalam keluaran program FizzBuzz yang umum sebagai masukan , dan keluaran yang masukan yang diberikan kepada program FizzBuzz yang umum. Dengan kata lain, tulis "program terbalik" untuk program FizzBuzz umum. Misalnya, mengingat blok kode di atas sebagai input, program Anda harus menampilkan 3 2,Ninja 5,Bear, 7,Monkey.

Ada beberapa aturan yang kata-katanya akan selalu mengikuti:

  • Selalu dimungkinkan untuk mengetahui dengan pasti faktor dan kata apa dari input.
  • Setiap kata akan dimulai dengan huruf kapital dan tidak akan berisi huruf kapital atau angka lainnya.
  • Setiap faktor unik.

Input dan Output Sampel

Memasukkan:

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

Keluaran:

6 6,Calvins 8,Hobbies

Memasukkan:

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

Keluaran:

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

Memasukkan:

DeliciousTartApplePie
DeliciousCreamPancakeStrawberry
DeliciousProfiterole
DeliciousCream
DeliciousPancake
DeliciousCreamStrawberryTart

Keluaran:

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

Anda bisa mendapatkan kode yang saya gunakan untuk menghasilkan input di sini .

Absinth
sumber
Apakah daftar selalu naik hingga tepat 100?
Dennis
@ Dennis Ya, batas atas selalu 100.
absinthhe
15
Merupakan suatu kehormatan untuk berada di salah satu contoh Anda.
NinjaBearMonkey
Ini adalah versi tantangan Anda yang jauh lebih baik daripada yang awalnya ada di kotak pasir :)
Beta Decay
1
@NinjaBearMonkey Saya kira memilih nama dengan banyak kata di dalamnya membuat kami contoh yang lebih baik. Terima kasih sudah menyertakan saya juga @Praha! :)
FryAmTheEggman

Jawaban:

10

Pyth, 73 byte

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

Itu benar-benar yang sulit. Saya pikir saya telah membahas semua kasus tepi, termasuk semua contoh @ MartinBüttner, dan contoh faktor no repeat.

NinjaBearMonkey , Deliciousness

Pada level tinggi, program pertama-tama menemukan semua kata dengan memotong string alfabet pada huruf kapital.

Kemudian, baris dipetakan ke apakah masing-masing string muncul di baris, dan setiap faktor yang mungkin diuji untuk melihat apakah itu menghasilkan urutan yang sama. Jika ya, faktor ditambahkan ke daftar gobal, yang memeriksa untuk melihat apakah faktor itu sudah ada. Jika belum ada, faktor yang digunakan. String diurutkan berdasarkan tampilan pertama pada input, yang menghilangkan urutan string yang masing-masing hanya muncul sekali di baris yang sama.

Setelah itu, tinggal memformat dan mencetak.

isaacg
sumber
5

Scala, 350 karakter

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

tidak menang ... tapi pertanyaan yang bagus.

hasil yang diuji:

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

Python 2, 366 340 331 byte

Program ini menerima input melalui stdin.

Pendekatan baru:

Hitung faktor dari hanya satu kata kejadian dengan jarak dari ujung garis. Sebagai contoh (dari sampel terakhir): DeliciousTartApplePiePie adalah menghitung sebagai: [95,19,5,1][0]dan Apple adalah: [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()))

Pendekatan lama:

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

Pemakaian:

python FizzBuzzReverseSolver.py < Sample1.txt

Penjelasan (dari pendekatan Lama):

  • Secara umum, program membuat daftar nomor baris dan daftar kata-kata (mis [(0, []), (1, ['Ninja']), (2, ['Bear']), ...].
  • Untuk setiap kata di setiap baris (mulai dari akhir baris):
    • Temukan kemunculan kata berikutnya dan masukkan perbedaan dan kata tersebut ke kamus yang telah ditentukan.
    • Jika tidak ditemukan, masukkan faktor terbesar dari nomor baris (termasuk sendiri) yang belum ada dalam kamus dan kata ke kamus.
TheCrypt
sumber