Anyfix Notasyonu uygulayın!


16

Önek notasyonunda, operatör argümanlardan önce gelir, böylece operatörün next()özyinelemeli olarak çağrıldığını hayal edebilirsiniz . Infix gösteriminde, operatör argümanlar arasında gider, böylece onu sadece bir ayrıştırma ağacı olarak hayal edebilirsiniz. Postfix gösterimlerinde, işleç bağımsız değişkenlerden sonra gelir, böylece yalnızca yığın tabanlı olarak hayal edebilirsiniz.

Herhangi bir düzeltme göstergesinde, operatör herhangi bir yere * gidebilir . Bir operatör görünürse ve yeterli sayıda bağımsız değişken yoksa, operatör yeterli bağımsız değişken olana kadar bekler. Bu zorluk için, çok basit bir anyfix değerlendiricisi uygulamanız gerekir. (Not anyfix sana etrafında oynayabileceği terk ettiğini bir eğlence dil olduğunu burada ya check out burada )

Aşağıdaki komutları desteklemeniz gerekir:

(Yardımlaşma 1)

  • çiftleme
  • olumsuz

(İkili 2)

  • ilave
  • çarpma işlemi
  • eşitlik: döndürür 0veya 1.

Bu komutlar için beyaz boşluk olmayan beş sembol kullanmayı seçebilirsiniz. Gösteri amaçlı olarak, "çoğaltma, ×çarpma ve toplama olarak kullanacağım +.

Değişmez değerler için, yalnızca negatif olmayan tamsayıları desteklemeniz gerekir, ancak yorumcunuz tüm tamsayıları (dilinizin (makul) tamsayı aralığında) içerebilmelidir.

Bir örneğe bakalım: 10+5. Depolama alanı bir sıra değil, yığın olarak davranmalıdır. Bu nedenle, ilk önce yığın başlar []ve sıradaki operatör listesi başlar []. Daha sonra, 10yığını oluşturan değişmezi değerlendirilir [10]. Ardından, +iki argüman gerektiren operatör değerlendirilir. Ancak, yığın üzerinde yalnızca bir bağımsız değişken vardır, bu nedenle sıraya alınmış işleç listesi olur ['+']. Daha sonra, 5yığını oluşturan değişmezi değerlendirilir [10, 5]. Bu noktada, operatör '+'yığıtı [15]ve kuyruğu oluşturacak şekilde değerlendirilebilir [].

Nihai sonuç olmalıdır [15]için + 10 5, 10 + 5ve 10 5 +.

En daha sert bir örneğe bakalım: 10+". Yığın ve kuyruk olarak başlar []ve []. 10ilk önce yığını yapan değerlendirilir [10]. Sonra, +değerlendirilir, bu da yığını değiştirmez (çünkü yeterli bağımsız değişken yoktur) ve kuyruğu yapar ['+']. Sonra "değerlendirilir. Bu hemen çalışabilir, böylece yığını yapar [10, 10]. +artık yığın [20]ve kuyruk haline gelebilir []. Nihai sonuç [20].

Operasyon sırası ne olacak?

Hadi bir bakalım ×+"10 10. Yığın ve kuyruk şu şekilde başlar []:

  • ×: Yığın değişmez ve kuyruk olur ['×'].
  • +: Yığın değişmez ve kuyruk olur ['×', '+'].
  • ": Yığın değişmez ve kuyruk olur ['×', '+', '"'].
  • 10: Yığın olur [10]. ×İlk göründüğünden beri değerlendirilecek ilk operatör olsa da , "hemen çalışabilir ve operatörlerin hiçbiri yapmadan önce çalışabilir, bu yüzden değerlendirilir. Yığın olur [10, 10]ve kuyruk ['×', '+']. ×artık değerlendirilebilir, bu da yığını [100]ve kuyruğu yapar ['+'].
  • 10: Yığın [100, 10], +değerlendirilmesine izin veren hale gelir . Yığın olur [110]ve kuyruk [].

Nihai sonuç [110].

Bu gösterilerde kullanılan komutlar, herhangi bir düzeltme dilinin komutlarıyla tutarlıdır; ancak, son örnek yorumcumdaki bir hata nedeniyle çalışmaz. (Feragatname: Gönderileriniz herhangi bir düzeltme yorumlayıcısında kullanılmayacaktır)

Meydan okuma

5 boşluk olmayan, rakam olmayan bir karakter kümesi seçin ve yukarıdaki özelliklere göre bir düzeltme yorumlayıcısı oluşturun. Programınız tekil diziyi veya içerdiği değeri çıktılayabilir; değer yığınının yürütme sonunda yalnızca tek bir değer içereceği ve yürütme sonunda operatör sırasının boş olacağı garanti edilir.

Bu yani bayt en kısa kodu kazanır.

Test Durumları

Bu test durumları için, yinelenen ", negatif olan -, toplama +, çarpma olan ×ve eşitliktir =.

Input -> Output
1+2×3 -> 9
1"+"+ -> 4
2"××" -> 16
3"×+" -> 18
3"+×" -> 36
123"= -> 1 ("= always gives 1)
1+2=3 -> 1
1"=2+ -> 3
1-2-+ -> -3
-1-2+ -> 3 (hehe, the `-1` becomes `+1` at the `-` rather than making the `2` a `-1`)
+×"10 10 -> 200 (after the 10 is duplicated (duplication is delayed), 10 + 10 is performed and then 20 * 10, giving 200)

kurallar

  • Standart Loopholes Uygula
  • İsterseniz anyfix resmi yorumlayıcısını alıp golf oynayabilirsiniz. Korkunç bir şekilde kaybetmeyi bekle.

Girdi bir dize olarak verilir ve bir dizi olarak tek bir tamsayı olarak çıktılanır. Girişin yalnızca boşluk, rakam ve seçtiğiniz 5 karakteri içerdiğini varsayabilirsiniz.

* aslında değil


2
İstediğiniz yere gidin * ™.
Jonathan Allan

Eşitlik operatörünün sonucu nedir? 0ve 1?
Felix Palmen

1
@JonathanAllan yukarıya bakın; Bir komut
ripini

1
@RickHitchcock Tabii.
HyperNeutrino

1
Muhtemelen ×+"10 10test senaryolarını veya 1) boşluk kullanarak ve 2) yinelenen operatörün kullanımını (tamamen kaçırdığım iki şey ) geciktiren diğer örnekleri dahil etmelisiniz .
Arnauld

Yanıtlar:


5

JavaScript (ES6), 204 203 , 200 bayt

Bir tamsayı döndürür.

e=>e.replace(/\d+|\S/g,v=>{for((1/v?s:v>','?u:b)[U='unshift'](v);!!u[0]/s[0]?s[U](u.pop()>'c'?s[0]:-S()):!!b[0]/s[1]?s[U](+eval(S(o=b.pop())+(o<'$'?'==':o)+S())):0;);},s=[],u=[],b=[],S=_=>s.shift())|s

Kullanılan karakterler:

  • +: ilave
  • *: çarpma işlemi
  • #: eşitlik
  • d: çiftleme
  • -: olumsuz

Test senaryoları

Biçimlendirilmiş ve yorumlanmış

e => e.replace(                     // given an expression e, for each value v matching
  /\d+|\S/g, v => {                 // a group of digits or any other non-whitespace char.
    for(                            //   this loop processes as many operators as possible
      (                             //   insert v at the beginning of the relevant stack:
        1 / v ? s : v > ',' ? u : b //     either value, unary operator or binary operator
      )[U = 'unshift'](v);          //     (s[], u[] or b[] respectively)
      !!u[0] / s[0] ?               //   if there's at least 1 value and 1 unary operator:
        s[U](                       //     unshift into s[]:
          u.pop() > 'c' ?           //       for the duplicate operator:
            s[0]                    //         a copy of the last value
          :                         //       else, for the negative operator:
            -S()                    //         the opposite of the last value
        ) :                         //     end of unshift()
      !!b[0] / s[1] ?               //   if there's at least 2 values and 1 binary operator:
        s[U](                       //     unshift into s[]:
          +eval(                    //       the result of the following expression:
            S(o = b.pop()) +        //         the last value, followed by the
            (o < '$' ? '==' : o) +  //         binary operator o with '#' replaced by '=='
            S()                     //         followed by the penultimate value
          )                         //       end of eval()
        ) : 0;                      //     end of unshift()
    );                              //   end of for()
  },                                // end of replace() callback
  s = [],                           // initialize the value stack s[]
  u = [],                           // initialize the unary operator stack u[]
  b = [],                           // initialize the binary operator stack b[]
  S = _ => s.shift()                // S = helper function to shift from s[]
) | s                               // return the final result

Bunun işe yaradığını düşünmeyin -1+-2. -3 yerine 3 döndürür.
Rick Hitchcock

1
@RickHitchcock Anladığım kadarıyla 2nci hemen -uygulanmalıdır -1.
Arnauld

Ben başka bir operatör sonra geliyor beri 2 -gitmek istiyorum düşünürdüm . Belki de @HyperNeutrino açıklayabilir. Negatif operatör bazı durumlarda belirsiz olabilir. 2
Rick Hitchcock

3

JavaScript (ES6), 162 152 143 150 bayt

(s,N=s.replace(/(-?\d+)-|-(-)/g,'- $1 ').match(/(- ?)*?\d+|R/g))=>+eval(`R=${N[0]>'9'?N[1]:N[0]},${s.match(/[+*=]/g).map((o,i)=>'R=R'+o+'='+N[i+1])}`)

Hafifçe soluksuz:

(s,
 N=s.replace(/(-?\d+)-|-(-)/g,'- $1 ').      //change postfix negatives to prefix,
                                             //and change "--" to "- - "
     match(/(- ?)*?\d+|R/g)                  //grab numbers and duplicates
)=>+eval(`R=${N[0] > '9' ?  N[1] : N[0]},    //handle a delayed duplicate
          ${s.match(/[+*=]/g).               //grab the operators
              map((o,i)=>'R=R'+o+'='+N[i+1]) //create a comma-separated list of assignments
           }
         `)

açıklama

*Çarpma ve Rçoğaltma için kullanıyorum . Diğer operatörler sorudakiyle aynıdır.

N sayıların dizisi haline gelir (kopyalar dahil).

replaceEksi işareti geliyor durumda işler sonra sayı. Örneğin, değişecek 1-için - 1ve -1-için - -1.

İçinde eval, s.matchikili operatörlerin dizi oluşturur. Bunun her zaman bir öğeden daha az öğeye sahip olacağını unutmayın N.

İşlevin sonucu eval, sayıların ve işleçlerin eşlenmesidir.

İşte budur evalTest durumların her birinde, ed:

0+2*3        R=0,R=R+=2,R=R*=3        = 6 
1+2*3        R=1,R=R+=2,R=R*=3        = 9 
1R+R+        R=1,R=R+=R,R=R+=R        = 4 
2R**R        R=2,R=R*=R,R=R*=R        = 16 
3R*+R        R=3,R=R*=R,R=R+=R        = 18 
3R+*R        R=3,R=R+=R,R=R*=R        = 36 
123R=        R=123,R=R==R             = 1 
1+2=3        R=1,R=R+=2,R=R==3        = 1 
1R=2+        R=1,R=R==R,R=R+=2        = 3 
1-2-+        R=- 1,R=R+=- 2           = -3 
-1-2+        R=1,R=R+=2               = 3 
*+R10 10     R=10,R=R*=10,R=R+=10     = 110 
+*R10 10     R=10,R=R+=10,R=R*=10     = 200 
-1+--2       R=-1,R=R+=- -2           = 1 
-1+-2        R=-1,R=R+=-2             = -3 

JavaScript ifadesindeki virgül operatörü son ifadesinin sonucunu döndürür, böylece mapotomatik olarak kullanılabilir bir ifade döndürür.

+İşareti önce tabi evaldeğiştirmek trueiçin 1ve falseiçin 0.

RHem değişken hem de yinelenen işleç olarak kullanmak , mapalt ifadelerini büyük ölçüde basitleştirir .

Test senaryoları:


2
replaceİşleri amaçlandığı gibi düşünmüyorum . Bu döner 3için -1+--2bence ve 1(doğru olacaktır 1için ikinci argüman var önce değişiklikleri üç kez oturum +mevcut sonuçlanan -1 + 2).
Felix Palmen

Harika yakalama @FelixPalmen. Şimdi düzeltildi.
Rick Hitchcock

2

JavaScript, 321 311 bayt

_="f=a=>(a.replace(/\\d+|./g,mq!~(b='+*=\"- '.indexOf(a))|b>2j3j4j5&&o+aw1/y?(y*=-1wcz:1/y?oywcz:hz,rql.map(z=>m(lki,1)[0],i)),hq1/s[1]?sk0,2,+eval(`y${a=='='?a+a:a}s[1]`)):cz,cqlki,0,a),s=[],l=[],e='splice'),s)z(a,i)ys[0]w)^r``:q=z=>os.unshift(k[e](j?b-";for(i of"jkoqwyz")with(_.split(i))_=join(pop());eval(_)

Çevrimiçi deneyin!

Beş karakter, *çarpma hariç , sorudakiyle aynıdır .
Komut dosyası RegPack kullanılarak sıkıştırılır . Orijinal komut dosyası, _değerlendirmeden sonra değişkende saklanır .


Bunun işe yaradığını düşünmeyin -1+-2. -3 yerine 3 döndürür.
Rick Hitchcock

@RickHitchcock. Neden -3bunun yerine geri dönmesi gerektiğine inanıyorsunuz 3?

Negatif operatörü yanlış anlıyor olabilirim. Genellikle -1 + -2öyle -3, ama --1 + 2bunun yerine ayrıştırılmalı mı?
Rick Hitchcock

1
@RickHitchcock. Sonuç olduğundan eminim 3. Yığına gelmeden önce 2ikincisi -değerlendirilir ve bu yüzden 1 2 +gerçekten var 3. Ah, ve muhtemelen cevabını da düzenlemek zorundasın.

Muhtemelen haklısın. Sen ve Arnauld da aynı cevabı aldınız ve ben OP'den açıklama istedim. Eğer yapabilseydim sana tekrar oy verirdim
Rick Hitchcock

1

Haskell , 251 bayt

(#([],[]))
(x:r)#(o,n)|x>'9'=r#h(o++[x],n)|[(a,t)]<-lex$x:r=t#h(o,read a:n)
_#(o,n:_)=n
h=e.e
e(o:s,n:m:r)|o>'N'=e(s,g[o]n m:r)
e(o:s,n:r)|o=='D'=e(s,n:n:r)|o=='N'=e(s,-n:r)
e(o:s,n)|(p,m)<-e(s,n)=(o:p,m)
e t=t
g"a"=(+)
g"m"=(*)
g"q"=(((0^).abs).).(-)

Çevrimiçi deneyin! Şu karakterleri kullanır: atoplama miçin, çarpma qiçin, eşitlik Diçin, yinelenen ve Nolumsuzlama için. ( eEşitlik için kullanmak istedim , ancak sayı olarak lexayrışan sorunla karşılaştım 2e3.) Örnek kullanım: (#([],[])) "2a3 4m"verim 20.


1

6502 makine kodu (C64), 697 bayt

00 C0 A2 00 86 29 86 26 86 27 86 28 86 4B 86 4C 86 CC 20 E4 FF F0 FB C9 0D F0
10 C9 20 30 F3 A6 27 9D B7 C2 20 D2 FF E6 27 D0 E7 C6 CC A9 20 20 1C EA A9 0D
20 D2 FF 20 95 C0 20 09 C1 20 95 C0 A6 26 E4 27 F0 4E BD B7 C2 E6 26 C9 20 F0
E8 C9 2D D0 09 A6 4C A9 01 9D B7 C3 D0 32 C9 22 D0 09 A6 4C A9 02 9D B7 C3 D0
25 C9 2B D0 09 A6 4C A9 81 9D B7 C3 D0 18 C9 2A D0 09 A6 4C A9 82 9D B7 C3 D0
0B C9 3D D0 0D A6 4C A9 83 9D B7 C3 E6 28 E6 4C D0 A3 4C 8A C2 A6 29 F0 6F A4
28 F0 6B CA F0 4B C6 28 A6 4B E6 4B BD B7 C3 F0 F5 30 14 AA CA D0 0B 20 7B C2
20 E1 C1 20 4D C2 D0 D9 20 5C C2 D0 D4 29 0F AA CA D0 0B 20 6D C2 20 08 C2 20
4D C2 D0 C3 CA D0 0B 20 6D C2 20 16 C2 20 4D C2 D0 B5 20 6D C2 20 F4 C1 20 4D
C2 D0 AA A4 4B B9 B7 C3 F0 02 10 AC C8 C4 4C F0 0F B9 B7 C3 F0 F6 30 F4 AA A9
00 99 B7 C3 F0 A6 60 A0 00 A6 26 E4 27 F0 15 BD B7 C2 C9 30 30 0E C9 3A 10 0A
E6 26 99 37 C4 C8 C0 05 D0 E5 C0 00 F0 08 A9 00 99 37 C4 20 39 C2 60 A2 FF E8
BD 37 C4 D0 FA A0 06 88 CA 30 0A BD 37 C4 29 0F 99 37 C4 10 F2 A9 00 99 37 C4
88 10 F8 A9 00 8D 3D C4 8D 3E C4 A2 10 A0 7B 18 B9 BD C3 90 02 09 10 4A 99 BD
C3 C8 10 F2 6E 3E C4 6E 3D C4 CA D0 01 60 A0 04 B9 38 C4 C9 08 30 05 E9 03 99
38 C4 88 10 F1 30 D2 A2 06 A9 00 9D 36 C4 CA D0 FA A2 10 A0 04 B9 38 C4 C9 05
30 05 69 02 99 38 C4 88 10 F1 A0 04 0E 3D C4 2E 3E C4 B9 38 C4 2A C9 10 29 0F
99 38 C4 88 10 F2 CA D0 D6 C0 05 F0 06 C8 B9 37 C4 F0 F6 09 30 9D 37 C4 E8 C8
C0 06 F0 05 B9 37 C4 90 F0 A9 00 9D 37 C4 60 A9 FF 45 FC 85 9F A9 FF 45 FB 85
9E E6 9E D0 02 E6 9F 60 A2 00 86 9F A5 FB C5 FD D0 07 A5 FC C5 FE D0 01 E8 86
9E 60 A5 FB 18 65 FD 85 9E A5 FC 65 FE 85 9F 60 A9 00 85 9E 85 9F A2 10 46 FC
66 FB 90 0D A5 FD 18 65 9E 85 9E A5 FE 65 9F 85 9F 06 FD 26 FE CA 10 E6 60 20
33 C1 A6 29 AD 3D C4 9D 3F C4 AD 3E C4 9D 3F C5 E6 29 60 A6 29 A5 9E 9D 3F C4
A5 9F 9D 3F C5 E6 29 60 A6 29 BD 3E C4 9D 3F C4 BD 3E C5 9D 3F C5 E6 29 60 C6
29 A6 29 BD 3F C4 85 FD BD 3F C5 85 FE C6 29 A6 29 BD 3F C4 85 FB BD 3F C5 85
FC 60 A6 29 BD 3E C5 10 13 20 7B C2 20 E1 C1 20 4D C2 A9 2D 20 D2 FF A6 29 BD
3E C5 8D 3E C4 BD 3E C4 8D 3D C4 20 8B C1 A9 37 A0 C4 4C 1E AB

Çevrimiçi demo

Kullanımı sys49152 daha sonra anyfix ifade ve basın dönüşü girin.

  • hiçbir hata kontrol yakın, bu yüzden geçersiz ifadeler komik çıkışlar bekliyoruz.
  • çarpma sembolü *, diğerleri önerildiği gibi.
  • maksimum giriş uzunluğu 256 karakterdir, kuyrukta en fazla 127 operatör olabilir.
  • Giriş rutin değil bu yüzden yanlış yazmanız yok, kontrol karakterleri işlemek;)
  • tamsayılar 16bit imzalı, taşma sessizce sarar.
  • Bu işlemci bile çarpma bilmiyor ve C64 OS / ROM size vermez çünkü bayt sayısı biraz büyük olan herhangi bir ondalık dizeleri / konumuna tam sayı aritmetiği veya dönüşümleri.

İşte okunabilir ca65 tarzı birleştirici kaynak kodu .


1

VB.NET (.NET 4.5) 615 576 bayt

-39 değiştirerek Felix Palmen sayesinde bayt \r\niçin\n

Gerekli Imports System.Collections.Generic(bayt sayısına dahil)

Dim s=New Stack(Of Long),q=New List(Of String),i=Nothing,t=0,c=0
Function A(n)
For Each c In n
If Long.TryParse(c,t)Then
i=i &"0"+t
Else
If c<>" "Then q.Add(c)
If i<>A Then s.Push(i)
i=A
End If
If i=A Then E
Next
If i<>A Then s.Push(i)
E
A=s
End Function
Sub E()
c=s.Count
If c=0Then Exit Sub
For Each op In q
If op="-"Or op="d"Or c>1Then
Select Case op
Case"*"
s.Push(s.Pop*s.Pop)
Case"+"
s.Push(s.Pop+s.Pop)
Case"="
s.Push(-(s.Pop=s.Pop))
Case"-"
s.Push(-s.Pop)
Case"d"
s.Push(s.Peek)
End Select
q.Remove(op)
E
Exit Sub
End If
Next
End Sub

Giriş noktası, Abir dizeyi girdi olarak alan ve a döndüren İşlev'dir Stack(Of Long).

Semboller:

  • İlave - +
  • Çarpma işlemi - *
  • Eşitlik - =
  • Olumsuzluk - -
  • Çoğaltma - d

Genel bakış:

Fonksiyon Agirişi alır ve tokenler. Çok Long?basamaklı tamsayılar için akan bir toplam yapmak için a kullanır , bu Nothingda şu anda bir tamsayı okumadığımızı gösterir.

Alt yordam E, tamsayılar ve işleçlerin sırasını alır ve anyfix gösterimini değerlendirir. Hiçbir eylem kalmayıncaya kadar kendini yinelemeli olarak çağırır.

Hem beyanda hem de parametre geçişinde bayt tasarrufu için küresel parametreleri bir kerede beyan ederim.

'Den dönüş değeri A, eşleşen değişkene bir değer atanarak ayarlanır A.

VB Trueeşdeğerdir -1, böylece işlem doğru değeri elde etmek için sonucu reddetmelidir.

Çevrimiçi deneyin!


eklemenizi öneririz Çevrimiçi deneyin!
Felix Palmen

btw, Importssadece bayt sayımı alıyorum 576- yanlış saymış olabilir misiniz?
Felix Palmen

@FelixPalmen \r\nyerine saydım \n, bu yüzden tutarsızlık burada.
Brian J

@FelixPalmen TIO eklendi, hatırlattığınız için teşekkürler! :) (Oh, bu yazı için zaten yaptığını fark etmedim)
Brian J
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.