FizzBuzz Revers Solver


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(поскольку Monkey больше, чем Bear).

Ваша программа должна взять на выходе обобщенной программы 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?
Деннис

@ Денис Да, верхняя граница всегда 100.
Абсент

15
Это просто честь быть в одном из ваших примеров.
NinjaBearMonkey

Это намного лучшая версия твоего испытания, чем было изначально в песочнице :)
Beta Decay

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

Python 2, 366 340 331 байт

Эта программа получает ввод через стандартный ввод.

Новый подход:

Рассчитайте коэффициент слов только одного вхождения по расстоянию от конца строки. Например (из последнего образца): 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.