codewords_solver 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4886e4d8eb69c91a00c9c8d9aacab82dc3a6b1957a586e1789a4a3b94b0b92c
4
- data.tar.gz: 19c61ba5ff23c5a3a0cc10a9306a5a818ccd24791a2cac3a5ba9c75b6f286568
3
+ metadata.gz: 8e22e424b515d90124d77fdc91aed5a3f7837155319a257b2af480e377ef5b18
4
+ data.tar.gz: e8d8b37d0b9b98ac5529a34b9a21385512944d1171bd413cdb176723c65a34bf
5
5
  SHA512:
6
- metadata.gz: 8647b9cc57b9e004a58141d571a62f3d2a4b4336eac4e3575aea018055ddb52782b8fe3a5534b365591454c78dde4fbe040cc7fce530ccc481088c3ca159c361
7
- data.tar.gz: a82e7e300ce1162def0024db9ad268c0036f1c183b81f5928eab080f09e92b0d860ec8df376ccb2c755d7449f5e4f534de58ab5d784f6db36410f8188128d839
6
+ metadata.gz: ef8ce498d02038c4db158dfe9c111b8b987b9fa2252753841a88d2ad7fb58b087aed970e09f37ab021c155a6352e5d8cdd9c85690932e39682c26ac2b7697b05
7
+ data.tar.gz: 50951b1cb93f810c7e58c991bf44791b89e768a6af1cfd27b0d1813f285b6d8923f5d52cdd46e94c22b6fe779a5c8beb1353a36dea755771ead030d2de1c408f
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- codewords_solver (0.0.1)
4
+ codewords_solver (0.0.3)
5
5
  activesupport (~> 7.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -49,6 +49,12 @@ grid = [
49
49
  [22, 21, 17, 4, 15, 7, 17, 17, 19],
50
50
  ]
51
51
  ```
52
+
53
+ which is a machine-representation of a real-world grid that looks like this:
54
+
55
+ ![IMG_2891](https://github.com/johansenja/codewords_solver/assets/43235608/27741a76-9a14-4dba-b25c-a59a89fcc51d)
56
+
57
+
52
58
  **Note that while a codewords puzzle is typically formed into a grid with intersecting words, you do not need to mark such intersections here. A simple array of each of the numbered words will suffice!**
53
59
 
54
60
  ### Please note
@@ -4,16 +4,26 @@ class CodewordsSolver
4
4
  class Dictionary
5
5
  include ActiveSupport::Inflector
6
6
 
7
+ DEFAULT_FILEPATH = File.join(__dir__, "..", "..", "word_list.txt")
8
+
7
9
  def initialize
8
- @words = import_words_by_filepath(
9
- File.join(__dir__, "..", "..", "word_list.txt")
10
- )
10
+ load!
11
11
  end
12
12
 
13
13
  def find_by_regexp(regexp)
14
14
  @words.filter { |w| w.length > 2 and w.match? regexp }
15
15
  end
16
16
 
17
+ def has?(word)
18
+ @words.include? word
19
+ end
20
+
21
+ def load!
22
+ @words = import_words_by_filepath(DEFAULT_FILEPATH)
23
+ end
24
+
25
+ alias_method :reload!, :load!
26
+
17
27
  private
18
28
 
19
29
  def import_words_by_filepath(filepath)
@@ -1,3 +1,3 @@
1
1
  class CodewordsSolver
2
- VERSION = "0.0.2".freeze
2
+ VERSION = "0.0.3".freeze
3
3
  end
@@ -1,19 +1,20 @@
1
- require "codewords_solver/dictionary"
1
+ require_relative "codewords_solver/dictionary"
2
2
 
3
3
  class CodewordsSolver
4
- def self.solve!(coded_words:, starting_letters:)
5
- new(coded_words, starting_letters).solve!
4
+ def self.solve!(coded_words:, starting_letters:, **rest)
5
+ new(coded_words, starting_letters, **rest).solve!
6
6
  end
7
7
 
8
8
  MAX_LOOP_ATTEMPTS = 5
9
9
 
10
- def initialize(coded_words, starting_letters)
10
+ def initialize(coded_words, starting_letters, debug: false)
11
11
  @coded_words = coded_words
12
12
  @starting_letters = starting_letters
13
13
  @letters_by_number = (1..26).to_h { |n| [n, nil] }.merge(
14
14
  starting_letters.transform_values(&:upcase)
15
15
  )
16
16
  @dictionary = Dictionary.new
17
+ @debug = debug
17
18
  end
18
19
 
19
20
  def solve!
@@ -52,9 +53,11 @@ class CodewordsSolver
52
53
  # this is a bit of a leak/hack; at this point, we're going a bit beyond regex's capabilities
53
54
  possibilities = filter_invalid_possibilities(possibilities, coded_word)
54
55
 
55
- # puts(
56
- # "Found #{possibilities.length > 10 ? possibilities.length : possibilities.join(", ")} for #{coded_word} (regexp: /#{regexp}/)"
57
- # )
56
+ if @debug
57
+ puts(
58
+ "Found #{possibilities.length > 10 ? possibilities.length : possibilities.join(", ")} for #{coded_word} (regexp: /#{regexp}/)"
59
+ )
60
+ end
58
61
 
59
62
  assign_word(coded_word, possibilities[0]) if possibilities.length == 1
60
63
 
@@ -68,6 +71,7 @@ class CodewordsSolver
68
71
  end
69
72
  end
70
73
 
74
+ try_to_fill_last_letter
71
75
  break if complete?
72
76
  end
73
77
  end
@@ -102,6 +106,21 @@ class CodewordsSolver
102
106
  @letters_by_number.each_value.all? { |letter| !letter.nil? }
103
107
  end
104
108
 
109
+ # in cases where there is only one letter remaining, but the word that it spells isn't in the
110
+ # dictionary, then this will put the final piece into place via process of elimination
111
+ def try_to_fill_last_letter
112
+ remaining = unassigned_letters
113
+
114
+ return unless remaining.length == 1
115
+
116
+ @letters_by_number.each do |num, val|
117
+ next if val
118
+
119
+ @letters_by_number[num] = remaining[0]
120
+ break
121
+ end
122
+ end
123
+
105
124
  def filter_invalid_possibilities(possibilities, coded_word)
106
125
  possibilities.filter { |poss| poss.chars.uniq.length == coded_word.uniq.length }
107
126
  end
@@ -114,9 +133,15 @@ class CodewordsSolver
114
133
 
115
134
  def print_words
116
135
  words = @coded_words.map do |code_word|
117
- code_word.each_with_object("") do |number, word|
118
- word << @letters_by_number[number]
136
+ word = code_word.each_with_object("") do |number, str|
137
+ str << @letters_by_number[number]
119
138
  end
139
+
140
+ unless @dictionary.has? word
141
+ puts "!! #{word} not in dictionary - consider adding it to word_list.txt"
142
+ end
143
+
144
+ word
120
145
  end
121
146
 
122
147
  max_word_length = words.max_by(&:length).length
@@ -126,11 +151,13 @@ class CodewordsSolver
126
151
  end
127
152
  end
128
153
 
154
+ def unassigned_letters
155
+ ("A".."Z").to_a - @letters_by_number.values.reject(&:nil?)
156
+ end
157
+
129
158
  def to_regexp(coded_word)
130
159
  backreferences_for_unknown_numbers = []
131
160
 
132
- unassigned_letters = ("A".."Z").to_a.join("").tr @letters_by_number.values.join(""), ""
133
-
134
161
  regexp_chars = coded_word.map do |number|
135
162
  letter = @letters_by_number[number]
136
163
  next letter if letter
@@ -139,7 +166,7 @@ class CodewordsSolver
139
166
 
140
167
  if backreference_num.nil?
141
168
  backreferences_for_unknown_numbers << number
142
- "(#{unassigned_letters.split("").join("|")})"
169
+ "(#{unassigned_letters.join("|")})"
143
170
  else
144
171
  "\\#{backreference_num + 1}"
145
172
  end
data/word_list.txt CHANGED
@@ -129,6 +129,7 @@ adelaide
129
129
  adequate
130
130
  adidas
131
131
  adipex
132
+ adieu
132
133
  adjacent
133
134
  adjust
134
135
  adjustable
@@ -222,6 +223,7 @@ agreements
222
223
  agrees
223
224
  agricultural
224
225
  agriculture
226
+ ague
225
227
  ahead
226
228
  aid
227
229
  aids
@@ -791,6 +793,7 @@ battery
791
793
  battle
792
794
  battlefield
793
795
  bay
796
+ bazaar
794
797
  bbc
795
798
  bbs
796
799
  bbw
@@ -836,6 +839,7 @@ beginner
836
839
  beginners
837
840
  beginning
838
841
  begins
842
+ beguile
839
843
  begun
840
844
  behalf
841
845
  behavior
@@ -934,6 +938,7 @@ biotechnology
934
938
  bird
935
939
  birds
936
940
  birmingham
941
+ biro
937
942
  birth
938
943
  birthday
939
944
  bishop
@@ -1313,6 +1318,7 @@ carefully
1313
1318
  carey
1314
1319
  cargo
1315
1320
  caribbean
1321
+ caribou
1316
1322
  caring
1317
1323
  carl
1318
1324
  carlo
@@ -1648,6 +1654,7 @@ clouds
1648
1654
  cloudy
1649
1655
  club
1650
1656
  clubs
1657
+ clue
1651
1658
  cluster
1652
1659
  clusters
1653
1660
  cms
@@ -2302,6 +2309,7 @@ dee
2302
2309
  deemed
2303
2310
  deep
2304
2311
  deeper
2312
+ deepness
2305
2313
  deeply
2306
2314
  deer
2307
2315
  def
@@ -2821,11 +2829,13 @@ effort
2821
2829
  efforts
2822
2830
  egg
2823
2831
  eggs
2832
+ ego
2824
2833
  egypt
2825
2834
  egyptian
2826
2835
  eight
2827
2836
  either
2828
2837
  ejaculation
2838
+ elbow
2829
2839
  elder
2830
2840
  elderly
2831
2841
  elect
@@ -2841,6 +2851,8 @@ electron
2841
2851
  electronic
2842
2852
  electronics
2843
2853
  elegant
2854
+ elegise
2855
+ elegize
2844
2856
  element
2845
2857
  elementary
2846
2858
  elements
@@ -3108,6 +3120,7 @@ exempt
3108
3120
  exemption
3109
3121
  exercise
3110
3122
  exercises
3123
+ exert
3111
3124
  exhaust
3112
3125
  exhibit
3113
3126
  exhibition
@@ -3291,6 +3304,7 @@ feelings
3291
3304
  feels
3292
3305
  fees
3293
3306
  feet
3307
+ feetless
3294
3308
  fell
3295
3309
  fellow
3296
3310
  fellowship
@@ -3306,6 +3320,7 @@ festivals
3306
3320
  fetish
3307
3321
  fever
3308
3322
  few
3323
+ fiance
3309
3324
  fewer
3310
3325
  fiber
3311
3326
  fibre
@@ -3497,6 +3512,7 @@ forming
3497
3512
  forms
3498
3513
  formula
3499
3514
  fort
3515
+ fortress
3500
3516
  forth
3501
3517
  fortune
3502
3518
  forty
@@ -3828,6 +3844,9 @@ grey
3828
3844
  grid
3829
3845
  griffin
3830
3846
  grill
3847
+ grind
3848
+ grinds
3849
+ grinder
3831
3850
  grip
3832
3851
  grocery
3833
3852
  groove
@@ -3843,6 +3862,7 @@ growing
3843
3862
  grown
3844
3863
  grows
3845
3864
  growth
3865
+ grubby
3846
3866
  gsm
3847
3867
  gst
3848
3868
  gtk
@@ -3996,6 +4016,7 @@ heavily
3996
4016
  heavy
3997
4017
  hebrew
3998
4018
  heel
4019
+ heedless
3999
4020
  height
4000
4021
  heights
4001
4022
  held
@@ -4517,6 +4538,7 @@ involvement
4517
4538
  involves
4518
4539
  involving
4519
4540
  ion
4541
+ iota
4520
4542
  iowa
4521
4543
  ipaq
4522
4544
  ipod
@@ -4649,6 +4671,7 @@ journals
4649
4671
  journey
4650
4672
  joy
4651
4673
  joyce
4674
+ joyful
4652
4675
  jpeg
4653
4676
  jpg
4654
4677
  juan
@@ -4708,6 +4731,7 @@ kent
4708
4731
  kentucky
4709
4732
  kenya
4710
4733
  kept
4734
+ kerb
4711
4735
  kernel
4712
4736
  kerry
4713
4737
  kevin
@@ -4892,6 +4916,7 @@ legislation
4892
4916
  legislative
4893
4917
  legislature
4894
4918
  legitimate
4919
+ lego
4895
4920
  legs
4896
4921
  leisure
4897
4922
  lemon
@@ -5167,6 +5192,7 @@ maintained
5167
5192
  maintaining
5168
5193
  maintains
5169
5194
  maintenance
5195
+ maize
5170
5196
  major
5171
5197
  majority
5172
5198
  make
@@ -5251,6 +5277,8 @@ marshall
5251
5277
  mart
5252
5278
  martha
5253
5279
  martial
5280
+ martian
5281
+ martians
5254
5282
  martin
5255
5283
  marvel
5256
5284
  mary
@@ -5334,6 +5362,7 @@ meditation
5334
5362
  mediterranean
5335
5363
  medium
5336
5364
  medline
5365
+ meekness
5337
5366
  meet
5338
5367
  meeting
5339
5368
  meetings
@@ -5594,6 +5623,7 @@ mounted
5594
5623
  mounting
5595
5624
  mounts
5596
5625
  mouse
5626
+ mousse
5597
5627
  mouth
5598
5628
  move
5599
5629
  moved
@@ -5663,6 +5693,7 @@ name
5663
5693
  named
5664
5694
  namely
5665
5695
  names
5696
+ namesake
5666
5697
  namespace
5667
5698
  namibia
5668
5699
  nancy
@@ -5953,8 +5984,10 @@ only
5953
5984
  ons
5954
5985
  ontario
5955
5986
  onto
5987
+ onus
5956
5988
  ooo
5957
5989
  oops
5990
+ opal
5958
5991
  open
5959
5992
  opened
5960
5993
  opening
@@ -5992,6 +6025,7 @@ options
5992
6025
  oracle
5993
6026
  oral
5994
6027
  orange
6028
+ oratory
5995
6029
  orbit
5996
6030
  orchestra
5997
6031
  order
@@ -6059,6 +6093,7 @@ overcome
6059
6093
  overhead
6060
6094
  overnight
6061
6095
  overseas
6096
+ oversleep
6062
6097
  overview
6063
6098
  owen
6064
6099
  own
@@ -6228,6 +6263,8 @@ peas
6228
6263
  pediatric
6229
6264
  pee
6230
6265
  peeing
6266
+ peel
6267
+ peeled
6231
6268
  peer
6232
6269
  peers
6233
6270
  pen
@@ -7044,6 +7081,7 @@ reduction
7044
7081
  reductions
7045
7082
  reed
7046
7083
  reef
7084
+ reefer
7047
7085
  reel
7048
7086
  ref
7049
7087
  refer
@@ -7417,6 +7455,7 @@ routines
7417
7455
  routing
7418
7456
  rover
7419
7457
  row
7458
+ rowlock
7420
7459
  rows
7421
7460
  roy
7422
7461
  royal
@@ -7568,6 +7607,7 @@ scotland
7568
7607
  scott
7569
7608
  scottish
7570
7609
  scout
7610
+ scramble
7571
7611
  scratch
7572
7612
  screen
7573
7613
  screening
@@ -7730,6 +7770,7 @@ shakespeare
7730
7770
  shakira
7731
7771
  shall
7732
7772
  shame
7773
+ shampoo
7733
7774
  shanghai
7734
7775
  shannon
7735
7776
  shape
@@ -8093,6 +8134,7 @@ squad
8093
8134
  square
8094
8135
  squirt
8095
8136
  squirting
8137
+ squishy
8096
8138
  src
8097
8139
  sri
8098
8140
  ssl
@@ -8471,6 +8513,7 @@ target
8471
8513
  targeted
8472
8514
  targets
8473
8515
  tariff
8516
+ tartan
8474
8517
  task
8475
8518
  tasks
8476
8519
  taste
@@ -8506,6 +8549,9 @@ techrepublic
8506
8549
  ted
8507
8550
  teddy
8508
8551
  tee
8552
+ teem
8553
+ teeming
8554
+ teemed
8509
8555
  teen
8510
8556
  teenage
8511
8557
  teens
@@ -9018,6 +9064,7 @@ unsubscribe
9018
9064
  until
9019
9065
  untitled
9020
9066
  unto
9067
+ unused
9021
9068
  unusual
9022
9069
  unwrap
9023
9070
  upc
@@ -9037,6 +9084,7 @@ ups
9037
9084
  upset
9038
9085
  upskirt
9039
9086
  upskirts
9087
+ upstream
9040
9088
  urban
9041
9089
  urge
9042
9090
  urgent
@@ -9294,6 +9342,7 @@ warned
9294
9342
  warner
9295
9343
  warning
9296
9344
  warnings
9345
+ warplane
9297
9346
  warrant
9298
9347
  warranties
9299
9348
  warranty
@@ -9570,8 +9619,10 @@ zambia
9570
9619
  zdnet
9571
9620
  zealand
9572
9621
  zen
9622
+ zeolite
9573
9623
  zero
9574
9624
  zimbabwe
9625
+ zillion
9575
9626
  zinc
9576
9627
  zip
9577
9628
  zoloft
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: codewords_solver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Johansen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-17 00:00:00.000000000 Z
11
+ date: 2024-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport