Зворотний вирішувач FizzBuzz


32

Короткий огляд : З огляду на вихід узагальненої програми FizzBuzz, поверніть список факторів та слів, які використовуються для програми.

Опис виклику

Уявіть узагальнену програму FizzBuzz, яка приймає в якості списку факторів і слів, які слід використовувати, і число, з якого слід починати. Наприклад, якщо вхід цієї програми був

3 2,Ninja 5,Bear 7,Monkey

Програма буде друкувати цифри від 3до 100, замінивши числа ділиться на 2з Ninja, числа , що діляться на 5з Bear, і числа , що діляться на 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 Так, верхня межа завжди 100.
абсент

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 , чудовий

На високому рівні програма спочатку знаходить усі слова, подрібнюючи алфавітні рядки з великої літери.

Потім рядки відображаються у тому, чи відображається чи не кожен рядок у рядку, і кожен можливий коефіцієнт тестується, щоб побачити, чи він виробляє однакове впорядкування. Якщо це так, фактор додається до списку гобалів, який перевіряється, чи чинник вже присутній. Якщо його вже не було, використовується коефіцієнт. Рядки впорядковуються за першим появою на вході, що розмежовує впорядкування рядків, які відображаються лише один раз у тому ж рядку.

Після цього це просто форматування та друк.


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.

Новий підхід:

Обчисліть коефіцієнт лише одного слова виникнення на відстань від кінця рядка. Наприклад (з останнього зразка): DeliciousTartApplePiePie вираховують як: [95,19,5,1][0]і Apple , є: [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']), ...].
  • Для кожного слова у кожному рядку (починаючи з кінця рядка):
    • Знайдіть наступне виникнення слова та вставте різницю та слово у заздалегідь заданий словник.
    • Якщо він не знайдений, вставте найбільший коефіцієнт номера рядка (включаючи самого себе), який у словнику вже не існує, а слово до словника.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.