Một máy tính như một danh sách các số và toán tử


20

Nhiệm vụ của bạn là lấy một danh sách các đối số là số nguyên hoặc toán tử và phân tích chúng như vậy:

  1. Có một toán tử hiện tại, bắt đầu là +.

  2. Mỗi khi một toán tử được tìm thấy, toán tử hiện tại sẽ thay đổi thành nó.

  3. Các toán tử có thể là: "+", "-", "*", "/" và "%", tương ứng với ý nghĩa của chúng trong C và hầu hết các ngôn ngữ.

  4. Có một giải pháp đang chạy, bắt đầu từ 0.

  5. Mỗi lần tìm thấy một số nguyên, giải pháp được sửa đổi theo số lượng tùy thuộc vào toán tử; ví dụ: nếu toán tử là "/" thì giải pháp được chia cho số.

  6. Nếu một hoạt động sẽ dẫn đến một số hỗn hợp (tức là với một số thập phân) thì nó phải được đưa trở lại một số nguyên (tức là số thập phân phải được cắt nhỏ).

  7. Đưa ra giải pháp cuối cùng.

Ví dụ:

Các đối số 5 8 25 * 9 6 2 - 104 / 4 7 + 6 % 14sẽ dẫn đến:

  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 đầu vào sẽ là đối số dòng lệnh hoặc hàm hoặc tương đương với ngôn ngữ của bạn.

Mã ngắn nhất sẽ thắng!


Khi bạn nói ý nghĩa trong C, bạn có nghĩa chính xác như họ làm trong C, hoặc có ổn không nếu làm %tròn theo hướng -inf thay vì 0?
Maltysen

@Maltysen: Dù ngôn ngữ của bạn là gì.
Trebuchette

3
Các số nguyên từ đầu vào có thể âm?
Dennis

Các điểm 3 và 6 trái ngược nhau: trong C và hầu hết các ngôn ngữ, phép chia số nguyên làm tròn về 0 thay vì xếp tầng.
Peter Taylor

Thật thú vị khi thấy một thử thách khác tương tự như thế này, nhưng bao gồm cả ưu tiên dấu ngoặc đơn ...
Joshpbarron

Câu trả lời:


6

Pyth - 24 23 22 20 byte

2 byte được lưu nhờ vào @issacg và 1 nhờ vào @orlp!

Sử dụng giảm với trường hợp cơ sở 0và kiểm tra xem có 'phải là repr để phát hiện chuỗi so với int.

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

Không hoạt động trực tuyến vì tôi sử dụng eval đầy đủ bị vô hiệu hóa trực tuyến vì lý do bảo mật. Lấy đầu vào từ stdin trong một danh sách như vậy : 5, 8, 25, "*", 9, 6, 2, "-", 104, "/", 4, 7, "+", 6.


Bạn có thể lưu 2 byte bằng cách chuyển từ ?sang .x, bởi vì chỉ có khối khác có thể ném ngoại lệ và nó sẽ làm như vậy mỗi lần. Bạn không thể sử dụng K, mặc dù. u.xsv++GbH&=bHG+\+QZ, đặc biệt.
isaacg

6

JavaScript (ES6) 53

Một hàm lấy một mảng làm đầu vào.

Chạy đoạn trích trong Firefox để kiểm tra.

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

Julia, 85 83 byte

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

Điều này tạo ra một hàm không tên chấp nhận một chuỗi làm đầu vào và trả về một số nguyên.

Ung dung:

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

Đã sửa lỗi và lưu 2 byte nhờ Glen O.


Julia phàn nàn rằng o is not definedkhi bạn cố gắng chạy chức năng mới. Nó cố gắng chạy chức năng "o = ifloor ..." trong Main, chứ không phải bên trong chức năng (xem tại đây github.com/JuliaLang/julia/issues/2386 ). Tôi có thể đề nghị s->(o=0;p="+";for i=split(s) isdigit(i)?o=eval(parse("ifloor($o$p$i)")):p=i;end;o)?
Glen O

@GlenO Tôi không biết làm thế nào tôi không nắm bắt được điều đó. : / Cảm ơn, đã sửa.
Alex A.

4

elisp, 101 byte

Với các đối số được truyền dưới dạng danh sách được trích dẫn: vd (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))

Phiên bản với các dòng mới:

    (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 byte

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

Đây là một chương trình đầy đủ đọc đầu vào dưới dạng đối số dòng lệnh.

Để thử mã trực tuyến trong trình thông dịch CJam (không hỗ trợ đối số dòng lệnh), hãy thay thế eabằng lS/cách đọc từ STDIN mô phỏng.

Làm thế nào nó hoạt động

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 byte

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

tại sao o+ +t? dù sao bạn cũng đang xây dựng một chuỗi, không cần phải chuyển đổi thành số. Hơn nữa, .forEachkhông có chỗ trong Code Golf: sử dụng.map
edc65

... và ~ ~ thay vì 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 byte.
Ismael Miguel

3

Lua, 142 byte

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

Ung dung:

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 byte

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

vô đạo đức;

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

Nếu biến ẩn trong for-every là toán tử chứ không phải số, Invoke-Expression (POSH's eval()) sẽ thất bại và trạng thái thực thi $?sẽ là sai.

Sàn trong POSH là khó sử dụng - $foo=[math]::floor($foo)$foo-=$foo%1là giải pháp thay thế golf nhất mà tôi có thể nghĩ ra.


Tốt đẹp. Tôi đọc nó nhiều hơn một chút theo nghĩa đen bằng cách giả sử một đầu vào chuỗi và phân tích cú pháp trên các khoảng trắng, sau đó nhập ifvào các chữ số, nhưng về cơ bản là giống nhau. 89 Byte $o="+";$r=0;$args-split'\s+'|%{if($_-match'^\d+$'){$r=iex $r$o$_;$r-=$r%1}Else{$o=$_}};$r
admBorkBork

3

GNU Sed (với phần mở rộng eval, + dc), 102

(Điểm bao gồm +1 cho tùy chọn -r để sed.)

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

Chuyển đổi biểu thức đầu vào thành ký hiệu đánh bóng ngược, và sau đó sử dụng dcđể đánh giá nó.

Đầu ra thử nghiệm:

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

2

CJam, 34 byte

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

Dùng thử trực tuyến

Tôi nghĩ rằng điều này sẽ khá hợp lý. Nhưng tôi không đủ nhanh để đăng nó thành câu trả lời ngắn nhất của CJam ít nhất là trong một khoảnh khắc. :


2

Python 3 - 131 byte 129 byte 121 byte 116 Byte

Cảm ơn Maltysen đã cạo sạch hai byte, Beta Decay để cạo 8 và Steven Rumbalski để cạo 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

Tôi đang cố gắng tìm ra một cách để giảm độ dài của câu lệnh if, nhưng bây giờ điều này có vẻ như là chơi golf như tôi có thể có được nó. Lấy đầu vào như một danh sách.


bạn có thể lưu một số byte khi thụt lề và thay thế intbằng//1
Maltysen

Ngoài ra, tại sao các parens trong `nếu?
Maltysen

@ Maltysen rất tiếc, tôi quên tôi không cần dấu ngoặc trong câu lệnh if. Cảm ơn. Tôi không nghĩ rằng việc sử dụng // 1 sẽ được cho phép, mặc dù tôi không nghĩ sẽ sử dụng nó, vì nó dường như để lại dấu 0 (ví dụ 10.0) mà tôi không nghĩ là được phép.
cole

Tôi không nghĩ rằng bạn cần khoảng trống giữa invà trích dẫn.
Maltysen

Bạn có thể lưu một số byte bằng cách giả sử rằng danh sách đó được truyền vào trong các đối số hàm và loại bỏ .split().
Beta Decay

2

Bash, 69

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

Điều này chỉ hoạt động với các số nguyên không âm - nó không rõ ràng trong câu hỏi nếu điều này là ok hay không.


2

Groovy, 79 byte

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}

Bản giới thiệu:

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

Ung dung:

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 (có cảnh báo) 165 (nếu dòng kết thúc được tính là 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);}

Nhưng nếu bạn đang biên dịch nó với mingw32, bạn cần tắt tính năng toàn cầu (xem https://www.cygwin.com/ml/cygwin/1999-11/msg00052.html ) bằng cách biên dịch như thế này:

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

1

Perl 5.10+, 52 byte

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

Bản giới thiệu:

$ 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

(Lưu ý rằng *phải được thoát trong vỏ của tôi để nó không được hiểu là mô hình toàn cầu.)

Ung dung:

$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 byte

Hàm này giả sử đầu vào là hợp lệ. Điều này là khó khăn cho C # do không có evaltương đương.

Cảm ơn edc65 đã lưu 33 byte!

Ấn định cho rõ ràng.

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

Bạn có thể lấy ra hầu hết các dòng mới.
Trebuchette

Tôi đã không đếm bất kỳ dòng mới hoặc khoảng trắng không đáng kể.
Thực phẩm điện tử cầm tay

1
132 sử dụng ?:->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

Ruby, 59 byte

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

Chạy thử nghiệm:

$ ruby calc.rb <<< "5 8 25 * 9 6 2 - 104 / 4 7 + 6 % 14"
8
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.