Sayıların ve operatörlerin listesi olarak hesap makinesi


20

Göreviniz tamsayı veya işleç olan bağımsız değişkenlerin bir listesini almak ve bunları şu şekilde ayrıştırmaktır:

  1. + Olarak başlayan geçerli bir operatör var.

  2. Bir operatör her bulunduğunda, mevcut operatör ona değişecektir.

  3. Olası işleçler şunlardır: "+", "-", "*", "/" ve "%", C ve çoğu dilde anlamlarına karşılık gelir.

  4. Tutulan ve 0'dan başlayan çalışan bir çözüm var.

  5. Bir tam sayı bulunduğunda, çözüm operatöre bağlı olarak numara ile değiştirilir; örneğin, operatör "/" ise çözüm sayıya bölünür.

  6. Bir işlem karışık bir sayıyla sonuçlanırsa (yani ondalık ile), bir tamsayıya geri döşenmelidir (yani ondalık kesilmelidir).

  7. Nihai çözümün çıktısını alın.

Örneğin:

Argümanlar 5 8 25 * 9 6 2 - 104 / 4 7 + 6 % 14şunlarla sonuçlanır:

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

Girişler komut satırı veya işlev bağımsız değişkenleri veya diliniz için eşdeğer olacaktır.

En kısa kod kazanır!


C'deki anlamlar derken C'deki gibi mi demek istersiniz yoksa %0 yerine -inf'e yuvarlanırsa sorun olmaz mı?
Maltysen

@Maltysen: Diliniz ne yaparsa yapın.
Trebuchette

3
Girdideki tamsayılar negatif olabilir mi?
Dennis

3 ve 6 nolu noktalar birbiriyle çelişmektedir: C ve birçok dilde, tamsayı bölümü döşeme yerine sıfıra yuvarlar.
Peter Taylor

Buna benzer başka bir zorluk görmek ilginç olurdu, ancak parantez önceliği de dahil ...
Joshpbarron

Yanıtlar:


6

Pyth - 24 23 22 20 bayt

@İssacg sayesinde 2 bayt ve @orlp sayesinde 1 bayt tasarruf etti!

Baz durumuna göre küçültme kullanır 0ve 'string vs int algılamak için repr olup olmadığını kontrol eder .

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

Güvenlik nedeniyle çevrimiçi olarak devre dışı bırakılan tam değerlendirmeyi kullandığım için çevrimiçi çalışmıyor. Gibi bir listede girdiyi standart girdiden Alır: 5, 8, 25, "*", 9, 6, 2, "-", 104, "/", 4, 7, "+", 6.


Sen geçiş yaparak 2 bayt kaydedebilirsiniz ?için .xsadece başka bir blok bir istisna, çünkü ve her zaman bunu yapacağız. KYine de kullanamazsın . u.xsv++GbH&=bHG+\+QZ, özellikle.
isaacg

6

JavaScript (ES6) 53

Bir diziyi girdi olarak alan bir işlev.

Test etmek için snippet'i Firefox'ta çalıştırın.

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 bayt

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

Bu, bir dizeyi girdi olarak kabul eden ve bir tamsayı döndüren adsız bir işlev oluşturur.

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

Glen O sayesinde sorun giderildi ve 2 bayt kaydedildi.


Julia o is not defined, fonksiyonu yeni çalıştırmaya çalıştığınızda şikayet ediyor . "O = ifloor ..." işlevini işlev içinde değil Ana'da çalıştırmaya çalışır (bkz . Github.com/JuliaLang/julia/issues/2386 ). Önerebilir miyim s->(o=0;p="+";for i=split(s) isdigit(i)?o=eval(parse("ifloor($o$p$i)")):p=i;end;o)?
Glen O

@GlenO Bunu nasıl yakalamadığımı bilmiyorum. : / Teşekkürler, düzeltildi.
Alex

4

elisp, 101 bayt

Bağımsız değişkenler tırnak içine alınmış bir liste olarak aktarıldığında: ör. (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))

Yeni satırlı sürüm:

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

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

Bu, girdiyi komut satırı bağımsız değişkenleri olarak okuyan tam bir programdır.

CJam yorumlayıcısında (komut satırı bağımsız değişkenlerini desteklemeyen) çevrimiçi kodu denemek için simüle edilmiş STDIN'den okumak için eaile değiştirin lS/.

Nasıl çalışır

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 bayt

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

neden o+ +t? yine de bir dize inşa ediyorsun, sayıya dönüştürmeye gerek yok. Dahası, .forEachCode Golf'te yeri yok: kullanım.map
edc65


prompt(o="+",r=0).split(" ").forEach(t=>+t+1?r=+eval(r+o+ +t):o=t);alert(r)-> 75 bayt.
Ismael Miguel

3

Lua, 142 bayt

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 bayt

$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

For-each içindeki örtük değişken sayı yerine bir işleçse, Çağırma-İfade (POSH'ler eval()) başarısız olur ve yürütme durumu $?yanlış olur.

POSH katında hantal - $foo=[math]::floor($foo)ve $foo-=$foo%1düşünebildiğim en golf alternatif oldu.


Güzel. Bir dize girdisi varsayarak ve boşluklarda ayrıştırarak, daha sonra ifrakamlara bakarak, ama aslında aynı şekilde biraz daha okudum . 89 Bayt $o="+";$r=0;$args-split'\s+'|%{if($_-match'^\d+$'){$r=iex $r$o$_;$r-=$r%1}Else{$o=$_}};$r
AdmBorkBork

3

GNU Sed (eval uzantısı ile, + dc), 102

(-R seçeneği sed için + 1 puan içerir.)

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

Girdi ifadesini cila gösterimini tersine çevirir ve sonra dcdeğerlendirmek için kullanır .

Test çıktısı:

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

2

CJam, 34 bayt

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

Çevrimiçi deneyin

Bunun oldukça makul olacağını düşündüm. Ama en azından bir an için en kısa CJam cevabı olacak kadar hızlı gönderemedim. :(


2

Python 3-131 bayt 129 bayt 121 bayt 116 Bayt

İki baytını tıraş ettiği için Maltysen'e, 8'i tıraş ettiği için Beta Çürümesine ve 5'i tıraş ettiği için Steven Rumbalski'ye teşekkürler.

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 ifadesinin uzunluğunu azaltmak için bir yol bulmaya çalışıyorum, ama şimdilik bu alabilirim gibi golf gibi görünüyor. Girişi liste olarak alır.


Eğer girinti bazı bayt kaydetmek ve değiştirilmesi olabilir intile//1
Maltysen

ayrıca, neden `` eğer?
Maltysen

@ Maltysen whoops, if deyiminde parantezlere ihtiyacım olmadığını unuttum. Teşekkürler. // 1 kullanmaya izin verileceğini düşünmüyorum, ancak kullanmayı düşünmüyorum, izin verildiğini düşünmediğim bir iz 0 (örneğin 10.0) bıraktığı gibi.
cole

inve alıntı arasındaki boşluğa ihtiyacınız olduğunu düşünmüyorum .
Maltysen

Listenin işlev argümanlarında geçtiğini varsayarak ve kurtularak bazı baytlar kaydedebilirsiniz .split().
Beta Çürümesi

2

Baş, 69

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

Bu sadece negatif olmayan tamsayılarla çalışır - bu sorun olup olmadığı soruda net değildir.


2

Groovy, 79 bayt

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}

Demo:

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 (uyarılarla) 165 (satır sonu 1 olarak sayılırsa)

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

Ancak mingw32 ile derliyorsanız, bu şekilde derleyerek globbing'i kapatmanız gerekir (bkz. 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 bayt

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

Demo:

$ 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

( *Kabuğumdan kaçması gerektiğini unutmayın, böylece bir glob deseni olarak yorumlanmaz.)

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 #, 132166168 bayt

Bu işlev girişin geçerli olduğunu varsayar. evalEşdeğer olmadığı göz önüne alındığında bu C # için zor .

Teşekkürler edc6533 bayt için !

Netlik için girintili.

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

Yeni satırların çoğunu çıkarabilirsiniz.
Trebuchette

Hiçbir satırsonu veya önemsiz boşluk saymadım.
El-E-Yiyecek

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 bayt

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

Test sürüşü:

$ ruby calc.rb <<< "5 8 25 * 9 6 2 - 104 / 4 7 + 6 % 14"
8
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.