wordsearch 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 40b077651ba82fae5a89b3babaaaa74dc7f4d678
4
+ data.tar.gz: 609dd795e2d88ba662db9ec083a41c16b8040afe
5
+ SHA512:
6
+ metadata.gz: fe430fbdfb154a7f8ae10b4ff2a265bf1be8ebac28b56a398cf95f16f2efbd088f1f9073dde699559505677063fec5428bb7ee47969af6cacc7737192167ad97
7
+ data.tar.gz: 55e7bc01df141af89c8da0318fa0f2330b04cef52ca01393d9df86f544be6076b46049baa6928f419eaa59102fa811b32564a730e56f2a313f208ab39104122d
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ *.o
4
+ .bundle
5
+ *.bundle
6
+ .config
7
+ .yardoc
8
+ Gemfile.lock
9
+ Makefile
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wordsearch.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Pete Bevin
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Wordsearch
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'wordsearch'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install wordsearch
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/wordsearch/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,73 @@
1
+ #include <memory.h>
2
+ #include <ctype.h>
3
+
4
+ static char accent_map[256];
5
+
6
+ void
7
+ strip_accents(char *str)
8
+ {
9
+ int i;
10
+ for (i = 0; str[i]; i++) {
11
+ int ch = str[i];
12
+ char unaccented = accent_map[ch];
13
+ if (unaccented != 0) {
14
+ str[i] = unaccented;
15
+ }
16
+ }
17
+ }
18
+
19
+ int
20
+ canon(char *dst, char *str, int keep_spc)
21
+ {
22
+ char *p = str;
23
+ char *q = dst;
24
+
25
+ for (; *p; p++) {
26
+ unsigned char ch = (unsigned char)*p;
27
+ if (accent_map[ch]) {
28
+ ch = accent_map[ch];
29
+ }
30
+
31
+ if (isalpha(ch)) {
32
+ *q++ = tolower(ch);
33
+ }
34
+ else if (keep_spc && ch == ' ') {
35
+ *q++ = ch;
36
+ }
37
+ }
38
+ *q = 0;
39
+
40
+ return q - dst;
41
+ }
42
+
43
+
44
+ static void
45
+ add_accents(int unaccented, char *accented)
46
+ {
47
+ unsigned char *p;
48
+
49
+ for (p = (unsigned char *)accented; *p; p++) {
50
+ accent_map[(int)*p] = unaccented;
51
+ accent_map[(int)*p - 0x20] = unaccented - 0x20;
52
+ }
53
+ }
54
+
55
+ void init_accent()
56
+ {
57
+ memset(accent_map, 0, sizeof(accent_map));
58
+ char a[] = { 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0 };
59
+ char c[] = { 0xe7, 0 };
60
+ char e[] = { 0xe8, 0xe9, 0xea, 0xeb, 0 };
61
+ char i[] = { 0xec, 0xed, 0xee, 0xef, 0 };
62
+ char n[] = { 0xf1, 0 };
63
+ char o[] = { 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0 };
64
+ char u[] = { 0xf9, 0xfa, 0xfb, 0xfc, 0 };
65
+
66
+ add_accents('a', a);
67
+ add_accents('c', c);
68
+ add_accents('e', e);
69
+ add_accents('i', i);
70
+ add_accents('n', n);
71
+ add_accents('o', o);
72
+ add_accents('u', u);
73
+ }
@@ -0,0 +1,2 @@
1
+ extern void init_accent();
2
+ extern int canon(char *dst, char *str, int keep_spc);
@@ -0,0 +1,62 @@
1
+ #include <ctype.h>
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <string.h>
5
+ #include <getopt.h>
6
+ #include "accent.h"
7
+ #include "wordfun.h"
8
+
9
+ static int
10
+ cmp_char(const void *a, const void *b)
11
+ {
12
+ const char *aa = (char *)a;
13
+ const char *bb = (char *)b;
14
+
15
+ return *aa - *bb;
16
+ }
17
+
18
+
19
+ int
20
+ canon_sort(char *dst, char *str, int expectlen)
21
+ {
22
+ int len = canon(dst, str, 0);
23
+ if (expectlen >= 0 && len != expectlen)
24
+ return 1;
25
+
26
+ qsort(dst, len, 1, cmp_char);
27
+ return 0;
28
+ }
29
+
30
+ static char *filename = DICT;
31
+
32
+ int
33
+ an_main(char *pattern, char *dictfile, void(*callback)(const char *word)) {
34
+ FILE *fp;
35
+ char an[100];
36
+ char buf[100];
37
+ char buf2[100];
38
+ int anlen;
39
+ int c;
40
+
41
+ init_accent();
42
+ canon_sort(an, pattern, -1);
43
+ anlen = strlen(an);
44
+
45
+ fp = fopen(dictfile, "r");
46
+ if (fp == 0) {
47
+ perror(dictfile);
48
+ return 1;
49
+ }
50
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
51
+ if (canon_sort(buf2, buf, anlen))
52
+ continue;
53
+ if (strcmp(an, buf2) == 0) {
54
+ /* fputs(buf, stdout); */
55
+ buf[strlen(buf) - 1] = 0;
56
+ callback(buf);
57
+ }
58
+ }
59
+ fclose(fp);
60
+
61
+ return 0;
62
+ }
@@ -0,0 +1,2 @@
1
+ require 'mkmf'
2
+ create_makefile("wordsearch")
@@ -0,0 +1,108 @@
1
+ #include <ctype.h>
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <string.h>
5
+ #include <getopt.h>
6
+ #include "accent.h"
7
+ #include "wordfun.h"
8
+
9
+ int
10
+ direct_match(const char *pat, char *str)
11
+ {
12
+ int i;
13
+
14
+ for (i = 0; pat[i] && str[i]; i++) {
15
+ if (pat[i] == '.')
16
+ continue;
17
+ if (pat[i] == '/' && str[i] == ' ')
18
+ continue;
19
+ if (pat[i] == str[i])
20
+ continue;
21
+ return 0;
22
+ }
23
+
24
+ return pat[i] == str[i]; /* both 0 */
25
+ }
26
+
27
+ int
28
+ canon_match(const char *pat, char *str)
29
+ {
30
+ int i;
31
+
32
+ for (i = 0; pat[i] && str[i]; i++) {
33
+ if (pat[i] == '.')
34
+ continue;
35
+ if (pat[i] == str[i])
36
+ continue;
37
+ return 0;
38
+ }
39
+
40
+ return pat[i] == str[i]; /* both 0 */
41
+ }
42
+
43
+ int crypto_match(const char *pat, char *str)
44
+ {
45
+ int i;
46
+ char key[256];
47
+ char rkey[256];
48
+ memset(key, 0, 256);
49
+ memset(rkey, 0, 256);
50
+
51
+ for (i = 0; pat[i] && str[i]; i++) {
52
+ int idx = pat[i];
53
+ int idx2 = str[i];
54
+ char ch = key[idx];
55
+ char ch2 = rkey[idx2];
56
+ if (ch && str[i] != ch) return 0;
57
+ if (ch2 && pat[i] != ch2) return 0;
58
+
59
+ key[idx] = str[i];
60
+ rkey[idx2] = pat[i];
61
+ }
62
+
63
+ return pat[i] == str[i]; /* both 0 */
64
+ }
65
+
66
+
67
+ int
68
+ fw_main(const char *pattern, const char *dictfile, int cryptogram, void (*callback)(const char *word)) {
69
+ FILE *fp;
70
+ char buf[100];
71
+ char buf2[100];
72
+ int spaces;
73
+ int c;
74
+
75
+ init_accent();
76
+
77
+ spaces = strchr(pattern, '/') != 0;
78
+
79
+ fp = fopen(dictfile, "r");
80
+ if (fp == 0) {
81
+ perror(dictfile);
82
+ return 1;
83
+ }
84
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
85
+ buf[strlen(buf) - 1] = 0;
86
+ if (cryptogram) {
87
+ canon(buf2, buf, 1);
88
+ if (crypto_match(pattern, buf2)) {
89
+ callback(buf);
90
+ }
91
+ }
92
+ else if (spaces) {
93
+ canon(buf2, buf, 1);
94
+ if (direct_match(pattern, buf2)) {
95
+ callback(buf);
96
+ }
97
+ }
98
+ else {
99
+ canon(buf2, buf, 0);
100
+ if (canon_match(pattern, buf2)) {
101
+ callback(buf);
102
+ }
103
+ }
104
+ }
105
+ fclose(fp);
106
+
107
+ return 0;
108
+ }
@@ -0,0 +1 @@
1
+ #define DICT "/usr/share/dict/anadict"
@@ -0,0 +1,38 @@
1
+ #include <ruby.h>
2
+
3
+ extern int an_main(const char *pattern, const char *dictfile, void(*)(const char *word));
4
+ extern int fw_main(const char *pattern, const char *dictfile, int cryptogram, void(*)(const char *word));
5
+
6
+ void wsYield(const char *word) {
7
+ rb_yield(rb_str_new2(word));
8
+ }
9
+
10
+ const char *dictfile(VALUE self) {
11
+ VALUE dict = rb_iv_get(self, "@dict");
12
+ return StringValueCStr(dict);
13
+ }
14
+
15
+ VALUE an(VALUE self, VALUE pattern) {
16
+ const char *pat = StringValueCStr(pattern);
17
+ an_main(pat, dictfile(self), wsYield);
18
+ return Qnil;
19
+ }
20
+
21
+ VALUE fw(VALUE self, VALUE pattern) {
22
+ const char *pat = StringValueCStr(pattern);
23
+ fw_main(pat, dictfile(self), 0, wsYield);
24
+ return Qnil;
25
+ }
26
+
27
+ VALUE cr(VALUE self, VALUE pattern) {
28
+ const char *pat = StringValueCStr(pattern);
29
+ fw_main(pat, dictfile(self), 1, wsYield);
30
+ return Qnil;
31
+ }
32
+
33
+ void Init_wordsearch() {
34
+ VALUE wordsearch = rb_define_class("Wordsearch", rb_cObject);
35
+ rb_define_method(wordsearch, "an", an, 1);
36
+ rb_define_method(wordsearch, "fw", fw, 1);
37
+ rb_define_method(wordsearch, "cr", cr, 1);
38
+ }
@@ -0,0 +1,3 @@
1
+ class Wordsearch
2
+ VERSION = "1.0.0"
3
+ end
data/lib/wordsearch.rb ADDED
@@ -0,0 +1,20 @@
1
+ require "wordsearch/version"
2
+ require "wordsearch/wordsearch"
3
+
4
+ class Wordsearch
5
+ def initialize(dictionary=ENV["ANAGRAM_DICT"])
6
+ @dict = dictionary
7
+ end
8
+
9
+ def anagrams(pattern, &block)
10
+ an(pattern, &block)
11
+ end
12
+
13
+ def find_words(pattern, &block)
14
+ fw(pattern, &block)
15
+ end
16
+
17
+ def solve_cryptogram(pattern, &block)
18
+ cr(pattern, &block)
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wordsearch/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wordsearch"
8
+ spec.version = Wordsearch::VERSION
9
+ spec.authors = ["Pete Bevin"]
10
+ spec.email = ["pete@petebevin.com"]
11
+ spec.summary = %q{Search dictionary for anagrams, missing letters, etc.}
12
+ # spec.description = %q{TODO: Write a longer description. Optional.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+ spec.extensions = ["ext/wordsearch/extconf.rb"]
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib", "ext"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.5"
23
+ spec.add_development_dependency "rake"
24
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wordsearch
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Pete Bevin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-25 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.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ - pete@petebevin.com
44
+ executables: []
45
+ extensions:
46
+ - ext/wordsearch/extconf.rb
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - ext/wordsearch/accent.c
55
+ - ext/wordsearch/accent.h
56
+ - ext/wordsearch/an.c
57
+ - ext/wordsearch/extconf.rb
58
+ - ext/wordsearch/fw.c
59
+ - ext/wordsearch/wordfun.h
60
+ - ext/wordsearch/wordsearch.c
61
+ - lib/wordsearch.rb
62
+ - lib/wordsearch/version.rb
63
+ - wordsearch.gemspec
64
+ homepage: ''
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ - ext
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.0.3
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Search dictionary for anagrams, missing letters, etc.
89
+ test_files: []