console
var rows = 2;
var cols = 3;
function testData() {
rows = 4;
cols = 4;
rebuildInputParams();
document.getElementById('rows').value = rows;
document.getElementById('cols').value = cols;
document.getElementById('11').value = 2;
document.getElementById('12').value = 3;
document.getElementById('13').value = 4;
document.getElementById('14').value = 5;
document.getElementById('21').value = 3;
document.getElementById('22').value = "";
document.getElementById('23').value = 5;
document.getElementById('24').value = 6;
document.getElementById('31').value = 4;
document.getElementById('32').value = 5;
document.getElementById('33').value = 6;
document.getElementById('34').value = 7;
document.getElementById('41').value = 5;
document.getElementById('42').value = 6;
document.getElementById('43').value = 7;
document.getElementById('44').value = 8;
}
function init() {
document.getElementById('rows').value = rows;
document.getElementById('cols').value = cols;
rebuildInputParams();
testData();
}
function dimChange() {
rows = document.getElementById('rows').value;
cols = document.getElementById('cols').value;
rebuildInputParams();
}
function rebuildInputParams() {
var paramsDiv = document.getElementById('params');
paramsDiv.innerHTML = "";
for (var r = 0; r < rows; r++) {
for (var c = 0; c < cols; c++) {
var input = document.createElement('input');
input.id = (r + 1) * 10 + c + 1;
input.type = "Number";
paramsDiv.appendChild(input);
}
paramsDiv.innerHTML += '<br><br>';
}
document.getElementById('msg').style.visibility = "hidden";
}
init();
function run() {
getParamsData();
if (rows < 4 && cols < 4) {
return null;
}
analyse();
solve();
}
var params = [];
var target = [];
function getParamsData() {
params = [];
for (var r = 0; r < rows; r++) {
row = [];
for (var c = 0; c < cols; c++) {
var input = document.getElementById((r + 1) * 10 + c + 1);
if (input.value.trim() === "") {
row.push(null);
target.push([r, c, false]);
} else {
row.push(Number(input.value.trim()));
}
}
params.push(row);
}
}
function add(a, b) {
if (Array.isArray(a)) {
return [a[0] + b, a[1]];
}
if (Array.isArray(b)) {
return [a + b[0], b[1]];
}
return a + b;
}
function minus(a, b) {
if (Array.isArray(a)) {
return [a[0] - b, a[1]];
}
if (Array.isArray(b)) {
return [a - b[0], b[1]];
}
return a - b;
}
function multiply(a, b) {
if (Array.isArray(a)) {
return [a[0] * b, a[1] * b];
}
if (Array.isArray(b)) {
return [a * b[0], a * b[1]];
}
return a * b;
}
function divide(a, b) {
if (Array.isArray(a)) {
if (b !== 0) {
return [a[0] / b, a[1] / b];
} else {
return null;
}
}
if (Array.isArray(b)) {
if (b[0] !== 0 && b[1] !== 0) {
return [a / b[0], a / b[1]];
} else {
return null;
}
}
if (b !== 0) {
return a / b;
} else {
return null;
}
}
var operations = [{
func: add,
symbo: '+',
priority: 1
},
{
func: minus,
symbo: '-',
priority: 1
},
{
func: multiply,
symbo: '×',
priority: 2
},
{
func: divide,
symbo: '÷',
priority: 2
}];
var patterns;
function analyse() {
patterns = [];
var colParamsIndex = permutation(cols);
var rowParamsIndex = permutation(rows);
var colOperationsIndex = permutation(operations.length, cols - 1)
var rowOperationsIndex = permutation(operations.length, rows - 1);
for (var cp = 0; cp < colParamsIndex.length; cp++) {
if (isArrayRepeat(colParamsIndex[cp])) {
continue;
} else {
for (var co = 0; co < colOperationsIndex.length; co++) {
var row = [];
var result = [];
for (var i = 0; i < rows; i++) {
var ans = evaluate("row", i, colParamsIndex[cp], colOperationsIndex[co], null);
if (ans === null) {
row.push(null);
} else {
row.push(ans.answer);
}
result.push(ans);
}
var ap = isAP(row);
if (ap !== null) {
patterns.push({
type: "row",
paramsIndex: colParamsIndex[cp],
operationIndex: colOperationsIndex[co],
result: result,
ap: ap
})
}
}
}
}
for (var rp = 0; rp < rowParamsIndex.length; rp++) {
if (isArrayRepeat(rowParamsIndex[rp])) {
continue;
} else {
for (var ro = 0; ro < rowOperationsIndex.length; ro++) {
var col = [];
var result = [];
for (var j = 0; j < cols; j++) {
var ans = evaluate("col", j, rowParamsIndex[rp], rowOperationsIndex[ro], null);
if (ans === null) {
col.push(null);
} else {
col.push(ans.answer);
}
result.push(ans);
}
var ap = isAP(col);
if (ap !== null) {
patterns.push({
type: "col",
paramsIndex: rowParamsIndex[rp],
operationIndex: rowOperationsIndex[ro],
result: result,
ap: ap
})
}
}
}
}
}
function permutation(indexLength, selected) {
selected = selected || indexLength;
var permutations = [];
var p = [];
for (var i = 0; i < Math.pow(indexLength, selected); i++) {
p = convertBase(i, indexLength);
while (p.length < selected) {
p.push(0);
}
permutations.push(p);
}
return permutations;
}
function convertBase(num, base) {
var ct = [];
var quotient, remainder;
while (true) {
quotient = parseInt(num / base);
remainder = num % base;
ct.push(remainder);
if (quotient > 0) {
num = quotient;
} else {
break;
}
}
return ct;
}
function isArrayRepeat(array) {
var arr = array;
for (var i = 0; i < arr.length - 1; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
return true;
}
}
}
return false;
}
function solve() {
}
function evaluate(type, index, paramsIndex, operationsIndex, answer) {
var i, j;
if (type === "row") {
i = index;
for (var j = 0; j < cols; j++) {
if (params[i][j] === null) {
return null;
}
}
var r = params[i][paramsIndex[0]];
var s = r.toString();
for (var j = 0; j < operationsIndex.length; j++) {
r = operations[operationsIndex[j]].func(r, params[i][paramsIndex[j + 1]]);
if (j > 0 && operations[operationsIndex[j - 1]].priority < operations[operationsIndex[j]].priority) {
s = '(' + s + ')';
}
s += operations[operationsIndex[j]].symbo + params[i][paramsIndex[j + 1]].toString();
}
} else if (type === "col") {
j = index;
for (var i = 0; i < rows; i++) {
if (params[i][j] === null) {
return null;
}
}
var r = params[paramsIndex[0]][j];
var s = r.toString();
for (var i = 0; i < operationsIndex.length; i++) {
r = operations[operationsIndex[i]].func(r, params[paramsIndex[i + 1]][j]);
if (i > 0 && operations[operationsIndex[i - 1]].priority < operations[operationsIndex[i]].priority) {
s = '(' + s + ')';
}
s += operations[operationsIndex[i]].symbo + params[paramsIndex[i + 1]][j];
}
}
if (answer) {
return {
equation: s,
answer: answer,
x: (answer - r[0]) / r[1]
};
} else {
return {
equation: s,
answer: r,
x: null
};
}
}
function isAP(data) {
var notnull = 0;
var a = null;
var b = null;
for (var i = 0; i < data.length; i++) {
if (data[i] !== null) {
notnull += 1;
if (a === null) {
a = [data[i], i];
} else if (b === null) {
b = [data[i], i];
}
}
}
if (notnull < 3) {
return null;
}
var d = (a[0] - b[0]) / (a[1] - b[1]);
for (var i = 0; i < data.length; i++) {
if (data[i] !== null && (data[i] - a[0]) !== (i - a[1]) * d) {
return null;
}
}
for (var i = 0; i < data.length; i++) {
if (data[i] === null) {
data[i] = (i - a[1]) * d + a[0];
}
}
return [d, data];
}
<h1>
小学生数字找规律
</h1>
<p>
共
<input id=rows type=number onchange=dimChange()>
组,每组
<input id=cols type=number onchange=dimChange()>
个数字。
</p>
<div>
---------------------------------------------
<p>
已知数字,请按顺序填写。要求解的位置请留白。
</p>
<div id=params>
</div>
---------------------------------------------
<br>
<button onclick=run()>
开始计算
</button>
<p id=msg hidden>
根据已知数据,共计算出
<span id=patternCount></span>
条规则
</p>
<div id=solve></div>
</div>
input {
width: 50px;
height: 1.5rem;
font-size: 1rem;
font-weight: bold;
text-align: center;
margin: 0 10px;
}
input.error {
background-color: lightpink;
color: darkred;
}
span#patternCount {
color: darkred;
font-weight: bold;
font-size: 1.2rem;
}
p.solution {
font-weight: bold;
color: red;
}