word_scramble 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -17,3 +17,5 @@ test/version_tmp
17
17
  tmp
18
18
  .rvmrc
19
19
  .rspec
20
+ time.rb
21
+ time/*
data/README.md CHANGED
@@ -29,8 +29,8 @@ You can use it from the command line, like this
29
29
  Or you can call the Descrambler library directly
30
30
 
31
31
  ```ruby
32
- descrambler = WordScramble::Descrambler.new("realapin")
33
- descrambler.matching_words # => ["airplane", ... ]
32
+ descrambler = WordScramble::Descrambler.new("liopts")
33
+ descrambler.matching_words # => ["pilots", "spoilt", "pistol"]
34
34
  ```
35
35
 
36
36
  ## Contributing
data/bin/descramble CHANGED
@@ -7,6 +7,9 @@ if ARGV.empty?
7
7
  end
8
8
 
9
9
  descrambler = WordScramble::Descrambler.new(ARGV.first)
10
+
11
+ puts "no matches" if descrambler.matching_words.empty?
12
+
10
13
  descrambler.matching_words.each do |word|
11
14
  puts word
12
15
  end
data/lib/word_scramble.rb CHANGED
@@ -7,23 +7,26 @@ require "word_scramble/version"
7
7
  # A game played in the Virgin Airlines waiting lounge.
8
8
  #
9
9
  # Input is a scrambled string.
10
- # You try to make a word (or words) from those letters.
10
+ # You try to make a word from those letters.
11
11
  #
12
12
  # ===== Examples
13
- # "valesages" => "las vegas"
13
+ # "rnmteial" => "terminal"
14
14
  # "realapin" => "airplane"
15
15
  # "liopt" => "pilot"
16
16
  #
17
17
  # ==== Usage
18
18
  #
19
19
  # descrambler = WordScramble::Descrambler.new("realapin")
20
- # descrambler.matching_words # => ["airplane", ... ]
20
+ # descrambler.matching_words # => ["airplane"]
21
21
 
22
22
  module WordScramble
23
23
  DICTIONARY = File.open(File.expand_path('../dictionary.txt', __FILE__)) do |f|
24
- dictionary = []
24
+ dictionary = {}
25
25
  f.each_line do |line|
26
- dictionary.push(line.strip)
26
+ word = line.strip
27
+ length = word.length
28
+ dictionary[length] ||= []
29
+ dictionary[length].push(word)
27
30
  end
28
31
  dictionary
29
32
  end
@@ -31,3 +34,4 @@ end
31
34
 
32
35
  require File.expand_path('../word_scramble/scrambled_word', __FILE__)
33
36
  require File.expand_path('../word_scramble/descrambler', __FILE__)
37
+ require File.expand_path('../word_scramble/letter_frequency', __FILE__)
@@ -13,7 +13,7 @@ class WordScramble::Descrambler
13
13
  end
14
14
 
15
15
  def descramble
16
- WordScramble::DICTIONARY.each do |word|
16
+ same_length_words.each do |word|
17
17
  if @scrambled_word.can_make?(word)
18
18
  @matching_words.push(word)
19
19
  end
@@ -22,4 +22,12 @@ class WordScramble::Descrambler
22
22
  @already_descrambled = true
23
23
  end
24
24
 
25
+ def same_length_words
26
+ if WordScramble::DICTIONARY[@scrambled_word.length].nil?
27
+ []
28
+ else
29
+ WordScramble::DICTIONARY[@scrambled_word.length]
30
+ end
31
+ end
32
+
25
33
  end
@@ -0,0 +1,18 @@
1
+ class WordScramble::LetterFrequency
2
+ attr_reader :frequency_hash, :length
3
+
4
+ def initialize(str)
5
+ @length = str.length
6
+ @frequency_hash = {}
7
+
8
+ str.downcase.each_char do |c|
9
+ @frequency_hash[c] ||= 0
10
+ @frequency_hash[c] += 1
11
+ end
12
+ end
13
+
14
+ def ==(other)
15
+ other.is_a?(WordScramble::LetterFrequency) and other.frequency_hash == @frequency_hash
16
+ end
17
+
18
+ end
@@ -1,38 +1,17 @@
1
1
  class WordScramble::ScrambledWord
2
2
 
3
3
  def initialize(scrambled_word)
4
- @scrambled_word = scrambled_word
4
+ @scrambled_word = WordScramble::LetterFrequency.new(scrambled_word)
5
5
  end
6
6
 
7
7
  def can_make(word)
8
- WordChecker.new(@scrambled_word, word).matches?
8
+ WordScramble::LetterFrequency.new(word) == @scrambled_word
9
9
  end
10
10
 
11
- alias_method :can_make?, :can_make
12
-
13
- class WordChecker
14
- def initialize(scrambled_word, word)
15
- @scrambled_letters = scrambled_word.downcase.split('').sort.inject({}) do |frequency_hash, l|
16
- frequency_hash[l] ||= 0
17
- frequency_hash[l] += 1
18
- frequency_hash
19
- end
20
- @word_letters = word.downcase.split('').sort.inject({}) do |frequency_hash, l|
21
- frequency_hash[l] ||= 0
22
- frequency_hash[l] += 1
23
- frequency_hash
24
- end
25
- end
26
-
27
- def matches?
28
- @word_letters.each do |letter, count|
29
- scrambled_count = @scrambled_letters[letter]
30
- return false if scrambled_count.nil? or scrambled_count < count
31
- end
32
- return true
33
- end
34
-
35
- alias_method :matches, :matches?
11
+ def length
12
+ @scrambled_word.length
36
13
  end
37
14
 
15
+ alias_method :can_make?, :can_make
16
+
38
17
  end
@@ -1,3 +1,3 @@
1
1
  module WordScramble
2
- VERSION = "0.0.5"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -18,9 +18,27 @@ describe WordScramble::Descrambler do
18
18
  descrambled.should include("airplane")
19
19
  end
20
20
 
21
- it "orders the matching words by length" do
21
+ it "only returns words of the same length as the scrambled string" do
22
22
  @scrambled = "liopt"
23
- descrambled.first.downcase.should == "pilot"
23
+ descrambled.select { |word| word.length != @scrambled.length }.should be_empty
24
+ end
25
+
26
+ it "doesnt crash with strings that are longer than any words in the dictionary" do
27
+ @scrambled = "a" * 100
28
+ lambda {descrambled}.should_not raise_error
29
+ end
30
+
31
+ describe "same_length_words" do
32
+ let(:descrambler) { WordScramble::Descrambler.new(@scrambled) }
33
+ it "returns an array of words" do
34
+ @scrambled = "fxo"
35
+ descrambler.same_length_words.should include("fox")
36
+ end
37
+
38
+ it "returns an empty array if there are no words of the same length" do
39
+ @scrambled = "a" * 100
40
+ descrambler.same_length_words.should be_empty
41
+ end
24
42
  end
25
43
 
26
44
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe WordScramble::LetterFrequency do
4
+ it 'knows that "pilots" and "spoilt" have the same letters' do
5
+ pilots = WordScramble::LetterFrequency.new("pilots")
6
+ spoilt = WordScramble::LetterFrequency.new("spoilt")
7
+ pilots.should == spoilt
8
+ end
9
+
10
+ it 'knows that "neocon" and "satan" have different letter' do
11
+ neocon = WordScramble::LetterFrequency.new("neocon")
12
+ satan = WordScramble::LetterFrequency.new("satan")
13
+ neocon.should_not == satan
14
+ end
15
+
16
+ it "knows how long the word should be" do
17
+ WordScramble::LetterFrequency.new("pop").length.should == 3
18
+ end
19
+ end
@@ -12,5 +12,9 @@ describe WordScramble::ScrambledWord do
12
12
  sw.can_make("hooligans").should == false
13
13
  end
14
14
 
15
+ it "knows how longs it is" do
16
+ sw.length.should == "valesags".length
17
+ end
18
+
15
19
  end
16
20
  end
@@ -1,11 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe WordScramble do
4
- it "has a Dictionary" do
5
- WordScramble::DICTIONARY.count.should be > 80000
6
- end
7
4
 
8
- it "has some common words in the dictionary" do
9
- WordScramble::DICTIONARY.should include("porridge")
5
+ describe "Dictionary" do
6
+ let(:d) { WordScramble::DICTIONARY }
7
+ it "contains hello" do
8
+ d[5].should include("hello")
9
+ end
10
+
11
+ it "contains fox" do
12
+ d[3].should include("fox")
13
+ end
14
+
15
+ it "contains willow" do
16
+ d[6].should include("willow")
17
+ end
18
+
10
19
  end
11
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: word_scramble
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-15 00:00:00.000000000 Z
12
+ date: 2012-04-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &75348930 !ruby/object:Gem::Requirement
16
+ requirement: &75502060 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *75348930
24
+ version_requirements: *75502060
25
25
  description: Take a string of scrambled characters and find all the words that can
26
26
  be made from those characters.
27
27
  email:
@@ -40,12 +40,13 @@ files:
40
40
  - lib/dictionary.txt
41
41
  - lib/word_scramble.rb
42
42
  - lib/word_scramble/descrambler.rb
43
+ - lib/word_scramble/letter_frequency.rb
43
44
  - lib/word_scramble/scrambled_word.rb
44
45
  - lib/word_scramble/version.rb
45
46
  - spec/descrambler_spec.rb
47
+ - spec/letter_frequency_spec.rb
46
48
  - spec/scrambled_word_spec.rb
47
49
  - spec/spec_helper.rb
48
- - spec/word_checker_spec.rb
49
50
  - spec/word_scramble_spec.rb
50
51
  - word_scramble.gemspec
51
52
  homepage: ''
@@ -75,7 +76,7 @@ summary: Written to solve the Word Scramble game that they give out on Virgin Ai
75
76
  when the flight is delayed.
76
77
  test_files:
77
78
  - spec/descrambler_spec.rb
79
+ - spec/letter_frequency_spec.rb
78
80
  - spec/scrambled_word_spec.rb
79
81
  - spec/spec_helper.rb
80
- - spec/word_checker_spec.rb
81
82
  - spec/word_scramble_spec.rb
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe WordScramble::ScrambledWord::WordChecker do
4
- describe "lelho" do
5
- let(:scrambled_word) { "lelho" }
6
-
7
- it "matches 'hello'" do
8
- wc = WordScramble::ScrambledWord::WordChecker.new(scrambled_word, "hello")
9
- wc.matches?.should be_true
10
- end
11
-
12
- it "doesn't match 'kittens'" do
13
- wc = WordScramble::ScrambledWord::WordChecker.new(scrambled_word, "kittens")
14
- wc.matches.should be_false
15
- end
16
-
17
- it "'princess' doesn't match 'princes'" do
18
- wc = WordScramble::ScrambledWord::WordChecker.new("princes", "princess")
19
- wc.matches.should be_false
20
- end
21
-
22
- it "is case insensitive" do
23
- wc = WordScramble::ScrambledWord::WordChecker.new("chicago", "Chicago")
24
- wc.matches.should be_true
25
- end
26
- end
27
- end