숫자와 연산자의 목록으로 계산기


20

당신의 작업은 정수 또는 연산자 인 인수 목록을 가져 와서 다음과 같이 구문 분석합니다.

  1. 현재 연산자가 +로 시작합니다.

  2. 운영자를 찾을 때마다 현재 운영자가 운영자로 변경됩니다.

  3. 가능한 연산자는 "+", "-", "*", "/"및 "%"이며 C와 대부분의 언어에서 의미에 해당합니다.

  4. 0에서 시작하는 실행중인 솔루션이 있습니다.

  5. 정수가 발견 될 때마다 솔루션은 연산자에 따라 숫자로 수정됩니다. 예를 들어 연산자가 "/"이면 솔루션은 숫자로 나뉩니다.

  6. 연산 결과 혼합 된 숫자 (즉, 10 진수)가 나오면 정수로 다시 바닥되어야합니다 (즉, 10 진수는 잘 려야합니다).

  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의 의미와 정확히 일치 %합니까? 아니면 0 대신 -inf로 반올림 해도 괜찮 습니까?
Maltysen

@ Maltysen : 당신의 언어가 무엇을 하든지.
Trebuchette

3
입력의 정수가 음수 일 수 있습니까?
데니스

점 3과 6은 서로 모순됩니다. C와 대부분의 언어에서 정수 나누기는 바닥이 아니라 0으로 반올림합니다.
피터 테일러

괄호 우선 순위를 포함하여 이와 유사한 또 다른 도전을 보는 것이 흥미로울 것입니다.
Joshpbarron

답변:


6

Pyth- 24 23 22 20 바이트

@issacg 덕분에 2 바이트가 절약되고 @orlp 덕분에 1 바이트가 절약되었습니다!

문자열 대 int를 감지하기 위해 recase에 0있는지 점검 하고 base case와 함께 reduce를 사용합니다 '.

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

보안상의 이유로 온라인으로 비활성화 된 전체 평가를 사용하기 때문에 온라인으로 작동하지 않습니다. stdin에서 다음과 같은 목록으로 입력을받습니다 5, 8, 25, "*", 9, 6, 2, "-", 104, "/", 4, 7, "+", 6.


당신은에서 전환하여 2 바이트를 저장할 수 ?.x단지 다른 블록이 예외를 던질 수 있기 때문에, 그것은 때마다 있도록 할 것입니다. K더 이상 사용할 수 없습니다 . u.xsv++GbH&=bHG+\+QZ구체적으로.
isaacg

6

자바 스크립트 (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 바이트가 절약되었습니다.


Julia 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

@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

자바 스크립트, 85 바이트

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

o+ +t? 어쨌든 문자열을 작성 중이므로 숫자로 변환 할 필요가 없습니다. 또한, .forEach사용 : 더 코드 골프의 장소가 없습니다.map
edc65

... 및 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 바이트
Ismael Miguel

3

루아, 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

파워 쉘, 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의 내재 된 변수가 숫자가 아닌 연산자 인 경우, POSH (Invoke-Expression 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

3

GNU Sed (eval 확장명, + dc), 102

(-s 옵션에 sed에 대한 점수는 +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 바이트

2 바이트를 면도 한 Maltysen, 8을 면도하는 Beta Decay, 5를 면도하는 Steven Rumbalski에게 감사드립니다.

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'의 parens입니까?
Maltysen

@ Maltysen whoops, 나는 if 문에 괄호가 필요하지 않은 것을 잊었다. 감사. // 1을 사용하는 것은 허용되지 않는다고 생각하지만 // 1을 사용하는 것은 허용되지 않는다고 생각합니다.
cole

나는 당신 in이 따옴표 사이에 그 공간이 필요하다고 생각하지 않습니다 .
Maltysen

목록이 함수 인수에 전달되고를 제거하여 일부 바이트를 절약 할 수 .split()있습니다.
Beta Decay

2

배쉬, 69

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

이것은 음이 아닌 정수로만 작동합니다-이것이 괜찮은지에 대해서는 질문에서 명확하지 않습니다.


2

그루비, 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

(참고 * 내 쉘에서 이스케이프 처리해야하므로 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;}
using-

1

루비, 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.