叕做了一件很无意义的工作……
编了一天,调试了一天。Bug 的原因是我定义好了一个函数、变量,总想着尽可能套用,节省代码长度。但是为此需要付出更大的努力,并且会出现更多的困难与错误。由其是变量,还是各用各得好,思路更清晰。
目前只编了加法,减法、乘除、开方等运算后面有时间再写吧。
![b6f2cd418c190def764d27295c9bece3.gif](https://i-blog.csdnimg.cn/blog_migrate/a25be76d14e19b0517b27a38a3847100.gif)
abacus <- function(M, time = 1) # M 个正整数的加法;time 拨珠时间间隔
{
###输入加数
addend <- list(); len <- c()
for(j in 1:M)
{
print("请输入加数")
addend[[j]] = scan()
len = c(len, length(addend[[j]]))
}
N = max(max(len)+3, 10) #档数
###画算盘
plot(0,0,type = "n", axes = FALSE, xlab = "", ylab = "", yaxt = "n",
xlim = c(0,N + 1), ylim = c(-6,9), bty = "o")
##框架
ab <- function()
{
segments(1:N, 0, 1:N, 9)
segments(1.2 : (N + 0.2), 0, 1.2 : (N+0.2), 9) #档
segments(-1, 0, N + 2, 0, lwd = 15) #框
segments(-1, 9, N + 2, 9, lwd = 15)
segments(-1, 6, N + 2, 6, lwd = 15) #梁
points(seq(N+0.1, 1.1, -3) , rep(6, ceiling(N/3)),
pch = 19, cex = 1, col = "white")
}
xball = 1.1:(N + 0.1)
##清零
ooo <- function()
{
points(xball , rep(8, N) , pch = 18, cex = 6) #上珠
points(xball , rep(1, N) , pch = 18, cex = 6) #下珠
points(xball , rep(2, N) , pch = 18, cex = 6)
points(xball , rep(3, N) , pch = 18, cex = 6)
points(xball , rep(4, N) , pch = 18, cex = 6)
}
ab(); ooo()
segments(-1, -4, N + 2, -4, col = "red") #答案分割线
text(2, -3, "+", cex = 3, col = "red")
text(2, -5, "=", cex = 3, col = "red")
##数字
number <- function(n, d) #显示在第 d 档(从右往左数)的数字 n
{
points(rep(N - d + 1.1, 5) , 1:5 , pch = 18, cex = 6, col = "white")
points(rep(N - d + 1.1, 2) , 7:8 , pch = 18, cex = 6, col = "white")
ab()
if(n == 0)
{
points(rep(N - d + 1.1, 4) , 1:4 , pch = 18, cex = 6)
points(N - d + 1.1 , 8 , pch = 18, cex = 6)
}
if(n == 1)
{
points(rep(N - d + 1.1, 3) , 1:3 , pch = 18, cex = 6)
points(N - d + 1.1 , 5 , pch = 18, cex = 6)
points(N - d + 1.1 , 8 , pch = 18, cex = 6)
}
if(n == 2)
{
points(rep(N - d + 1.1, 2) , 1:2 , pch = 18, cex = 6)
points(rep(N - d + 1.1, 2) , 4:5 , pch = 18, cex = 6)
points(N - d + 1.1 , 8 , pch = 18, cex = 6)
}
if(n == 3)
{
points(N - d + 1.1 , 1 , pch = 18, cex = 6)
points(rep(N - d + 1.1, 3) , 3:5 , pch = 18, cex = 6)
points(N - d + 1.1 , 8 , pch = 18, cex = 6)
}
if(n == 4)
{
points(rep(N - d + 1.1, 4) , 2:5 , pch = 18, cex = 6)
points(N - d + 1.1 , 8 , pch = 18, cex = 6)
}
if(n == 5)
{
points(rep(N - d + 1.1, 4) , 1:4 , pch = 18, cex = 6)
points(N - d + 1.1 , 7 , pch = 18, cex = 6)
}
if(n == 6)
{
points(rep(N - d + 1.1, 3) , 1:3 , pch = 18, cex = 6)
points(N - d + 1.1 , 5 , pch = 18, cex = 6)
points(N - d + 1.1 , 7 , pch = 18, cex = 6)
}
if(n == 7)
{
points(rep(N - d + 1.1, 2) , 1:2 , pch = 18, cex = 6)
points(rep(N - d + 1.1, 2) , 4:5 , pch = 18, cex = 6)
points(N - d + 1.1 , 7 , pch = 18, cex = 6)
}
if(n == 8)
{
points(N - d + 1.1 , 1 , pch = 18, cex = 6)
points(rep(N - d + 1.1, 3) , 3:5 , pch = 18, cex = 6)
points(N - d + 1.1 , 7 , pch = 18, cex = 6)
}
if(n == 9)
{
points(rep(N - d + 1.1, 4) , 2:5 , pch = 18, cex = 6)
points(N - d + 1.1 , 7 , pch = 18, cex = 6)
}
}
for(i in 1:len[1])number(addend[[1]][i], len[1] - i + 1)
##在底部打出第 k 个数
npaste <- function(k, j, l = 0) #第 k 个加数 ;第 j(=1,2,3)行;第 l 个数字标红
{
lett1 = paste(addend[[k]]); L = length(addend[[k]])
for(i in 1:L)points(N - L + i + 0.1, -j, cex=2, pch=lett1[i],
col = c("black", "red")[if(l >= 1 & i == l){2}else{1}])
}
npaste(1,1,0)
##擦除(k = 1,2,3)
erase <- function(k, x = 4, y = N + 2)segments(x, -k, y, -k, lwd = 30, col = "white")
###运算
for(k in 2:M)
{
erase(5)
lenn = max(len[1], len[k])
addend[[1]] = c(rep(0,lenn - len[1]), addend[[1]]) #对位
addend[[k]] = c(rep(0,lenn - len[k]), addend[[k]])
len[1] = lenn; len[k] = lenn
new = addend[[1]]
i = 1; up = 0
for(i in 1: len[1])
{
erase(1); erase(3)
npaste(1, 1, i) #显示加数
npaste(k, 3, i)
if(addend[[k]][i] == 0)
{
Sys.sleep(time)
points(N - len[1] + i + 0.1, -5, cex = 2, pch = paste(addend[[1]][i]), col = "red")
next
}
digit = addend[[1]][i] + addend[[k]][i] #第 i 个位置上的和
if(digit < 10) ##不需要进位的情况
{
Sys.sleep(time)
number(digit, len[1] - i + 1) #拨出数字
new[i] = digit
erase(5, N - len[1] + i - 0.15, N - len[1] + i + 0.35)
points(N - len[1] + i + 0.1, -5, cex=2, pch = paste(digit), col = "red")
}
vd = len[1] - i + 1
j = i
while(digit > 9) ##需要进位的情况
{
Sys.sleep(time)
digit = digit - 10
new[j] = digit
number(digit, vd)
erase(5, N - len[1] + j - 0.15, N - len[1] + j + 0.35)
points(N - len[1] + j + 0.1, -5, cex=2, pch = paste(digit), col = "red")
vd = vd + 1 #第 vd 档
j = j - 1 #第 j 位
if(j < 1)
{
digit = 1
up = 1
Sys.sleep(time)
number(1, N - len[1])
points(N - len[1] + 0.1, -5, cex = 2, pch = "1", col = "red")
}else{digit = new[j] + 1}
if(digit < 10)
{
Sys.sleep(time)
number(digit, vd)
new[j] = digit
erase(5, N - len[1] + j - 0.15, N - len[1] + j + 0.35)
points(N - len[1] + j + 0.1, -5, cex=2, pch = paste(digit), col = "red")
}
}
}
if(up == 1){new = c(1, new)}
addend[[1]] = new
len[1] = length(new)
Sys.sleep(time)
}
}
abacus(3,1)