เครื่องคิดเลขเป็นรายการตัวเลขและตัวดำเนินการ


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?
Maltysen

@Maltysen: ไม่ว่าภาษาของคุณจะเป็นเช่นไร
Trebuchette

3
จำนวนเต็มจากอินพุตสามารถเป็นค่าลบได้หรือไม่?
Dennis

คะแนน 3 และ 6 ขัดแย้งกัน: ในภาษา C และภาษาส่วนใหญ่การหารจำนวนเต็มจะปัดเศษเป็นศูนย์แทนที่จะปูพื้น
Peter Taylor

มันจะน่าสนใจเพื่อดูความท้าทายอื่นที่คล้ายกันนี้ แต่รวมทั้งวงเล็บความสำคัญ ...
Joshpbarron

คำตอบ:


6

Pyth - 24 23 22 20 ไบต์

บันทึก 2 ไบต์ขอบคุณ @issacg และ 1 ขอบคุณ @orlp!

ใช้การลดด้วยตัวพิมพ์ใหญ่ของ0และตรวจสอบ'ว่ามีการตอบโต้เพื่อตรวจจับสตริงเทียบกับ int

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

ไม่ทำงานออนไลน์เพราะใช้ eval แบบเต็มซึ่งถูกปิดการใช้งานออนไลน์ด้วยเหตุผลด้านความปลอดภัย นำข้อมูลจาก stdin 5, 8, 25, "*", 9, 6, 2, "-", 104, "/", 4, 7, "+", 6ในรายการเป็นเช่น:


คุณสามารถบันทึก 2 ไบต์โดยสลับจาก?เป็น.xเพราะเฉพาะบล็อกอื่นเท่านั้นที่สามารถโยนข้อยกเว้นได้และจะทำทุกครั้ง อย่างไรก็ตามคุณไม่สามารถใช้งานได้Kอีกต่อไป 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

Julia, 85 83 ไบต์

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

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่มีชื่อที่ยอมรับสตริงเป็นอินพุตและส่งกลับจำนวนเต็ม

Ungolfed:

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

แก้ไขปัญหาและบันทึก 2 ไบต์ด้วย Glen O


จูเลียบ่นว่าo is not definedเมื่อคุณพยายามเรียกใช้ฟังก์ชั่นใหม่ มันพยายามเรียกใช้ฟังก์ชัน "o = ifloor ... " ใน Main ไม่ใช่ภายในฟังก์ชัน (ดูที่นี่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 ฉันไม่ทราบว่าฉันไม่ได้จับที่ : / ขอบคุณคงที่
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 (ซึ่งไม่สนับสนุนอาร์กิวเมนต์บรรทัดคำสั่ง) ให้แทนที่eaด้วยlS/เพื่ออ่านจาก 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

... และ ~~ แทน 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

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

Ungolfed:

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

ungolfed;

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

หากตัวแปร implicit ใน for-each เป็นโอเปอเรเตอร์แทนที่จะเป็นตัวเลข Invoke-Expression (POSH's eval()) จะล้มเหลวและสถานะการดำเนินการ$?จะเป็นเท็จ

ชั้นใน POSH นั้นไม่มั่นคง- $foo=[math]::floor($foo)และ$foo-=$foo%1เป็นทางเลือกที่กอล์ฟที่สุดที่ฉันคิดได้


ดี ฉันอ่านมันอีกเล็กน้อยตามตัวอักษรโดยสมมติว่าอินพุตสตริงและแยกวิเคราะห์ในช่องว่างจากนั้นifอิงกับตัวเลข แต่โดยพื้นฐานแล้วก็เหมือนกัน 89 Bytes $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

(คะแนนรวม +1 สำหรับตัวเลือก -r เพื่อ sed)

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$~}?}/\;

ลองออนไลน์

ฉันคิดว่ามันจะสมเหตุสมผล แต่ฉันก็ยังไม่เร็วพอที่จะโพสต์ให้เป็นคำตอบที่สั้นที่สุดอย่างน้อยสักครู่ :(


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

ยังทำไม parens ใน `ถ้า?
Maltysen

@ Maltysen อ๊ะฉันลืมฉันไม่ต้องการวงเล็บในคำสั่ง if ขอบคุณ ฉันไม่คิดว่าการใช้ // 1 จะได้รับอนุญาต แต่ฉันไม่คิดว่าจะใช้เพราะดูเหมือนว่าจะปล่อย 0 ต่อท้าย (เช่น 10.0) ซึ่งฉันคิดว่าไม่ได้รับอนุญาต
โคล

ฉันไม่คิดว่าคุณต้องการช่องว่างระหว่างinและกับคำพูด
Maltysen

.split()คุณสามารถประหยัดไบต์บางส่วนโดยการสมมติว่ารายการที่ถูกส่งผ่านในการขัดแย้งฟังก์ชั่นและการกำจัด
Beta Decay


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

Ungolfed:

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)

Ungolfed:

$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ไบต์

ฟังก์ชั่นนี้ถือว่าอินพุตถูกต้อง สิ่งนี้ยากสำหรับ 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

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.