CHARDONNAY OR CABERNET (CODEEVAL)

だんだん問題文が物語風になってきました。
文字列の中に文字列の断片が含まれるかどうかを探索する問題。
当初正規表現で書きましたが、どうもscoreが100にならないので
1文字ずつ探索しては置換する方法で実装。

CHALLENGE DESCRIPTION:

Your good friend Tom is admirer of tasting different types of fine wines. What he loves even more is to guess their names. One day, he was sipping very extraordinary wine. Tom was sure he had tasted it before, but what was its name? The taste of this wine was so familiar, so delicious, so pleasant… but what is it exactly? To find the answer, Tom decided to taste the wines we had. He opened wine bottles one by one, tasted different varieties of wines, but still could not find the right one. He was getting crazy, “No, it’s not that!” desperately breaking a bottle of wine and opening another one. Tom went off the deep end not knowing what this wine was. Everything he could say is just several letters of its name. You can no longer look at it and decided to help him. Your task is to write a program that will find the wine name, containing all letters that Tom remembers.

INPUT SAMPLE:

The first argument is a path to a file. Each line includes a test case, which contains names of wines and letters that Tom remembers. Names and letters are separated by a vertical bar ‘|’.

Cabernet Merlot Noir | ot
Chardonnay Sauvignon | ann
Shiraz Grenache | o

OUTPUT SAMPLE:

You should print wine names, containing all letters that Tom remembered. Letters can be anywhere in wine names. If there is no name with all letters, print False.

Merlot
Chardonnay Sauvignon
False

CONSTRAINTS:

  1. Wine name length can be from 2 to 15 characters.
  2. Number of letters that Tom remembered does not exceed 5.
  3. Number of wine names in a test case can be from 2 to 10.
  4. If there is no wine name containing all letters, print False.
  5. The number of test cases is 40.

My Code

#!/usr/bin/env ruby -w

def find_candidates(wines, keyword)
  # 正規表現で実装したが、score 100 にならなかった
  # pattern = /#{keyword.split("").join("(.*?)")}/i
  # wines.find_all { |wine| wine =~ pattern }

  wines.inject([]) do |candidates, wine|
    wine_str = wine.dup.downcase
    candidates << wine if keyword.each_char.all? { |char| wine_str.sub!(char, "") }
    candidates
  end
end

ARGF.each_line do |line|
  str_wines, keyword = line.chomp.split(" | ")
  wines = str_wines.split
  candidates = find_candidates(wines, keyword)
  puts (candidates.empty? ? "False" : candidates.join(" "))
end