用yacc编写的算术运算计算器_如何用现代计算机编写古代计算器?

叕做了一件很无意义的工作……

编了一天,调试了一天。Bug 的原因是我定义好了一个函数、变量,总想着尽可能套用,节省代码长度。但是为此需要付出更大的努力,并且会出现更多的困难与错误。由其是变量,还是各用各得好,思路更清晰。

目前只编了加法,减法、乘除、开方等运算后面有时间再写吧。

b6f2cd418c190def764d27295c9bece3.gif
动图展示的是40567+889+657的连加过程
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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值