FizzBuzz Reverse Solver
Pyth, 73 bytes
jd+J-101lK.zjL\,Sm,_-F>2+_Jf}d@KTUKd{smtcdf-@dTGUdf>T\:K
That was certaintly a tough one. I think I've covered all the edge cases, including everything in @MartinBüttner's example, and the no repeat factors example.
NinjaBearMonkey, Deliciousness
At the high level, the program first finds all of the words by chopping up the alphabetical strings on capital letters.
Then, the rows are mapped to whether or not each string appears in the row, and each possible factor is tested to see if it produces the same ordering. If it does, the factor is added to a gobal list, which is check to see if the factor was already present. If it was not already present, the factor is used. The strings are ordered by first appearance in the input, which disambiguates the ordering of strings that each appear only once in the same row.
After that, it's just formatting and printing.
Scala, 350 characters
(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}
not winning... but nice question.
tested results:
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
Python 2, 366 340 331 bytes
This program receive input via stdin.
New approach:
Calculate the factor of only one occurrence's words by the distance from the end of the line. For example (from the last sample): DeliciousTartApplePie
Pie is calculate as: [95,19,5,1][0]
and Apple is: [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()))
Old approach:
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()))
Usage:
python FizzBuzzReverseSolver.py < Sample1.txt
Explanation (of Old approach):
- In general, the program creates a list of line number and list of
words (e.g.
[(0, []), (1, ['Ninja']), (2, ['Bear']), ...]
. - For each word in every line (starting from the end of the line):
- Find the next occurrence of the word and insert the difference and the word to a predefined dictionary.
- If it doesn't found, insert the biggest factor of the line number (including itself) that doesnt already exist in the dictionary and the word to the dictionary.