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 +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
|