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 +2 -0
- data/README.md +2 -2
- data/bin/descramble +3 -0
- data/lib/word_scramble.rb +9 -5
- data/lib/word_scramble/descrambler.rb +9 -1
- data/lib/word_scramble/letter_frequency.rb +18 -0
- data/lib/word_scramble/scrambled_word.rb +6 -27
- data/lib/word_scramble/version.rb +1 -1
- data/spec/descrambler_spec.rb +20 -2
- data/spec/letter_frequency_spec.rb +19 -0
- data/spec/scrambled_word_spec.rb +4 -0
- data/spec/word_scramble_spec.rb +14 -5
- metadata +7 -6
- data/spec/word_checker_spec.rb +0 -27
data/.gitignore
CHANGED
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("
|
33
|
-
descrambler.matching_words # => ["
|
32
|
+
descrambler = WordScramble::Descrambler.new("liopts")
|
33
|
+
descrambler.matching_words # => ["pilots", "spoilt", "pistol"]
|
34
34
|
```
|
35
35
|
|
36
36
|
## Contributing
|
data/bin/descramble
CHANGED
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
|
10
|
+
# You try to make a word from those letters.
|
11
11
|
#
|
12
12
|
# ===== Examples
|
13
|
-
# "
|
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
|
-
|
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
|
-
|
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
|
-
|
8
|
+
WordScramble::LetterFrequency.new(word) == @scrambled_word
|
9
9
|
end
|
10
10
|
|
11
|
-
|
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
|
data/spec/descrambler_spec.rb
CHANGED
@@ -18,9 +18,27 @@ describe WordScramble::Descrambler do
|
|
18
18
|
descrambled.should include("airplane")
|
19
19
|
end
|
20
20
|
|
21
|
-
it "
|
21
|
+
it "only returns words of the same length as the scrambled string" do
|
22
22
|
@scrambled = "liopt"
|
23
|
-
descrambled.
|
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
|
data/spec/scrambled_word_spec.rb
CHANGED
data/spec/word_scramble_spec.rb
CHANGED
@@ -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
|
-
|
9
|
-
WordScramble::DICTIONARY
|
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
|
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-
|
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: &
|
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: *
|
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
|
data/spec/word_checker_spec.rb
DELETED
@@ -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
|