İfadeyi Panfix Gösterimine Dönüştürme


19

Esolangs'a göz atıyordum ve bu dile geçtim: https://github.com/catseye/Quylthulg .

Bu dil hakkında ilginç bir şey, önek, postfix veya infix kullanmaması, üçünü de "panfix" gösterimi olarak kullanmasıdır.

İşte bir örnek. 1+2Panfix'te normal infix'i temsil etmek için : olur +1+2+. Operatörün hem işlenenlerden önce, arasında hem de sonrasında nasıl olduğuna dikkat edin. Başka bir örnek (1+2)*3. Bu olur *+1+2+*3*. Yine *her üç yerde de işlenenlere +1+2+ve nasıl olduğuna dikkat edin 3.

Meydan okuma

Tahmin edebileceğiniz gibi, bu zorluktaki göreviniz bir ifadeyi infix'ten panfix'e dönüştürmektir.

Birkaç açıklama:

  • Sadece dört temel işlemle uğraşmak zorundasınız: +-*/
  • Bunların tekli versiyonlarıyla uğraşmak zorunda kalmayacaksınız, sadece ikili
  • Parantez ile uğraşmak zorundasın
  • Normal öncelik kuralları varsayalım */sonra +-ve hepsi için birleşim bıraktı.
  • Sayılar negatif olmayan tamsayılar olacak
  • İsteğe bağlı olarak hem giriş hem de çıkışta boşluklar olabilir

Test Durumları

1+2  ->  +1+2+
1+2+3  ->  ++1+2++3+
(1+2)*3  ->  *+1+2+*3*
10/2*5  ->  */10/2/*5*
(5+3)*((9+18)/4-1)  ->  *+5+3+*-/+9+18+/4/-1-*

Bu , bayt en kısa kod kazanır!

Yanıtlar:


3

JavaScript (ES6), 160 bayt

f=(s,t=s.replace(/[*-/]/g,"'$&'"),u=t.replace(/^(.*?)([*-9]+)'([*/])'([*-9]+)|([*-9]+)'([+-])'([*-9]+)|\(([*-9]+)\)/,"$1$3$2$3$4$3$6$5$6$7$6$8"))=>t==u?t:f(s,u)

(Önce onları karakter kodlarını veren tüm operatörler alıntı yaparak İşleri *ardından kullanılabilir arayan) '*'veya '/'operasyonlar, '+'ya '-'operasyonlar veya ()s ve bunun panfix gösterimi ile ilk değiştirerek. Misal:

(5+3)*((9+18)/4-1)
(5'+'3)'*'((9'+'18)'/'4'-'1)
(+5+3+)'*'((9'+'18)'/'4'-'1)
+5+3+'*'((9'+'18)'/'4'-'1)
+5+3+'*'((+9+18+)'/'4'-'1)
+5+3+'*'(+9+18+'/'4'-'1)
+5+3+'*'(/+9+18+/4/'-'1)
+5+3+'*'(-/+9+18+/4/-1-)
+5+3+'*'-/+9+18+/4/-1-
*+5+3+*-/+9+18+/4/-1-*

3

JavaScript (ES6), 285 282 281 267 251 243 241 238 234 232 231 bayt

Neil sayesinde ~ 15 bayt .

f=(I,E=I.match(/\d+|./g),i=0)=>(J=T=>T.map?T.map(J).join``:T)((R=(H,l=(P=_=>(t=E[i++])<")"?R(0):t)(),C,F)=>{for(;(C=P())>")"&&(q=C>"*"&&C<"/")*H-1;)F=q+H?l=[C,l,C,P(),C]:F?l[3]=[C,l[3],C,R(1),C]:l=R(1,l,i--)
i-=C>")"
return l})(0))

JavaScript'te bu Mathematica'dakinden biraz daha zordur. Bu temelde aşırı uzmanlaşmış ve golfçü operatör öncelik ayrıştırıcısıdır .

Geçersiz girişlerde yığın taşmasına neden olur.

gösteri

Ungolfed

convert = input => {
  tokens = input.match(/\d+|./g);
  i = 0;
  parse_token = () => (token = tokens[i++]) == "(" ? parse_tree(false) : token;
  parse_tree = (mul_div_mode, left = parse_token()) => {
    while ((oper = parse_token()) != ")" && !((is_plus_minus = oper == "+" || oper == "-") && mul_div_mode)) {
      if (is_plus_minus || mul_div_mode)
        left = [oper, left, oper, parse_token(), oper];
      else if (non_first)
        left[3] = [oper, left[3], oper, parse_tree(true), oper];
      else
        left = parse_tree(true, left, i--);
      non_first = true;
    }
    if (oper != ")")
      i--;
    return left;
  };
  format_tree = tree => tree.map ? tree.map(format_tree).join("") : tree;
  return format_tree(parse_tree(false));
}

S.split``olmalı [...S]aslında yardım eşleşmesini rağmen, /\d+|./gbunun yerine yukarı-ön ve işi.
Neil

@Neil Teşekkürler. Buna bakacağım.
PurkkaKoodari

2

Mathematica, 203 195 bayt

Bu muhtemelen daha az verimlidir, ancak işi yapıyor gibi görünüyor.

Function[f,ReleaseHold[(Inactivate@f/._[Plus][a_,b_/;b<0]:>a~"-"~-b//Activate@*Hold)//.a_/b_:>a~"/"~b/.{a_Integer:>ToString@a,Plus:>"+",Times:>"*"}]//.a_String~b_~c_String:>b<>a<>b<>c<>b,HoldAll]

Bu, gerçek bir ifade alan ve panfix gösterimi içeren bir dize döndüren anonim bir işlevdir. Mathematica, değerlendirme zamanından ziyade ayrıştırma zamanında operatörlerin önceliğini sıralar, bu nedenle yuvalama otomatik olarak doğru olmalıdır. En azından test senaryoları beklendiği gibi çalışıyor.

Açıklama: Tüm ifadeyi bir ağaç olarak yorumlamak yeterince kolaydır, şöyle:

ağaç

Bu aşamada işleçler (yaprak olmayan her düğüm) artık işleç değildir, aslında gibi dizelere dönüştürülmüştür "+". Tamsayılar da dizgilere dökülür. Ardından, yinelenen bir değiştirme kuralı, tam olarak iki yaprağı olan her düğümü panfix'e dönüştürür parent-leaf1-parent-leaf2-parent. Bazı yinelemelerden sonra ağaç tek bir dizgeye indirgenir.

Bayt sayısındaki temel kayıp Mathematica'nın yorumlamasıdır

5 - 4 -> 5 + (-4)
9 / 3 -> 9 * (3^(-1))

Ve bu ayrıştırma zamanında da olur.

Desen a_/b_de yorumlandığından , biraz golf a_ * (b_)^(-1). Ayrıca başka yerlerde bazı küçük optimizasyonlar.


1

Prolog, 87 bayt

x(T)-->{T=..[O,A,B]}->[O],x(A),[O],x(B),[O];[T].
p:-read(T),x(T,L,[]),maplist(write,L).

Bu bir işlevdir; (tam programı yazarken Prolog'da Demirbaş karabasanımsı düzeyi vardır çünkü çoğunlukla normal, hatta eğer derlemek adlandırılan bir program, bir repl çalıştırmak üretir) p. Stdin'den girdi alır ve stdout'ta çıktı alır. Prolog'un giriş rutinlerinin çalışma şeklinin talihsiz bir sonucu olan girişe bir nokta eklemeniz gerektiğini unutmayın (girişteki periyotları diğer dillerdeki yeni satırları kullandıkları gibi kullanırlar); cevabı diskalifiye edebilir veya etmeyebilir.

açıklama

Prolog'daki aritmetik işleçler normalde tuple yapıcıları olarak yorumlanır . Ancak, dayandıkları gerçek aritmetik işleçlerle aynı öncelik kurallarına uyarlar; infix gösterimi ile tuples oluşturabilir +ve bir grup içinde önceliği soldan sağa alınan ve -daha az sıkı bir şekilde bağlayabilirsiniz . Sorunun aynısı budur; bu nedenle, girdiden tüm iç içe bir tupu okuyabiliriz ve zaten doğru yapıya sahiptir. İşte böyle.*/p

Sonra, bunu panfix gösterimine dönüştürmemiz gerekiyor. xKurucular ve tamsayılar bir panfixed listesine girdi dönüştürür ve neredeyse doğrudan bir İngiliz cümle olarak okunabilir: " xarasında T: if Tkurucu ile başlık olur Ove argümanlar A, Bdaha sonra O, xbir A, O, xbir B, Obaşka T". Son olarak, biz sadece yani kullanarak herhangi ayracı (listesini yazdırmak zorunda maplistçağrısınawrite listenin her bir öğesini için).

Bunu test etmek için SWI-Prolog'u kullandım, çünkü GNU Prolog sürümüm maplisthenüz (görünüşe göre daha yeni bir sürüme eklenmiş) değil, ancak genellikle Prolog uygulamaları arasında oldukça taşınabilir olmalıdır.

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.