项目Euler Q22:为什么我会根据删除引号时得到不同的结果?

时间:2013-07-07 21:49:23

标签: ruby

如果我运行这个怎么样:

get_score = proc{ |word, position|
  val = 0
  word[1..-2].each_byte do |c|
    val = val + (c.ord - 64)
  end
  name_score = val*(position+1)
}

puts File.read("names.txt").split(',').sort.map.with_index(&get_score).inject(:+)

我得到答案:871193872

但如果我这样做:

get_score = proc{ |word, position|
  val = 0
  word.each_byte do |c|
    val = val + (c.ord - 64)
  end
  name_score = val*(position+1)
}

puts File.read("names.txt").gsub('"','').split(',').sort.map.with_index(&get_score).inject(:+)

我明白了:871190344

(不同之处在于,在第二个我使用gsub删除引号但在第一个我保留它们直到我使用单词[1 ..- 2]只迭代引号之间的字符)

在第三个版本中,它使用scan(/ \ w + /)搜索空格,即使文件中没有空格,但这是给出正确答案的那个:

names = File.open('names.txt').read.scan(/\w+/).sort
puts names.map { |name|
        word_score = name.each_byte.map { |c| c - 64 }.reduce(:+)
        (names.index(name) + 1) * word_score
}.reduce(:+)

修改

以下是示例数据:http://projecteuler.net/project/names.txt

1 个答案:

答案 0 :(得分:2)

我担心您复制并粘贴输入文件或类似的内容而不是保存它。我尝试了你的两个代码,它们工作得很好:

$ ruby p22.rb
87119XX82
87119XX82

现在,如果你问我怎么写它(你没有写:-)),让我们保留抽象get_score但重构一下:

indexes = Hash[("A".."Z").map.with_index(1).to_a]
get_score = proc { |word, idx| indexes.values_at(*word.chars).reduce(:+) * idx }
sorted_names = File.read("names.txt").delete('"').split(',').sort
solution = sorted_names.map.with_index(1, &get_score).reduce(0, :+)