そろばんの計算の仕組みをシミュレートして足し算をするプログラムを書いてみました。
JavaScriptで書きました。
コードをページの下部に記載します。自前の特殊文字置換ツールを利用しました。
答えに出てくる記号の羅列は、計算の操作をした結果で出るそろばんの形を表しています。
行の上から下の桁になります
*はそろばんの珠、ーは珠のないところ、|はそろばんの5の位と1の位を分ける線です。
10進数を基に計算していますので、小数でも誤差は出ないです。
今のところ小数には対応していませんが…
また引き算や、掛け算割り算にも対応できるはずです。
現在最大5桁の自然数の加算ができます。
"use strict";
const f = [["*","-","|","-","*","*","*","*"],["*","-","|","*","-","*","*","*"],["*","-","|","*","*","-","*","*"],["*","-","|","*","*","*","-","*"],["*","-","|","*","*","*","*","-"],["-","*","|","-","*","*","*","*"],["-","*","|","*","-","*","*","*"],["-","*","|","*","*","-","*","*"],["-","*","|","*","*","*","-","*"],["-","*","|","*","*","*","*","-"]];
function abacus_operation(pos, add, a){
if(add===1){
if(a[pos][1]==="*"){
[a[pos][0],a[pos][1]] = [a[pos][1],a[pos][0]];
abacus_operation(pos+1, 3, a);
}else{
[a[pos][0],a[pos][1]] = [a[pos][1],a[pos][0]];
}
}else{
let count=3;
while(a[pos][count]==="*"){
count++;
}
if(7-count<add-2){
if(a[pos][1]==="*"){
[a[pos][0],a[pos][1]] = [a[pos][1],a[pos][0]];
for(let i=0; i<5-(add-2); i++){
[a[pos][count-i],a[pos][count-1-i]] = [a[pos][count-1-i],a[pos][count-i]];
}
abacus_operation(pos+1, 3, a);
}else{
[a[pos][0],a[pos][1]] = [a[pos][1],a[pos][0]];
for(let i=0; i<5-(add-2); i++){
[a[pos][count-i],a[pos][count-1-i]] = [a[pos][count-1-i],a[pos][count-i]];
}
}
}else{
for(let i=0; i<add-2; i++){
[a[pos][count+i],a[pos][count+i+1]] = [a[pos][count+i+1],a[pos][count+i]];
}
}
}
}
document.getElementById("bt").onclick=function(){
let num1_pre = document.getElementById("num1").value;
let num2_pre = document.getElementById("num2").value;
if(num1_pre.match(/^\d{0,5}$/) && num2_pre.match(/^\d{0,5}$/)){
const num1 = num1_pre.split("");
const num2 = num2_pre.split("");
let a = [];
let b = [];
for(let i=num1.length-1; i>=0; i--){
a.push([...f[num1[i]]]);
}
for(let i=0; i<=5-num1.length; i++){
a.push([...f[0]]);
}
for(let i=num2.length-1; i>=0; i--){
b.push([...f[num2[i]]]);
}
for(let i=b.length-1; i>=0; i--){
for(let j=0; j<4; j++){
if(j===0 || j===2){
continue;
}
else if(j===1){
if(b[i][1]==="*"){
abacus_operation(i, 1, a);
}
}else{
let count = 3;
while(b[i][count]==="*"){
count++;
}
if(count!=3){
abacus_operation(i, count-1, a);
}
}
}
}
const result = document.getElementById("result");
let a_ans = [];
for(let i=0; i<a.length; i++){
a_ans.push(a[i].join("")+"<br>");
}
result.innerHTML = a_ans.join("");
let ans = [];
for(let i=5; i>=0; i--){
for(let j=0; j<10; j++){
if(a[i].toString()===f[j].toString()){
ans.push(j);
break;
}
}
}
const ans_num = document.createElement("div");
ans_num.innerText = ans.join("");
result.appendChild(ans_num);
}else{
const result = document.getElementById("result");
result.innerHTML = "値が不正です。";
}
}