word_scramble 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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