@logic-pad/core 0.26.1 → 0.26.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 (241) hide show
  1. package/README.md +31 -31
  2. package/assets/logic-core.global.d.ts +3264 -3262
  3. package/package.json +4 -1
  4. package/dist/benchmark/helper.d.ts +0 -21
  5. package/dist/benchmark/helper.js +0 -34
  6. package/dist/benchmark/prepareBench.d.ts +0 -1
  7. package/dist/benchmark/prepareBench.js +0 -140
  8. package/dist/benchmark/runBench.d.ts +0 -1
  9. package/dist/benchmark/runBench.js +0 -206
  10. package/dist/src/data/config.d.ts +0 -119
  11. package/dist/src/data/config.js +0 -72
  12. package/dist/src/data/configurable.d.ts +0 -14
  13. package/dist/src/data/configurable.js +0 -26
  14. package/dist/src/data/dataHelper.d.ts +0 -92
  15. package/dist/src/data/dataHelper.js +0 -217
  16. package/dist/src/data/events/eventHelper.d.ts +0 -1
  17. package/dist/src/data/events/eventHelper.js +0 -6
  18. package/dist/src/data/events/onFinalValidation.d.ts +0 -14
  19. package/dist/src/data/events/onFinalValidation.js +0 -4
  20. package/dist/src/data/events/onGetTile.d.ts +0 -7
  21. package/dist/src/data/events/onGetTile.js +0 -4
  22. package/dist/src/data/events/onGridChange.d.ts +0 -6
  23. package/dist/src/data/events/onGridChange.js +0 -4
  24. package/dist/src/data/events/onGridResize.d.ts +0 -9
  25. package/dist/src/data/events/onGridResize.js +0 -4
  26. package/dist/src/data/events/onSetGrid.d.ts +0 -7
  27. package/dist/src/data/events/onSetGrid.js +0 -19
  28. package/dist/src/data/events/onSymbolDisplay.d.ts +0 -16
  29. package/dist/src/data/events/onSymbolDisplay.js +0 -4
  30. package/dist/src/data/events/onSymbolMerge.d.ts +0 -10
  31. package/dist/src/data/events/onSymbolMerge.js +0 -4
  32. package/dist/src/data/events/onSymbolValidation.d.ts +0 -18
  33. package/dist/src/data/events/onSymbolValidation.js +0 -4
  34. package/dist/src/data/grid.d.ts +0 -410
  35. package/dist/src/data/grid.js +0 -1106
  36. package/dist/src/data/gridConnections.d.ts +0 -25
  37. package/dist/src/data/gridConnections.js +0 -309
  38. package/dist/src/data/gridZones.d.ts +0 -26
  39. package/dist/src/data/gridZones.js +0 -117
  40. package/dist/src/data/instruction.d.ts +0 -26
  41. package/dist/src/data/instruction.js +0 -29
  42. package/dist/src/data/primitives.d.ts +0 -138
  43. package/dist/src/data/primitives.js +0 -177
  44. package/dist/src/data/puzzle.d.ts +0 -73
  45. package/dist/src/data/puzzle.js +0 -105
  46. package/dist/src/data/rules/banPatternRule.d.ts +0 -30
  47. package/dist/src/data/rules/banPatternRule.js +0 -125
  48. package/dist/src/data/rules/cellCountPerZoneRule.d.ts +0 -23
  49. package/dist/src/data/rules/cellCountPerZoneRule.js +0 -39
  50. package/dist/src/data/rules/cellCountRule.d.ts +0 -33
  51. package/dist/src/data/rules/cellCountRule.js +0 -138
  52. package/dist/src/data/rules/completePatternRule.d.ts +0 -24
  53. package/dist/src/data/rules/completePatternRule.js +0 -46
  54. package/dist/src/data/rules/connectAllRule.d.ts +0 -29
  55. package/dist/src/data/rules/connectAllRule.js +0 -88
  56. package/dist/src/data/rules/connectZonesRule.d.ts +0 -29
  57. package/dist/src/data/rules/connectZonesRule.js +0 -111
  58. package/dist/src/data/rules/containsShapeRule.d.ts +0 -34
  59. package/dist/src/data/rules/containsShapeRule.js +0 -125
  60. package/dist/src/data/rules/customRule.d.ts +0 -34
  61. package/dist/src/data/rules/customRule.js +0 -74
  62. package/dist/src/data/rules/differentCountPerZoneRule.d.ts +0 -30
  63. package/dist/src/data/rules/differentCountPerZoneRule.js +0 -96
  64. package/dist/src/data/rules/exactCountPerZoneRule.d.ts +0 -33
  65. package/dist/src/data/rules/exactCountPerZoneRule.js +0 -99
  66. package/dist/src/data/rules/foresightRule.d.ts +0 -36
  67. package/dist/src/data/rules/foresightRule.js +0 -107
  68. package/dist/src/data/rules/index.d.ts +0 -3
  69. package/dist/src/data/rules/index.js +0 -10
  70. package/dist/src/data/rules/lyingSymbolRule.d.ts +0 -31
  71. package/dist/src/data/rules/lyingSymbolRule.js +0 -207
  72. package/dist/src/data/rules/musicControlLine.d.ts +0 -82
  73. package/dist/src/data/rules/musicControlLine.js +0 -167
  74. package/dist/src/data/rules/musicGridRule.d.ts +0 -51
  75. package/dist/src/data/rules/musicGridRule.js +0 -212
  76. package/dist/src/data/rules/mysteryRule.d.ts +0 -39
  77. package/dist/src/data/rules/mysteryRule.js +0 -146
  78. package/dist/src/data/rules/noLoopsRule.d.ts +0 -29
  79. package/dist/src/data/rules/noLoopsRule.js +0 -218
  80. package/dist/src/data/rules/offByXRule.d.ts +0 -32
  81. package/dist/src/data/rules/offByXRule.js +0 -124
  82. package/dist/src/data/rules/perfectionRule.d.ts +0 -45
  83. package/dist/src/data/rules/perfectionRule.js +0 -158
  84. package/dist/src/data/rules/regionAreaRule.d.ts +0 -34
  85. package/dist/src/data/rules/regionAreaRule.js +0 -149
  86. package/dist/src/data/rules/regionShapeRule.d.ts +0 -22
  87. package/dist/src/data/rules/regionShapeRule.js +0 -58
  88. package/dist/src/data/rules/rule.d.ts +0 -18
  89. package/dist/src/data/rules/rule.js +0 -19
  90. package/dist/src/data/rules/rules.gen.d.ts +0 -23
  91. package/dist/src/data/rules/rules.gen.js +0 -27
  92. package/dist/src/data/rules/sameCountPerZoneRule.d.ts +0 -30
  93. package/dist/src/data/rules/sameCountPerZoneRule.js +0 -95
  94. package/dist/src/data/rules/sameShapeRule.d.ts +0 -28
  95. package/dist/src/data/rules/sameShapeRule.js +0 -68
  96. package/dist/src/data/rules/symbolsPerRegionRule.d.ts +0 -38
  97. package/dist/src/data/rules/symbolsPerRegionRule.js +0 -181
  98. package/dist/src/data/rules/undercluedRule.d.ts +0 -24
  99. package/dist/src/data/rules/undercluedRule.js +0 -53
  100. package/dist/src/data/rules/uniqueShapeRule.d.ts +0 -28
  101. package/dist/src/data/rules/uniqueShapeRule.js +0 -65
  102. package/dist/src/data/rules/wrapAroundRule.d.ts +0 -36
  103. package/dist/src/data/rules/wrapAroundRule.js +0 -241
  104. package/dist/src/data/serializer/allSerializers.d.ts +0 -32
  105. package/dist/src/data/serializer/allSerializers.js +0 -71
  106. package/dist/src/data/serializer/compressor/allCompressors.d.ts +0 -14
  107. package/dist/src/data/serializer/compressor/allCompressors.js +0 -43
  108. package/dist/src/data/serializer/compressor/checksumCompressor.d.ts +0 -6
  109. package/dist/src/data/serializer/compressor/checksumCompressor.js +0 -21
  110. package/dist/src/data/serializer/compressor/compressorBase.d.ts +0 -16
  111. package/dist/src/data/serializer/compressor/compressorBase.js +0 -2
  112. package/dist/src/data/serializer/compressor/deflateCompressor.d.ts +0 -7
  113. package/dist/src/data/serializer/compressor/deflateCompressor.js +0 -17
  114. package/dist/src/data/serializer/compressor/gzipCompressor.d.ts +0 -5
  115. package/dist/src/data/serializer/compressor/gzipCompressor.js +0 -9
  116. package/dist/src/data/serializer/compressor/streamCompressor.d.ts +0 -6
  117. package/dist/src/data/serializer/compressor/streamCompressor.js +0 -41
  118. package/dist/src/data/serializer/serializerBase.d.ts +0 -32
  119. package/dist/src/data/serializer/serializerBase.js +0 -2
  120. package/dist/src/data/serializer/serializer_checksum.d.ts +0 -35
  121. package/dist/src/data/serializer/serializer_checksum.js +0 -179
  122. package/dist/src/data/serializer/serializer_v0.d.ts +0 -55
  123. package/dist/src/data/serializer/serializer_v0.js +0 -484
  124. package/dist/src/data/shapes.d.ts +0 -19
  125. package/dist/src/data/shapes.js +0 -137
  126. package/dist/src/data/solver/allSolvers.d.ts +0 -3
  127. package/dist/src/data/solver/allSolvers.js +0 -13
  128. package/dist/src/data/solver/auto/autoSolver.d.ts +0 -18
  129. package/dist/src/data/solver/auto/autoSolver.js +0 -156
  130. package/dist/src/data/solver/backtrack/backtrackSolver.d.ts +0 -11
  131. package/dist/src/data/solver/backtrack/backtrackSolver.js +0 -54
  132. package/dist/src/data/solver/backtrack/backtrackWorker.d.ts +0 -1
  133. package/dist/src/data/solver/backtrack/backtrackWorker.js +0 -312
  134. package/dist/src/data/solver/backtrack/data.d.ts +0 -47
  135. package/dist/src/data/solver/backtrack/data.js +0 -151
  136. package/dist/src/data/solver/backtrack/rules/banPattern.d.ts +0 -9
  137. package/dist/src/data/solver/backtrack/rules/banPattern.js +0 -77
  138. package/dist/src/data/solver/backtrack/rules/cellCount.d.ts +0 -7
  139. package/dist/src/data/solver/backtrack/rules/cellCount.js +0 -25
  140. package/dist/src/data/solver/backtrack/rules/connectAll.d.ts +0 -7
  141. package/dist/src/data/solver/backtrack/rules/connectAll.js +0 -44
  142. package/dist/src/data/solver/backtrack/rules/regionArea.d.ts +0 -8
  143. package/dist/src/data/solver/backtrack/rules/regionArea.js +0 -71
  144. package/dist/src/data/solver/backtrack/rules/regionShape.d.ts +0 -8
  145. package/dist/src/data/solver/backtrack/rules/regionShape.js +0 -57
  146. package/dist/src/data/solver/backtrack/rules/sameShape.d.ts +0 -8
  147. package/dist/src/data/solver/backtrack/rules/sameShape.js +0 -14
  148. package/dist/src/data/solver/backtrack/rules/symbolsPerRegion.d.ts +0 -10
  149. package/dist/src/data/solver/backtrack/rules/symbolsPerRegion.js +0 -82
  150. package/dist/src/data/solver/backtrack/rules/uniqueShape.d.ts +0 -8
  151. package/dist/src/data/solver/backtrack/rules/uniqueShape.js +0 -14
  152. package/dist/src/data/solver/backtrack/symbols/areaNumber.d.ts +0 -9
  153. package/dist/src/data/solver/backtrack/symbols/areaNumber.js +0 -75
  154. package/dist/src/data/solver/backtrack/symbols/dart.d.ts +0 -8
  155. package/dist/src/data/solver/backtrack/symbols/dart.js +0 -45
  156. package/dist/src/data/solver/backtrack/symbols/directionLinker.d.ts +0 -11
  157. package/dist/src/data/solver/backtrack/symbols/directionLinker.js +0 -121
  158. package/dist/src/data/solver/backtrack/symbols/focus.d.ts +0 -9
  159. package/dist/src/data/solver/backtrack/symbols/focus.js +0 -48
  160. package/dist/src/data/solver/backtrack/symbols/galaxy.d.ts +0 -9
  161. package/dist/src/data/solver/backtrack/symbols/galaxy.js +0 -14
  162. package/dist/src/data/solver/backtrack/symbols/letter.d.ts +0 -9
  163. package/dist/src/data/solver/backtrack/symbols/letter.js +0 -95
  164. package/dist/src/data/solver/backtrack/symbols/lotus.d.ts +0 -11
  165. package/dist/src/data/solver/backtrack/symbols/lotus.js +0 -55
  166. package/dist/src/data/solver/backtrack/symbols/minesweeper.d.ts +0 -9
  167. package/dist/src/data/solver/backtrack/symbols/minesweeper.js +0 -44
  168. package/dist/src/data/solver/backtrack/symbols/myopia.d.ts +0 -7
  169. package/dist/src/data/solver/backtrack/symbols/myopia.js +0 -73
  170. package/dist/src/data/solver/backtrack/symbols/viewpoint.d.ts +0 -7
  171. package/dist/src/data/solver/backtrack/symbols/viewpoint.js +0 -51
  172. package/dist/src/data/solver/cspuz/cspuzSolver.d.ts +0 -13
  173. package/dist/src/data/solver/cspuz/cspuzSolver.js +0 -124
  174. package/dist/src/data/solver/cspuz/cspuzWorker.d.ts +0 -1
  175. package/dist/src/data/solver/cspuz/cspuzWorker.js +0 -82
  176. package/dist/src/data/solver/cspuz/jsonify.d.ts +0 -3
  177. package/dist/src/data/solver/cspuz/jsonify.js +0 -215
  178. package/dist/src/data/solver/eventIteratingSolver.d.ts +0 -8
  179. package/dist/src/data/solver/eventIteratingSolver.js +0 -54
  180. package/dist/src/data/solver/solver.d.ts +0 -77
  181. package/dist/src/data/solver/solver.js +0 -59
  182. package/dist/src/data/solver/universal/universalSolver.d.ts +0 -7
  183. package/dist/src/data/solver/universal/universalSolver.js +0 -13
  184. package/dist/src/data/solver/universal/universalWorker.d.ts +0 -1
  185. package/dist/src/data/solver/universal/universalWorker.js +0 -128
  186. package/dist/src/data/symbols/areaNumberSymbol.d.ts +0 -31
  187. package/dist/src/data/symbols/areaNumberSymbol.js +0 -80
  188. package/dist/src/data/symbols/customIconSymbol.d.ts +0 -35
  189. package/dist/src/data/symbols/customIconSymbol.js +0 -94
  190. package/dist/src/data/symbols/customSymbol.d.ts +0 -25
  191. package/dist/src/data/symbols/customSymbol.js +0 -45
  192. package/dist/src/data/symbols/customTextSymbol.d.ts +0 -35
  193. package/dist/src/data/symbols/customTextSymbol.js +0 -95
  194. package/dist/src/data/symbols/dartSymbol.d.ts +0 -36
  195. package/dist/src/data/symbols/dartSymbol.js +0 -96
  196. package/dist/src/data/symbols/directionLinkerSymbol.d.ts +0 -29
  197. package/dist/src/data/symbols/directionLinkerSymbol.js +0 -232
  198. package/dist/src/data/symbols/everyLetterSymbol.d.ts +0 -32
  199. package/dist/src/data/symbols/everyLetterSymbol.js +0 -119
  200. package/dist/src/data/symbols/focusSymbol.d.ts +0 -40
  201. package/dist/src/data/symbols/focusSymbol.js +0 -159
  202. package/dist/src/data/symbols/galaxySymbol.d.ts +0 -27
  203. package/dist/src/data/symbols/galaxySymbol.js +0 -61
  204. package/dist/src/data/symbols/hiddenSymbol.d.ts +0 -38
  205. package/dist/src/data/symbols/hiddenSymbol.js +0 -113
  206. package/dist/src/data/symbols/houseSymbol.d.ts +0 -33
  207. package/dist/src/data/symbols/houseSymbol.js +0 -104
  208. package/dist/src/data/symbols/index.d.ts +0 -3
  209. package/dist/src/data/symbols/index.js +0 -10
  210. package/dist/src/data/symbols/letterSymbol.d.ts +0 -32
  211. package/dist/src/data/symbols/letterSymbol.js +0 -118
  212. package/dist/src/data/symbols/lotusSymbol.d.ts +0 -30
  213. package/dist/src/data/symbols/lotusSymbol.js +0 -132
  214. package/dist/src/data/symbols/minesweeperSymbol.d.ts +0 -33
  215. package/dist/src/data/symbols/minesweeperSymbol.js +0 -106
  216. package/dist/src/data/symbols/myopiaSymbol.d.ts +0 -37
  217. package/dist/src/data/symbols/myopiaSymbol.js +0 -182
  218. package/dist/src/data/symbols/numberSymbol.d.ts +0 -19
  219. package/dist/src/data/symbols/numberSymbol.js +0 -32
  220. package/dist/src/data/symbols/symbol.d.ts +0 -29
  221. package/dist/src/data/symbols/symbol.js +0 -87
  222. package/dist/src/data/symbols/symbols.gen.d.ts +0 -15
  223. package/dist/src/data/symbols/symbols.gen.js +0 -19
  224. package/dist/src/data/symbols/unsupportedSymbol.d.ts +0 -23
  225. package/dist/src/data/symbols/unsupportedSymbol.js +0 -47
  226. package/dist/src/data/symbols/viewpointSymbol.d.ts +0 -32
  227. package/dist/src/data/symbols/viewpointSymbol.js +0 -95
  228. package/dist/src/data/tile.d.ts +0 -26
  229. package/dist/src/data/tile.js +0 -56
  230. package/dist/src/data/tileConnections.d.ts +0 -25
  231. package/dist/src/data/tileConnections.js +0 -74
  232. package/dist/src/data/validate.d.ts +0 -5
  233. package/dist/src/data/validate.js +0 -131
  234. package/dist/src/data/validateAsync.d.ts +0 -15
  235. package/dist/src/data/validateAsync.js +0 -71
  236. package/dist/src/data/validateAsyncWorker.d.ts +0 -1
  237. package/dist/src/data/validateAsyncWorker.js +0 -9
  238. package/dist/src/index.d.ts +0 -109
  239. package/dist/src/index.js +0 -112
  240. package/dist/src/polyfill/streamPolyfill.d.ts +0 -2
  241. package/dist/src/polyfill/streamPolyfill.js +0 -1
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@logic-pad/core",
3
- "version": "0.26.1",
3
+ "version": "0.26.2",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
7
7
  "assets"
8
8
  ],
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
9
12
  "homepage": "https://github.com/logic-pad/logic-pad",
10
13
  "repository": {
11
14
  "type": "git",
@@ -1,21 +0,0 @@
1
- import { Puzzle } from '../src/data/puzzle.js';
2
- import CompressorBase from '../src/data/serializer/compressor/compressorBase.js';
3
- declare class BunCompressor extends CompressorBase {
4
- get id(): string;
5
- compress(input: string): Promise<string>;
6
- decompress(input: string): Promise<string>;
7
- }
8
- export declare const bunCompressor: BunCompressor;
9
- export interface PuzzleEntry {
10
- pid: number;
11
- difficulty: number;
12
- puzzleLink: string;
13
- }
14
- export interface BenchmarkEntry {
15
- pid: number;
16
- supported: boolean;
17
- solveTime: number;
18
- solveCorrect: boolean;
19
- }
20
- export declare function parseLink(link: string): Promise<Puzzle>;
21
- export {};
@@ -1,34 +0,0 @@
1
- import { Serializer } from '../src/data/serializer/allSerializers.js';
2
- import { encode, decode } from 'uint8-to-base64';
3
- import CompressorBase from '../src/data/serializer/compressor/compressorBase.js';
4
- const decoder = new TextDecoder();
5
- const encoder = new TextEncoder();
6
- class BunCompressor extends CompressorBase {
7
- get id() {
8
- return 'dfl';
9
- }
10
- compress(input) {
11
- const data = Bun.deflateSync(encoder.encode(input), {
12
- library: 'libdeflate',
13
- level: 12,
14
- });
15
- return Promise.resolve(`${this.id}_${encode(data).replace(/\+/g, '-').replace(/\//g, '_')}`);
16
- }
17
- decompress(input) {
18
- const data = decode(input.replace(`${this.id}_`, '').replace(/-/g, '+').replace(/_/g, '/'));
19
- const result = Bun.inflateSync(data, {
20
- library: 'libdeflate',
21
- level: 12,
22
- });
23
- return Promise.resolve(decoder.decode(result));
24
- }
25
- }
26
- export const bunCompressor = new BunCompressor();
27
- export async function parseLink(link) {
28
- const url = new URL(link);
29
- const data = url.searchParams.get('d');
30
- if (data === null) {
31
- throw new Error('Missing data parameter');
32
- }
33
- return Serializer.parsePuzzle(await bunCompressor.decompress(data));
34
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,140 +0,0 @@
1
- import { parseArgs } from 'util';
2
- import { allSolvers } from '../src/data/solver/allSolvers.js';
3
- import { parseLink } from './helper.js';
4
- import PQueue from 'p-queue';
5
- const allPuzzlesPath = 'benchmark/data/all_puzzles_logic_pad.json';
6
- const { values, positionals } = parseArgs({
7
- args: Bun.argv,
8
- options: {
9
- maxTime: {
10
- type: 'string',
11
- default: '10',
12
- short: 't',
13
- },
14
- maxCount: {
15
- type: 'string',
16
- default: '99999',
17
- short: 'c',
18
- },
19
- concurrency: {
20
- type: 'string',
21
- default: '4',
22
- short: 'n',
23
- },
24
- help: {
25
- type: 'boolean',
26
- short: 'h',
27
- },
28
- },
29
- strict: true,
30
- allowPositionals: true,
31
- });
32
- positionals.splice(0, 2); // Remove "bun" and script name
33
- if (values.help || positionals.length !== 1) {
34
- console.log(`
35
- Usage: bun bench:prepare <solver> [options]
36
-
37
- Options:
38
- -t, --maxTime <number> Maximum seconds allowed for each solve (default: 10)
39
- -c, --maxCount <number> Maximum number of puzzles included (default: 100)
40
- -n, --concurrency <number> Number of solves to run concurrently (default: 4)
41
- -h, --help Show this help message
42
-
43
- Solver:
44
- Name of the solver to benchmark. Available solvers are:
45
- ${[...allSolvers.keys()].map(s => ` - ${s}`).join('\n')}
46
- `);
47
- process.exit(0);
48
- }
49
- const maxTime = parseFloat(values.maxTime) * 1000;
50
- const maxCount = parseInt(values.maxCount);
51
- const solverName = positionals[0];
52
- const solver = allSolvers.get(solverName);
53
- if (!solver) {
54
- console.error(`Error: Solver "${solverName}" not found.`);
55
- process.exit(1);
56
- }
57
- const allPuzzles = (await Bun.file(allPuzzlesPath).json());
58
- allPuzzles.sort(() => Math.random() - 0.5);
59
- const results = [];
60
- const pqueue = new PQueue({ concurrency: 4 });
61
- function printEntry(benchmarkEntry, entryId, solverId, pid) {
62
- if (benchmarkEntry.supported) {
63
- console.log(`${solverId}\t| ${entryId} / ${allPuzzles.length}\t| ${pid}\t| ${Number.isNaN(benchmarkEntry.solveTime)
64
- ? 'timeout'
65
- : `${benchmarkEntry.solveTime.toFixed(0)}ms`} ${benchmarkEntry.solveCorrect ? '✓' : '✗'}`);
66
- }
67
- else {
68
- console.log(`${solverId}\t| ${entryId} / ${allPuzzles.length}\t| ${pid}\t| unsupported`);
69
- }
70
- }
71
- console.log('Available\t| Selected\t| PID\t| Result');
72
- for (const entry of allPuzzles) {
73
- if (results.filter(r => r.result.solveCorrect && r.result.supported).length >=
74
- maxCount) {
75
- break;
76
- }
77
- const puzzle = await parseLink(entry.puzzleLink);
78
- void pqueue.add(async () => {
79
- if (!solver.isGridSupported(puzzle.grid)) {
80
- results.push({
81
- puzzle: entry,
82
- result: {
83
- pid: entry.pid,
84
- supported: false,
85
- solveTime: Number.NaN,
86
- solveCorrect: false,
87
- },
88
- });
89
- printEntry(results[results.length - 1].result, results.length, solverName, entry.pid);
90
- return;
91
- }
92
- const startTime = performance.now();
93
- const abortController = new AbortController();
94
- const benchmarkEntry = {
95
- pid: entry.pid,
96
- supported: true,
97
- solveTime: Number.NaN,
98
- solveCorrect: false,
99
- };
100
- let step = 0;
101
- const handle = setTimeout(() => {
102
- abortController.abort();
103
- }, maxTime);
104
- try {
105
- for await (const solution of solver.solve(puzzle.grid, abortController.signal)) {
106
- if (step === 0) {
107
- const solveCorrect = solution?.colorEquals(puzzle.solution) ?? false;
108
- if (!solveCorrect)
109
- break;
110
- }
111
- else {
112
- benchmarkEntry.solveCorrect = solution === null;
113
- if (benchmarkEntry.solveCorrect)
114
- benchmarkEntry.solveTime = performance.now() - startTime;
115
- break;
116
- }
117
- step++;
118
- }
119
- }
120
- catch {
121
- benchmarkEntry.solveCorrect = false;
122
- }
123
- clearTimeout(handle);
124
- results.push({ puzzle: entry, result: benchmarkEntry });
125
- printEntry(results[results.length - 1].result, results.length, solverName, entry.pid);
126
- });
127
- }
128
- await pqueue.onIdle();
129
- const selectedPuzzles = results.filter(r => r.result.solveCorrect && r.result.supported);
130
- const benchmarkEntries = selectedPuzzles.map(r => r.result);
131
- await Bun.write(`benchmark/data/bench_${solverName}_puzzles.json`, JSON.stringify(selectedPuzzles.map(r => r.puzzle), null, 2));
132
- await Bun.write(`benchmark/data/bench_${solverName}_results.json`, JSON.stringify(benchmarkEntries, null, 2));
133
- console.log(`
134
- Benchmark preparation completed. Selected ${selectedPuzzles.length} puzzles.
135
-
136
- - Solver: ${solverName} Max Time: ${maxTime}ms Max Count: ${maxCount}
137
- - Average time: ${benchmarkEntries.filter(e => !Number.isNaN(e.solveTime)).reduce((a, b) => a + b.solveTime, 0) / benchmarkEntries.filter(e => !Number.isNaN(e.solveTime)).length}ms
138
- - Number of timeouts: ${benchmarkEntries.filter(e => Number.isNaN(e.solveTime)).length}
139
- - Solve correctness: ${benchmarkEntries.filter(e => e.solveCorrect).length} / ${benchmarkEntries.length}
140
- `);
@@ -1 +0,0 @@
1
- export {};
@@ -1,206 +0,0 @@
1
- import { parseArgs } from 'util';
2
- import { allSolvers } from '../src/data/solver/allSolvers.js';
3
- import { parseLink } from './helper.js';
4
- import PQueue from 'p-queue';
5
- const { values, positionals } = parseArgs({
6
- args: Bun.argv,
7
- options: {
8
- maxTime: {
9
- type: 'string',
10
- default: '10',
11
- short: 't',
12
- },
13
- maxCount: {
14
- type: 'string',
15
- default: '99999',
16
- short: 'c',
17
- },
18
- concurrency: {
19
- type: 'string',
20
- default: '4',
21
- short: 'n',
22
- },
23
- help: {
24
- type: 'boolean',
25
- short: 'h',
26
- },
27
- },
28
- strict: true,
29
- allowPositionals: true,
30
- });
31
- positionals.splice(0, 2); // Remove "bun" and script name
32
- if (values.help || positionals.length === 0) {
33
- console.log(`
34
- Usage: bun bench:run <solver> [options]
35
-
36
- Options:
37
- -t, --maxTime <number> Maximum seconds allowed for each solve (default: 10)
38
- -c, --maxCount <number> Maximum number of puzzles included (default: 100)
39
- -n, --concurrency <number> Number of solves to run concurrently (default: 4)
40
- -h, --help Show this help message
41
-
42
- Solvers available for benchmarking:
43
- ${[...allSolvers.keys()].map(s => ` - ${s}`).join('\n')}
44
- `);
45
- process.exit(0);
46
- }
47
- const maxTime = parseFloat(values.maxTime) * 1000;
48
- const maxCount = parseInt(values.maxCount);
49
- const concurrency = parseInt(values.concurrency);
50
- for (const name of positionals) {
51
- if (!allSolvers.has(name)) {
52
- console.error(`Error: Solver "${name}" not found.`);
53
- process.exit(1);
54
- }
55
- }
56
- const allPuzzles = (await Bun.file(`benchmark/data/bench_${positionals[0]}_puzzles.json`).json());
57
- allPuzzles.sort(() => Math.random() - 0.5);
58
- allPuzzles.splice(maxCount);
59
- const benchmarkEntries = Object.fromEntries(positionals.map(name => [
60
- name,
61
- allPuzzles.map(p => ({
62
- pid: p.pid,
63
- supported: false,
64
- solveTime: Number.NaN,
65
- solveCorrect: false,
66
- })),
67
- ]));
68
- const pqueue = new PQueue({ concurrency });
69
- function printEntry(benchmarkEntry, entryId, solverId, pid) {
70
- if (benchmarkEntry.supported) {
71
- console.log(`${solverId}\t| ${entryId} / ${allPuzzles.length}\t| ${pid}\t| ${Number.isNaN(benchmarkEntry.solveTime)
72
- ? 'timeout'
73
- : `${benchmarkEntry.solveTime.toFixed(0)}ms`} ${benchmarkEntry.solveCorrect ? '✓' : '✗'}`);
74
- }
75
- else {
76
- console.log(`${solverId}\t| ${entryId} / ${allPuzzles.length}\t| ${pid}\t| unsupported`);
77
- }
78
- }
79
- console.log('Solver \t| Trial \t| PID\t| Result');
80
- console.log();
81
- for (let i = 0; i < allPuzzles.length; i++) {
82
- const entry = allPuzzles[i];
83
- const solvers = positionals.slice().sort(() => Math.random() - 0.5);
84
- const puzzle = await parseLink(entry.puzzleLink);
85
- for (const solverId of solvers) {
86
- const solver = allSolvers.get(solverId);
87
- void pqueue.add(async () => {
88
- if (!solver.isGridSupported(puzzle.grid)) {
89
- benchmarkEntries[solverId][i] = {
90
- pid: entry.pid,
91
- supported: false,
92
- solveTime: Number.NaN,
93
- solveCorrect: false,
94
- };
95
- printEntry(benchmarkEntries[solverId][i], i + 1, solverId, entry.pid);
96
- return;
97
- }
98
- const startTime = performance.now();
99
- const abortController = new AbortController();
100
- const benchmarkEntry = {
101
- pid: entry.pid,
102
- supported: true,
103
- solveTime: Number.NaN,
104
- solveCorrect: false,
105
- };
106
- let step = 0;
107
- const handle = setTimeout(() => {
108
- abortController.abort();
109
- }, maxTime);
110
- try {
111
- for await (const solution of solver.solve(puzzle.grid, abortController.signal)) {
112
- if (step === 0) {
113
- const solveCorrect = solution?.colorEquals(puzzle.solution) ?? false;
114
- if (!solveCorrect)
115
- break;
116
- }
117
- else {
118
- benchmarkEntry.solveCorrect = solution === null;
119
- if (benchmarkEntry.solveCorrect)
120
- benchmarkEntry.solveTime = performance.now() - startTime;
121
- break;
122
- }
123
- step++;
124
- }
125
- }
126
- catch {
127
- benchmarkEntry.solveCorrect = false;
128
- }
129
- clearTimeout(handle);
130
- benchmarkEntries[solverId][i] = benchmarkEntry;
131
- printEntry(benchmarkEntry, i + 1, solverId, entry.pid);
132
- });
133
- }
134
- }
135
- await pqueue.onIdle();
136
- const results = positionals.map(name => ({
137
- solver: name,
138
- fastestCount: 0,
139
- solve25: 0,
140
- solve50: 0,
141
- solve75: 0,
142
- solveSD: 0,
143
- unsupportedCount: 0,
144
- incorrectCount: 0,
145
- }));
146
- for (let i = 0; i < benchmarkEntries[positionals[0]].length; i++) {
147
- let fastestSolveTime = Number.POSITIVE_INFINITY;
148
- let fastestSolverIndex = null;
149
- for (let j = 0; j < positionals.length; j++) {
150
- const entry = benchmarkEntries[positionals[j]][i];
151
- if (!entry.supported) {
152
- results[j].unsupportedCount++;
153
- continue;
154
- }
155
- if (entry.solveCorrect && !Number.isNaN(entry.solveTime)) {
156
- if (entry.solveTime < fastestSolveTime) {
157
- fastestSolveTime = entry.solveTime;
158
- fastestSolverIndex = j;
159
- }
160
- }
161
- else {
162
- results[j].incorrectCount++;
163
- }
164
- }
165
- if (fastestSolverIndex !== null) {
166
- results[fastestSolverIndex].fastestCount++;
167
- }
168
- }
169
- for (let j = 0; j < positionals.length; j++) {
170
- const entries = benchmarkEntries[positionals[j]].filter(e => e.supported && e.solveCorrect && !Number.isNaN(e.solveTime));
171
- // 25th percentile
172
- const times = entries.map(e => e.solveTime).sort((a, b) => a - b);
173
- results[j].solve25 =
174
- times.length === 0
175
- ? Number.NaN
176
- : times[Math.floor((times.length - 1) * 0.25)];
177
- // 50th percentile (median)
178
- results[j].solve50 =
179
- times.length === 0
180
- ? Number.NaN
181
- : times[Math.floor((times.length - 1) * 0.5)];
182
- // 75th percentile
183
- results[j].solve75 =
184
- times.length === 0
185
- ? Number.NaN
186
- : times[Math.floor((times.length - 1) * 0.75)];
187
- // Standard deviation
188
- const mean = times.reduce((sum, time) => sum + time, 0) / (times.length || 1);
189
- const variance = times.reduce((sum, time) => sum + (time - mean) ** 2, 0) /
190
- (times.length || 1);
191
- results[j].solveSD = Math.sqrt(variance);
192
- }
193
- console.log('\nBenchmark Results:');
194
- for (const result of results) {
195
- console.log(`
196
- ${result.solver}:
197
- Fastest Solves: ${result.fastestCount}
198
- Solve time:
199
- P25: ${Number.isNaN(result.solve25) ? 'N/A' : `${result.solve25.toFixed(2)}ms`}
200
- P50: ${Number.isNaN(result.solve50) ? 'N/A' : `${result.solve50.toFixed(2)}ms`}
201
- P75: ${Number.isNaN(result.solve75) ? 'N/A' : `${result.solve75.toFixed(2)}ms`}
202
- SD: ${Number.isNaN(result.solveSD) ? 'N/A' : `${result.solveSD.toFixed(2)}ms`}
203
- Unsupported Puzzles: ${result.unsupportedCount}
204
- Incorrect Solutions: ${result.incorrectCount}
205
- `);
206
- }
@@ -1,119 +0,0 @@
1
- import GridData from './grid.js';
2
- import { Color, Comparison, Direction, DirectionToggle, Instrument, Orientation, OrientationToggle, Position, Wrapping } from './primitives.js';
3
- import { ControlLine } from './rules/musicControlLine.js';
4
- export declare enum ConfigType {
5
- Boolean = "boolean",
6
- NullableBoolean = "nullableBoolean",
7
- Number = "number",
8
- NullableNumber = "nullableNumber",
9
- String = "string",
10
- Color = "color",
11
- Comparison = "comparison",
12
- Wrapping = "wrapping",
13
- Direction = "direction",
14
- DirectionToggle = "directionToggle",
15
- Orientation = "orientation",
16
- OrientationToggle = "orientationToggle",
17
- Tile = "tile",
18
- Shape = "shape",
19
- Grid = "grid",
20
- NullableGrid = "nullableGrid",
21
- Icon = "icon",
22
- ControlLines = "controlLines",
23
- NullableNote = "nullableNote",
24
- NullableInstrument = "nullableInstrument",
25
- SolvePath = "solvePath"
26
- }
27
- export interface Config<T> {
28
- readonly type: ConfigType;
29
- readonly field: string;
30
- readonly description: string;
31
- readonly explanation?: string;
32
- readonly default: T;
33
- readonly configurable: boolean;
34
- }
35
- export interface BooleanConfig extends Config<boolean> {
36
- readonly type: ConfigType.Boolean;
37
- }
38
- export interface NullableBooleanConfig extends Config<boolean | null> {
39
- readonly type: ConfigType.NullableBoolean;
40
- }
41
- export interface NumberConfig extends Config<number> {
42
- readonly type: ConfigType.Number;
43
- readonly min?: number;
44
- readonly max?: number;
45
- readonly step?: number;
46
- }
47
- export interface NullableNumberConfig extends Config<number | null> {
48
- readonly type: ConfigType.NullableNumber;
49
- readonly min?: number;
50
- readonly max?: number;
51
- readonly step?: number;
52
- }
53
- export interface StringConfig extends Config<string> {
54
- readonly type: ConfigType.String;
55
- readonly maxLength?: number;
56
- readonly placeholder?: string;
57
- }
58
- export interface ColorConfig extends Config<Color> {
59
- readonly type: ConfigType.Color;
60
- readonly allowGray: boolean;
61
- }
62
- export interface ComparisonConfig extends Config<Comparison> {
63
- readonly type: ConfigType.Comparison;
64
- }
65
- export interface WrappingConfig extends Config<Wrapping> {
66
- readonly type: ConfigType.Wrapping;
67
- }
68
- export interface DirectionConfig extends Config<Direction> {
69
- readonly type: ConfigType.Direction;
70
- }
71
- export interface DirectionToggleConfig extends Config<DirectionToggle> {
72
- readonly type: ConfigType.DirectionToggle;
73
- }
74
- export interface OrientationConfig extends Config<Orientation> {
75
- readonly type: ConfigType.Orientation;
76
- }
77
- export interface OrientationToggleConfig extends Config<OrientationToggle> {
78
- readonly type: ConfigType.OrientationToggle;
79
- }
80
- export interface TileConfig extends Config<GridData> {
81
- readonly type: ConfigType.Tile;
82
- readonly resizable: boolean;
83
- }
84
- export interface ShapeConfig extends Config<GridData> {
85
- readonly type: ConfigType.Shape;
86
- readonly resizable: boolean;
87
- }
88
- export interface GridConfig extends Config<GridData> {
89
- readonly type: ConfigType.Grid;
90
- }
91
- export interface NullableGridConfig extends Config<GridData | null> {
92
- readonly type: ConfigType.NullableGrid;
93
- readonly nonNullDefault: GridData;
94
- }
95
- export interface IconConfig extends Config<string> {
96
- readonly type: ConfigType.Icon;
97
- }
98
- export interface ControlLinesConfig extends Config<ControlLine[]> {
99
- readonly type: ConfigType.ControlLines;
100
- }
101
- export interface NullableNoteConfig extends Config<string | null> {
102
- readonly type: ConfigType.NullableNote;
103
- }
104
- export interface NullableInstrumentConfig extends Config<Instrument | null> {
105
- readonly type: ConfigType.NullableInstrument;
106
- }
107
- export interface SolvePathConfig extends Config<Position[]> {
108
- readonly type: ConfigType.SolvePath;
109
- }
110
- export type AnyConfig = BooleanConfig | NullableBooleanConfig | NumberConfig | NullableNumberConfig | StringConfig | ColorConfig | ComparisonConfig | WrappingConfig | DirectionConfig | DirectionToggleConfig | OrientationConfig | OrientationToggleConfig | TileConfig | ShapeConfig | GridConfig | NullableGridConfig | IconConfig | ControlLinesConfig | NullableNoteConfig | NullableInstrumentConfig | SolvePathConfig;
111
- /**
112
- * Compare two config values for equality, using an appropriate method for the config type.
113
- *
114
- * @param type The type of the config.
115
- * @param a The first value to compare.
116
- * @param b The second value to compare.
117
- * @returns Whether the two values are equal.
118
- */
119
- export declare function configEquals<C extends AnyConfig>(type: C['type'], a: C['default'], b: C['default']): boolean;
@@ -1,72 +0,0 @@
1
- import { DIRECTIONS, ORIENTATIONS, } from './primitives.js';
2
- import { normalizeShape, shapeEquals, tilesToShape } from './shapes.js';
3
- export var ConfigType;
4
- (function (ConfigType) {
5
- ConfigType["Boolean"] = "boolean";
6
- ConfigType["NullableBoolean"] = "nullableBoolean";
7
- ConfigType["Number"] = "number";
8
- ConfigType["NullableNumber"] = "nullableNumber";
9
- ConfigType["String"] = "string";
10
- ConfigType["Color"] = "color";
11
- ConfigType["Comparison"] = "comparison";
12
- ConfigType["Wrapping"] = "wrapping";
13
- ConfigType["Direction"] = "direction";
14
- ConfigType["DirectionToggle"] = "directionToggle";
15
- ConfigType["Orientation"] = "orientation";
16
- ConfigType["OrientationToggle"] = "orientationToggle";
17
- ConfigType["Tile"] = "tile";
18
- ConfigType["Shape"] = "shape";
19
- ConfigType["Grid"] = "grid";
20
- ConfigType["NullableGrid"] = "nullableGrid";
21
- ConfigType["Icon"] = "icon";
22
- ConfigType["ControlLines"] = "controlLines";
23
- ConfigType["NullableNote"] = "nullableNote";
24
- ConfigType["NullableInstrument"] = "nullableInstrument";
25
- ConfigType["SolvePath"] = "solvePath";
26
- })(ConfigType || (ConfigType = {}));
27
- /**
28
- * Compare two config values for equality, using an appropriate method for the config type.
29
- *
30
- * @param type The type of the config.
31
- * @param a The first value to compare.
32
- * @param b The second value to compare.
33
- * @returns Whether the two values are equal.
34
- */
35
- export function configEquals(type, a, b) {
36
- if (type === ConfigType.ControlLines) {
37
- const aLines = a;
38
- const bLines = b;
39
- if (aLines.length !== bLines.length)
40
- return false;
41
- return aLines.every((line, i) => line.equals(bLines[i]));
42
- }
43
- if (type === ConfigType.Tile || type === ConfigType.Grid) {
44
- return a.equals(b);
45
- }
46
- if (type === ConfigType.Shape) {
47
- const aShape = normalizeShape(tilesToShape(a.tiles));
48
- const bShape = normalizeShape(tilesToShape(b.tiles));
49
- return shapeEquals(aShape, bShape);
50
- }
51
- if (type === ConfigType.NullableGrid) {
52
- if (a === null && b === null)
53
- return true;
54
- if (a === null || b === null)
55
- return false;
56
- return a.equals(b);
57
- }
58
- if (type === ConfigType.DirectionToggle) {
59
- return DIRECTIONS.every(dir => a[dir] === b[dir]);
60
- }
61
- if (type === ConfigType.OrientationToggle) {
62
- return ORIENTATIONS.every(dir => a[dir] === b[dir]);
63
- }
64
- if (type === ConfigType.SolvePath) {
65
- const aPath = a;
66
- const bPath = b;
67
- if (aPath.length !== bPath.length)
68
- return false;
69
- return aPath.every((pos, i) => pos.x === bPath[i].x && pos.y === bPath[i].y);
70
- }
71
- return a === b;
72
- }
@@ -1,14 +0,0 @@
1
- import { AnyConfig } from './config.js';
2
- export default abstract class Configurable {
3
- abstract get title(): string;
4
- abstract get configExplanation(): string;
5
- get configs(): readonly AnyConfig[] | null;
6
- abstract copyWith(props: Record<string, unknown>): this;
7
- /**
8
- * Check if this instruction is equal to another instruction by comparing their IDs and configs.
9
- *
10
- * @param other The other instruction to compare to.
11
- * @returns Whether the two instructions are equal.
12
- */
13
- equals(other: Configurable): boolean;
14
- }
@@ -1,26 +0,0 @@
1
- import { configEquals } from './config.js';
2
- export default class Configurable {
3
- get configs() {
4
- return null;
5
- }
6
- /**
7
- * Check if this instruction is equal to another instruction by comparing their IDs and configs.
8
- *
9
- * @param other The other instruction to compare to.
10
- * @returns Whether the two instructions are equal.
11
- */
12
- equals(other) {
13
- const configs = this.configs;
14
- if (configs === null)
15
- return true;
16
- // this is only possible when an instruction is instantiated before the class itself is completely defined
17
- // in this case, we can only compare the instances themselves
18
- if (configs === undefined)
19
- return this === other;
20
- for (const config of this.configs) {
21
- if (!configEquals(config.type, this[config.field], other[config.field]))
22
- return false;
23
- }
24
- return true;
25
- }
26
- }