From: Joe Date: 2007-12-11T09:06:18+09:00 Subject: Re: [QUIZ] Word Loop (#149) /(.*?)(.)(.(?:..)+?)\2(.*)/i break it up: (.*?) looks for a non-greedy string of anything (.) any character (.(?:..)+?) non-greedy matching of an odd number of characters. I'm not sure what the ?: adds to the regular expression. I got this: "(?: ) grouping without backreferences" from here: http://www.zenspider.com/Languages/Ruby/QuickRef.html#11 \2 matches the any character from before (.*) a string of any length at the end i - at the end that means case insensitive. Joe On Dec 10, 2007 1:14 PM, Michal Suchanek wrote: > > On 09/12/2007, Ken Bloom wrote: > > > > def loopword word > > matchinfo= > > word.match(/(.*?)(.)(.(?:..)+?)\2(.*)/i) > > if matchinfo > > _,before,letter,looplets,after=matchinfo.to_a > > pad=" "*before.size > > after.reverse.split(//).each{|l| puts pad+l} > > looplets=looplets.split(//) > > puts before+letter+looplets.shift > > until looplets.empty? > > puts pad+looplets.pop+looplets.shift > > end > > else > > puts "No loop." > > end > > end > > > > loopword "Mississippi" > > puts > > loopword "Markham" > > puts > > loopword "yummy" > > puts > > loopword "Dana" > > puts > > loopword "Organization" > > > > > > outputs: > > > > i > > p > > p > > Mis > > ss > > si > > > > Ma > > ar > > hk > > > > yu > > mm > > > > No loop. > > > > n > > Or > > ig > > ta > > an > > zi > > > > (The last is a testcase which makes sure that I get the #shifts and #pops > > right) > > > > I thought this one is too easy once you understand what it is about > but people always come up with difficult solutions. I wish I knew what > the regexp does :S > > For those who cannot understand it either: > > def indexes l, i > res = [] > ptr = 0 > while (ptr = l.index i, ptr) > res << ptr > ptr+=1 > end > res > end > # . > #.c1=c5..c2 > # . . > # c4.....c3 > def draw_loop word, c1, c5 > length = (c5 - c1) -4 > width = length/4 > height = length/2 - width > word = word[0..0].upcase + word[1..-1] > c2 = c1 + width +1 > c3 = c2 + height +1 > c4 = c3 + width +1 > word[(c5+1)..-1].reverse.scan(/./).map{|c| " "*c1 + c + "\n"}.join + > word[0..c2] + "\n" + > (1..height).map{|i| " "*c1 + word[c5 - i].chr + " "*width + > word[c2 + i].chr + "\n"}.join + > " "*c1 + word[c3..c4].reverse + "\n" > end > def wloop word > word=word.downcase > tried=[] > ptr=0 > while ptr < word.length > if tried.include? word[ptr] > ptr+=1 > next > end > char = word[ptr] > tried << char > pos = indexes word, char > next unless pos.length > 1 > i, j = 0 > while i < pos.length - 1 > j=pos.length - 1 > while j > i > diff = pos[j] - pos[i] > if (diff)>=4 && (diff) % 2 == 0 > return draw_loop word, pos[i], pos[j] > end > j-=1 > end > i+=1 > end > ptr += 1 > end > "No loop \n" > end > >