计算器作为数字和运算符的列表


20

您的任务是获取一个整数或运算符的参数列表,并按如下方式解析它们:

  1. 当前有一个运算符,以+开头。

  2. 每次找到操作员时,当前操作员都会更改为该操作员。

  3. 可能的运算符为:“ +”,“-”,“ *”,“ /”和“%”,它们对应于C语言和大多数语言的含义。

  4. 保留了一个从0开始的运行解决方案。

  5. 每次找到整数,解决方案都会根据运算符的数字进行修改。例如,如果运算符为“ /”,则解决方案除以数字。

  6. 如果一个运算将导致一个混合数(即一个十进制数),则必须将其下限返回整数(即必须将十进制数切掉)。

  7. 输出最终解决方案。

例如:

该参数5 8 25 * 9 6 2 - 104 / 4 7 + 6 % 14将导致:

  5 8  25 * 9   6    2    - 104  / 4    7      + 6 % 14
0 5 13 38   342 2052 4104   4000   1000 142   148    8  -> 8

输入将作为命令行或函数参数,或者与您的语言等效。

最短的代码胜出!


当您在C语言中表达含义时,您的含义是否与C语言中的含义完全相同,或者将%-inf舍入为0而不是0可以吗?
马蒂森(Maltysen)

@Maltysen:无论您使用哪种语言。
Trebuchette

3
输入的整数可以为负吗?
丹尼斯

第3点和第6点相互矛盾:在C语言和大多数语言中,整数除法舍入为零而不是取整。
彼得·泰勒

看到与此类似但又包含括号优先级的另一个挑战很有趣……
Joshpbarron

Answers:


6

Pyth- 24 23 22 20字节

@issacg节省了2个字节,@ orlp节省了1个字节!

与的基本情况一起使用reduce,0并检查'是否在检测字符串与int之间。

u.xsv++GbH&=bHG+\+QZ

无法在线工作,因为我使用完整的评估,出于安全原因,该评估已在线禁用。从标准输入中获取输入,例如:5, 8, 25, "*", 9, 6, 2, "-", 104, "/", 4, 7, "+", 6


通过从切换?.x,您可以节省2个字节,因为只有else块可以抛出异常,并且每次都会抛出异常。不过,您不能再使用K了。u.xsv++GbH&=bHG+\+QZ,特别是。
isaacg's

6

JavaScript(ES6)53

以数组为输入的函数。

在Firefox中运行代码段进行测试。

f=a=>a.map(t=>t<'0'?o=t:v=eval(v+o+t)|0,v=0,o='+')&&v

// TEST
out=x=>O.innerHTML=x;

input = [5,8,25,"*",9,6,2,"-",104,"/",4,7,"+",6,"%",14];
out(input.join(' ')+' -> '+f(input));

function go() {
  i=I.value.split(/ +/),out(I.value+' -> '+f(i))
}  
<pre id=O></pre>
Your test:<input id=I><button onclick='go()'>GO</button>


4

朱莉娅85 83字节

s->(o=0;p="+";for i=split(s) isdigit(i)?o=eval(parse("ifloor($o$p$i)")):(p=i)end;o)

这将创建一个未命名函数,该函数接受字符串作为输入并返回整数。

取消高尔夫:

function f(s::String)
    # Assign the starting output value o and operator p
    o = 0
    p = "+"

    # Split the input string into an array on spaces
    for i = split(s)
        if isdigit(i)
            # Assign o using string interpolation
            o = eval(parse("ifloor($o $p $i)"))
        else
            # Assign p to the new operator
            p = i
        end
    end
end

已修复问题,并通过Glen O节省了2个字节。


朱莉娅抱怨说,o is not defined当您尝试重新运行该功能时。它试图在Main中而不是在函数内部运行“ o = ifloor ...”函数(请参见github.com/JuliaLang/julia/issues/2386)。我可以建议s->(o=0;p="+";for i=split(s) isdigit(i)?o=eval(parse("ifloor($o$p$i)")):p=i;end;o)吗?
Glen O'9

@GlenO我不知道我是如何被抓住的。:/谢谢,固定。
Alex A.

4

elisp,101个字节

将参数作为带引号的列表传递:例如 (c '(5 5 * 10))

    (defun c(a)(let((f 0)(o '+))(dolist(x a)(if(not(integerp x))(setf o x)(setq f (eval(list o f x)))))f))

带有新行的版本:

    (defun c (a)
      (let ((f 0)
            (o '+))
        (dolist (x a)
          (if (not (integerp x))
              (setf o x) 
            (setq f (eval (list o f x)))))
        f))

4

CJam,24个字节

0'+ea+{_A,s&O{:O;}?S}%s~

这是一个完整的程序,将输入作为命令行参数读取。

要在CJam解释器(不支持命令行参数)中在线尝试代码,请替换ealS/以从模拟的STDIN中读取。

怎么运行的

0'+                       Push a 0 and the character '+'.
   ea                     Push the array of command-line arguments.
     +                    Prepend the character to the array.
      {             }%    For each element:
       _                    Push a copy.
        A,s                 Push "0123456789".
           &                Intersect the copy with the string of digits.
             {   }?         If the intersection is non-empty:
            O                 The element is a number. Push O.
              :O;             The element is an operator. Save it in O.
                   S        Push a space.
                      s~  Flatten the array of strings and evaluate it.

3

JavaScript,85个字节

r=0;o="+";prompt().split(" ").forEach(t=>+t+1?r=parseInt(eval(r+o+ +t)):o=t);alert(r)

为什么o+ +t呢?无论如何,您都在构建字符串,无需转换为数字。此外,.forEach在Code Golf中没有位置:使用.map
edc65

... and ~~代替parseInt(codegolf.stackexchange.com/a/2788/21348
edc65

prompt(o="+",r=0).split(" ").forEach(t=>+t+1?r=+eval(r+o+ +t):o=t);alert(r)-> 75个字​​节。
伊斯梅尔·米格尔

3

Lua,142个字节

function f(s)o="+"r=0 for c in s:gmatch"%S+" do if tonumber(c)~=nil then loadstring("r=r"..o..c)() else o=c end r=math.floor(r)end print(r)end

取消高尔夫:

function f(s)
    o="+" --original operator
    r=0 --return value
    for c in s:gmatch"%S+" do --split by spaces
        if tonumber(c)~=nil then --check if the current character is a number
            loadstring("r=r"..o..c)() --appends the current operator and current character ex "r=r+5" and then evaluates as another Lua script 
        else 
            o=c --if the character is not a number, it is the new operator
        end
        r=math.floor(r) --floor after each operation
    end 
    print(r) --print the result
end

3

Powershell,57个字节

$o="+"
$args|%{$r=iex "$r$o$_"
if(!$?){$o=$_}$r-=$r%1}
$r

松散

$operator="+"
$args | ForEach-Object
{
    $result = Invoke-Expression "$result $operator $_"
    if(!$?)
    {
        $operator=$_
    }
    $result -= $result % 1
}
$result

如果for-each中的隐式变量是运算符而不是数字,则Invoke-Expression(POSH's eval())将失败并且执行状态$?将为false。

在POSH楼笨重- $foo=[math]::floor($foo)$foo-=$foo%1是golfiest替代我能想到的。


真好 我通过假设一个字符串输入并在空格处解析它,然后if在数字上输入,从字面上读了一点,但是本质上是相同的。89字节 $o="+";$r=0;$args-split'\s+'|%{if($_-match'^\d+$'){$r=iex $r$o$_;$r-=$r%1}Else{$o=$_}};$r
AdmBorkBork 2015年

3

GNU Sed(带有eval扩展名,+ dc),102

(得分包括s + 1的s + 1。)

s/.*/0 + &p/
s/([-+/*%]) ([0-9]+)/\2 \1/g
:
s/([-+/*%] )([0-9]+ )([0-9]+)/\1\2\1\3/
t
s/.*/dc<<<'&'/e

将输入表达式转换为逆波兰表示法,然后用于dc对其求值。

测试输出:

$ sed -rf calclist.sed <<< '5 8 25 * 9 6 2 - 104 / 4 7 + 6 % 14'
8
$ 


2

Python 3-131字节 129字节 121字节 116字节

感谢Maltysen删除了两个字节,Beta Decay删除了8个字节,以及Steven Rumbalski删除了5个字节。

def f(x):
    a,b="+",0
    for i in x:
        if i in"+-*/%":a=i
        else:b=int(eval(str(b)+a+i))
    return b

我正在尝试寻找一种减少if语句长度的方法,但是就目前看来,这似乎已经尽力了。将输入作为列表。


您可以节省一些缩进字节并替换int//1
Maltysen

另外,为什么要在`if'中加括号?
马蒂森(Maltysen)

@ Maltysen哎呀,我忘了我不需要if语句中的括号。谢谢。我不认为将允许使用// 1,尽管我没有考虑使用它,因为它似乎留下了尾随的0(例如10.0),我认为这是不允许的。
2015年

我认为您in和引号之间不需要空格。
马蒂森(Maltysen)

您可以通过假定列表在函数参数中传递并摆脱来节省一些字节.split()
Beta Decay's

2

巴什69

set -f
for t in $*
do
((1${t}1>2))&&((r${o-+}=$t))||o=$t
done
echo $r

这仅适用于非负整数-是否可以,在问题中不清楚。


2

Groovy,79个字节

def f(x,a=0,b='+'){x.each{z->a=z=~/\d/?Eval.me(a+b+z)as int:a;b=z=~/\d/?b:z};a}

演示:

groovy> f([5,8,25,'*',9,6,2,'-',104,'/',4,7,'+',6,'%', 14])
Result: 8

取消高尔夫:

def f(x, a=0, b='+') {                                   
    x.each {z->
        a = z =~ /\d/ ? Eval.me(a+b+z) as int : a
        b = z =~ /\d/ ? b : z
    }
    a
}

1

gcc(带有警告)165(如果行结束计数为1)

#define A atoi(*a);break;case
o='+',s=0;main(c,a)char**a;{while(*++a)if(**a<48)o=**a;else switch(o){case'+':s+=A'-':s-=A'*':s*=A'/':s/=A'%':s%=A 0:;}printf("%d",s);}

但是,如果您使用mingw32进行编译,则需要通过以下编译来关闭globbing(请参阅https://www.cygwin.com/ml/cygwin/1999-11/msg00052.html):

gcc x.c C:\Applications\mingw32\i686-w64-mingw32\lib\CRT_noglob.o

1

Perl 5.10 +,52个字节

perl -E '$o="+";/\D/?$o=$_:eval"\$x=int\$x$o$_"for@ARGV;say$x'

演示:

$ perl -E '$o="+";/\D/?$o=$_:eval"\x=int\$x$o$_"for@ARGV;say$x' 5 8 25 \* 9 6 2 - 104 / 4 7 + 6 % 14
8

(请注意,*必须在我的shell中进行转义,因此不会将其解释为glob模式。)

取消高尔夫:

$o="+";                      # Start with addition
/\D/ ? $o=$_                 # If not a number, update the current operator
     : eval"\$x=int\$x$o$_"  # Otherwise, make a string like '$x=int$x+1' and eval it
for@ARGV;                    # Repeat for each item in the argument list
say$x                        # Print the result

1

C#,132165168字节

此功能假定输入有效。对于C#,这很困难,因为没有eval等效的方法。

谢谢edc65节省了33个字节!

为清楚起见缩进。

int C(string[]a){
    int o=1,r=0,n;
    foreach(var b in a)
        n=int.TryParse(b,out n)
            ?r=o<0?r%n
              :o<1?r*n
              :o<2?r+n
              :o<4?r-n
                  :r/n
            :o=b[0]-42;
    return r;
}

您可以删除大多数换行符。
Trebuchette

我没有计算任何换行符或无关紧要的空格。
Hand-E-Food

1
132使用?:->int C(string[]a){int o=1,r=0,n;foreach(var b in a)n=int.TryParse(b,out n)?r=o<0?r%n:o<1?r*n:o<3?r+n:o<5?r-n:r/n:o=b[0]-42;return r;}
edc65'9

1

Ruby,59个字节

a=0
o=?+
gets.split.map{|s|s=~/\d/?a=eval([a,s]*o):o=s}
p a

测试运行:

$ ruby calc.rb <<< "5 8 25 * 9 6 2 - 104 / 4 7 + 6 % 14"
8
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.