#!/usr/bin/env ruby## find_first_singleton.rb# # Given a string, find the first character that appears only once in the# string. For instance, given the string “aabbcddd”, the first character# that appears only once is the “c” found at the 4th character in the# string, counting from 0. Be sure that your program properly handles the# case that all characters appear more than once.# % find_first_singleton -unrepeated-char 'somestring'# o# String.each_char_with_index {|c| code block with #c }classStringdefeach_char_with_indexx=0whilex<self.lengthdochar=self[x,1]yield[char,x]x+=1endend# String.find_first_singleton(char) => [char, index] or nildeffind_first_singletonletters={}# hash of letters & occurencesself.each_char_with_indexdo|letter,x|letters[letter]||=0letters[letter]+=1end# all letters counted; find the first with count == 1self.each_char_with_indexdo|letter,x|return[letter,x]ifletters[letter]==1endnilendend# String enhancement# [letter, index].pretty => "#{letter} at #{index}"classArray# [x, y].compare([r, s])defcompare(pair)s,x=pairreturntrueifself.nil?&&s.nil?returnfalseifself.nil?self[0]==s&&self[1]==xenddefprettyself.nil??'nil':self[0].to_s+' at '+self[1].to_sendendclassNilClassdefpretty'nil'endenddefrun_teststests=[['foo',['f',0]],['foobar',['f',0]],['oofbar',['f',2]],['foofbar',['b',4]],['foofbab',['a',5]],['foofbob',[nil]],['bar',['b',0]],['barboy',['a',1]],['barfbag',['r',2]],['barfbar',['f',3]],['barffrab',[nil]]]testc=0whiletestc<tests.sizedoinstr,answer=tests[testc]testc+=1printf"Test %02d: %10s => ",testc,instrresult=instr.find_first_singletonifanswer.compare(result)puts"OK: #{result.pretty}\n"elseputs"Failed: got #{result.pretty}; should be #{answer.pretty}"endendexitend# run_testsifARGV.size<1# if no args, run testsrun_testselsestr=ARGV.shift# get the argumentputs"Input: #{str}"putsstr.find_first_singleton.prettyendexit