pressletter 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +6 -0
- data/Gemfile +1 -1
- data/README.md +52 -5
- data/benchmarks/benchmark.rb +92 -0
- data/lib/pressletter/core/find_words.rb +5 -0
- data/lib/pressletter/version.rb +1 -1
- metadata +3 -1
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,16 +1,46 @@
|
|
1
1
|
# Pressletter
|
2
2
|
|
3
|
+
[![Build Status](https://secure.travis-ci.org/searls/pressletter.png)](http://travis-ci.org/searls/pressletter)
|
4
|
+
|
3
5
|
Letterpress is a fantastic game for iOS written by [Loren Brichter](http://www.atebits.com). Pressletter is a gem that solves Letterpress boards using an included plaintext dictionary of words.
|
4
6
|
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
### global install
|
10
|
+
|
11
|
+
To install pressletter to your system, run:
|
12
|
+
|
13
|
+
```
|
14
|
+
$ gem install pressletter
|
15
|
+
```
|
16
|
+
|
17
|
+
### bundler
|
18
|
+
|
19
|
+
If you're using [Bundler](http://gembundler.com), add the pressletter gem to your Gemfile:
|
20
|
+
|
21
|
+
``` ruby
|
22
|
+
source 'https://rubygems.org'
|
23
|
+
|
24
|
+
gem 'pressletter'
|
25
|
+
```
|
26
|
+
|
27
|
+
and then run:
|
28
|
+
|
29
|
+
```
|
30
|
+
$ bundle install
|
31
|
+
```
|
32
|
+
|
33
|
+
Inside your Bundler project, the binary can then be accessed with `bundle exec pressletter`.
|
34
|
+
|
5
35
|
## Example
|
6
36
|
|
7
|
-
Here's what a board looked like in a game I played with @steveklabnik:
|
37
|
+
Here's what a board looked like in a game I played with [@steveklabnik](https://github.com/steveklabnik):
|
8
38
|
|
9
39
|
![pressletter Screen](http://i.minus.com/ibv4sMC7Msl5Fv.png)
|
10
40
|
|
11
|
-
Using the pressletter gem, you can
|
41
|
+
Using the pressletter gem, you can search for playable words by providing the 25 letters on the game board (even any repeats, since the game rules stipulate that each letter can only be used as many times as it appears on the board).
|
12
42
|
|
13
|
-
|
43
|
+
For instance, the letters in the provided screenshot are: `E I P T C T B N T Y M E I P H O X V I T K M Z I B`.
|
14
44
|
|
15
45
|
### command-line
|
16
46
|
|
@@ -37,13 +67,30 @@ E I P T C T B N T Y M E I P H O X V I T K M Z I B
|
|
37
67
|
|
38
68
|
```
|
39
69
|
|
40
|
-
|
70
|
+
In each case, the results will print in order of largest-to-smallest length (with secondary alphabetical order for words of the same length). The output looks like:
|
71
|
+
|
72
|
+
```
|
73
|
+
$ pressletter eiptctbntymeiphoxvitkmzib
|
74
|
+
COMPETITIVITE
|
75
|
+
BIOETHICIEN
|
76
|
+
...
|
77
|
+
XI
|
78
|
+
```
|
79
|
+
|
80
|
+
### Ruby
|
81
|
+
|
82
|
+
You can, of course, also look for solutions using pure ruby. The public API is exceedingly simple:
|
83
|
+
|
84
|
+
**Pressletter.solve(letters[, config])**
|
85
|
+
|
86
|
+
For input, all that's needed is a string or array of candidate letters. A config object that responds to `dictionary_location` with a path of a dictionary file can also be optionally provided. An array (sorted largest-to-smallest) of valid words is returned.
|
41
87
|
|
42
|
-
Here's an interactive
|
88
|
+
Here's an interactive session that uses the gem programmatically:
|
43
89
|
|
44
90
|
``` ruby
|
45
91
|
$ irb
|
46
92
|
irb(main):001:0> require 'pressletter'
|
93
|
+
=> true
|
47
94
|
irb(main):002:0> letters = ["e", "i", "p", "t", "c", "t", "b", "n", "t", "y", "m", "e", "i", "p", "h", "o", "x", "v", "i", "t", "k", "m", "z", "i", "b"]
|
48
95
|
=> ["e", "i", "p", "t", "c", "t", "b", "n", "t", "y", "m", "e", "i", "p", "h", "o", "x", "v", "i", "t", "k", "m", "z", "i", "b"]
|
49
96
|
irb(main):003:0> Pressletter.solve(letters)
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Bench
|
2
|
+
def self.mark(name, &experiment)
|
3
|
+
@marks ||= Marks.new
|
4
|
+
@marks.add(name, &experiment)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.run
|
8
|
+
return unless @marks
|
9
|
+
@marks.run
|
10
|
+
end
|
11
|
+
|
12
|
+
class Marks
|
13
|
+
def initialize
|
14
|
+
@marks = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(name, &experiment)
|
18
|
+
raise "Benchmark named \"#{name}\" was already defined!" if @marks.has_key?(name)
|
19
|
+
@marks[name] = {:experiment => experiment }
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
require 'benchmark'
|
24
|
+
|
25
|
+
Results.new(
|
26
|
+
@marks.map do |(name, mark)|
|
27
|
+
begin
|
28
|
+
{
|
29
|
+
:name => name,
|
30
|
+
:errors => nil,
|
31
|
+
:time => Benchmark.measure(&mark[:experiment]).total
|
32
|
+
}
|
33
|
+
rescue
|
34
|
+
{
|
35
|
+
:name => name,
|
36
|
+
:errors => [$!.message],
|
37
|
+
:time => nil
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Results
|
46
|
+
def initialize(results)
|
47
|
+
@results = results
|
48
|
+
end
|
49
|
+
|
50
|
+
def as_array
|
51
|
+
@results
|
52
|
+
end
|
53
|
+
|
54
|
+
def total_time
|
55
|
+
raise failure_message if failures?
|
56
|
+
@results.map {|r| r[:time] }.inject(&:+)
|
57
|
+
end
|
58
|
+
|
59
|
+
def average_time
|
60
|
+
total_time / @results.size
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def failure_message
|
66
|
+
"Errors occurred, total benchmark time is meaningless:\n\n #{errors}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def failures?
|
70
|
+
@results.any? {|r| r[:errors] }
|
71
|
+
end
|
72
|
+
|
73
|
+
def errors
|
74
|
+
@results.map { |r| r[:errors] }.flatten.compact.join("\n")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
82
|
+
require 'pressletter'
|
83
|
+
|
84
|
+
Bench.mark "eiptctbntymeiphoxvitkmzib" do
|
85
|
+
Pressletter.solve("eiptctbntymeiphoxvitkmzib")
|
86
|
+
end
|
87
|
+
|
88
|
+
# Bench.mark "agslumxaeyylyuwfoszmddjhi" do
|
89
|
+
# Pressletter.solve("agslumxaeyylyuwfoszmddjhi")
|
90
|
+
# end
|
91
|
+
|
92
|
+
puts Bench.run.total_time
|
@@ -10,6 +10,7 @@ module Pressletter::Core
|
|
10
10
|
private
|
11
11
|
|
12
12
|
def letters_can_buy?(letters, word)
|
13
|
+
return if impossible?(letters, word)
|
13
14
|
letters = letters.as_hash.dup
|
14
15
|
word.dup.split('').all? do |char|
|
15
16
|
decrement_char!(char, letters)
|
@@ -20,4 +21,8 @@ private
|
|
20
21
|
letters[char] -= 1 if letters[char] && letters[char] > 0
|
21
22
|
end
|
22
23
|
|
24
|
+
def impossible?(letters, word)
|
25
|
+
word.split('').any? { |c| !letters.as_array.include?(c) }
|
26
|
+
end
|
27
|
+
|
23
28
|
end
|
data/lib/pressletter/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pressletter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -73,12 +73,14 @@ extra_rdoc_files: []
|
|
73
73
|
files:
|
74
74
|
- .gitignore
|
75
75
|
- .rspec
|
76
|
+
- .travis.yml
|
76
77
|
- Gemfile
|
77
78
|
- Guardfile
|
78
79
|
- LICENSE.txt
|
79
80
|
- README.md
|
80
81
|
- Rakefile
|
81
82
|
- assets/dictionary.txt
|
83
|
+
- benchmarks/benchmark.rb
|
82
84
|
- bin/pressletter
|
83
85
|
- lib/pressletter.rb
|
84
86
|
- lib/pressletter/core/create_letters.rb
|