On Aug 12, 2011, at 01:19 PM, Gavin K. [email protected] wrote:
On Aug 12, 2011, at 12:31 PM, Jesper B. [email protected] wrote:
I have a list of 22000 8 digit numbers. Im looking for a number which is
the “best” from a defined set of patterns.
a pattern could be “abababab” givng a score of 10, and another would be
“abab” giving a score of 5. Patterns could also be specific digits, so
another pattern defining “a0b0” - giving 7 points would mean that it
would only match if there is zeroes in the number such as 10203040 (with
all the above rules it would give 21 points).
This way the number 52525252 would give a score of 25 and the number
52526262 would give the score of 10.
Code follows; it lets you perform arbitrary scoring tests, and then sums
those up over all sub-sections of a string. Note that 52525252 scores 35
(not 25), because it gets 10 from abababab and 25 from five matches of
“abab” - three occurrences of 5252 and two occurrences of 2525. If this
is not correct, then you’ll have to explain what the matching rules are
more exactly.
…however, the code I posted gave an incorrect score for 52526262,
since my regexps were not anchored. Here’s an updated version of the
code with a debug mode that fixes the problem and shows you when the
matches are found. (Actual code is preceded by the output.)
#=> Scoring “52525252”
#=> …“52525252” scored 10 using abababab
#=> …“52525252” scored 5 using abab
#=> …“2525252” scored 5 using abab
#=> …“525252” scored 5 using abab
#=> …“25252” scored 5 using abab
#=> …“5252” scored 5 using abab
#=> …final score: 35
#=> Scoring “52526262”
#=> …“52526262” scored 5 using abab
#=> …“26262” scored 5 using abab
#=> …“6262” scored 5 using abab
#=> …final score: 15
#=> Scoring “10203040”
#=> …“10203040” scored 7 using a0b0
#=> …“203040” scored 7 using a0b0
#=> …“3040” scored 7 using a0b0
#=> …final score: 21
#=> “52525252”
def run
$DEBUG = true
numbers = DATA.readlines.map(&:chomp)
p numbers.max_by{ |s| Scorer.score(s) }
#=> “52525252”
end
module Scorer
@scorers = {}
def self.add(name,&block)
@scorers[name] = block
end
def self.score(str)
puts “Scoring #{str.inspect}” if $DEBUG
total = 0
(0…str.length).each do |offset|
s = str[offset…-1]
@scorers.each do |name,block|
score = block[s].to_i
if $DEBUG && score!=0
puts “…#{s.inspect} scored #{score} using #{name}”
end
total += score
end
end
puts “…final score: #{total}”
total
end
end
Scorer.add(‘abababab’){ |s| 10 if s =~ /^(.)(.)\1\2\1\2\1\2/ &&
s[0]!=s[1] }
Scorer.add(‘abab’ ){ |s| 5 if s =~ /^(.)(.)\1\2/ && s[0]!=s[1] }
Scorer.add(‘a0b0’ ){ |s| 7 if s =~ /^(.)0(.)0/ && s[0]!=s[2] }
run if FILE==$0
END
52525252
52526262
10203040