Ters Lehçe gösterimi


41

Ters Lehçe yazımında yazılmış bir dize değerlendirmeli ve sonuç çıktısı almalısınız .

Program bir girişi kabul etmeli ve çıkışı iade etmelidir. Giriş / çıkış alacak fonksiyonları olmayan programlama dilleri için readLine / print gibi fonksiyonlar üstlenebilir.

Programda herhangi bir "eval" kullanmanıza izin verilmez.

Sayılar ve operatörler bir veya daha fazla boşlukla ayrılır .

En azından +, -, * ve / operatörleri desteklemelisiniz.

Negatif sayılara (örneğin, -4aynı şey değil 0 4 -) ve kayan nokta sayılarına destek eklemeniz gerekir .

Girişin geçerli olduğunu ve yukarıdaki kuralları takip ettiğini varsayabilirsiniz.


Test Kılıfları

Giriş:

-4 5 +

Çıktı:

1

Giriş:

5 2 /

Çıktı:

2.5

Giriş:

5 2.5 /

Çıktı:

2

Giriş:

5 1 2 + 4 * 3 - +

Çıktı:

14

Giriş:

4 2 5 * + 1 3 2 * + /

Çıktı:

2

8
Aksi GolfScript çözümü 1 karakter, hiçbir eval izin yazık: ~. :-P
Chris Jester-Young,

5
Bu yüzden izin verilmiyor: - P, StackOverflow'taki bu soru dc ile 4 karakterli bir cevap aldı.

1
@SHiNKiROU: evalNumaraları ayrıştırmak için hangi dili kullanmanızı gerektirir ? Kulağa çok bozuk geliyor. (GolfScript, bildiğim kadarıyla böyle bir dil. Sanırım onun da kırık olduğunu düşünüyorum.)
Chris Jester-Young

3
-4 nasıl 0 4 - ile aynı değildir?
Keith Randall

1
Bence sadece dizeleri sayılara dönüştürmek için olsaydı, değerlendirmenin iyi olması gerektiğini düşünüyorum. Örneğin. python eval(s)içinde daha iyidirfloat(s)
gnibbler

Yanıtlar:


15

Yakut - 95 77 karakter

a=[]
gets.split.each{|b|a<<(b=~/\d/?b.to_f: (j,k=a.pop 2;j.send b,k))}
p a[0]

Stdin'de girdi alır.

Test kodu

[
  "-4 5 +",
  "5 2 /",
  "5 2.5 /",
  "5 1 2 + 4 * 3 - +",
  "4 2 5 * + 1 3 2 * + /",
  "12 8 3 * 6 / - 2 + -20.5 "
].each do |test|
  puts "[#{test}] gives #{`echo '#{test}' | ruby golf-polish.rb`}"
end

verir

[-4 5 +] gives 1.0
[5 2 /] gives 2.5
[5 2.5 /] gives 2.0
[5 1 2 + 4 * 3 - +] gives 14.0
[4 2 5 * + 1 3 2 * + /] gives 2.0
[12 8 3 * 6 / - 2 + -20.5 ] gives 10.0

C versiyonundan farklı olarak, bu girilen değere eklenmiş sayılar varsa, son geçerli sonucu verir.


1
Her karakter yerine haritayı kullanarak bir karakteri tıraş edebilirsiniz
addison

10

Python - 124 karakter

s=[1,1]
for i in raw_input().split():b,a=map(float,s[:2]);s[:2]=[[a+b],[a-b],[a*b],[a/b],[i,b,a]]["+-*/".find(i)]
print s[0]

Python - 133 karakter

s=[1,1]
for i in raw_input().split():b,a=map(float,s[:2]);s={'+':[a+b],'-':[a-b],'*':[a*b],'/':[a/b]}.get(i,[i,b,a])+s[2:]
print s[0]

1
Yığın manipülasyonunu seviyorum.
Alexandru

2
Sen olamaz 0... ikinci işlenen olarak
JBernardo

2
[a/b]b and[a/b]İkinci işlenen olarak 0 alabilmeniz için değiştirilmelidir .
flornquake

10

Şema, 162 karakter

(Netlik için eklenen satır sonları - tümü isteğe bağlıdır.)

(let l((s'()))(let((t(read)))(cond((number? t)(l`(,t,@s)))((assq t
`((+,+)(-,-)(*,*)(/,/)))=>(lambda(a)(l`(,((cadr a)(cadr s)(car s))
,@(cddr s)))))(else(car s)))))

Tamamen biçimlendirilmiş (ungolfed) sürüm:

(let loop ((stack '()))
  (let ((token (read)))
    (cond ((number? token) (loop `(,token ,@stack)))
          ((assq token `((+ ,+) (- ,-) (* ,*) (/ ,/)))
           => (lambda (ass) (loop `(,((cadr ass) (cadr stack) (car stack))
                                    ,@(cddr stack)))))
          (else (car stack)))))

Seçilmiş yorum

`(,foo ,@bar)aynıdır (cons foo bar)(yani, (etkin ) önceden fooplanlanmış olan yeni bir liste döndürür bar), tüm boşlukları sıkıştırırsanız bir karakter daha kısa olması dışında.

Böylece, yineleme maddelerini gözlerinizde daha kolay (loop (cons token stack))ve (loop (cons ((cadr ass) (cadr stack) (car stack)) (cddr stack)))eğer varsa okuyabilirsiniz .

`((+ ,+) (- ,-) (* ,*) (/ ,/))Diğer operatörlerle aynı şekilde , prosedürle eşleştirilmiş sembolü ile bir ilişkilendirme listesi oluşturur . Bu nedenle basit bir sembol arama tablosu (çıplak kelimeler semboller içindedir, bu yüzden başka işlem gerekmemektedir). Dernek listelerinde O (n) araması vardır ve bu nedenle burada olduğu gibi sadece kısa listeler için uygundur. :-P+ +(read)token

† Bu teknik olarak doğru değildir, ancak Lisp olmayan programcılar için, yeterince haklı bir fikir edinir.


Bunu okuyabilir misin? Ciddi anlamda?

1
@ M28: ungolfed versiyonu, evet. Programda yarı düzenli olarak program yapıyorum (gerçek, ciddi programlar için).
Chris Jester-Young,

Ne yazık ki, Scheme ayrıntılı bir dildir ve golf oynamak için meşhurca zordur. Bu yüzden bazı Perl gönderimlerinin bunu yendiğini görünce şaşırmam.
Chris Jester-Young,

7
Golf versiyonundaki dört suratı seviyorum.
34'te yapılacak

2
lambda (ass)Değişken isim seçimi için +1: P
Downgoat

7

c - 424 gerekli karakter

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define O(X) g=o();g=o() X g;u(g);break;
char*p=NULL,*b;size_t a,n=0;float g,s[99];float o(){return s[--n];};
void u(float v){s[n++]=v;};int main(){getdelim(&p,&a,EOF,stdin);for(;;){
b=strsep(&p," \n\t");if(3>p-b){if(*b>='0'&&*b<='9')goto n;switch(*b){case 0:
case EOF:printf("%f\n",o());return 0;case'+':O(+)case'-':O(-)case'*':O(*)
case'/':O(/)}}else n:u(atof(b));}}

Stdio.h dosyasına dahil edilecek yeni bir libc dosyanız olduğunu varsayar getdelim. Yaklaşım dümdüzdür, tüm girdi bir tampon belleğe okunur, daha sonra strsepher birini sınıflamak için uzunluk ve başlangıç ​​karakteri ile belirtilir ve kullanılır. Kötü girişe karşı koruma yoktur. "+ - * / + - ..." beslediğinizde, hata kesilinceye kadar "altındaki" bellekten bir şeyler çıkar. Tüm operatör olmayan kullanıcılar, atofsayılar gibi görünmüyorsa sıfır değeri anlamına gelen değişkenler olarak yorumlanır .

Okunabilir ve yorumladı:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *p=NULL,*b;
size_t a,n=0;
float g,s[99];
float o(){        /* pOp */
  //printf("\tpoping '%f'\n",s[n-1]);
  return s[--n];
};
void u(float v){  /* pUsh */
  //printf("\tpushing '%f'\n",v);
  s[n++]=v;
};
int main(){
  getdelim(&p,&a,EOF,stdin); /* get all the input */
  for(;;){
    b=strsep(&p," \n\t"); /* now *b though *(p-1) is a token and p
                 points at the rest of the input */
    if(3>p-b){
      if (*b>='0'&&*b<='9') goto n;
      //printf("Got 1 char token '%c'\n",*b);
      switch (*b) {
      case 0:
      case EOF: printf("%f\n",o()); return 0;
      case '+': g=o(); g=o()+g; u(g); break;
      case '-': g=o(); g=o()-g; u(g); break;
      case '*': g=o(); g=o()*g; u(g); break;
      case '/': g=o(); g=o()/g; u(g); break;
    /* all other cases viciously ignored */
      } 
    } else { n:
      //printf("Got token '%s' (%f)\n",b,atof(b));
      u(atof(b));
    }
  }
}

Doğrulama:

 $ gcc -c99 rpn_golf.c 
 $ wc rpn_golf.c
  9  34 433 rpn_golf.c
 $ echo -4 5 + | ./a.out
1.000000
 $ echo 5 2 / | ./a.out
2.500000
 $ echo 5 2.5 / | ./a.out
2.000000

Heh! *İçinde bir şeyler alıntı yapmalıyım ...

 $ echo "5 1 2 + 4 * 3 - +" | ./a.out
14.000000
 $ echo "4 2 5 * + 1 3 2 * + /" | ./a.out
2.000000

ve kendi sınav davam

 $ echo "12 8 3 * 6 / - 2 + -20.5 " | ./a.out
-20.500000

caseBir makro ile değiştirerek bazı karakterleri koruyabilirsiniz .
FUZxxl

7

Haskell (155)

f#(a:b:c)=b`f`a:c
(s:_)![]=print s
s!("+":v)=(+)#s!v
s!("-":v)=(-)#s!v
s!("*":v)=(*)#s!v
s!("/":v)=(/)#s!v
s!(n:v)=(read n:s)!v
main=getLine>>=([]!).words

"(S: _)! [] = S" - "(s: _)! [] = Baskı s" ve "main = getLine >> = putStrLn.show. ([] 'U değiştirerek 9 karakterin kaldırılmasını sağlayabilirsiniz. ) .words "to" main = getLine >> = ([]!). words "
19:13

Ve sonra bir satırlık case-deyimi kullanarak diğer birkaç karakteri daha kaldırın.
Fors

s!(n:v)=case n of{"+"->(+)#s;"-"->(-)#s;"*"->(*)#s;"/"->(/)#s;_->(read n:s)}!v14 karakter kaydederdi.
Fors

7

MATLAB - 158 , 147

C=strsplit(input('','s'));D=str2double(C);q=[];for i=1:numel(D),if isnan(D(i)),f=str2func(C{i});q=[f(q(2),q(1)) q(3:end)];else q=[D(i) q];end,end,q

(giriş kullanıcı girişinden okunur, çıktı yazdırılır).


Aşağıda belirtilen ve yorumlanan kod, hemen hemen (ifadelerin geçerli olduğu varsayımıyla) açıklanan postfix algoritmasını uygular :

C = strsplit(input('','s'));         % prompt user for input and split string by spaces
D = str2double(C);                   % convert to numbers, non-numeric are set to NaN
q = [];                              % initialize stack (array)
for i=1:numel(D)                     % for each value
    if isnan(D(i))                   % if it is an operator
        f = str2func(C{i});          % convert op to a function
        q = [f(q(2),q(1)) q(3:end)]; % pop top two values, apply op and push result
    else
        q = [D(i) q];                % else push value on stack
    end
end
q                                    % show result

Bonus:

Yukarıdaki kodda, biz operatörler her zaman ikili olduğunu varsayıyorum ( +, -, *, /). nargin(f)İşlenenin / işlevin gerektirdiği argüman sayısını belirlemek için kullanarak genelleştirebiliriz ve isteklerdeki doğru miktarda değeri uygun bir şekilde şu şekilde yazabiliriz:

f = str2func(C{i});
n = nargin(f);
args = num2cell(q(n:-1:1));
q = [f(args{:}) q(n+1:end)];

Bu şekilde şu ifadeleri değerlendirebiliriz:

str = '6 5 1 2 mean_of_three 1 + 4 * +'

burada mean_of_threeüç girişli bir kullanıcı tanımlı bir fonksiyondur:

function d = mean_of_three(a,b,c)
    d = (a+b+c)/3;
end

6

Perl (134)

@a=split/\s/,<>;/\d/?push@s,$_:($x=pop@s,$y=pop@s,push@s,('+'eq$_?$x+$y:'-'eq$_?$y-$x:'*'eq$_?$x*$y:'/'eq$_?$y/$x:0))for@a;print pop@s

Bir dahaki sefere, özyinelemeli regexp şey kullanacağım.

Ungolfed:

@a = split /\s/, <>;
for (@a) {
    /\d/
  ? (push @s, $_)
  : ( $x = pop @s,
      $y = pop @s,
      push @s , ( '+' eq $_ ? $x + $y
                : '-' eq $_ ? $y - $x
                : '*' eq $_ ? $x * $y
                : '/' eq $_ ? $y / $x
                : 0 )
      )
}
print(pop @s);

F # benim tek hayal programlama dilim olsa da ...


Daha kısa bir Perl 5 uygulaması var.
dolmen,

6

Windows PowerShell, 152 181 192

Okunabilir biçimde, çünkü şimdiye kadar onları ayırma şansı olmayan sadece iki satır var:

$s=@()
switch -r(-split$input){
  '\+'        {$s[1]+=$s[0]}
  '-'         {$s[1]-=$s[0]}
  '\*'        {$s[1]*=$s[0]}
  '/'         {$s[1]/=$s[0]}
  '-?[\d.]+'  {$s=0,+$_+$s}
  '.'         {$s=$s[1..($s.count)]}}
$s

2010-01-30 11:07 (192) - İlk deneme.

2010-01-30 11:09 (170) - İşlevin bir scriptblock'a çevrilmesi, kapsam sorunlarını çözer. Sadece her çağrıyı iki bayt daha uzun yapar.

2010-01-30 11:19 (188) - Kapsam sorununu çözmedi, test davası az önce maskeledi. Endeks son çıktıdan kaldırıldı ve yine de gereksiz bir satır sonu kaldırıldı. Ve iki katına değişti float.

2010-01-30 11:19 (181) - Kendi tavsiyemi bile hatırlayamıyorum. Sayısal bir türe döküm tek bir karakterle yapılabilir.

2010-01-30 11:39 (152) - İçinde regex eşleşmesi kullanılarak büyük ölçüde azaltıldı switch. Tamamlamak için önceki kapsam sorunlarını çözme yığına erişerek çözer.


5

Raket 131:

(let l((s 0))(define t(read))(cond[(real? t)
(l`(,t,@s))][(memq t'(+ - * /))(l`(,((eval t)(cadr s)
(car s)),@(cddr s)))][0(car s)]))

Satır sonları isteğe bağlı.

Chris Jester-Young'ın Scheme çözümünü temel alıyor.


4

Python, 166 karakter

import os,operator as o
S=[]
for i in os.read(0,99).split():
 try:S=[float(i)]+S
 except:S=[{'+':o.add,'-':o.sub,'/':o.div,'*':o.mul}[i](S[1],S[0])]+S[2:]
print S[0]

Kullanım raw_input()kodu birden fazla satıra bölünmez.
JPvdMerwe,

Sonra deneyebilirsiniz: from operator import*ve değiştirme o.divile div.
JPvdMerwe

4

Python 3, 119 bayt

s=[]
for x in input().split():
 try:s+=float(x),
 except:o='-*+'.find(x);*s,a,b=s;s+=(a+b*~-o,a*b**o)[o%2],
print(s[0])

Giriş: 5 1 1 - -7 0 * + - 2 /

Çıktı: 2.5

(Düzenleme geçmişinde 128 karakterlik bir Python 2 sürümü bulabilirsiniz.)


Oldukça zekice :) İpte ihtiyacın olmadığını /beğeniyorum.
Daniel Lubarov


ZeroDivisionErrorİkinci işlenen 0 olduğunda (örneğin 5 0 +) bir dakika ile kırılan @EriktheOutgolfer .
Flornquake

ord(x) - 42Yöntemi kullanarak 1 karakter kaydedebilirsiniz .
frederick99

@ frederick99 Nasıl olduğunu göremiyorum.
flornquake

3

JavaScript (157)

Bu kod, şu iki işlev olduğunu varsayar: readLine ve print

a=readLine().split(/ +/g);s=[];for(i in a){v=a[i];if(isNaN(+v)){f=s.pop();p=s.pop();s.push([p+f,p-f,p*f,p/f]['+-*/'.indexOf(v)])}else{s.push(+v)}}print(s[0])

prompt()Bunun yerine kullanırsanız daha kısa readLine()(ve belki de eşleşmek alert()yerine ). print()prompt()
nyuszika7h

3

Perl, 128

Bu, diğer Perl cevabının yanında gerçekten rekabetçi değil, fakat farklı (en iyi) bir yolu araştırıyor.

perl -plE '@_=split" ";$_=$_[$i],/\d||
do{($a,$b)=splice@_,$i-=2,2;$_[$i--]=
"+"eq$_?$a+$b:"-"eq$_?$a-$b:"*"eq$_?
$a*$b:$a/$b;}while++$i<@_'

Karakterler basit bir perl -e ''çağrıya göre sayılır .


2

Python, 161 karakter:

from operator import*;s=[];i=raw_input().split(' ')
q="*+-/";o=[mul,add,0,sub,0,div]
for c in i:
 if c in q:s=[o[ord(c)-42](*s[1::-1])]+s 
 else:s=[float(c)]+s
print(s[0])

2

PHP, 439 265 263 262 244 240 karakter

<? $c=fgets(STDIN);$a=array_values(array_filter(explode(" ",$c)));$s[]=0;foreach($a as$b){if(floatval($b)){$s[]=$b;continue;}$d=array_pop($s);$e=array_pop($s);$s[]=$b=="+"?$e+$d:($b=="-"?$e-$d:($b=="*"?$e*$d:($b=="/"?$e/$d:"")));}echo$s[1];

Bu kod, stdin ile test edilmemiş olsa da stdin ile çalışmalıdır.

Tüm durumlarda test edildi, sonuncunun çıktısı (ve kodu) burada:
http://codepad.viper-7.com/fGbnv6

Ungolfed, 314 330 326 karakter

<?php
$c = fgets(STDIN);
$a = array_values(array_filter(explode(" ", $c)));
$s[] = 0;
foreach($a as $b){
    if(floatval($b)){
        $s[] = $b;
        continue;
    }
    $d = array_pop($s);
    $e = array_pop($s);
    $s[] = $b == "+" ? $e + $d : ($b == "-" ? $e - $d : ($b == "*" ? $e * $d : ($b == "/" ? $e / $d :"")));
}
echo $s[1];

Görev tanımından alıntı yapın: »Girdi / çıktı alacak işlevi olmayan programlama dilleri için, readLine / print gibi işlevler üstlenebilirsiniz« - açıkça PHP'nin bunu yapması için işlevleri vardır , bu nedenle varsayım yanlıştır.
Joey

Stdin kullanmak için güncellendi ve biraz daha golf oynadı.
Kevin Brown

2

esnek - 157

%{
float b[100],*s=b;
#define O(o) s--;*(s-1)=*(s-1)o*s;
%}
%%
-?[0-9.]+ *s++=strtof(yytext,0);
\+ O(+)
- O(-)
\* O(*)
\/ O(/)
\n printf("%g\n",*--s);
.
%%

Eğer aşina değilseniz, derleyin flex rpn.l && gcc -lfl lex.yy.c


2

Python, 130 karakter

Düşersek 124 karakter olur b and(hangi Python cevaplarının eksik olduğu). Ve 42 içeriyor!

s=[]
for x in raw_input().split():
 try:s=[float(x)]+s
 except:b,a=s[:2];s[:2]=[[a*b,a+b,0,a-b,0,b and a/b][ord(x)-42]]
print s[0]

Gerçekten güzel cevap. Ancak 130 karakter sayıyorum. ;)
flornquake

@flornquake haklısın, düzeltme için teşekkürler.
Daniel Lubarov

2

Python 3, 126 132 karakter

s=[2,2]
for c in input().split():
    a,b=s[:2]
    try:s[:2]=[[a+b,b-a,a*b,a and b/a]["+-*/".index(c)]]
    except:s=[float(c)]+s
print(s[0])

Daha önce de daha iyi çözümler var, ama şimdi yazdım (daha önce yapılan başvuruları okumadan, elbette - kodumun onları birlikte kopyalamış gibi göründüğümü itiraf etmeme rağmen), paylaşmak istedim, çok.


b/aile değiştirilmelidir a and b/a, aksi takdirde ikinci işlenen 0 (örn. 4 0 -) ise bu çözüm işe yaramaz .
flornquake

@flornquake Onun için düzeltildi.
mbomb007

2

c99 gcc 235

Bu benim için çalışıyor (uyarılarla birlikte):

#include <stdlib.h>
#define O(x):--d;s[d]=s[d]x s[d+1];break;
float s[99];main(c,v)char**v;{for(int i=1,d=0;i<c;i++)switch(!v[i][1]?*v[i]:' '){case'+'O(+)case'-'O(-)case'*'O(*)case'/'O(/)default:s[++d]=atof(v[i]);}printf("%f\n",s[1]);}

Ancak eğer bunu mingw32 ile derliyorsanız, şu şekilde derleyerek globbing'i kapatmanız gerekir (bakınız https://www.cygwin.com/ml/cygwin/1999-11/msg00052.html ):

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

Yapmazsanız *, mingw32 CRT tarafından otomatik olarak genişletilir.

break;case'*':s[--d]*=s[d+1];+ Karakterini parametre olarak kabul eden bir makroya nasıl dönüştüğünü bilen var mı?O(+)O(-)O(*)O(/)

H:\Desktop>gcc -std=c99 x.c C:\Applications\mingw32\i686-w64-mingw32\lib\CRT_noglob.o
x.c:3:13: warning: return type defaults to 'int'
 float s[99];main(c,v)char**v;{for(int i=1,d=0;i<c;i++)switch(!v[i][1]?*v[i]:' '){case'+'O(+)case'-'O(-)case'*'O(*)case'/'O(/)default:s[++d]=atof(v[i]);}printf("%f\n",s[1]);}
x.c: In function 'main':
x.c:3:13: warning: type of 'c' defaults to 'int'
x.c:3:1: warning: implicit declaration of function 'atof' [-Wimplicit-function-declaration]
 float s[99];main(c,v)char**v;{for(int i=1,d=0;i<c;i++)switch(!v[i][1]?*v[i]:' '){case'+'O(+)case'-'O(-)case'*'O(*)case'/'O(/)default:s[++d]=atof(v[i]);}printf("%f\n",s[1]);}
x.c:3:1: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration]
x.c:3:153: warning: incompatible implicit declaration of built-in function 'printf'
 float s[99];main(c,v)char**v;{for(int i=1,d=0;i<c;i++)switch(!v[i][1]?*v[i]:' '){case'+'O(+)case'-'O(-)case'*'O(*)case'/'O(/)default:s[++d]=atof(v[i]);}printf("%f\n",s[1]);}
H:\Desktop>a -4 5 +
1.000000
H:\Desktop>a 5 2 /
2.500000
H:\Desktop>a 5 2.5 /
2.000000
H:\Desktop>a 5 1 2 + 4 * 3 - +
14.000000
H:\Desktop>a 4 2 5 * + 1 3 2 * + /
2.000000

2

C, 232 229 bayt

Özyineleme ile eğlenceli.

#include <stdlib.h>
#define b *p>47|*(p+1)>47
char*p;float a(float m){float n=strtof(p,&p);b?n=a(n):0;for(;*++p==32;);m=*p%43?*p%45?*p%42?m/n:m*n:m-n:m+n;return*++p&&b?a(m):m;}main(c,v)char**v;{printf("%f\n",a(strtof(v[1],&p)));}

Ungolfed:

#include <stdlib.h>

/* Detect if next char in buffer is a number */
#define b *p > 47 | *(p+1) > 47

char*p; /* the buffer */

float a(float m)
{
    float n = strtof(p, &p); /* parse the next number */

    /* if the next thing is another number, recursively evaluate */
    b ? n = a(n) : 0;

    for(;*++p==32;); /* skip spaces */

    /* Perform the arithmetic operation */
    m = *p%'+' ? *p%'-' ? *p%'*' ? m/n : m*n : m-n : m+n;

    /* If there's more stuff, recursively parse that, otherwise return the current computed value */
    return *++p && b ? a(m) : m;
}

int main(int c, char **v)
{
    printf("%f\n", a(strtof(v[1], &p)));
}

Test Durumları:

$ ./a.out "-4 5 +"
1.000000
$ ./a.out "5 2 /"
2.500000
$ ./a.out "5 2.5 /"
2.000000
$ ./a.out "5 1 2 + 4 * 3 - +"
14.000000
$ ./a.out "4 2 5 * + 1 3 2 * + /"
2.000000


1

PHP - 259 karakter

$n=explode(" ",$_POST["i"]);$s=array();for($i=0;$i<count($n);$s=$d-->0?array_merge($s,!$p?array($b,$a,$c):array($p)):$s){if($c=$n[$i++]){$d=1;$a=array_pop($s);$b=array_pop($s);$p=$c=="+"?$b+$a:($c=="-"?$b-$a:($c=="*"?$b*$a:($c=="/"?$b/$a:false)));}}echo$s[2];

POST değişkeninde girdi varsayalım i .


2
Orijinal açıklamadan alıntılanmıştır »Giriş / çıkış alma fonksiyonu olmayan dilleri programlama için, readLine / print gibi fonksiyonlar üstlenebilir.
Kevin Brown

1

392 karakter

namespace System.Collections.Generic{class P{static void Main(){var i=Console.ReadLine().Split(' ');var k=new Stack<float>();float o;foreach(var s in i)switch (s){case "+":k.Push(k.Pop()+k.Pop());break;case "-":o=k.Pop();k.Push(k.Pop()-o);break;case "*":k.Push(k.Pop()*k.Pop());break;case "/":o=k.Pop();k.Push(k.Pop()/o);break;default:k.Push(float.Parse(s));break;}Console.Write(k.Pop());}}}

Ancak, standart girdi yerine argümanlar kullanılabilirse, onu aşağıya çekebiliriz.

366 karakter

namespace System.Collections.Generic{class P{static void Main(string[] i){var k=new Stack<float>();float o;foreach(var s in i)switch (s){case "+":k.Push(k.Pop()+k.Pop());break;case "-":o=k.Pop();k.Push(k.Pop()-o);break;case "*":k.Push(k.Pop()*k.Pop());break;case "/":o=k.Pop();k.Push(k.Pop()/o);break;default:k.Push(float.Parse(s));break;}Console.Write(k.Pop());}}}

Küçük bir optimizasyonla 23 karakter kaydedebilirsiniz: 1. isim alanı numarasını, ihtiyacı olan iki türü açıkça belirtin. "Namespace" anahtar sözcüğünü ve karşılık gelen parantezleri kaydedersiniz. 2. [] ve i dizgileri, case anahtar kelimeler ve etiketler, anahtar ve parens arasındaki boşlukları kaldırın. 3. Kayan noktadan kurtulun ve doğru sonuçları elde etmek için matematiği kullanın (örn. -K.Pop () + k.Pop () eksi için ve 1 / k.Pop () * k.Pop () bölme için .
MikeP

1

Scala 412 376 349 335 312:

object P extends App{
def p(t:List[String],u:List[Double]):Double={
def a=u drop 2
t match{
case Nil=>u.head
case x::y=>x match{
case"+"=>p(y,u(1)+u(0)::a)
case"-"=>p(y,u(1)-u(0)::a)
case"*"=>p(y,u(1)*u(0)::a)
case"/"=>p(y,u(1)/u(0)::a)
case d=>p(y,d.toDouble::u)}}}
println(p((readLine()split " ").toList,Nil))}

1

Python - 206

import sys;i=sys.argv[1].split();s=[];a=s.append;b=s.pop
for t in i:
 if t=="+":a(b()+b())
 elif t=="-":m=b();a(b()-m)
 elif t=="*":a(b()*b())
 elif t=="/":m=b();a(b()/m)
 else:a(float(t))
print(b())

Ungolfed versiyonu:

# RPN

import sys

input = sys.argv[1].split()
stack = []

# Eval postfix notation
for tkn in input:
    if tkn == "+":
        stack.append(stack.pop() + stack.pop())
    elif tkn == "-":
        tmp = stack.pop()
        stack.append(stack.pop() - tmp)
    elif tkn == "*":
        stack.append(stack.pop() * stack.pop())
    elif tkn == "/":
        tmp = stack.pop()
        stack.append(stack.pop()/tmp)
    else:
        stack.append(float(tkn))

print(stack.pop())

Komut satırı bağımsız değişkeninden giriş; standart çıktıda çıktı.


1

ECMAScript 6 (131)

Sadece birkaç saniye içinde yazdığınız için muhtemelen daha fazla golf oynayabilir ya da daha iyi bile yaklaşılabilir. Yarın tekrar ziyaret edebilirim:

f=s=>(p=[],s.split(/\s+/).forEach(t=>+t==t?p.push(t):(b=+p.pop(),a=+p.pop(),p.push(t=='+'?a+b:t=='-'?a-b:t=='*'?a*b:a/b))),p.pop())

1

C # - 323 284 241

class P{static void Main(string[] i){int x=0;var a=new float[i.Length];foreach(var s in i){var o="+-*/".IndexOf(s);if(o>-1){float y=a[--x],z=a[--x];a[x++]=o>3?z/y:o>2?z*y:o>1?z-y:y+z;}else a[x++]=float.Parse(s);}System.Console.Write(a[0]);}}

Düzenleme: Yığını Array ile değiştirmek çok daha kısa

Edit2: ifs'i üçlü ifadeyle değiştirdi


string[] i=> string[]i.
Zacharý,

1

Python 2

Şimdiye kadar yayınlananlara farklı yaklaşımlar denedim. Bunların hiçbiri en iyi Python çözümleri kadar kısa değil, ancak yine de bazılarınız için ilginç olabilir.

Özyinelemeyi kullanma, 146

def f(s):
 try:x=s.pop();r=float(x)
 except:b,s=f(s);a,s=f(s);r=[a+b,a-b,a*b,b and a/b]['+-*'.find(x)]
 return r,s
print f(raw_input().split())[0]

Liste manipülasyonunu kullanma, 149

s=raw_input().split()
i=0
while s[1:]:
 o='+-*/'.find(s[i])
 if~o:i-=2;a,b=map(float,s[i:i+2]);s[i:i+3]=[[a+b,a-b,a*b,b and a/b][o]]
 i+=1
print s[0]

Kullanarak reduce(), 145

print reduce(lambda s,x:x in'+-*/'and[(lambda b,a:[a+b,a-b,a*b,b and a/b])(*s[:2])['+-*'.find(x)]]+s[2:]or[float(x)]+s,raw_input().split(),[])[0]

1

Matlab, 228

F='+-/*';f={@plus,@minus,@rdivide,@times};t=strsplit(input('','s'),' ');i=str2double(t);j=~isnan(i);t(j)=num2cell(i(j));while numel(t)>1
n=find(cellfun(@(x)isstr(x),t),1);t{n}=bsxfun(f{t{n}==F},t{n-2:n-1});t(n-2:n-1)=[];end
t{1}

Ungolfed:

F = '+-/*'; %// possible operators
f = {@plus,@minus,@rdivide,@times}; %// to be used with bsxfun
t = strsplit(input('','s'),' '); %// input string and split by one or multiple spaces
i = str2double(t); %// convert each split string to number
j =~ isnan(i); %// these were operators, not numbers ...
t(j) = num2cell(i(j)); %// ... so restore them
while numel(t)>1
    n = find(cellfun(@(x)isstr(x),t),1); %// find left-most operator
    t{n} = bsxfun(f{t{n}==F}, t{n-2:n-1}); %// apply it to preceding numbers and replace
    t(n-2:n-1)=[]; %// remove used numbers
end
t{1} %// display result

Her şeyi tek bir satıra yerleştirerek 2 bayttan tasarruf edebilirsiniz (veya yeni satır için yalnızca bir karakter kullanan bir metin düzenleyicisi kullanın)
Hoki

@Hoki Çizgiyi kesmemeyi gerektirdiğinde yalnızca yeni çizgiler kullanıyorum ;. Bu yüzden bayt sayısı aynı olduğunu düşünüyorum
Luis Mendo

tam olarak değil, çoğu pencere metin düzenleyicisi cr+lfyeni bir satır için 2 karakter kullanır. Notepad ++ benim 3 satır sürümünüzde 230 karakter sayıyordu, ancak her şeyi bir satıra yapıştırırsam sadece 128 (2 yeni satırdan 2 * 2 = 4 karakter kaldırıldı ve iki tane ekledi ;). Kendiniz deneyin;)
Hoki

@Hoki Haklısın. Aslında, üç satırlı sürümü mothereff.in/byte-counter (metin baytları saymak için kullandığım) üzerine yapıştıysam , 228 verir. hat. 230 numarayı nereden aldım bilmiyorum. Teşekkürler! Düzeltildi
Luis Mendo,

1

K5, 70 bayt

`0:*{$[-9=@*x;((*(+;-;*;%)@"+-*/"?y).-2#x;x,.y)@47<y;(.x;.y)]}/" "\0:`

K5 piyasaya çıktığında bu yüzden emin değilim kudreti sayılmaz. Hala harika!

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.