# Please Forward: Ruby Quiz Submission

**URL:** <https://rubytalk.org/t/please-forward-ruby-quiz-submission/41409>\
**Category:** ruby-talk\
**Created:** [15 October 2007 21:54 UTC](https://rubytalk.org/t/please-forward-ruby-quiz-submission/41409 "2007-10-15T21:54:36Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [15 October 2007 21:54 UTC](https://rubytalk.org/t/please-forward-ruby-quiz-submission/41409/1 "2007-10-15T21:54:36Z")

</div>

> From: Pusztai Tibor \<kondi@inf.elte.hu\>  
> Date: October 15, 2007 4:09:41 PM CDT  
> To: submission@rubyquiz.com  
> Cc: gbence@cs.bme.hu  
> Subject: Please Forward: Ruby Quiz Submission
> 
> Hello,
> 
> Please forward my solution to the Ruby Talk mailing list!
> 
> Thanks,  
> Tibor  
> # This solution is my homework for a ruby lesson  
> # Pusztai Tibor (PUTNAAI.ELTE)
> 
> MAX\_REPEAT = 3  
> DOT\_MATCH = /[a-zA-Z\d\.,;\^\-]/
> 
> class Concatenate \< Array
> 
> &nbsp;&nbsp;def multiIndex indexes  
> &nbsp;&nbsp;&nbsp;&nbsp;n = -1  
> &nbsp;&nbsp;&nbsp;&nbsp;indexes.map { |index|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at(n += 1).at(index)  
> &nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def cartesian  
> &nbsp;&nbsp;&nbsp;&nbsp;indexes = Array.new length, 0  
> &nbsp;&nbsp;&nbsp;&nbsp;out = Select.new  
> &nbsp;&nbsp;&nbsp;&nbsp;while true  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out \<\< multiIndex(indexes).join  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n = length - 1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (indexes[n] += 1) \>= at(n).length  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indexes[n] = 0  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (n -= 1) \< 0  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return out  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end  
> &nbsp;&nbsp;  
> &nbsp;&nbsp;def unfold  
> &nbsp;&nbsp;&nbsp;&nbsp;if length == 0  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Select.new(1, "")  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;map! { |item|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if item.is\_a? String  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Select.new 1, item  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item.unfold  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;cartesian  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def simplify  
> &nbsp;&nbsp;&nbsp;&nbsp;genSimplify self  
> &nbsp;&nbsp;&nbsp;&nbsp;self  
> &nbsp;&nbsp;end
> 
> end
> 
> class Select \< Array
> 
> &nbsp;&nbsp;def to\_a  
> &nbsp;&nbsp;&nbsp;&nbsp;map { |item| item }  
> &nbsp;&nbsp;end  
> &nbsp;&nbsp;  
> &nbsp;&nbsp;def unfold  
> &nbsp;&nbsp;&nbsp;&nbsp;out = Select.new  
> &nbsp;&nbsp;&nbsp;&nbsp;each { |item|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if item.is\_a? String  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out \<\< item  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.concat item.unfold  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;out  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;def simplify  
> &nbsp;&nbsp;&nbsp;&nbsp;genSimplify self  
> &nbsp;&nbsp;&nbsp;&nbsp;self  
> &nbsp;&nbsp;end
> 
> end
> 
> def genSimplify x  
> &nbsp;&nbsp;if x.is\_a? String  
> &nbsp;&nbsp;&nbsp;&nbsp;x  
> &nbsp;&nbsp;elsif x.length == 1  
> &nbsp;&nbsp;&nbsp;&nbsp;genSimplify x[0]  
> &nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;x.map! { |y|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;genSimplify y  
> &nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;end  
> end
> 
> def toTree source  
> &nbsp;&nbsp;stack = Concatenate.new  
> &nbsp;&nbsp;dotMatch = nil  
> &nbsp;&nbsp;source.scan(/(\.)|\[(.\*?[^\\])\]|\{([\d,]+)\}|([\(\)\|\?\+\*])|((\\.|[^\.\(\)\|\[\]\?\+\*\{\}])+)/) {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>dot, charClass, nTimes, control, s|  
> &nbsp;&nbsp;&nbsp;&nbsp;if dot  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charClass = DOT\_MATCH.inspect[2..-3]  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;if s  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack \<\< s.gsub(/\\(.)/, "\\1")  
> &nbsp;&nbsp;&nbsp;&nbsp;elsif charClass  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charClass.gsub!(/(^|[^\\])\\d/, "\\10-9")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charClass.gsub!(/\\([^-])/, "\\1")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charClass.gsub!(/([^\\])-(.)/) {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;($1..$2).to\_a.join  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charClass.gsub!(/\\-/, "-")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select = Select.new  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if charClass[0..0] == '^'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if !dotMatch  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dotMatch = DOT\_MATCH.generate.join  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charClass = dotMatch.delete charClass[1..-1].gsub(/[\^\-]/, "\\\\\\0")  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charClass.scan(/./m) { |ch|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select \<\< ch  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack \<\< select  
> &nbsp;&nbsp;&nbsp;&nbsp;elsif control  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case control  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when "("  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack \<\< :select\_open  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when "|"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack \<\< :select\_pipe  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when ")"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select = Select.new  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conc = Concatenate.new  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (elem = stack.pop) != :select\_open  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (elem == :select\_pipe)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select.unshift conc  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conc = Concatenate.new  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conc.unshift elem  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select.unshift conc  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack \<\< select  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when "?"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nTimes = "0,1"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when "\*"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nTimes = "0," + MAX\_REPEAT.to\_s  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when "+"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nTimes = "1," + MAX\_REPEAT.to\_s  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;if nTimes  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if nTimes.include? ','  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from, to = nTimes.split(',').map { |x| x.to\_i }  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if !to  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to = MAX\_REPEAT  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from = to = nTimes.to\_i  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;last = stack.pop  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if last.is\_a? String  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack \<\< last.chop  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;last = last[-1..-1]  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack \<\< Select.new(  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(from..to).map { |n|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Concatenate.new n, last  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;}  
> &nbsp;&nbsp;stack  
> end
> 
> class Regexp
> 
> &nbsp;&nbsp;def generate  
> &nbsp;&nbsp;&nbsp;&nbsp;toTree("("+self.inspect[1..-2]+")").simplify.unfold.to\_a.uniq  
> &nbsp;&nbsp;end
> 
> end

> **···**
>
> Begin forwarded message:
