puzzle-lib 1.3.0 → 1.6.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.
Files changed (180) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +38 -39
  3. package/build/src/Braille/BrailleCharacter.d.ts +15 -15
  4. package/build/src/Braille/BrailleCharacter.js +38 -37
  5. package/build/src/Braille/BrailleCharacter.js.map +1 -1
  6. package/build/src/Braille/BrailleData.d.ts +6 -6
  7. package/build/src/Braille/BrailleData.js +65 -64
  8. package/build/src/Braille/BrailleData.js.map +1 -1
  9. package/build/src/Braille/BrailleDot.d.ts +9 -9
  10. package/build/src/Braille/BrailleDot.js +13 -12
  11. package/build/src/Braille/BrailleDot.js.map +1 -1
  12. package/build/src/Braille/BrailleEncoding.d.ts +54 -54
  13. package/build/src/Braille/BrailleEncoding.js +65 -64
  14. package/build/src/Braille/BrailleEncoding.js.map +1 -1
  15. package/build/src/Braille/BrailleStream.d.ts +18 -18
  16. package/build/src/Braille/BrailleStream.js +75 -74
  17. package/build/src/Braille/BrailleStream.js.map +1 -1
  18. package/build/src/Cipher/AutoKeyString.d.ts +4 -4
  19. package/build/src/Cipher/AutoKeyString.js +34 -33
  20. package/build/src/Cipher/AutoKeyString.js.map +1 -1
  21. package/build/src/Cipher/CaesarString.d.ts +8 -8
  22. package/build/src/Cipher/CaesarString.js +31 -30
  23. package/build/src/Cipher/CaesarString.js.map +1 -1
  24. package/build/src/Cipher/CaesarUtils.d.ts +13 -13
  25. package/build/src/Cipher/CaesarUtils.js +57 -56
  26. package/build/src/Cipher/CaesarUtils.js.map +1 -1
  27. package/build/src/Cipher/KeyedCipherStringBase.d.ts +12 -12
  28. package/build/src/Cipher/KeyedCipherStringBase.js +28 -27
  29. package/build/src/Cipher/KeyedCipherStringBase.js.map +1 -1
  30. package/build/src/Cipher/VigenereString.d.ts +4 -4
  31. package/build/src/Cipher/VigenereString.js +21 -20
  32. package/build/src/Cipher/VigenereString.js.map +1 -1
  33. package/build/src/Common/CharacterImage.d.ts +6 -6
  34. package/build/src/Common/CharacterImage.js +10 -9
  35. package/build/src/Common/CharacterImage.js.map +1 -1
  36. package/build/src/Common/EncodingCategory.d.ts +8 -8
  37. package/build/src/Common/EncodingCategory.js +12 -11
  38. package/build/src/Common/EncodingCategory.js.map +1 -1
  39. package/build/src/Common/EncodingCharacterBase.d.ts +23 -23
  40. package/build/src/Common/EncodingCharacterBase.js +52 -51
  41. package/build/src/Common/EncodingCharacterBase.js.map +1 -1
  42. package/build/src/Common/EncodingDataBase.d.ts +7 -7
  43. package/build/src/Common/EncodingDataBase.js +29 -28
  44. package/build/src/Common/EncodingDataBase.js.map +1 -1
  45. package/build/src/Common/EncodingEntry.d.ts +8 -8
  46. package/build/src/Common/EncodingEntry.js +14 -13
  47. package/build/src/Common/EncodingEntry.js.map +1 -1
  48. package/build/src/Common/EncodingLookupResult.d.ts +6 -6
  49. package/build/src/Common/EncodingLookupResult.js +13 -12
  50. package/build/src/Common/EncodingLookupResult.js.map +1 -1
  51. package/build/src/Common/Helpers.d.ts +4 -4
  52. package/build/src/Common/Helpers.js +16 -15
  53. package/build/src/Common/Helpers.js.map +1 -1
  54. package/build/src/Common/InlineSvg.d.ts +7 -7
  55. package/build/src/Common/InlineSvg.js +14 -13
  56. package/build/src/Common/InlineSvg.js.map +1 -1
  57. package/build/src/Conversion/CharacterAutoConvert.d.ts +10 -7
  58. package/build/src/Conversion/CharacterAutoConvert.js +88 -80
  59. package/build/src/Conversion/CharacterAutoConvert.js.map +1 -1
  60. package/build/src/Conversion/CharacterConversion.d.ts +8 -8
  61. package/build/src/Conversion/CharacterConversion.js +50 -49
  62. package/build/src/Conversion/CharacterConversion.js.map +1 -1
  63. package/build/src/Conversion/CharacterEncoding.d.ts +9 -8
  64. package/build/src/Conversion/CharacterEncoding.js +13 -11
  65. package/build/src/Conversion/CharacterEncoding.js.map +1 -1
  66. package/build/src/Conversion/CharacterTableEntry.d.ts +10 -10
  67. package/build/src/Conversion/CharacterTableEntry.js +19 -18
  68. package/build/src/Conversion/CharacterTableEntry.js.map +1 -1
  69. package/build/src/Conversion/SignificantFigures.d.ts +7 -7
  70. package/build/src/Conversion/SignificantFigures.js +50 -49
  71. package/build/src/Conversion/SignificantFigures.js.map +1 -1
  72. package/build/src/Conversion/StringAutoConvert.d.ts +6 -6
  73. package/build/src/Conversion/StringAutoConvert.js +46 -45
  74. package/build/src/Conversion/StringAutoConvert.js.map +1 -1
  75. package/build/src/Morse/MorseCharacter.d.ts +22 -22
  76. package/build/src/Morse/MorseCharacter.js +96 -95
  77. package/build/src/Morse/MorseCharacter.js.map +1 -1
  78. package/build/src/Morse/MorseData.d.ts +6 -6
  79. package/build/src/Morse/MorseData.js +70 -69
  80. package/build/src/Morse/MorseData.js.map +1 -1
  81. package/build/src/Morse/MorseEncoding.d.ts +59 -59
  82. package/build/src/Morse/MorseEncoding.js +94 -93
  83. package/build/src/Morse/MorseEncoding.js.map +1 -1
  84. package/build/src/Morse/MorseString.d.ts +10 -10
  85. package/build/src/Morse/MorseString.js +66 -65
  86. package/build/src/Morse/MorseString.js.map +1 -1
  87. package/build/src/Nato/NatoCharacter.d.ts +5 -5
  88. package/build/src/Nato/NatoCharacter.js +10 -9
  89. package/build/src/Nato/NatoCharacter.js.map +1 -1
  90. package/build/src/Nato/NatoData.d.ts +7 -7
  91. package/build/src/Nato/NatoData.js +51 -50
  92. package/build/src/Nato/NatoData.js.map +1 -1
  93. package/build/src/NavalFlags/NavalFlags.d.ts +7 -7
  94. package/build/src/NavalFlags/NavalFlags.js +52 -50
  95. package/build/src/NavalFlags/NavalFlags.js.map +1 -1
  96. package/build/src/Resistor/Resistor.d.ts +24 -24
  97. package/build/src/Resistor/Resistor.js +86 -85
  98. package/build/src/Resistor/Resistor.js.map +1 -1
  99. package/build/src/Resistor/ResistorColorEntry.d.ts +12 -12
  100. package/build/src/Resistor/ResistorColorEntry.js +31 -30
  101. package/build/src/Resistor/ResistorColorEntry.js.map +1 -1
  102. package/build/src/Semaphore/SemaphoreCharacter.d.ts +20 -20
  103. package/build/src/Semaphore/SemaphoreCharacter.js +75 -74
  104. package/build/src/Semaphore/SemaphoreCharacter.js.map +1 -1
  105. package/build/src/Semaphore/SemaphoreData.d.ts +6 -6
  106. package/build/src/Semaphore/SemaphoreData.js +53 -52
  107. package/build/src/Semaphore/SemaphoreData.js.map +1 -1
  108. package/build/src/Semaphore/SemaphoreDegrees.d.ts +5 -5
  109. package/build/src/Semaphore/SemaphoreDegrees.js +26 -25
  110. package/build/src/Semaphore/SemaphoreDegrees.js.map +1 -1
  111. package/build/src/Semaphore/SemaphoreDirection.d.ts +11 -11
  112. package/build/src/Semaphore/SemaphoreDirection.js +15 -14
  113. package/build/src/Semaphore/SemaphoreDirection.js.map +1 -1
  114. package/build/src/Semaphore/SemaphoreEncoding.d.ts +40 -40
  115. package/build/src/Semaphore/SemaphoreEncoding.js +47 -46
  116. package/build/src/Semaphore/SemaphoreEncoding.js.map +1 -1
  117. package/build/src/Semaphore/SemaphoreStream.d.ts +17 -17
  118. package/build/src/Semaphore/SemaphoreStream.js +72 -71
  119. package/build/src/Semaphore/SemaphoreStream.js.map +1 -1
  120. package/build/src/WordSearch/Point.d.ts +4 -4
  121. package/build/src/WordSearch/Point.js +2 -2
  122. package/build/src/WordSearch/Result.d.ts +6 -6
  123. package/build/src/WordSearch/Result.js +10 -9
  124. package/build/src/WordSearch/Result.js.map +1 -1
  125. package/build/src/WordSearch/WordSearchDirection.d.ts +6 -6
  126. package/build/src/WordSearch/WordSearchDirection.js +10 -9
  127. package/build/src/WordSearch/WordSearchDirection.js.map +1 -1
  128. package/build/src/WordSearch/WordSearchSolver.d.ts +27 -18
  129. package/build/src/WordSearch/WordSearchSolver.js +222 -171
  130. package/build/src/WordSearch/WordSearchSolver.js.map +1 -1
  131. package/build/src/index.d.ts +35 -35
  132. package/build/src/index.js +72 -70
  133. package/build/src/index.js.map +1 -1
  134. package/package.json +40 -39
  135. package/src/Braille/BrailleCharacter.ts +49 -0
  136. package/src/Braille/BrailleData.ts +131 -0
  137. package/src/Braille/BrailleDot.ts +9 -0
  138. package/src/Braille/BrailleEncoding.ts +144 -0
  139. package/src/Braille/BrailleStream.ts +87 -0
  140. package/src/Cipher/AutoKeyString.ts +35 -0
  141. package/src/Cipher/CaesarString.ts +38 -0
  142. package/src/Cipher/CaesarUtils.ts +69 -0
  143. package/src/Cipher/KeyedCipherStringBase.ts +35 -0
  144. package/src/Cipher/VigenereString.ts +21 -0
  145. package/src/Common/CharacterImage.ts +11 -0
  146. package/src/Common/EncodingCategory.ts +10 -0
  147. package/src/Common/EncodingCharacterBase.ts +72 -0
  148. package/src/Common/EncodingDataBase.ts +31 -0
  149. package/src/Common/EncodingEntry.ts +17 -0
  150. package/src/Common/EncodingLookupResult.ts +10 -0
  151. package/src/Common/Helpers.ts +13 -0
  152. package/src/Common/InlineSvg.ts +15 -0
  153. package/src/Conversion/CharacterAutoConvert.ts +108 -0
  154. package/src/Conversion/CharacterConversion.ts +89 -0
  155. package/src/Conversion/CharacterEncoding.ts +9 -0
  156. package/src/Conversion/CharacterTableEntry.ts +23 -0
  157. package/src/Conversion/SignificantFigures.ts +55 -0
  158. package/src/Conversion/StringAutoConvert.ts +56 -0
  159. package/src/Morse/MorseCharacter.ts +112 -0
  160. package/src/Morse/MorseData.ts +143 -0
  161. package/src/Morse/MorseEncoding.ts +98 -0
  162. package/src/Morse/MorseString.ts +106 -0
  163. package/src/Nato/NatoCharacter.ts +9 -0
  164. package/src/Nato/NatoData.ts +49 -0
  165. package/src/NavalFlags/LICENSE +7 -0
  166. package/src/NavalFlags/NavalFlags.ts +293 -0
  167. package/src/Resistor/Resistor.ts +135 -0
  168. package/src/Resistor/ResistorColorEntry.ts +43 -0
  169. package/src/Semaphore/SemaphoreCharacter.ts +107 -0
  170. package/src/Semaphore/SemaphoreData.ts +58 -0
  171. package/src/Semaphore/SemaphoreDegrees.ts +26 -0
  172. package/src/Semaphore/SemaphoreDirection.ts +11 -0
  173. package/src/Semaphore/SemaphoreEncoding.ts +48 -0
  174. package/src/Semaphore/SemaphoreStream.ts +89 -0
  175. package/src/WordSearch/Point.ts +4 -0
  176. package/src/WordSearch/Result.ts +10 -0
  177. package/src/WordSearch/WordSearchDirection.ts +6 -0
  178. package/src/WordSearch/WordSearchSolver.ts +271 -0
  179. package/src/index.ts +38 -0
  180. package/src/trie-prefix-tree.d.ts +70 -0
@@ -0,0 +1,48 @@
1
+ import {SemaphoreDirection} from './SemaphoreDirection';
2
+
3
+ export enum SemaphoreEncoding {
4
+ None = 0,
5
+
6
+ // Letters
7
+ LetterA = SemaphoreDirection.SouthWest | SemaphoreDirection.South,
8
+ LetterB = SemaphoreDirection.West | SemaphoreDirection.South,
9
+ LetterC = SemaphoreDirection.NorthWest | SemaphoreDirection.South,
10
+ LetterD = SemaphoreDirection.North | SemaphoreDirection.South,
11
+ LetterE = SemaphoreDirection.NorthEast | SemaphoreDirection.South,
12
+ LetterF = SemaphoreDirection.East | SemaphoreDirection.South,
13
+ LetterG = SemaphoreDirection.SouthEast | SemaphoreDirection.South,
14
+ LetterH = SemaphoreDirection.SouthWest | SemaphoreDirection.West,
15
+ LetterI = SemaphoreDirection.SouthWest | SemaphoreDirection.NorthWest,
16
+ LetterJ = SemaphoreDirection.North | SemaphoreDirection.East,
17
+ LetterK = SemaphoreDirection.SouthWest | SemaphoreDirection.North,
18
+ LetterL = SemaphoreDirection.SouthWest | SemaphoreDirection.NorthEast,
19
+ LetterM = SemaphoreDirection.SouthWest | SemaphoreDirection.East,
20
+ LetterN = SemaphoreDirection.SouthWest | SemaphoreDirection.SouthEast,
21
+ LetterO = SemaphoreDirection.West | SemaphoreDirection.NorthWest,
22
+ LetterP = SemaphoreDirection.West | SemaphoreDirection.North,
23
+ LetterQ = SemaphoreDirection.West | SemaphoreDirection.NorthEast,
24
+ LetterR = SemaphoreDirection.West | SemaphoreDirection.East,
25
+ LetterS = SemaphoreDirection.West | SemaphoreDirection.SouthEast,
26
+ LetterT = SemaphoreDirection.NorthWest | SemaphoreDirection.North,
27
+ LetterU = SemaphoreDirection.NorthWest | SemaphoreDirection.NorthEast,
28
+ LetterV = SemaphoreDirection.North | SemaphoreDirection.SouthEast,
29
+ LetterW = SemaphoreDirection.East | SemaphoreDirection.NorthEast,
30
+ LetterX = SemaphoreDirection.SouthEast | SemaphoreDirection.NorthEast,
31
+ LetterY = SemaphoreDirection.NorthWest | SemaphoreDirection.East,
32
+ LetterZ = SemaphoreDirection.SouthEast | SemaphoreDirection.East,
33
+
34
+ // Numbers
35
+ Number1 = SemaphoreDirection.SouthWest | SemaphoreDirection.South,
36
+ Number2 = SemaphoreDirection.West | SemaphoreDirection.South,
37
+ Number3 = SemaphoreDirection.NorthWest | SemaphoreDirection.South,
38
+ Number4 = SemaphoreDirection.North | SemaphoreDirection.South,
39
+ Number5 = SemaphoreDirection.NorthEast | SemaphoreDirection.South,
40
+ Number6 = SemaphoreDirection.East | SemaphoreDirection.South,
41
+ Number7 = SemaphoreDirection.SouthEast | SemaphoreDirection.South,
42
+ Number8 = SemaphoreDirection.SouthWest | SemaphoreDirection.West,
43
+ Number9 = SemaphoreDirection.SouthWest | SemaphoreDirection.NorthWest,
44
+ Number0 = SemaphoreDirection.SouthWest | SemaphoreDirection.North,
45
+
46
+ // Formatting
47
+ FormattingNumber = SemaphoreDirection.North | SemaphoreDirection.NorthEast,
48
+ }
@@ -0,0 +1,89 @@
1
+ import {EncodingCategory} from '../Common/EncodingCategory';
2
+ import {SemaphoreCharacter} from './SemaphoreCharacter';
3
+ import {SemaphoreData} from './SemaphoreData';
4
+ import {SemaphoreEncoding} from './SemaphoreEncoding';
5
+
6
+ interface SemaphoreStreamState {
7
+ numberMode: boolean;
8
+ }
9
+
10
+ export class SemaphoreStream {
11
+ private readonly _chars: SemaphoreEncoding[] = [];
12
+ private readonly _state: SemaphoreStreamState;
13
+ private _currentStr = '';
14
+ private _processPosition = 0;
15
+
16
+ constructor(chars?: SemaphoreEncoding[]) {
17
+ if (chars) {
18
+ this._chars = Array.from(chars);
19
+ }
20
+
21
+ this._state = {
22
+ numberMode: false,
23
+ };
24
+
25
+ this.invalidate();
26
+ }
27
+
28
+ get chars() {
29
+ return this._chars;
30
+ }
31
+
32
+ set chars(value: SemaphoreEncoding[]) {
33
+ this.clear();
34
+
35
+ for (const ch of value) {
36
+ this._chars.push(ch);
37
+ }
38
+ }
39
+
40
+ append(ch: SemaphoreCharacter) {
41
+ this._chars.push(ch.valueOf());
42
+ }
43
+
44
+ clear() {
45
+ this._chars.length = 0;
46
+ this.invalidate();
47
+ }
48
+
49
+ space() {
50
+ this._chars.push(SemaphoreEncoding.None);
51
+ }
52
+
53
+ toString() {
54
+ this.update();
55
+ return this._currentStr;
56
+ }
57
+
58
+ private invalidate() {
59
+ this._currentStr = '';
60
+ this._processPosition = 0;
61
+ }
62
+
63
+ private update() {
64
+ while (this._processPosition < this._chars.length) {
65
+ const ch = this._chars[this._processPosition];
66
+
67
+ if (ch === SemaphoreEncoding.None) {
68
+ this._state.numberMode = false;
69
+ this._currentStr += ' ';
70
+ } else if (ch === SemaphoreEncoding.FormattingNumber) {
71
+ this._state.numberMode = true;
72
+ this._currentStr += '#';
73
+ } else {
74
+ const category =
75
+ EncodingCategory.Punctuation |
76
+ (this._state.numberMode
77
+ ? EncodingCategory.Number
78
+ : EncodingCategory.Letter);
79
+ const exact = SemaphoreData.instance.lookup(ch, category).exact;
80
+
81
+ if (exact.length > 0) {
82
+ this._currentStr += exact[0].toString();
83
+ }
84
+ }
85
+
86
+ this._processPosition++;
87
+ }
88
+ }
89
+ }
@@ -0,0 +1,4 @@
1
+ export interface Point {
2
+ x: number;
3
+ y: number;
4
+ }
@@ -0,0 +1,10 @@
1
+ import {Point} from './Point';
2
+
3
+ export class Result {
4
+ word: string;
5
+ points: Point[];
6
+ constructor(word: string, wordPoints: Point[]) {
7
+ this.word = word;
8
+ this.points = Array.from(wordPoints);
9
+ }
10
+ }
@@ -0,0 +1,6 @@
1
+ export enum WordSearchDirection {
2
+ None = 0,
3
+ Cardinal = 1,
4
+ Diagonal = 2,
5
+ CardinalAndDiagonal = 3,
6
+ }
@@ -0,0 +1,271 @@
1
+ import trie = require('trie-prefix-tree');
2
+
3
+ import {Point} from './Point';
4
+ import {Result} from './Result';
5
+ import {WordSearchDirection} from './WordSearchDirection';
6
+
7
+ export enum WordSearchSpaceTreatment {
8
+ None = 0,
9
+ RemoveWithinPuzzle = 1,
10
+ RemoveAll = 2,
11
+ }
12
+
13
+ export class WordSearchSolver {
14
+ // The grid of letters which makes up the wordsearch puzzle
15
+ private _matrix: string[][];
16
+ // Transpositions to apply when finding words
17
+ private _directions: number[][];
18
+ // Potential words to find in the letter grid
19
+ private _targets: ReturnType<typeof trie>;
20
+ // Should we search for words not following a line
21
+ private _canBend: boolean;
22
+ // What should we do with spaces
23
+ private _spaceTreatment: WordSearchSpaceTreatment;
24
+
25
+ constructor() {
26
+ // Use empty grid and list by default
27
+ this._matrix = [[]];
28
+ this._targets = trie([]);
29
+ // Use both sets of directions by default
30
+ this._directions = [
31
+ // Cardinal directions
32
+ [0, 1],
33
+ [-1, 0],
34
+ [1, 0],
35
+ [0, -1],
36
+ // Diagonal
37
+ [1, 1],
38
+ [-1, -1],
39
+ [1, -1],
40
+ [-1, 1],
41
+ ];
42
+ this._canBend = false;
43
+ this._spaceTreatment = WordSearchSpaceTreatment.None;
44
+ }
45
+
46
+ setWords(words: string[]) {
47
+ this._targets = trie([]);
48
+ for (const full of words) {
49
+ if (full === null || typeof full === 'undefined') {
50
+ throw new Error('Invalid input in WordSearchSolver.findWords()');
51
+ }
52
+ const word = full.trim();
53
+ if (word !== '') {
54
+ this._targets.addWord(word);
55
+ } else {
56
+ throw new Error('Cannot find an empty string in the wordsearch');
57
+ }
58
+ }
59
+ }
60
+
61
+ parseGrid(gridInputText: string) {
62
+ const lines = gridInputText.split(/\r?\n/);
63
+ const grid: string[][] = [];
64
+ for (const line of lines) {
65
+ grid.push(line.split(''));
66
+ }
67
+ this.setGrid(grid);
68
+ }
69
+
70
+ setGrid(matrix: string[][]) {
71
+ this._matrix = matrix;
72
+ this.checkSpaces();
73
+ }
74
+
75
+ setDirections(direction: WordSearchDirection) {
76
+ this._directions = [];
77
+ if (
78
+ direction === WordSearchDirection.Cardinal ||
79
+ direction === WordSearchDirection.CardinalAndDiagonal
80
+ ) {
81
+ this._directions = this._directions.concat([
82
+ [0, 1],
83
+ [-1, 0],
84
+ [1, 0],
85
+ [0, -1],
86
+ ]);
87
+ }
88
+ if (
89
+ direction === WordSearchDirection.Diagonal ||
90
+ direction === WordSearchDirection.CardinalAndDiagonal
91
+ ) {
92
+ this._directions = this._directions.concat([
93
+ [1, 1],
94
+ [-1, -1],
95
+ [1, -1],
96
+ [-1, 1],
97
+ ]);
98
+ }
99
+ }
100
+
101
+ setSpaceTreatment(treatment: WordSearchSpaceTreatment) {
102
+ this._spaceTreatment = treatment;
103
+
104
+ if (this._matrix.length > 0) {
105
+ this.checkSpaces();
106
+ }
107
+ }
108
+
109
+ setCanBend(canBend: boolean) {
110
+ this._canBend = canBend;
111
+ }
112
+
113
+ findWords(): Result[] {
114
+ const results: Result[] = [];
115
+ const numRows = this._matrix.length;
116
+ for (let yIdx = 0; yIdx < numRows; yIdx++) {
117
+ const lineLength = this._matrix[yIdx].length;
118
+ for (let xIdx = 0; xIdx < lineLength; xIdx++) {
119
+ const p: Point = {x: xIdx, y: yIdx};
120
+ const pointResults = this.search(p);
121
+ results.push(...pointResults);
122
+ }
123
+ }
124
+ return results;
125
+ }
126
+
127
+ private search(start: Point): Result[] {
128
+ const results: Result[] = [];
129
+ if (this._canBend) {
130
+ const history: Point[] = [];
131
+ const dfsResults = this.dfsCheck(start, new Set(), history);
132
+ results.push(...dfsResults);
133
+ } else {
134
+ for (const translation of this._directions) {
135
+ const directionalResults = this.lineCheck(start, translation);
136
+ results.push(...directionalResults);
137
+ }
138
+ }
139
+ return results;
140
+ }
141
+
142
+ private dfsCheck(
143
+ start: Point,
144
+ visited: Set<Point>,
145
+ history: Point[]
146
+ ): Result[] {
147
+ const results: Result[] = [];
148
+
149
+ if (visited.has(start)) {
150
+ return results;
151
+ }
152
+
153
+ visited.add(start);
154
+ history.push(start);
155
+
156
+ let currentString = '';
157
+
158
+ for (let i = 0; i < history.length; i++) {
159
+ const pt = history[i];
160
+ currentString = currentString + this._matrix[pt.y][pt.x];
161
+ }
162
+
163
+ const wordsWithPrefix = this._targets.getPrefix(currentString);
164
+ if (wordsWithPrefix.length === 0) {
165
+ visited.delete(start);
166
+ history.pop();
167
+ return results;
168
+ }
169
+
170
+ if (wordsWithPrefix.indexOf(currentString) !== -1) {
171
+ const foundWord = new Result(currentString, history);
172
+ results.push(foundWord);
173
+ }
174
+
175
+ for (const translation of this._directions) {
176
+ const next: Point = {
177
+ x: start.x + translation[0],
178
+ y: start.y + translation[1],
179
+ };
180
+
181
+ if (this.isInBounds(next)) {
182
+ results.push(...this.dfsCheck(next, visited, history));
183
+ }
184
+ }
185
+
186
+ visited.delete(start);
187
+ history.pop();
188
+
189
+ return results;
190
+ }
191
+
192
+ private lineCheck(start: Point, direction: number[]): Result[] {
193
+ const results: Result[] = [];
194
+
195
+ // Working set
196
+ let currentPoint = start;
197
+ let currentString = '';
198
+ const pointHistory = [];
199
+ while (this.isInBounds(currentPoint)) {
200
+ currentString =
201
+ currentString + this._matrix[currentPoint.y][currentPoint.x];
202
+
203
+ // Get the candidates with the current prefix string
204
+ const wordsWithPrefix = this._targets.getPrefix(currentString);
205
+
206
+ // No point in going on, we've run out of possibilities
207
+ if (wordsWithPrefix.length === 0) {
208
+ break;
209
+ }
210
+
211
+ const p: Point = {x: currentPoint.x, y: currentPoint.y};
212
+ pointHistory.push(p);
213
+
214
+ // Is a candidate an exact match for the current search string? Save it.
215
+ if (wordsWithPrefix.indexOf(currentString) !== -1) {
216
+ const foundWord = new Result(currentString, pointHistory);
217
+ results.push(foundWord);
218
+ }
219
+ const next: Point = {
220
+ x: currentPoint.x + direction[0],
221
+ y: currentPoint.y + direction[1],
222
+ };
223
+ currentPoint = next;
224
+ }
225
+
226
+ return results;
227
+ }
228
+
229
+ private isInBounds(point: Point): boolean {
230
+ if (point.y < 0 || point.y >= this._matrix.length) {
231
+ return false;
232
+ }
233
+ if (point.x < 0 || point.x >= this._matrix[point.y].length) {
234
+ return false;
235
+ }
236
+ return true;
237
+ }
238
+
239
+ private checkSpaces(): void {
240
+ if (
241
+ this._matrix.length === 0 ||
242
+ this._spaceTreatment === WordSearchSpaceTreatment.None
243
+ ) {
244
+ return;
245
+ }
246
+
247
+ const nextMatrix = [];
248
+ for (let yIdx = 0; yIdx < this._matrix.length; yIdx++) {
249
+ const line = [];
250
+ let inPuzzle = false;
251
+ for (let xIdx = 0; xIdx < this._matrix[yIdx].length; xIdx++) {
252
+ const letter = this._matrix[yIdx][xIdx];
253
+ if (letter !== ' ') {
254
+ inPuzzle = true;
255
+ }
256
+ if (
257
+ this._spaceTreatment === WordSearchSpaceTreatment.RemoveAll &&
258
+ letter !== ' '
259
+ ) {
260
+ line.push(this._matrix[yIdx][xIdx]);
261
+ } else if (letter !== ' ' && inPuzzle) {
262
+ line.push(this._matrix[yIdx][xIdx]);
263
+ }
264
+ }
265
+ if (line.length > 0) {
266
+ nextMatrix.push(line);
267
+ }
268
+ }
269
+ this._matrix = nextMatrix;
270
+ }
271
+ }
package/src/index.ts ADDED
@@ -0,0 +1,38 @@
1
+ export {BrailleCharacter} from './Braille/BrailleCharacter';
2
+ export {BrailleDot} from './Braille/BrailleDot';
3
+ export {BrailleEncoding} from './Braille/BrailleEncoding';
4
+ export {BrailleStream} from './Braille/BrailleStream';
5
+ export {AutoKeyString} from './Cipher/AutoKeyString';
6
+ export {CaesarString} from './Cipher/CaesarString';
7
+ export {KeyedCipherStringBase} from './Cipher/KeyedCipherStringBase';
8
+ export {VigenereString} from './Cipher/VigenereString';
9
+ export {CharacterImage} from './Common/CharacterImage';
10
+ export {EncodingCategory} from './Common/EncodingCategory';
11
+ export {EncodingEntry} from './Common/EncodingEntry';
12
+ export {InlineSvg} from './Common/InlineSvg';
13
+ export {CharacterAutoConvert} from './Conversion/CharacterAutoConvert';
14
+ export {CharacterConversion} from './Conversion/CharacterConversion';
15
+ export {CharacterEncoding} from './Conversion/CharacterEncoding';
16
+ export {CharacterTableEntry} from './Conversion/CharacterTableEntry';
17
+ export {SignificantFigures} from './Conversion/SignificantFigures';
18
+ export {StringAutoConvert} from './Conversion/StringAutoConvert';
19
+ export {MorseCharacter} from './Morse/MorseCharacter';
20
+ export {MorseEncoding} from './Morse/MorseEncoding';
21
+ export {MorseString} from './Morse/MorseString';
22
+ export {NatoCharacter} from './Nato/NatoCharacter';
23
+ export {NatoData} from './Nato/NatoData';
24
+ export {NavalFlags} from './NavalFlags/NavalFlags';
25
+ export {Resistor} from './Resistor/Resistor';
26
+ export {ResistorColorEntry} from './Resistor/ResistorColorEntry';
27
+ export {SemaphoreCharacter} from './Semaphore/SemaphoreCharacter';
28
+ export {SemaphoreDegrees} from './Semaphore/SemaphoreDegrees';
29
+ export {SemaphoreDirection} from './Semaphore/SemaphoreDirection';
30
+ export {SemaphoreEncoding} from './Semaphore/SemaphoreEncoding';
31
+ export {SemaphoreStream} from './Semaphore/SemaphoreStream';
32
+ export {Point as WordSearchPoint} from './WordSearch/Point';
33
+ export {Result as WordSearchResult} from './WordSearch/Result';
34
+ export {WordSearchDirection} from './WordSearch/WordSearchDirection';
35
+ export {
36
+ WordSearchSolver,
37
+ WordSearchSpaceTreatment,
38
+ } from './WordSearch/WordSearchSolver';
@@ -0,0 +1,70 @@
1
+ // Type definitions for trie-prefix-tree 1.5
2
+ // Project: https://github.com/lyndseybrowning/trie-prefix#readme
3
+ // Definitions by: James Lismore <https://github.com/jlismore>
4
+ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5
+ // TypeScript Version: 2.8
6
+
7
+ // The published typings don't seem to work correctly with ES6 module syntax,
8
+ // switch to CommonJS module syntax instead.
9
+ declare module 'trie-prefix-tree' {
10
+ function Trie(strings: string[]): {
11
+ /**
12
+ * Get a string representation of the trie
13
+ */
14
+ dump(spacer?: number): string;
15
+ /**
16
+ * Get the generated raw trie object
17
+ */
18
+ tree(): {};
19
+ /**
20
+ * Add a new word to the trie
21
+ */
22
+ addWord(word: string): ReturnType<typeof Trie>;
23
+ /**
24
+ * Remove an existing word from the trie
25
+ */
26
+ removeWord(word: string): ReturnType<typeof Trie>;
27
+ /**
28
+ * Check a prefix is valid
29
+ * @returns Boolean
30
+ */
31
+ isPrefix(word: string): boolean;
32
+ /**
33
+ * Count the number of words with the given prefixSearch
34
+ * @returns Number
35
+ */
36
+ countPrefix(word: string): number;
37
+ /**
38
+ * Get a list of all words in the trie with the given prefix
39
+ * @returns Array
40
+ */
41
+ getPrefix(word: string, sort?: boolean): string[];
42
+ /**
43
+ * Get a random word in the trie with the given prefix
44
+ * @returns Array
45
+ */
46
+ getRandomWordWithPrefix(prefix: string): string;
47
+ /**
48
+ * Get all words in the trie
49
+ * @returns Array
50
+ */
51
+ getWords(sorted?: boolean): string[];
52
+ /**
53
+ * Check the existence of a word in the trie
54
+ * @returns Boolean
55
+ */
56
+ hasWord(word: string): boolean;
57
+ /**
58
+ * Get a list of valid anagrams that can be made from the given letters
59
+ * @returns Array
60
+ */
61
+ getAnagrams(word: string): string[];
62
+ /**
63
+ * Get a list of all sub-anagrams that can be made from the given letters
64
+ * @returns Array
65
+ */
66
+ getSubAnagrams(word: string): string[];
67
+ };
68
+
69
+ export = Trie;
70
+ }