This repository has been archived by the owner on Jun 16, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nonogram.js
executable file
·51 lines (46 loc) · 2.06 KB
/
nonogram.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/usr/bin/env node
/* eslint no-console: "off" */
require('colors');
const fs = require('fs');
const program = require('commander');
const nonogram = require('.');
program
.version('0.0.0')
.usage('[options] [input]')
.description('Solve colored and black & white nonograms. Input is a json file with `rows` and `cols` where each is a list of constraints. Constraints are either strings like "4 3 1" for black and white nonograms, "4.2@" for colored nonograms where the number precedes the quantity of the character, or arrays of json objects like {char: "#", count: 3, multi: [ true | false ]} where multi indicates more than `count` of that character may be used (e.g. for spaces). The input file may also contain a `styles` attribute, where styles maps a character to a nodejs `colors` style (e.g. `black`, `underline`, `bgWhite`).')
.option('--no-stretch', "don't duplicate each 'pixel'")
.option('--no-color', 'disable colored output')
.parse(process.argv);
if (program.args.length > 1) {
console.error('\n error: only one input file may be specified\n');
process.exit(1);
}
/** Compresses an array into elements and counts. */
function count(elements) {
return elements.reduce((l, e) => {
if (!l.length || l[l.length - 1][0] !== e) {
l.push([e, 1]);
} else {
l[l.length - 1][1] += 1;
}
return l;
}, []);
}
const data = JSON.parse(fs.readFileSync(program.args.length ? program.args[0] : process.stdin.fd));
const styleMap = data.styles || {};
const rows = data.rows.map(con => (typeof con === 'string' ? nonogram.parseConstraint(con) : con));
const cols = data.cols.map(con => (typeof con === 'string' ? nonogram.parseConstraint(con) : con));
const raster = nonogram.solve(rows, cols);
raster.forEach((line) => {
console.log(count(line).map(([e, c]) => {
let run = Array(c * (program.stretch ? 2 : 1)).fill(e).join('');
(styleMap[e] || []).forEach((style) => {
run = run[style];
if (!run) {
console.error(`\n error: unknown style: ${style}\n`);
process.exit(1);
}
});
return run;
}).join(''));
});