puzzle-lib 2.0.0-beta.1 → 2.0.0-beta.2

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 (244) hide show
  1. package/README.md +62 -9
  2. package/build/src/{Braille → braille}/braille.d.ts +4 -4
  3. package/build/src/braille/braille.js +121 -0
  4. package/build/src/braille/braille.js.map +1 -0
  5. package/build/src/{Braille/BrailleDot.js → braille/dot.js} +3 -6
  6. package/build/src/braille/dot.js.map +1 -0
  7. package/build/src/{Braille/BrailleEncoding.js → braille/encoding.js} +4 -7
  8. package/build/src/braille/encoding.js.map +1 -0
  9. package/build/src/braille/index.d.ts +3 -0
  10. package/build/src/braille/index.js +4 -0
  11. package/build/src/braille/index.js.map +1 -0
  12. package/build/src/{Cipher → cipher}/cipher.js +10 -20
  13. package/build/src/cipher/cipher.js.map +1 -0
  14. package/build/src/cipher/index.d.ts +1 -0
  15. package/build/src/cipher/index.js +2 -0
  16. package/build/src/cipher/index.js.map +1 -0
  17. package/build/src/{Common/CharacterImage.d.ts → common/character-image.d.ts} +1 -1
  18. package/build/src/common/character-image.js +9 -0
  19. package/build/src/common/character-image.js.map +1 -0
  20. package/build/src/{Common/EncodingCategory.js → common/encoding-category.js} +3 -6
  21. package/build/src/common/encoding-category.js.map +1 -0
  22. package/build/src/{Common/EncodingEntry.d.ts → common/encoding-entry.d.ts} +1 -1
  23. package/build/src/{Common/EncodingEntry.js → common/encoding-entry.js} +2 -6
  24. package/build/src/common/encoding-entry.js.map +1 -0
  25. package/build/src/{Common/EncodingLookupResult.d.ts → common/encoding-lookup-result.d.ts} +1 -1
  26. package/build/src/common/encoding-lookup-result.js +8 -0
  27. package/build/src/common/encoding-lookup-result.js.map +1 -0
  28. package/build/src/common/index.d.ts +5 -0
  29. package/build/src/common/index.js +6 -0
  30. package/build/src/common/index.js.map +1 -0
  31. package/build/src/{Common/InlineSvg.js → common/inline-svg.js} +2 -6
  32. package/build/src/common/inline-svg.js.map +1 -0
  33. package/build/src/{Conversion/characterConversion.d.ts → conversion/character-conversion.d.ts} +1 -1
  34. package/build/src/{Conversion/characterConversion.js → conversion/character-conversion.js} +7 -13
  35. package/build/src/conversion/character-conversion.js.map +1 -0
  36. package/build/src/{Conversion/CharacterEncoding.d.ts → conversion/character-encoding.d.ts} +2 -1
  37. package/build/src/{Conversion/CharacterEncoding.js → conversion/character-encoding.js} +4 -6
  38. package/build/src/conversion/character-encoding.js.map +1 -0
  39. package/build/src/{Conversion/CharacterTableEntry.js → conversion/character-table-entry.js} +2 -6
  40. package/build/src/conversion/character-table-entry.js.map +1 -0
  41. package/build/src/{Conversion → conversion}/conversion.d.ts +3 -1
  42. package/build/src/{Conversion → conversion}/conversion.js +63 -27
  43. package/build/src/conversion/conversion.js.map +1 -0
  44. package/build/src/conversion/index.d.ts +5 -0
  45. package/build/src/conversion/index.js +6 -0
  46. package/build/src/conversion/index.js.map +1 -0
  47. package/build/src/{Conversion/significantFigures.js → conversion/significant-figures.js} +4 -9
  48. package/build/src/conversion/significant-figures.js.map +1 -0
  49. package/build/src/{Morse/MorseEncoding.js → morse/encoding.js} +3 -6
  50. package/build/src/morse/encoding.js.map +1 -0
  51. package/build/src/morse/index.d.ts +2 -0
  52. package/build/src/morse/index.js +3 -0
  53. package/build/src/morse/index.js.map +1 -0
  54. package/build/src/{Morse → morse}/morse.d.ts +3 -3
  55. package/build/src/morse/morse.js +222 -0
  56. package/build/src/morse/morse.js.map +1 -0
  57. package/build/src/nato/character.js +9 -0
  58. package/build/src/nato/character.js.map +1 -0
  59. package/build/src/nato/index.d.ts +2 -0
  60. package/build/src/nato/index.js +3 -0
  61. package/build/src/nato/index.js.map +1 -0
  62. package/build/src/{Nato → nato}/nato.d.ts +1 -1
  63. package/build/src/nato/nato.js +33 -0
  64. package/build/src/nato/nato.js.map +1 -0
  65. package/build/src/naval-flags/index.d.ts +1 -0
  66. package/build/src/naval-flags/index.js +2 -0
  67. package/build/src/naval-flags/index.js.map +1 -0
  68. package/build/src/{NavalFlags/navalFlags.d.ts → naval-flags/naval-flags.d.ts} +1 -1
  69. package/build/src/{NavalFlags/navalFlags.js → naval-flags/naval-flags.js} +32 -36
  70. package/build/src/naval-flags/naval-flags.js.map +1 -0
  71. package/build/src/ngrams/bigrams.d.ts +2 -0
  72. package/build/src/ngrams/bigrams.js +684 -0
  73. package/build/src/ngrams/bigrams.js.map +1 -0
  74. package/build/src/ngrams/index.d.ts +1 -0
  75. package/build/src/ngrams/index.js +2 -0
  76. package/build/src/ngrams/index.js.map +1 -0
  77. package/build/src/ngrams/ngrams.d.ts +13 -0
  78. package/build/src/ngrams/ngrams.js +71 -0
  79. package/build/src/ngrams/ngrams.js.map +1 -0
  80. package/build/src/ngrams/trigrams.d.ts +2 -0
  81. package/build/src/ngrams/trigrams.js +17583 -0
  82. package/build/src/ngrams/trigrams.js.map +1 -0
  83. package/build/src/ngrams/unigrams.d.ts +2 -0
  84. package/build/src/ngrams/unigrams.js +34 -0
  85. package/build/src/ngrams/unigrams.js.map +1 -0
  86. package/build/src/phone/index.d.ts +2 -0
  87. package/build/src/phone/index.js +2 -0
  88. package/build/src/phone/index.js.map +1 -0
  89. package/build/src/phone/phone-mapping.d.ts +10 -0
  90. package/build/src/phone/phone-mapping.js +27 -0
  91. package/build/src/phone/phone-mapping.js.map +1 -0
  92. package/build/src/phone/phone.d.ts +27 -0
  93. package/build/src/phone/phone.js +62 -0
  94. package/build/src/phone/phone.js.map +1 -0
  95. package/build/src/pigpen/encoding.d.ts +29 -0
  96. package/build/src/pigpen/encoding.js +36 -0
  97. package/build/src/pigpen/encoding.js.map +1 -0
  98. package/build/src/pigpen/index.d.ts +3 -0
  99. package/build/src/pigpen/index.js +4 -0
  100. package/build/src/pigpen/index.js.map +1 -0
  101. package/build/src/pigpen/pigpen.d.ts +35 -0
  102. package/build/src/pigpen/pigpen.js +137 -0
  103. package/build/src/pigpen/pigpen.js.map +1 -0
  104. package/build/src/pigpen/segment.d.ts +12 -0
  105. package/build/src/pigpen/segment.js +14 -0
  106. package/build/src/pigpen/segment.js.map +1 -0
  107. package/build/src/resistor/index.d.ts +2 -0
  108. package/build/src/resistor/index.js +2 -0
  109. package/build/src/resistor/index.js.map +1 -0
  110. package/build/src/{Resistor → resistor}/resistor.js +7 -14
  111. package/build/src/resistor/resistor.js.map +1 -0
  112. package/build/src/{Semaphore/SemaphoreDirection.js → semaphore/direction.js} +3 -6
  113. package/build/src/semaphore/direction.js.map +1 -0
  114. package/build/src/{Semaphore/SemaphoreEncoding.js → semaphore/encoding.js} +4 -7
  115. package/build/src/semaphore/encoding.js.map +1 -0
  116. package/build/src/semaphore/index.d.ts +3 -0
  117. package/build/src/semaphore/index.js +4 -0
  118. package/build/src/semaphore/index.js.map +1 -0
  119. package/build/src/{Semaphore → semaphore}/semaphore.d.ts +4 -4
  120. package/build/src/semaphore/semaphore.js +207 -0
  121. package/build/src/semaphore/semaphore.js.map +1 -0
  122. package/build/src/{WordSearch/WordSearchDirection.js → word-search/direction.js} +3 -6
  123. package/build/src/word-search/direction.js.map +1 -0
  124. package/build/src/word-search/index.d.ts +5 -0
  125. package/build/src/word-search/index.js +4 -0
  126. package/build/src/word-search/index.js.map +1 -0
  127. package/build/src/word-search/point.d.ts +4 -0
  128. package/build/src/word-search/point.js +2 -0
  129. package/build/src/word-search/point.js.map +1 -0
  130. package/build/src/word-search/result.d.ts +6 -0
  131. package/build/src/word-search/result.js +9 -0
  132. package/build/src/word-search/result.js.map +1 -0
  133. package/build/src/{WordSearch/wordSearch.d.ts → word-search/word-search.d.ts} +3 -3
  134. package/build/src/{WordSearch/wordSearch.js → word-search/word-search.js} +13 -17
  135. package/build/src/word-search/word-search.js.map +1 -0
  136. package/package.json +57 -3
  137. package/src/{Braille → braille}/braille.ts +5 -5
  138. package/src/{Braille/BrailleEncoding.ts → braille/encoding.ts} +1 -1
  139. package/src/braille/index.ts +8 -0
  140. package/src/{Cipher → cipher}/cipher.ts +1 -1
  141. package/src/cipher/index.ts +10 -0
  142. package/src/{Common/CharacterImage.ts → common/character-image.ts} +1 -1
  143. package/src/{Common/EncodingEntry.ts → common/encoding-entry.ts} +1 -1
  144. package/src/{Common/EncodingLookupResult.ts → common/encoding-lookup-result.ts} +1 -1
  145. package/src/common/index.ts +5 -0
  146. package/src/{Conversion/characterConversion.ts → conversion/character-conversion.ts} +1 -1
  147. package/src/{Conversion/CharacterEncoding.ts → conversion/character-encoding.ts} +1 -0
  148. package/src/{Conversion → conversion}/conversion.ts +57 -1
  149. package/src/conversion/index.ts +15 -0
  150. package/src/morse/index.ts +14 -0
  151. package/src/{Morse → morse}/morse.ts +4 -4
  152. package/src/nato/index.ts +2 -0
  153. package/src/{Nato → nato}/nato.ts +1 -1
  154. package/src/naval-flags/index.ts +1 -0
  155. package/src/{NavalFlags/navalFlags.ts → naval-flags/naval-flags.ts} +2 -2
  156. package/src/ngrams/bigrams.ts +684 -0
  157. package/src/ngrams/index.ts +1 -0
  158. package/src/ngrams/ngrams.ts +73 -0
  159. package/src/ngrams/trigrams.ts +17584 -0
  160. package/src/ngrams/unigrams.ts +34 -0
  161. package/src/phone/index.ts +2 -0
  162. package/src/phone/phone-mapping.ts +27 -0
  163. package/src/phone/phone.ts +77 -0
  164. package/src/pigpen/encoding.ts +66 -0
  165. package/src/pigpen/index.ts +11 -0
  166. package/src/pigpen/pigpen.ts +168 -0
  167. package/src/pigpen/segment.ts +12 -0
  168. package/src/resistor/index.ts +9 -0
  169. package/src/{Semaphore/SemaphoreEncoding.ts → semaphore/encoding.ts} +1 -1
  170. package/src/semaphore/index.ts +13 -0
  171. package/src/{Semaphore → semaphore}/semaphore.ts +5 -5
  172. package/src/trie-prefix-tree.d.ts +1 -3
  173. package/src/word-search/index.ts +5 -0
  174. package/src/word-search/point.ts +4 -0
  175. package/src/word-search/result.ts +10 -0
  176. package/src/{WordSearch/wordSearch.ts → word-search/word-search.ts} +26 -26
  177. package/build/src/Braille/BrailleDot.js.map +0 -1
  178. package/build/src/Braille/BrailleEncoding.js.map +0 -1
  179. package/build/src/Braille/braille.js +0 -127
  180. package/build/src/Braille/braille.js.map +0 -1
  181. package/build/src/Cipher/cipher.js.map +0 -1
  182. package/build/src/Common/CharacterImage.js +0 -13
  183. package/build/src/Common/CharacterImage.js.map +0 -1
  184. package/build/src/Common/EncodingCategory.js.map +0 -1
  185. package/build/src/Common/EncodingEntry.js.map +0 -1
  186. package/build/src/Common/EncodingLookupResult.js +0 -12
  187. package/build/src/Common/EncodingLookupResult.js.map +0 -1
  188. package/build/src/Common/InlineSvg.js.map +0 -1
  189. package/build/src/Conversion/CharacterEncoding.js.map +0 -1
  190. package/build/src/Conversion/CharacterTableEntry.js.map +0 -1
  191. package/build/src/Conversion/characterConversion.js.map +0 -1
  192. package/build/src/Conversion/conversion.js.map +0 -1
  193. package/build/src/Conversion/significantFigures.js.map +0 -1
  194. package/build/src/Morse/MorseEncoding.js.map +0 -1
  195. package/build/src/Morse/morse.js +0 -232
  196. package/build/src/Morse/morse.js.map +0 -1
  197. package/build/src/Nato/NatoCharacter.js +0 -13
  198. package/build/src/Nato/NatoCharacter.js.map +0 -1
  199. package/build/src/Nato/nato.js +0 -37
  200. package/build/src/Nato/nato.js.map +0 -1
  201. package/build/src/NavalFlags/navalFlags.js.map +0 -1
  202. package/build/src/Resistor/resistor.js.map +0 -1
  203. package/build/src/Semaphore/SemaphoreDirection.js.map +0 -1
  204. package/build/src/Semaphore/SemaphoreEncoding.js.map +0 -1
  205. package/build/src/Semaphore/semaphore.js +0 -218
  206. package/build/src/Semaphore/semaphore.js.map +0 -1
  207. package/build/src/WordSearch/Point.d.ts +0 -4
  208. package/build/src/WordSearch/Point.js +0 -3
  209. package/build/src/WordSearch/Point.js.map +0 -1
  210. package/build/src/WordSearch/Result.d.ts +0 -6
  211. package/build/src/WordSearch/Result.js +0 -13
  212. package/build/src/WordSearch/Result.js.map +0 -1
  213. package/build/src/WordSearch/WordSearchDirection.js.map +0 -1
  214. package/build/src/WordSearch/wordSearch.js.map +0 -1
  215. package/build/src/index.d.ts +0 -29
  216. package/build/src/index.js +0 -101
  217. package/build/src/index.js.map +0 -1
  218. package/src/WordSearch/Point.ts +0 -4
  219. package/src/WordSearch/Result.ts +0 -10
  220. package/src/index.ts +0 -86
  221. /package/build/src/{Braille/BrailleDot.d.ts → braille/dot.d.ts} +0 -0
  222. /package/build/src/{Braille/BrailleEncoding.d.ts → braille/encoding.d.ts} +0 -0
  223. /package/build/src/{Cipher → cipher}/cipher.d.ts +0 -0
  224. /package/build/src/{Common/EncodingCategory.d.ts → common/encoding-category.d.ts} +0 -0
  225. /package/build/src/{Common/InlineSvg.d.ts → common/inline-svg.d.ts} +0 -0
  226. /package/build/src/{Conversion/CharacterTableEntry.d.ts → conversion/character-table-entry.d.ts} +0 -0
  227. /package/build/src/{Conversion/significantFigures.d.ts → conversion/significant-figures.d.ts} +0 -0
  228. /package/build/src/{Morse/MorseEncoding.d.ts → morse/encoding.d.ts} +0 -0
  229. /package/build/src/{Nato/NatoCharacter.d.ts → nato/character.d.ts} +0 -0
  230. /package/build/src/{Resistor → resistor}/resistor.d.ts +0 -0
  231. /package/build/src/{Semaphore/SemaphoreDirection.d.ts → semaphore/direction.d.ts} +0 -0
  232. /package/build/src/{Semaphore/SemaphoreEncoding.d.ts → semaphore/encoding.d.ts} +0 -0
  233. /package/build/src/{WordSearch/WordSearchDirection.d.ts → word-search/direction.d.ts} +0 -0
  234. /package/src/{Braille/BrailleDot.ts → braille/dot.ts} +0 -0
  235. /package/src/{Common/EncodingCategory.ts → common/encoding-category.ts} +0 -0
  236. /package/src/{Common/InlineSvg.ts → common/inline-svg.ts} +0 -0
  237. /package/src/{Conversion/CharacterTableEntry.ts → conversion/character-table-entry.ts} +0 -0
  238. /package/src/{Conversion/significantFigures.ts → conversion/significant-figures.ts} +0 -0
  239. /package/src/{Morse/MorseEncoding.ts → morse/encoding.ts} +0 -0
  240. /package/src/{Nato/NatoCharacter.ts → nato/character.ts} +0 -0
  241. /package/src/{NavalFlags → naval-flags}/LICENSE +0 -0
  242. /package/src/{Resistor → resistor}/resistor.ts +0 -0
  243. /package/src/{Semaphore/SemaphoreDirection.ts → semaphore/direction.ts} +0 -0
  244. /package/src/{WordSearch/WordSearchDirection.ts → word-search/direction.ts} +0 -0
@@ -0,0 +1,34 @@
1
+ // Log-probabilities of English letter unigrams.
2
+ // Derived from bigram frequencies (sum of P(xy) over all y for each x).
3
+ // Original bigram source: Peter Norvig, Google Web Trillion Word Corpus (public domain)
4
+ // http://norvig.com/ngrams/count_2l.txt
5
+ export const UNIGRAM_LOG_PROB: Record<string, number> = {
6
+ e: -2.186224,
7
+ a: -2.448764,
8
+ t: -2.47288,
9
+ o: -2.501531,
10
+ i: -2.516878,
11
+ n: -2.681277,
12
+ r: -2.700564,
13
+ s: -2.800337,
14
+ l: -3.133597,
15
+ c: -3.206786,
16
+ h: -3.266123,
17
+ d: -3.428238,
18
+ u: -3.464367,
19
+ m: -3.543925,
20
+ p: -3.613343,
21
+ f: -3.87574,
22
+ g: -3.926056,
23
+ b: -4.025837,
24
+ w: -4.158706,
25
+ y: -4.284818,
26
+ v: -4.386163,
27
+ k: -4.895394,
28
+ x: -5.875251,
29
+ j: -5.90304,
30
+ q: -6.558017,
31
+ z: -6.560645,
32
+ };
33
+
34
+ export const MIN_UNIGRAM_LOG_PROB = -11.560645;
@@ -0,0 +1,2 @@
1
+ export {lettersToPhone, phoneToLetters, phoneToText} from './phone.js';
2
+ export type {PhoneResult} from './phone.js';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Standard telephone keypad mapping (ITU E.161 / T9).
3
+ * Maps digit characters to their corresponding letters.
4
+ */
5
+ export const PHONE_MAPPING: Partial<Record<string, readonly string[]>> = {
6
+ '2': ['a', 'b', 'c'],
7
+ '3': ['d', 'e', 'f'],
8
+ '4': ['g', 'h', 'i'],
9
+ '5': ['j', 'k', 'l'],
10
+ '6': ['m', 'n', 'o'],
11
+ '7': ['p', 'q', 'r', 's'],
12
+ '8': ['t', 'u', 'v'],
13
+ '9': ['w', 'x', 'y', 'z'],
14
+ };
15
+
16
+ /**
17
+ * Reverse mapping: letter to digit.
18
+ * Built automatically from PHONE_MAPPING.
19
+ */
20
+ export const LETTER_TO_DIGIT: Record<string, string> = {};
21
+ for (const [digit, letters] of Object.entries(PHONE_MAPPING)) {
22
+ if (letters) {
23
+ for (const letter of letters) {
24
+ LETTER_TO_DIGIT[letter] = digit;
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,77 @@
1
+ import {scoreNextLetter} from '../ngrams/ngrams.js';
2
+ import {LETTER_TO_DIGIT, PHONE_MAPPING} from './phone-mapping.js';
3
+
4
+ export interface PhoneResult {
5
+ /** The candidate text string. */
6
+ text: string;
7
+ /** Log-probability score (higher = more likely). */
8
+ score: number;
9
+ }
10
+
11
+ /**
12
+ * Returns the possible letters for a single digit.
13
+ * Returns an empty array for digits without letter mappings (0, 1).
14
+ */
15
+ export function phoneToLetters(digit: string): readonly string[] {
16
+ return PHONE_MAPPING[digit] ?? [];
17
+ }
18
+
19
+ /**
20
+ * Converts a string of letters to their corresponding phone digits.
21
+ * Non-letter characters are passed through unchanged.
22
+ */
23
+ export function lettersToPhone(text: string): string {
24
+ return text
25
+ .split('')
26
+ .map(ch => LETTER_TO_DIGIT[ch.toLowerCase()] ?? ch)
27
+ .join('');
28
+ }
29
+
30
+ /**
31
+ * Converts a string of phone digits (2-9) to ranked text candidates
32
+ * using beam search with n-gram scoring (unigram + bigram + trigram).
33
+ * Starts with unigram scoring for the first letter, bigram for the
34
+ * second, and trigrams for all subsequent letters.
35
+ *
36
+ * @param digits - String of digit characters (e.g., "43556")
37
+ * @param maxResults - Maximum number of results to return (default: 20, clamped to [1, 1000])
38
+ * @returns Array of PhoneResult sorted by score (highest first)
39
+ */
40
+ export function phoneToText(digits: string, maxResults = 20): PhoneResult[] {
41
+ const clampedMax = Math.max(1, Math.min(Math.trunc(maxResults) || 1, 1000));
42
+ const beamWidth = Math.max(100, clampedMax);
43
+ // Filter to valid digits with letter mappings
44
+ const validDigits = digits.split('').filter(d => PHONE_MAPPING[d]);
45
+
46
+ if (validDigits.length === 0) {
47
+ return [];
48
+ }
49
+
50
+ // Start with letters from the first digit, scored by unigram frequency
51
+ let candidates: PhoneResult[] = phoneToLetters(validDigits[0]).map(ch => ({
52
+ text: ch,
53
+ score: scoreNextLetter('', ch),
54
+ }));
55
+
56
+ // Expand one digit at a time with beam search
57
+ for (let i = 1; i < validDigits.length; i++) {
58
+ const letters = phoneToLetters(validDigits[i]);
59
+ const next: PhoneResult[] = [];
60
+
61
+ for (const candidate of candidates) {
62
+ for (const letter of letters) {
63
+ const text = candidate.text + letter;
64
+ const score = candidate.score + scoreNextLetter(candidate.text, letter);
65
+ next.push({text, score});
66
+ }
67
+ }
68
+
69
+ // Keep only top beamWidth candidates
70
+ next.sort((a, b) => b.score - a.score);
71
+ candidates = next.slice(0, beamWidth);
72
+ }
73
+
74
+ // Final sort and trim
75
+ candidates.sort((a, b) => b.score - a.score);
76
+ return candidates.slice(0, clampedMax);
77
+ }
@@ -0,0 +1,66 @@
1
+ import {PigpenSegment} from './segment.js';
2
+
3
+ export enum PigpenEncoding {
4
+ None = 0,
5
+
6
+ // Grid without dot (A-I)
7
+ LetterA = PigpenSegment.East | PigpenSegment.South,
8
+ LetterB = PigpenSegment.West | PigpenSegment.East | PigpenSegment.South,
9
+ LetterC = PigpenSegment.West | PigpenSegment.South,
10
+ LetterD = PigpenSegment.North | PigpenSegment.East | PigpenSegment.South,
11
+ LetterE = PigpenSegment.North |
12
+ PigpenSegment.East |
13
+ PigpenSegment.South |
14
+ PigpenSegment.West,
15
+ LetterF = PigpenSegment.North | PigpenSegment.West | PigpenSegment.South,
16
+ LetterG = PigpenSegment.North | PigpenSegment.East,
17
+ LetterH = PigpenSegment.North | PigpenSegment.West | PigpenSegment.East,
18
+ LetterI = PigpenSegment.North | PigpenSegment.West,
19
+
20
+ // Grid with dot (J-R)
21
+ LetterJ = PigpenSegment.East | PigpenSegment.South | PigpenSegment.Dot,
22
+ LetterK = PigpenSegment.West |
23
+ PigpenSegment.East |
24
+ PigpenSegment.South |
25
+ PigpenSegment.Dot,
26
+ LetterL = PigpenSegment.West | PigpenSegment.South | PigpenSegment.Dot,
27
+ LetterM = PigpenSegment.North |
28
+ PigpenSegment.East |
29
+ PigpenSegment.South |
30
+ PigpenSegment.Dot,
31
+ LetterN = PigpenSegment.North |
32
+ PigpenSegment.East |
33
+ PigpenSegment.South |
34
+ PigpenSegment.West |
35
+ PigpenSegment.Dot,
36
+ LetterO = PigpenSegment.North |
37
+ PigpenSegment.West |
38
+ PigpenSegment.South |
39
+ PigpenSegment.Dot,
40
+ LetterP = PigpenSegment.North | PigpenSegment.East | PigpenSegment.Dot,
41
+ LetterQ = PigpenSegment.North |
42
+ PigpenSegment.West |
43
+ PigpenSegment.East |
44
+ PigpenSegment.Dot,
45
+ LetterR = PigpenSegment.North | PigpenSegment.West | PigpenSegment.Dot,
46
+
47
+ // X without dot (S-V)
48
+ LetterS = PigpenSegment.NorthWest | PigpenSegment.NorthEast,
49
+ LetterT = PigpenSegment.NorthWest | PigpenSegment.SouthWest,
50
+ LetterU = PigpenSegment.NorthEast | PigpenSegment.SouthEast,
51
+ LetterV = PigpenSegment.SouthWest | PigpenSegment.SouthEast,
52
+
53
+ // X with dot (W-Z)
54
+ LetterW = PigpenSegment.NorthWest |
55
+ PigpenSegment.NorthEast |
56
+ PigpenSegment.Dot,
57
+ LetterX = PigpenSegment.NorthWest |
58
+ PigpenSegment.SouthWest |
59
+ PigpenSegment.Dot,
60
+ LetterY = PigpenSegment.NorthEast |
61
+ PigpenSegment.SouthEast |
62
+ PigpenSegment.Dot,
63
+ LetterZ = PigpenSegment.SouthWest |
64
+ PigpenSegment.SouthEast |
65
+ PigpenSegment.Dot,
66
+ }
@@ -0,0 +1,11 @@
1
+ export {
2
+ canTogglePigpenSegment,
3
+ decodePigpenStream,
4
+ hasPigpenSegment,
5
+ isCardinal,
6
+ isIntercardinal,
7
+ lookupPigpenEncoding,
8
+ togglePigpenSegment,
9
+ } from './pigpen.js';
10
+ export {PigpenEncoding} from './encoding.js';
11
+ export {PigpenSegment} from './segment.js';
@@ -0,0 +1,168 @@
1
+ import {EncodingCategory} from '../common/encoding-category.js';
2
+ import {EncodingEntry} from '../common/encoding-entry.js';
3
+ import {EncodingLookupResult} from '../common/encoding-lookup-result.js';
4
+ import {PigpenEncoding} from './encoding.js';
5
+ import {PigpenSegment} from './segment.js';
6
+
7
+ // Build the lookup table once
8
+ const PIGPEN_ENTRIES: Array<EncodingEntry<PigpenEncoding>> = [];
9
+
10
+ function addEntry(
11
+ encoding: PigpenEncoding,
12
+ category: EncodingCategory,
13
+ display: string,
14
+ ) {
15
+ PIGPEN_ENTRIES.push(new EncodingEntry(encoding, category, display));
16
+ }
17
+
18
+ // Letters
19
+ addEntry(PigpenEncoding.LetterA, EncodingCategory.Letter, 'A');
20
+ addEntry(PigpenEncoding.LetterB, EncodingCategory.Letter, 'B');
21
+ addEntry(PigpenEncoding.LetterC, EncodingCategory.Letter, 'C');
22
+ addEntry(PigpenEncoding.LetterD, EncodingCategory.Letter, 'D');
23
+ addEntry(PigpenEncoding.LetterE, EncodingCategory.Letter, 'E');
24
+ addEntry(PigpenEncoding.LetterF, EncodingCategory.Letter, 'F');
25
+ addEntry(PigpenEncoding.LetterG, EncodingCategory.Letter, 'G');
26
+ addEntry(PigpenEncoding.LetterH, EncodingCategory.Letter, 'H');
27
+ addEntry(PigpenEncoding.LetterI, EncodingCategory.Letter, 'I');
28
+ addEntry(PigpenEncoding.LetterJ, EncodingCategory.Letter, 'J');
29
+ addEntry(PigpenEncoding.LetterK, EncodingCategory.Letter, 'K');
30
+ addEntry(PigpenEncoding.LetterL, EncodingCategory.Letter, 'L');
31
+ addEntry(PigpenEncoding.LetterM, EncodingCategory.Letter, 'M');
32
+ addEntry(PigpenEncoding.LetterN, EncodingCategory.Letter, 'N');
33
+ addEntry(PigpenEncoding.LetterO, EncodingCategory.Letter, 'O');
34
+ addEntry(PigpenEncoding.LetterP, EncodingCategory.Letter, 'P');
35
+ addEntry(PigpenEncoding.LetterQ, EncodingCategory.Letter, 'Q');
36
+ addEntry(PigpenEncoding.LetterR, EncodingCategory.Letter, 'R');
37
+ addEntry(PigpenEncoding.LetterS, EncodingCategory.Letter, 'S');
38
+ addEntry(PigpenEncoding.LetterT, EncodingCategory.Letter, 'T');
39
+ addEntry(PigpenEncoding.LetterU, EncodingCategory.Letter, 'U');
40
+ addEntry(PigpenEncoding.LetterV, EncodingCategory.Letter, 'V');
41
+ addEntry(PigpenEncoding.LetterW, EncodingCategory.Letter, 'W');
42
+ addEntry(PigpenEncoding.LetterX, EncodingCategory.Letter, 'X');
43
+ addEntry(PigpenEncoding.LetterY, EncodingCategory.Letter, 'Y');
44
+ addEntry(PigpenEncoding.LetterZ, EncodingCategory.Letter, 'Z');
45
+
46
+ /** Mask covering all cardinal segments (grid shapes). */
47
+ const CARDINAL_MASK =
48
+ PigpenSegment.North |
49
+ PigpenSegment.East |
50
+ PigpenSegment.South |
51
+ PigpenSegment.West;
52
+
53
+ /** Mask covering all intercardinal segments (X shapes). */
54
+ const INTERCARDINAL_MASK =
55
+ PigpenSegment.NorthEast |
56
+ PigpenSegment.SouthEast |
57
+ PigpenSegment.SouthWest |
58
+ PigpenSegment.NorthWest;
59
+
60
+ /**
61
+ * Looks up a pigpen encoding in the data table.
62
+ */
63
+ export function lookupPigpenEncoding(
64
+ encoding: PigpenEncoding,
65
+ category: EncodingCategory = EncodingCategory.All,
66
+ ): EncodingLookupResult<PigpenEncoding> {
67
+ const result = new EncodingLookupResult<PigpenEncoding>();
68
+
69
+ for (const entry of PIGPEN_ENTRIES) {
70
+ if ((entry.category & category) !== 0) {
71
+ if (entry.encoding === encoding) {
72
+ result.exact.push(entry);
73
+ } else if ((entry.encoding & encoding) === encoding) {
74
+ result.partial.push(entry);
75
+ }
76
+ }
77
+ }
78
+
79
+ return result;
80
+ }
81
+
82
+ /**
83
+ * Toggles a segment flag in an encoding. Returns the encoding unchanged
84
+ * if toggling the segment on would mix cardinal and intercardinal segments.
85
+ * Toggling a segment off or toggling the dot is always allowed.
86
+ */
87
+ export function togglePigpenSegment(
88
+ encoding: PigpenEncoding,
89
+ segment: PigpenSegment,
90
+ ): PigpenEncoding {
91
+ if (!canTogglePigpenSegment(encoding, segment)) {
92
+ return encoding;
93
+ }
94
+ return (encoding ^ segment) as PigpenEncoding;
95
+ }
96
+
97
+ /**
98
+ * Checks if a segment flag is set in an encoding.
99
+ */
100
+ export function hasPigpenSegment(
101
+ encoding: PigpenEncoding,
102
+ segment: PigpenSegment,
103
+ ): boolean {
104
+ return (encoding & segment) === segment;
105
+ }
106
+
107
+ /**
108
+ * Returns true if the encoding uses cardinal (grid) segments.
109
+ */
110
+ export function isCardinal(encoding: PigpenEncoding): boolean {
111
+ return ((encoding as number) & CARDINAL_MASK) !== 0;
112
+ }
113
+
114
+ /**
115
+ * Returns true if the encoding uses intercardinal (X) segments.
116
+ */
117
+ export function isIntercardinal(encoding: PigpenEncoding): boolean {
118
+ return ((encoding as number) & INTERCARDINAL_MASK) !== 0;
119
+ }
120
+
121
+ /**
122
+ * Checks if a segment can be toggled without mixing cardinal and intercardinal
123
+ * segments. Toggling off and toggling the dot are always allowed.
124
+ */
125
+ export function canTogglePigpenSegment(
126
+ encoding: PigpenEncoding,
127
+ segment: PigpenSegment,
128
+ ): boolean {
129
+ // Toggling off is always allowed
130
+ if (hasPigpenSegment(encoding, segment)) {
131
+ return true;
132
+ }
133
+ // Dot is always compatible
134
+ if (segment === PigpenSegment.Dot) {
135
+ return true;
136
+ }
137
+ // Reject masks that mix cardinal and intercardinal bits
138
+ const segmentAsEncoding = segment as number as PigpenEncoding;
139
+ const segmentHasCardinal = isCardinal(segmentAsEncoding);
140
+ const segmentHasIntercardinal = isIntercardinal(segmentAsEncoding);
141
+ if (segmentHasCardinal && segmentHasIntercardinal) {
142
+ return false;
143
+ }
144
+ if (segmentHasCardinal) {
145
+ return !isIntercardinal(encoding);
146
+ }
147
+ return !isCardinal(encoding);
148
+ }
149
+
150
+ /**
151
+ * Decodes an array of pigpen encodings to a string.
152
+ */
153
+ export function decodePigpenStream(encodings: PigpenEncoding[]): string {
154
+ let result = '';
155
+
156
+ for (const ch of encodings) {
157
+ if (ch === PigpenEncoding.None) {
158
+ result += ' ';
159
+ } else {
160
+ const lookup = lookupPigpenEncoding(ch, EncodingCategory.Letter);
161
+ if (lookup.exact.length > 0) {
162
+ result += lookup.exact[0].toString();
163
+ }
164
+ }
165
+ }
166
+
167
+ return result;
168
+ }
@@ -0,0 +1,12 @@
1
+ export enum PigpenSegment {
2
+ None = 0,
3
+ North = 1 << 0,
4
+ NorthEast = 1 << 1,
5
+ East = 1 << 2,
6
+ SouthEast = 1 << 3,
7
+ South = 1 << 4,
8
+ SouthWest = 1 << 5,
9
+ West = 1 << 6,
10
+ NorthWest = 1 << 7,
11
+ Dot = 1 << 8,
12
+ }
@@ -0,0 +1,9 @@
1
+ export {
2
+ getResistorDisplayValue,
3
+ getResistorValue,
4
+ hasResistorTolerance,
5
+ hasResistorValue,
6
+ INVALID_RESISTOR,
7
+ RESISTOR_COLOR_TABLE,
8
+ } from './resistor.js';
9
+ export type {ResistorColor} from './resistor.js';
@@ -1,4 +1,4 @@
1
- import {SemaphoreDirection} from './SemaphoreDirection';
1
+ import {SemaphoreDirection} from './direction.js';
2
2
 
3
3
  export enum SemaphoreEncoding {
4
4
  None = 0,
@@ -0,0 +1,13 @@
1
+ export {
2
+ addSemaphoreDirection,
3
+ decodeSemaphoreStream,
4
+ degreesToSemaphoreDirection,
5
+ directionsToEncoding,
6
+ getEncodingDegrees,
7
+ hasSemaphoreDirection,
8
+ lookupSemaphoreEncoding,
9
+ removeSemaphoreDirection,
10
+ semaphoreDirectionToDegrees,
11
+ } from './semaphore.js';
12
+ export {SemaphoreDirection} from './direction.js';
13
+ export {SemaphoreEncoding} from './encoding.js';
@@ -1,8 +1,8 @@
1
- import {EncodingCategory} from '../Common/EncodingCategory';
2
- import {EncodingEntry} from '../Common/EncodingEntry';
3
- import {EncodingLookupResult} from '../Common/EncodingLookupResult';
4
- import {SemaphoreDirection} from './SemaphoreDirection';
5
- import {SemaphoreEncoding} from './SemaphoreEncoding';
1
+ import {EncodingCategory} from '../common/encoding-category.js';
2
+ import {EncodingEntry} from '../common/encoding-entry.js';
3
+ import {EncodingLookupResult} from '../common/encoding-lookup-result.js';
4
+ import {SemaphoreDirection} from './direction.js';
5
+ import {SemaphoreEncoding} from './encoding.js';
6
6
 
7
7
  // Build the lookup table once
8
8
  const SEMAPHORE_ENTRIES: Array<EncodingEntry<SemaphoreEncoding>> = [];
@@ -4,8 +4,6 @@
4
4
  // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5
5
  // TypeScript Version: 2.8
6
6
 
7
- // The published typings don't seem to work correctly with ES6 module syntax,
8
- // switch to CommonJS module syntax instead.
9
7
  declare module 'trie-prefix-tree' {
10
8
  function Trie(strings: string[]): {
11
9
  /**
@@ -66,5 +64,5 @@ declare module 'trie-prefix-tree' {
66
64
  getSubAnagrams(word: string): string[];
67
65
  };
68
66
 
69
- export = Trie;
67
+ export default Trie;
70
68
  }
@@ -0,0 +1,5 @@
1
+ export type {WordSearchPoint} from './point.js';
2
+ export {WordSearchResult} from './result.js';
3
+ export {WordSearchDirection} from './direction.js';
4
+ export {findWords, parseWordSearchGrid} from './word-search.js';
5
+ export type {WordSearchOptions} from './word-search.js';
@@ -0,0 +1,4 @@
1
+ export interface WordSearchPoint {
2
+ x: number;
3
+ y: number;
4
+ }
@@ -0,0 +1,10 @@
1
+ import {WordSearchPoint} from './point.js';
2
+
3
+ export class WordSearchResult {
4
+ word: string;
5
+ points: WordSearchPoint[];
6
+ constructor(word: string, wordPoints: WordSearchPoint[]) {
7
+ this.word = word;
8
+ this.points = Array.from(wordPoints);
9
+ }
10
+ }
@@ -1,8 +1,8 @@
1
- import trie = require('trie-prefix-tree');
1
+ import trie from 'trie-prefix-tree';
2
2
 
3
- import {Point} from './Point';
4
- import {Result} from './Result';
5
- import {WordSearchDirection} from './WordSearchDirection';
3
+ import {WordSearchPoint} from './point.js';
4
+ import {WordSearchResult} from './result.js';
5
+ import {WordSearchDirection} from './direction.js';
6
6
 
7
7
  export interface WordSearchOptions {
8
8
  grid: string[][];
@@ -35,7 +35,7 @@ export function parseWordSearchGrid(input: string): string[][] {
35
35
  return collapseSpaceColumns(grid);
36
36
  }
37
37
 
38
- export function findWords(options: WordSearchOptions): Result[] {
38
+ export function findWords(options: WordSearchOptions): WordSearchResult[] {
39
39
  const {
40
40
  words,
41
41
  directions: directionOption = WordSearchDirection.CardinalAndDiagonal,
@@ -61,12 +61,12 @@ export function findWords(options: WordSearchOptions): Result[] {
61
61
  const directionVectors = resolveDirections(directionOption);
62
62
 
63
63
  // Search
64
- const results: Result[] = [];
64
+ const results: WordSearchResult[] = [];
65
65
  const numRows = matrix.length;
66
66
  for (let yIdx = 0; yIdx < numRows; yIdx++) {
67
67
  const lineLength = matrix[yIdx].length;
68
68
  for (let xIdx = 0; xIdx < lineLength; xIdx++) {
69
- const p: Point = {x: xIdx, y: yIdx};
69
+ const p: WordSearchPoint = {x: xIdx, y: yIdx};
70
70
  const pointResults = search(
71
71
  p,
72
72
  matrix,
@@ -108,15 +108,15 @@ function resolveDirections(direction: WordSearchDirection): number[][] {
108
108
  }
109
109
 
110
110
  function search(
111
- start: Point,
111
+ start: WordSearchPoint,
112
112
  matrix: string[][],
113
113
  targets: ReturnType<typeof trie>,
114
114
  directions: number[][],
115
115
  canBend: boolean,
116
- ): Result[] {
117
- const results: Result[] = [];
116
+ ): WordSearchResult[] {
117
+ const results: WordSearchResult[] = [];
118
118
  if (canBend) {
119
- const history: Point[] = [];
119
+ const history: WordSearchPoint[] = [];
120
120
  const dfsResults = dfsCheck(
121
121
  start,
122
122
  new Set(),
@@ -136,14 +136,14 @@ function search(
136
136
  }
137
137
 
138
138
  function dfsCheck(
139
- start: Point,
140
- visited: Set<Point>,
141
- history: Point[],
139
+ start: WordSearchPoint,
140
+ visited: Set<WordSearchPoint>,
141
+ history: WordSearchPoint[],
142
142
  matrix: string[][],
143
143
  targets: ReturnType<typeof trie>,
144
144
  directions: number[][],
145
- ): Result[] {
146
- const results: Result[] = [];
145
+ ): WordSearchResult[] {
146
+ const results: WordSearchResult[] = [];
147
147
 
148
148
  if (visited.has(start)) {
149
149
  return results;
@@ -167,12 +167,12 @@ function dfsCheck(
167
167
  }
168
168
 
169
169
  if (wordsWithPrefix.indexOf(currentString) !== -1) {
170
- const foundWord = new Result(currentString, history);
170
+ const foundWord = new WordSearchResult(currentString, history);
171
171
  results.push(foundWord);
172
172
  }
173
173
 
174
174
  for (const translation of directions) {
175
- const next: Point = {
175
+ const next: WordSearchPoint = {
176
176
  x: start.x + translation[0],
177
177
  y: start.y + translation[1],
178
178
  };
@@ -191,16 +191,16 @@ function dfsCheck(
191
191
  }
192
192
 
193
193
  function lineCheck(
194
- start: Point,
194
+ start: WordSearchPoint,
195
195
  direction: number[],
196
196
  matrix: string[][],
197
197
  targets: ReturnType<typeof trie>,
198
- ): Result[] {
199
- const results: Result[] = [];
198
+ ): WordSearchResult[] {
199
+ const results: WordSearchResult[] = [];
200
200
 
201
201
  let currentPoint = start;
202
202
  let currentString = '';
203
- const pointHistory: Point[] = [];
203
+ const pointHistory: WordSearchPoint[] = [];
204
204
  while (isInBounds(currentPoint, matrix)) {
205
205
  currentString = currentString + matrix[currentPoint.y][currentPoint.x];
206
206
 
@@ -210,14 +210,14 @@ function lineCheck(
210
210
  break;
211
211
  }
212
212
 
213
- const p: Point = {x: currentPoint.x, y: currentPoint.y};
213
+ const p: WordSearchPoint = {x: currentPoint.x, y: currentPoint.y};
214
214
  pointHistory.push(p);
215
215
 
216
216
  if (wordsWithPrefix.indexOf(currentString) !== -1) {
217
- const foundWord = new Result(currentString, pointHistory);
217
+ const foundWord = new WordSearchResult(currentString, pointHistory);
218
218
  results.push(foundWord);
219
219
  }
220
- const next: Point = {
220
+ const next: WordSearchPoint = {
221
221
  x: currentPoint.x + direction[0],
222
222
  y: currentPoint.y + direction[1],
223
223
  };
@@ -227,7 +227,7 @@ function lineCheck(
227
227
  return results;
228
228
  }
229
229
 
230
- function isInBounds(point: Point, matrix: string[][]): boolean {
230
+ function isInBounds(point: WordSearchPoint, matrix: string[][]): boolean {
231
231
  if (point.y < 0 || point.y >= matrix.length) {
232
232
  return false;
233
233
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"BrailleDot.js","sourceRoot":"","sources":["../../../src/Braille/BrailleDot.ts"],"names":[],"mappings":";;;AAAA,IAAY,UAQX;AARD,WAAY,UAAU;IACpB,2CAAQ,CAAA;IACR,qDAAkB,CAAA;IAClB,uDAAmB,CAAA;IACnB,qDAAkB,CAAA;IAClB,uDAAmB,CAAA;IACnB,0DAAoB,CAAA;IACpB,wDAAmB,CAAA;AACrB,CAAC,EARW,UAAU,0BAAV,UAAU,QAQrB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"BrailleEncoding.js","sourceRoot":"","sources":["../../../src/Braille/BrailleEncoding.ts"],"names":[],"mappings":";;;AAAA,6CAAwC;AAExC,IAAY,eA6IX;AA7ID,WAAY,eAAe;IACzB,qDAAI,CAAA;IAEJ,yBAAyB;IACzB,2DAA8B,CAAA;IAC9B,2DAAsD,CAAA;IACtD,2DAAsD,CAAA;IACtD,4DAEwB,CAAA;IACxB,4DAAuD,CAAA;IACvD,4DAEuB,CAAA;IACvB,4DAGwB,CAAA;IACxB,4DAEwB,CAAA;IACxB,4DAAuD,CAAA;IACvD,4DAEwB,CAAA;IAExB,0BAA0B;IAC1B,2DAAqD,CAAA;IACrD,2DAA6E,CAAA;IAC7E,4DAA6E,CAAA;IAC7E,4DAGwB,CAAA;IACxB,4DAEwB,CAAA;IACxB,4DAGuB,CAAA;IACvB,4DAIwB,CAAA;IACxB,4DAGwB,CAAA;IACxB,4DAEuB,CAAA;IACvB,4DAGwB,CAAA;IAExB,yBAAyB;IACzB,4DAA6E,CAAA;IAC7E,4DAGuB,CAAA;IACvB,4DAGuB,CAAA;IACvB,4DAIwB,CAAA;IACxB,4DAGwB,CAAA;IAExB,0BAA0B;IAC1B,4DAGwB,CAAA;IAExB,UAAU;IACV,2DAA8B,CAAA;IAC9B,2DAAsD,CAAA;IACtD,2DAAsD,CAAA;IACtD,4DAEwB,CAAA;IACxB,4DAAuD,CAAA;IACvD,4DAEuB,CAAA;IACvB,4DAGwB,CAAA;IACxB,4DAEwB,CAAA;IACxB,4DAAuD,CAAA;IACvD,4DAEwB,CAAA;IAExB,aAAa;IACb,8EAGuB,CAAA;IACvB,gFAAyC,CAAA;IAEzC,cAAc;IACd,6EAAwC,CAAA;IACxC,qFAAmE,CAAA;IACnE,uFAA4C,CAAA;IAC5C,8EAAiE,CAAA;IACjE,gFAAgE,CAAA;IAChE,4FAAuE,CAAA;IACvE,oFAEuB,CAAA;IACvB,oGAEwB,CAAA;IACxB,sFAEuB,CAAA;IACvB,4FAEuB,CAAA;IACvB,wFAEuB,CAAA;IACvB,kFAGuB,CAAA;IACvB,8EAA+D,CAAA;AACjE,CAAC,EA7IW,eAAe,+BAAf,eAAe,QA6I1B"}