Skip to content

Instantly share code, notes, and snippets.

@lrechert
Last active April 18, 2016 18:41
Show Gist options
  • Select an option

  • Save lrechert/a29c14abbfca4837ad78 to your computer and use it in GitHub Desktop.

Select an option

Save lrechert/a29c14abbfca4837ad78 to your computer and use it in GitHub Desktop.
Ruby Weekly Challenge - Pattern Matcher
# Description:
# word_pattern(pattern, string)
# that given a pattern and a string str, find if str follows the same sequence as pattern.
# For example:
# word_pattern('abab', 'truck car truck car') == true
# word_pattern('aaaa', 'dog dog dog dog') == true
# word_pattern('abab', 'apple banana banana apple') == false
# word_pattern('aaaa', 'cat cat dog cat') == false
def word_pattern(pattern, string)
WordPattern.new(pattern: pattern, string: string).match?
end
class WordPattern
attr_reader :under_test, :pattern, :string, :expectations
def initialize(pattern:, string:)
fail ArgumentError, 'pattern and string must not be nil.' if pattern.nil? || string.nil?
@under_test = string.split(" ")
fail ArgumentError, 'pattern and string must be of equal length' unless pattern.length == under_test.length
@pattern = pattern
@string = string
@expectations = {}
end
def match?
(0..pattern.size-1).each do |i|
return false if new_pattern_but_expectation_exists(pattern[i], under_test[i]) ||
pattern_exists_but_new_expectation(pattern[i], under_test[i])
expectations[pattern[i]] = under_test[i] if new_pattern?(i)
return false unless expectations[pattern[i]] == under_test[i]
end
return true
end
def pattern_exists_but_new_expectation(p, s)
!new_pattern?(p) && new_string?(s)
end
def new_pattern_but_expectation_exists(p, s)
new_pattern?(p) && !new_string?(s)
end
def new_pattern?(p)
!expectations.keys.include?(p)
end
def new_string?(s)
!expectations.values.include?(s)
end
end
require_relative '../pattern_matcher'
describe "word_pattern" do
context "when the pattern matches" do
it "returns true" do
expect(word_pattern('abab', 'apple banana apple banana')).to be(true)
end
it "returns true" do
expect(word_pattern('abba', 'car truck truck car')).to be(true)
end
end
context "when the pattern does not match" do
it "returns false" do
expect(word_pattern('abab', 'apple banana banana apple')).to be(false)
end
it "returns false" do
expect(word_pattern('abba', 'dog dog dog dog')).to be(false)
end
it "returns false" do
expect(word_pattern('abcd', 'dog cat dog dog')).to be(false)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment