数字と演算子のリストとしての計算機


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での意味とまったく同じ%ですか、それとも0ではなく-infに向かって丸めても大丈夫ですか?
マルティセン

@Maltysen:あなたの言語が何であれ。
トレブシェット

3
入力の整数は負の値にできますか?
デニス

ポイント3と6は互いに矛盾しています。Cおよびほとんどの言語では、整数の除算はフローリングではなくゼロに丸められます。
ピーターテイラー

これに似た別の課題を見るのは面白いでしょうが、括弧の優先順位を含めて...
ジョシュバロン

回答:


6

Pyth- 24 23 22 20バイト

@issacgのおかげで2バイト、@ orlpのおかげで1バイト節約されました!

文字列とintを検出する0ため'に、reprのベースケースでreduceを使用してチェックします。

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

セキュリティ上の理由でオンラインで無効になっているevalを使用しているため、オンラインでは機能しません。リスト内の標準入力から入力を取得します5, 8, 25, "*", 9, 6, 2, "-", 104, "/", 4, 7, "+", 6


elseブロックのみが例外をスローでき、毎回例外をスローするため、から?に切り替えることで2バイトを節約できます.xKただし、もう使用できません。u.xsv++GbH&=bHG+\+QZ、具体的には。
isaacg

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

グレン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)
グレンO

@GlenOどうしてそれをつかまえなかったのかわかりません。:/ありがとう、修正しました。
アレックス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コードゴルフには場所がありません。使用.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バイト。
イスマエルミゲル

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、私が考えることができた最もゴルフの代わりでした。


いいね 文字列の入力を想定し、スペースで解析して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

(スコアには、sedの-rオプションの+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

CJam、34バイト

'+0lS/{"+-*/%"1$#){@;\}{i2$~}?}/\;

オンラインで試す

これはかなり合理的だと思いました。しかし、少なくとも一瞬、CJamの最短回答になるほど投稿するのに十分な速さではありませんでした。:(


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の括弧は?
マルティセン

@ Maltysenおっと、ifステートメントに括弧が必要ないことを忘れていました。ありがとう。// 1の使用が許可されるとは思わないが、使用するとは思わなかったが、許可されないと思われる末尾の0(10.0など)が残るようだ。
コール

in引用符とその間にスペースが必要だとは思わない。
マルティセン

リストが関数の引数で渡されると仮定し、を取り除くことで、いくつかのバイトを節約できます.split()
ベータ崩壊

2

バッシュ、69

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

これは、負でない整数でのみ機能します-これがOKかどうかの質問では明確ではありません。


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でコンパイルする場合は、次のようにコンパイルすることにより、グロビングを無効にする必要があります(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

(ご了承ください *これは、シェルでエスケープする必要があるため、グロブパターンとして解釈されないことにて。)

ゴルフをしていない:

$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#、132 165 168バイト

この関数は、入力が有効であることを前提としています。eval同等のものがないことを考えると、これはC#にとって困難です。

33バイトを節約してくれたedc65に感謝します!

わかりやすくするためにインデントされています。

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;
}

ほとんどの改行を削除できます。
トレブシェット

改行や重要でない空白は数えていません。
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

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.