console
var rows = 2;
var cols = 3;
function init() {
document.getElementById('rows').value = rows;
document.getElementById('cols').value = cols;
rebuildInputParams();
}
function dimChange() {
rows = document.getElementById('rows').value;
cols = document.getElementById('cols').value;
rebuildInputParams();
}
function rebuildInputParams() {
var paramsDiv = document.getElementById('params');
paramsDiv.innerHTML = "";
for (r = 0; r < rows; r++) {
for (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>';
}
}
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 colOperations, rowOperations;
function createOperationIndexList() {
colOperations = permutation(operations.length, cols - 1);
rowOperations = permutation(operations.length, rows - 1);
}
var colParams, rowParams;
function createParamIndexList() {
colParams = permutation(cols);
rowParams = permutation(rows);
}
var params = [];
var target = [];
function getParamsData() {
params = [];
for (r = 0; r < rows; r++) {
row = [];
for (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));
}
}
params.push(row);
}
}
function permutation(indexLength, selected) {
selected = selected || indexLength;
var permutations = [];
var p = [];
for (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 (i = 0; i < arr.length - 1; i++) {
for (j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
return true;
}
}
}
return false;
}
init();
function run() {
testData();
getParamsData();
createOperationIndexList();
createParamIndexList();
analyse();
solve();
}
function testData() {
rows = 3;
cols = 4;
rebuildInputParams();
document.getElementById('rows').value = rows;
document.getElementById('cols').value = cols;
document.getElementById('11').value = 2;
document.getElementById('12').value = 7;
document.getElementById('13').value = 10;
document.getElementById('14').value = 24;
document.getElementById('21').value = 3;
document.getElementById('22').value = 5;
document.getElementById('23').value = 6;
document.getElementById('24').value = 21;
document.getElementById('31').value = 4;
document.getElementById('32').value = 6;
document.getElementById('33').value = 5;
document.getElementById('34').value = "";
}
var patterns;
function analyse() {
patterns = [];
console.log('按列分析数据规则:');
for (rp = 0; rp < rowParams.length; rp++) {
var paramsIndex = rowParams[rp];
if (isArrayRepeat(paramsIndex)) {
continue;
}
for (ro = 0; ro < rowOperations.length; ro++) {
var operationsIndex = rowOperations[ro];
result = [];
for (j = 0; j < cols; j++) {
var hasNull = false;
for (i = 0; i < rows; i++) {
if (params[i][j] === null) {
hasNull = true;
break;
}
}
if (hasNull) {
result.push(null);
continue;
}
var paramsData = [];
for (i = 0; i < paramsIndex.length; i++) {
paramsData.push(params[paramsIndex[i]][j]);
}
var ans = evaluate(paramsData, operationsIndex, null);
result.push(ans);
}
var as = true;
var a = null;
var b = null;
for (i = 0; i < result.length - 1; i++) {
if (result[i] !== null) {
a = [result[i], i];
for (j = i + 1; j < result.length; j++) {
if (result[j] !== null) {
b = [result[j], j];
break;
}
}
if (b) {
break;
}
}
}
if (a && b) {
d = (b[0].answer - a[0].answer) / (b[1] - a[1]);
for (i = 0; i < result.length; i++) {
if (result[i]) {
if ((result[i].answer - a[0].answer) !== d * (i - a[1])) {
as = false;
break;
}
}
}
if (as) {
patterns.push({
type: 'row',
paramsIndex: paramsIndex,
operationsIndex: operationsIndex,
delta: d,
result: result
});
}
}
}
}
document.getElementById("patternCount").innerText = patterns.length;
}
function solve() {
var slv = document.getElementById('solve');
var inner = "";
slv.innerHTML = "";
while (true) {
for (t = 0; t < target.length; t++) {
if (target[t][2] === true) {
continue;
}
inner += "<h4>求解空白参数,位置(" +
(target[t][0] + 1).toString() + ", " +
(target[t][1] + 1).toString() + ")</h4>";
inner += "<ul>"
var r = 0;
var c = 0;
for (i = 0; i < rows; i++) {
if (params[i][target[t][1]] === null) {
r += 1;
}
}
for (j = 0; j < cols; j++) {
if (params[target[t][0]][j] === null) {
c += 1;
}
}
if (r === 1) {
for (p = 0; p < patterns.length; p++) {
var pattern = patterns[p];
inner += "<li>规则" + (p + 1).toString() + ", 等差数列公差为 : " + pattern.delta.toString();
for (i = 0; i < pattern.result.length; i++) {
if (pattern.result[i]) {
inner += "<p>" + pattern.result[i].equation + " = " + pattern.result[i].answer + "</p>";
}
}
var answer = 0;
for (i = 0; i < pattern.result.length; i++) {
if (pattern.result[i]) {
answer = pattern.result[i].answer + pattern.delta * (target[t][1] - i);
break;
}
}
var paramsData = [];
for (i = 0; i < rows; i++) {
if (params[pattern.paramsIndex[i]][target[t][1]] === null) {
paramsData.push([0, 1]);
} else {
paramsData.push(params[pattern.paramsIndex[i]][target[t][1]]);
}
}
var ans = evaluate(paramsData, pattern.operationsIndex, answer);
inner += "<p>" + ans.equation.replace("0,1", "x") + " = " + ans.answer.toString() + "</p>";
inner += "<p class=solution>x = " + ans.x.toString() + "</p>";
inner += "</li>";
}
}
if (c === 1) {}
inner += "</ul>";
}
break;
}
slv.innerHTML = inner;
}
function evaluate(data, operationsIndex, answer) {
var r = data[0];
var s = r.toString();
for (i = 0; i < operationsIndex.length; i++) {
r = operations[operationsIndex[i]].func(r, data[i + 1]);
if (i > 0 && operations[operationsIndex[i - 1]].priority < operations[operationsIndex[i]].priority) {
s = '(' + s + ')';
}
s += operations[operationsIndex[i]].symbo + data[i + 1].toString();
}
if (answer) {
return {
equation: s,
answer: answer,
x: (answer - r[0]) / r[1]
};
} else {
return {
equation: s,
answer: r,
x: null
};
}
}
<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>
根据已知数据,共计算出
<span id=patternCount>
20
</span>
条规则
</p>
<div id=solve>
<h4>
求解空白1
</h4>
<ul id=patterns>
<li>
No.1
<p>
1+1+1=3
</p>
<p>
2+3+4=9
</p>
<p>
4+5+x=15
</p>
<p>
x=6
</p>
</li>
<li>
No.2
</li>
</ul>
</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;
}