biscotti 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/exe/biscotti ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ Signal.trap('INT') { exit(130) }
5
+ Signal.trap('SIGINT') { exit(130) }
6
+ Signal.trap('TERM') { exit(143) }
7
+
8
+ require 'bundler/setup'
9
+
10
+ require 'biscotti'
11
+ require 'biscotti/cli'
12
+
13
+ require 'optparse'
14
+
15
+ OptionParser.new do |opts|
16
+ opts.banner = 'Usage: bundle exec biscotti [--version] [--help] <letters>'
17
+
18
+ opts.on('-V', '--version', 'Print version info') do
19
+ $stdout.puts("biscotti version #{Biscotti::VERSION}")
20
+ exit(0)
21
+ end
22
+
23
+ # TODO: Print dictionary
24
+ # TODO: Minimum character count
25
+ # TODO: Provide a custom dictionary
26
+ # TODO: Output as a grouped list by word length
27
+
28
+ opts.on_tail('-h', '--help', 'Show this message') do
29
+ warn(opts)
30
+ exit(0)
31
+ end
32
+ end.parse!
33
+
34
+ # raise 'File not processable' unless Biscotti::CLI.processable?
35
+
36
+ begin
37
+ dictionary = Biscotti.load_dictionary(File.join(Dir.pwd, 'data', 'biscotti', 'words.lst').freeze)
38
+ letters = ARGV.flat_map { |word| word.downcase.split('') }.sort.join
39
+ min_word_length = 2
40
+
41
+ output = Biscotti.find_words(
42
+ letters,
43
+ dictionary: dictionary,
44
+ min_word_length: min_word_length
45
+ )
46
+
47
+ output.each do |word|
48
+ $stdout.puts(word)
49
+ end
50
+ rescue Errno::EPIPE
51
+ exit(74)
52
+ end
data/lib/biscotti.rb ADDED
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'biscotti/version'
4
+
5
+ module Biscotti
6
+ module_function
7
+
8
+ def letters_frequency_idx(letters)
9
+ Hash[
10
+ letters
11
+ .group_by { |x| letters.count { |y| x == y } }
12
+ .flat_map do |k, v|
13
+ v.uniq.map { |l| [l, k] }
14
+ end
15
+ ]
16
+ end
17
+
18
+ def load_dictionary(dictionary_file)
19
+ File.open(dictionary_file, 'r').readlines
20
+ end
21
+
22
+ def word_length_idx(words)
23
+ words.group_by(&:length)
24
+ end
25
+
26
+ def find_words(input, min_word_length: 2, dictionary: [])
27
+ puts "#{dictionary.count} words in dictionary"
28
+
29
+ letters = input.split('').sort
30
+
31
+ letters_frequency_idx = Biscotti.letters_frequency_idx(letters)
32
+
33
+ words = letters.count.downto(min_word_length).each_with_object([]) do |letter_count, w|
34
+ w.concat(letters.permutation(letter_count).to_a.map(&:join))
35
+ end
36
+
37
+ words & dictionary
38
+ .map(&:chomp)
39
+ .select { |word| word.length >= min_word_length }
40
+ .select { |word| word.length <= letters.count }
41
+ .map { |word| word.strip.downcase.split('') }
42
+ .select { |word| (word - letters).empty? }
43
+ .select { |word| word.all? { |l0| word.count { |l1| l1 == l0 } <= letters_frequency_idx[l0] } }
44
+ .map(&:join)
45
+ end
46
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biscotti
4
+ module CLI
5
+ def self.run(app, io)
6
+ # app.new(railroad: Sodor::Railroad::Marshal.load(io))
7
+ end
8
+
9
+ def self.processable?
10
+ ARGF.filename != '-' || !(STDIN.tty? || STDIN.closed?)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biscotti
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: biscotti
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mike Hall
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-08-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: Generate a list of possible words for a given set of letters.
56
+ email:
57
+ - mike@just3ws.com
58
+ executables:
59
+ - biscotti
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".rubocop.yml"
66
+ - ".ruby-gemset"
67
+ - ".ruby-version"
68
+ - ".travis.yml"
69
+ - COPYING
70
+ - Gemfile
71
+ - Gemfile.lock
72
+ - Guardfile
73
+ - README.md
74
+ - Rakefile
75
+ - bin/console
76
+ - bin/setup
77
+ - biscotti.gemspec
78
+ - data/biscotti/words.lst
79
+ - exe/biscotti
80
+ - lib/biscotti.rb
81
+ - lib/biscotti/cli.rb
82
+ - lib/biscotti/version.rb
83
+ homepage: https://github.com/just3ws/biscotti
84
+ licenses:
85
+ - GPL-3.0+
86
+ metadata: {}
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 2.7.7
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Totally not a way to cheat at letter scramble games.
107
+ test_files: []