Çok amaçlı adres hesap makinesi oluşturma


16

İlham. Ters.

Belirli bir omnifix ifadesini değerlendirin.

Omnifix normal matematiğin ek gösterimi gibidir, ancak argümanları çevreleyen her sembolün ek kopyaları ile. Dış semboller parantezin yerini alır ve bu nedenle ek parantezlere gerek yoktur.

Diliniz -0-n-için makul bir aralıkta toplama, çıkarma, çarpma, bölme ve pozitif gerçek sayıları (negatif olanlar yazılabilir ) desteklemelisiniz.

Artı ve eksi olmalı +ve -ancak kullanabilir *veya ×kez ve /ya ÷bölünerek. Talep üzerine diğer makul sembollere izin verilecektir.

Brownie, açıklama ve ek özellikler (ek işlemler, negatif sayılar, dizeler vb.)

Lütfen mümkünse çözümünüzü test etmek için bir bağlantı sağlayın.

Örnekler

Açıklığa kavuşturmak için, aşağıdaki açıklamalar ¯negatif sayıları belirtmek için yüksek eksi ( ) kullanır. Negatif sayıları makul bir format kullanarak döndürebilirsiniz.

-5-2-3

+2+×3×2×+8 ( +2+×3×2×++2+6+8)

-14--3-1--12 ( -4--3-1---14-2-12)

+2.1+×3.5×2.2×+9.8 ( +2.1+×3.5×2.2×++2.1+7.7+9.8)

×3×÷-0-6-÷2÷×-9 ( ×3×÷-0-6-÷2÷××3×÷¯6÷2÷××3ׯ3ׯ9)

÷4÷-3-÷1÷2÷-÷1.6 ( ÷4÷-3-÷1÷2÷-÷÷4÷-3-0.5-÷÷4÷2.5÷1.6)


1
The explanations below use high minus (`¯`) to indicate negative numbers.APL'yi kesinlikle seviyorsun.
Outgolfer Erik

@EriktheOutgolfer Daha iyi bir öneriniz mi var? Ayrıca, TI-BASIC yüksek eksi kullanır.
Adám

Aslında -s ile -s karıştırılamaz, s ¯ile karıştırılamaz -.
Outgolfer Erik

Bah, sadece gerçek sayı ihtiyacını fark ettim. 290 baytlık tamsayı aritmetik Retina çözümüm için çok fazla ...
Neil

@Neil Neden cevap olarak göndermiyorsun?
Adam

Yanıtlar:


4

C # (.NET Core) , 198197188 bayt

float O(string s){try{return float.Parse(s);}catch{var f=s[0];int i=s.IndexOf(f,1);float a=O(s.Substring(1,i-1)),b=O(s.Substring(i+1,s.Length-i-2));return f<43?a*b:f<44?a+b:f<46?a-b:a/b;}}

Çevrimiçi deneyin!

Kullanır *ve /.

Özyinelemeli işlev. Önce girdi dizesini a olarak ayrıştırmaya çalışır float. Başarısız olursa, birinci ve ikinci işlenenleri bağımsız değişken olarak yinelemeli olarak geçirir ve ardından seçilen işlemi sonuçlarda gerçekleştirir.

  • Bay Xcoder sayesinde 1 bayt kurtarıldı!
  • TheLethalCoder sayesinde 9 bayt kurtarıldı!

IndefOf(f, 1)olabilirIndexOf(f,1)
Bay Xcoder

1
floatBunun yerine s tuşlarını kullanın, karakter kodlarını kullanın, bunlara sahip olduğunuzda muhtemelen birkaç yerde >ve <birkaç yerde kısaltabilirsiniz .
TheLethalCoder

Sen golf bir bayt değiştirerek yapabilirsiniz i+1,s.Length-i-2için ++i,s.Length+~i.
Kevin Cruijssen

4

Python 3, 159 158 152 144 136 135 132 bayt

def t(i,a=1):
 while'-'<l[i]!='/':i+=1;a=0
 if a:l[i]='(';i=t(t(i+1));l[i-1]=')'
 return-~i
*l,=input()
t(0)
print(eval(''.join(l)))

Çevrimiçi deneyin!

Negatif sayılara izin vermez ( -0-5-elbette çalışır) ve python operatörleri gerektirir.


Bir TIO bağlantısı ekleyebilir misiniz?
Adám

1
while~-(l[i]in'+-*/'):i+=1;a=1ve *l,=input()152 bayt için
Felipe Nardi Batista

1
tüm test senaryoları ile: bağlantı
Felipe Nardi Batista


1
if a:l[i]='(';i=t(t(i+1));l[i-1]=')'ile return-~i135 bayt için: P
Felipe Nardi Batista

3

Retina , 290 287 286 bayt

\d+
¦$&$*
¯¦
¯
{`\+([¯¦]1*)\+([¯¦]1*)\+
-$1-¯$2-
-(¯|¦)(1*)-([¯¦]+1*\2)-
-¯$3-¯$1$2-
(×|÷)¯(1*\1)([¯¦]1*\1)
$1¦$2¯$3
צ×[¯¦]1*×|¯¯¦?
¦
¯¦|¦¯
¯
+`-((¯|¦)1*)(1*)-\2\3-
$1
-([¯¦]1*)-[¯¦](1*)-
$1$2
צ1(1*)×([¯¦]1*)×
+צ$1×$2×+$2+
}`÷¦(?=1*÷(¯|¦)(1+)÷)(\2)*1*÷\1\2÷
$1$#3$*
((¯)|¦)(1*)
$2$.3

Çevrimiçi deneyin! Not: Sadece tamsayı aritmetiği yapabilir, bu nedenle bazı test durumları kaldırılmıştır. ¯Öneki kullanarak negatif sayıları kabul eder ve döndürür . Düzenleme: @Cowsquack sayesinde kaydedilmiş 3 4 bayt. Açıklama:

\d+
¦$&$*

Sıfır kullanmanın ¦bir yoluna ihtiyacım vardı, bu yüzden pozitif bir sayı öneki olarak kullanıyorum. Numaralar daha sonra tekli olarak dönüştürülür.

¯¦
¯

Ancak negatif sayılar için yalnızca bir ¯önek gerekir .

{`\+([¯¦]1*)\+([¯¦]1*)\+
-$1-¯$2-

Alıntılar +çirkinleşir, bu yüzden toplamaları çıkartmalara dönüştürürüm.

-(¯|¦)(1*)-([¯¦]+1*\2)-
-¯$3-¯$1$2-

Bir çıkarma işleminin LHS'sinin mutlak değeri RHS'den düşükse, bunları değiştirin ve her iki tarafı da reddedin.

(×|÷)¯(1*\1)([¯¦]1*\1)
$1¦$2¯$3

Ayrıca çarpma veya bölmenin LHS'si negatifse, her iki tarafı da reddedin.

צ×[¯¦]1*×|¯¯¦?
¦

Ayrıca çarpmanın LHS'si sıfırsa, sonuç sıfırdır. Ayrıca, iki eksi artı bir artı.

¯¦|¦¯
¯

Ancak eksi ve artı (veya tersi) eksi oluşturur.

+`-((¯|¦)1*)(1*)-\2\3-
$1

Aynı işaretin iki sayısını çıkarın. Böyle bir çıkarma kalmayıncaya kadar bunu tekrar tekrar yapın.

-([¯¦]1*)-[¯¦](1*)-
$1$2

Hala bir çıkarma varsa, işaretler farklı olmalıdır, bu yüzden sayıları birlikte ekleyin. (Ancak bunu sadece bir kez yapın, çünkü bu aynı işaretin iki sayısının tekrar çıkarılmasını gösterebilir.)

צ1(1*)×([¯¦]1*)×
+צ$1×$2×+$2+

Tekrarlanan toplama ile çarpma işlemini gerçekleştirin.

}`÷¦(?=1*÷(¯|¦)(1+)÷)(\2)*1*÷\1\2÷
$1$#3$*

Tamsayı bölümü gerçekleştirin. Yukarıdaki adımlardan biri ifadeyi basitleştirmiş olacaktır, bu yüzden hiçbir işlem kalmayana kadar geri dönün.

((¯)|¦)(1*)
$2$.3

Ondalık biçime geri dön.


Vay canına, bu - destansı. PPCG'deki en büyük Retina yazısı? Bununla birlikte, genellikle QuadR ve Retina çözümleri birbirine çok benzemektedir. İlham verebilir miyim?
Adam

Bu çizgide +`-(([¯¦])1*)(1*)-\2\3-, [¯¦]olabilir¯|¦
Kritixi Lithos

@Cowsquack Aslında üç kez olur, teşekkürler!
Neil

Kaçırdığınız biri var ([×÷]);)
Kritixi Lithos

1
@Cowsquack Başka bir tane bulmasan iyi edersin, aksi takdirde 4'ü geçmek zorunda kalacağım ...
Neil

2

PHP , 116 114 109 bayt

-5 Martin Ender sayesinde

for($s=$argv[$o=1];$o!=$s;)$s=preg_replace('#([*+/-])(([\d.]+|(?R))\1(?3))\1#','($2)',$o=$s);eval("echo$s;");

*Çarpma ve /bölme için kullanır . Olumsuz rakamlar işe yaramıyor, ancak bunun olması için belirli bir girişimde bulunmuyorum.

Çevrimiçi deneyin!

Açıklanamayan ve Açıklanan

for($s=$argv[$o=1];   # Initialize with $s = input and $o = 1;
    $o!=$s;)          # While $o != $s
    # Set $o to $s and set $s to be $s after this regex replacement:
    $s=preg_replace('#([*+/-])(([\d.]+|(?R))\1(?3))\1#','($2)',$o=$s);
    # i.e., continue to do this replacement until the result is the same on two consecutive
    # steps (no replacement was made)
# Once $o == $s (i.e. no more replacement can be made), eval the result and print
eval("echo$s;"); 

Normal ifadeyi de açıklayacağım çünkü biraz büyülü:

([*+/-])(([\d.]+|(?R))\1(?3))\1


([*+/-])

İlk olarak, dört operatörden herhangi birini eşleştirmek istiyoruz: *+/-

([\d.]+|(?R))

Ardından, bir sayı [\d.]+veya başka bir geçerli çok amaçlı harf ifadesiyle eşleşmemiz gerekir (?R).

\1

Ardından, başlangıçtaki operatörle eşleşiriz.

(?3)

Daha sonra grup 3'te yaptığımızla aynı şeyi yapıyoruz: bir sayı veya çok amaçlı harf ifadesiyle eşleşin.

\1

Son olarak, ilk operatörü tekrar eşleştirin.

Bununla eşleşen her şey ile değiştirilir ($2). Bu, çevredeki operatörlerin içindeki parçayı alır ve parantez içine alır, bu nedenle normal infix gösterimi gibi görünür.


2

QuadR , 33 32 27 bayt

-1 sayesinde Cows Quack . -5 Outgolfer Erik sayesinde .

((.)[\d¯\.]+){2}\2
⍎¯11↓⍵M

argüman / bayrak ile

Çevrimiçi deneyin!

Bu, 40 bayt Dyalog APL çözümüne eşdeğerdir:

'((.)[\d¯\.]+){2}\2'R{⍕⍎1↓¯1↓⍵.Match}⍣≡

Çevrimiçi deneyin!

açıklama

(parantez içindeki metin QuadR yerine Dyalog APL'yi belirtir)

(){2}\2 Aşağıdaki örüntü iki kez ve tüm ikisi de iki kez eşleşir:
  (.) herhangi bir karakter
  []+ ardından aşağıdaki karakter kümelerinden biri veya daha fazlası gelir:
   \dd igits,
   ¯ yüksek eksi (negatif işaret)
   \. süre

( ⎕R Olup R ' ile eplaced :)

( {} An ad alanına uygulanan aşağıdaki anonim fonksiyonun sonucu :)

⍵M ( ⍵.Match) Metni M atch
¯1↓ son karakteri (sembolü damla + - ×veya ÷)
1↓ ilk karakteri (simge) damla
 APL kodu olarak yürütmek
 (  stringify)

 ( ⍣≡) başka değişiklik kalmayana kadar değiştirme işlemini tekrarlayın


Bence düşebilirsin
Kritixi Lithos

@Cowsquack QuadR konusunda haklısınız. ⎕Rsayısal veriler üzerinde çalışmaz. Teşekkürler.
Adam


1

Haskell , 132 karakter

(134 bayt, çünkü ×ve ÷UTF-8 iki bayt almak)

f y|(n@(_:_),r)<-span(`elem`['.'..'9'])y=(read n,r)
f(c:d)|(l,_:s)<-f d,(m,_:r)<-f s=(o[c]l m,r)
o"+"=(+)
o"-"=(-)
o"×"=(*)
o"÷"=(/)

Çevrimiçi deneyin!

fgirdiyi olabildiğince ayrıştırır ve sonucun yanı sıra kalan dizeyi de (test durumlarında boştur) verir. Bu kurallara uygun değilse, ayrıştırılamayan kalan dizgiyi

Haskell , 139 karakter

...
g=fst.f

0

Perl, 64 53 bayt

Dahil +1için-p

perl -pe 's%([*-/])(([\d.]+|(?0))\1(?3))\1%($2)%&&redo;$_=eval' <<< "/4/-3-/1/2/-/"

Yanlışlıkla ayrıca ,(ilk argümanı atar) ve bazen de .(argümanları bir araya getirin) uygular . .hem ayrıştırma düzeyinde hem de değerlendirme düzeyinde ondalık noktaya müdahale ettiğinden çok güvenilir çalışmaz


0

Java 8, 205200 bayt

float O(String s){try{return new Float(s);}catch(Exception e){int f=s.charAt(0),i=s.indexOf(f,1);float a=O(s.substring(1,i)),b=O(s.substring(i+1,s.length()-1));return f<43?a*b:f<44?a+b:f<46?a-b:a/b;}}

Port of @Charlie C # cevabı . @Ceilingcat
sayesinde -5 bayt .

Çevrimiçi deneyin.

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.