Farklı taraflardan matematiksel bir ifade çözme


9

İfadenin alternatif kenarlarındaki öğeleri kullanarak matematiksel bir ifadeyi çözen bir program oluşturun. Yapılma şekli, soldan sağa okumak yerine, ilk karakteri, sonra sonuncuyu, sonra ikincisini, sonra ikincisini sonuncuyu vb. Okumanızdır. Bu, değerlendirmeniz ve çıkmanız gereken yeni bir ifade verecektir.

a*b/c+d-e
135798642  <-- Order you read the expression in
ae*-bd/+c  <-- Order of operation. 

Misal:

1*3/2+4-5
15*-34/+2 = -255

İfade "işe yaramazsa", çalışması 1için gerekli konumlara a eklenmelidir.

Birkaç örnek muhtemelen daha iyi gösterecektir:

Input: 1+1+1+1+1
Result: 23     // Because 1+1+1+1+1 -> 11++11++1 -> 23

Input: 1+2-3+12-5
Result: -19    // Because 1+2-3+12-5 -> 15+-22-13+ -> 15+-22-13+1 -> -19
               //                                 |
               //                                 Not valid expression

Input: 2*2*2*2*2
Result: 968    // Because 2*2*2*2*2 -> 22**22**2 -> 22*1*22*1*2 -> 968
               //                        ||  ||
               //                        Not valid, 1 must be inserted

Input: 17/2
Output: 127    // Because 17/2 = 127/ -> 127/1 -> 127

Desteklenmesi gereken operatörler + - * /. Parantez olmayacak. Normal matematik kuralları ve "sözdizimi" kullanılır, bu nedenle örneğin **üs anlamına gelmez. a++++1eşdeğerdir a+1(yani MATLAB stili, C ++ değil).

Herhangi bir şüphe durumunda, bazı geçerli işlemler şunlardır:

-a
+a
a++b
a+-b
a*-b
a*+b
a*++b
a/b
a/-b
a/+b
-a/--b

Ancak aşağıdakilerin tümü geçerli değildir. Ne ile değiştirilmeleri gerektiği gösterilmiştir:

a+      | a+1
a-      | a-1
a++++   | a++++1   (This is equivalent to a+1)
a*+++   | a*+++1   (This is equivalent to a*1)
a**b    | a*1*b
a*/b    | a*1/b
a/*b    | a/1*b
a*      | a*1
*a      | 1*a
***a    | 1*1*1*a

Kurallar:

  • Kod bir işlev veya tam bir program olabilir
  • Giriş STDIN veya işlev bağımsız değişkeni olabilir
  • Giriş, tırnak işaretleri olmadan''"" geçerli bir matematiksel ifade olmalıdır veya .
  • Çıktı, bir tamsayı, ondalık veya basitleştirilmiş bir kesir olarak yeni ifadeye yanıt olmalıdır.
  • Ondalık noktadan sonra en az üç basamak desteklenmelidir. Öyleyse 1/3 = 0.333değil 0.33. 0.333333333kabul edildi.
  • ans = ... kabul edildi.
  • Öncü ve sondaki satır ve boşluklar kabul edilir.
  • Giriş yalnızca tamsayı olacak
  • Sıfıra bölme bir hata, NaN, Inf vb. İle sonuçlanabilir. Bir sayının çıkışı kabul edilmez.

Her zaman olduğu gibi, bayttaki en kısa kod kazanır. Kazanan, yarışmanın yayınlandığı günden bir hafta sonra seçilecektir. Daha sonra gönderilen cevaplar, mevcut liderden daha kısasa yine de kazanabilir.


giriş dizgisinde maksimum uzunluk veya operatör / tamsayı girişi sayısı var mı? Ayrıca, matematik kadar desteklemem 2^64gerekiyor ve eğer devam ederseniz hata veya sarmalı mı?
kedi

"Çıktı cevap [ ... ] basitleştirilmiş kesir olmalıdır ..." yani 0/0ifade tamsayı bölme veya modulo sıfıra dönüştüğünde geri dönebilir miyim ?
kedi

2
Cevap sıfıra bölme verirse x/0geçerli bir çıktıdır. Yanlış bir cevap vermediği sürece sorun değil. Hata ve "Sayı değil" tanımı gereği doğrudur ve sonsuzluk "yeterince doğrudur",
Stewie Griffin

Emin olmak için - eval kullanılabilir, değil mi?
orlp

Evet, eval tamam.
Stewie Griffin

Yanıtlar:


3

Perl, 108100 bayt

$_="";while(@F){$_.=shift@F;$_.=pop@F}s@(\*|/)\1+@\1@g;s@^[*/]@1$&@;s@\D$@$&1@;s@\D@$&@g;$_=eval

Kod 96 bayt artı komut satırı bağımsız değişkeni için 4'tür -pF//; burada

  • -pekler while (<>) { .. } continue { print }ve
  • -F//girişi böler ve koyar @F.

Girişin sondaki bir satırsonu olmaması gerektiğini unutmayın, bu nedenle /bin/echo -n 'formula' | perl ...

Daha az golf:

$_='';              # reset $_
while(@F) {         # reorder input
   $_.=shift @F;    # take first element off of @_
   $_.=pop @F       # idem for last; if @F is empty, undef is appended
}

s@(\*|/)\1+@\1@g;   # replace 2 or more '*' or '/' with just one: *1 and /1 = nop
s@^[*/]@1$&@;       # if expression starts with * or / prepend a 1
s@\D$@$&1@;         # if expression doesn't end with a number, append 1
s@\D@$& @g;         # eval doesn't like '++1': add spaces after operators
$_ = eval           # set $_ to 3v1l, so the `-p` will print the new value

Test yapmak

Yukarıdakini adlı bir dosyaya 114.plve aşağıdaki test komut dosyasını yanındaki bir dosyaya koyun:

%test = (
    '1+1+1+1+1' =>   23,
    '1*3/2+4-5' => -255,
    '1+2-3+12-5'=>  -19,
    '2*2*2*2*2' =>  968,
    '17/2'      =>  127,
    '--/-1-2-'  =>   -2,
    '**2*'      =>    2,
    '++1++'     =>    1,
    '/2/'       =>  0.5,
    '10/'       =>   '',
);

printf "%-20s -> %5s: %5s\n", $_, $test{$_}, `/bin/echo -n '$_' | perl -pF// 114.pl`
for keys %test;

Çalıştırmak çıktılar:

++1++                ->     1:     1
**2*                 ->     2:     2
17/2                 ->   127:   127
10/                  ->      :
1+1+1+1+1            ->    23:    23
1*3/2+4-5            ->  -255:  -255
2*2*2*2*2            ->   968:   968
1+2-3+12-5           ->   -19:   -19
--/-1-2-             ->    -2:    -2
/2/                  ->   0.5:   0.5

1/0Sıfır hata ile bölünmeye neden olduğunu unutmayın : boş dize ile temsil edilen evalçıktılar undef.


Birkaç test durumu daha! Onları kullanacağım
edc65

3

JavaScript ES6, 105 106

Düzenle Kaydedilmiş 1 byte thx @Kenney

t=>eval("for(t=[...t],p=o='';c=t.reverse().pop();p=c)o+=p<'0'?(c=='/'|c<'+'||' ')+c:c;eval(p<'0'?o+1:o)")

// Less golfed
t=>{
  for(t = [...t], p = o = '';
      c = t.reverse().pop();
      p = c)
    o += p<'0' 
     ? (c=='/' | c=='*' || ' ')+c  // '1' or ' '
     : c;
  return eval(p<'0' ? o+1 : o)
}

Test snippet'i

f=t=>eval("for(t=[...t],p=o='';c=t.reverse().pop();p=c)o+=p<'0'?(c=='/'|c<'+'||' ')+c:c;eval(p<'0'?o+1:o)")

console.log=x=>O.innerHTML+=x+'\n'

function test() { console.log(I.value + ' -> '+f(I.value)) }

;['1+1+1+1+1', '1*3/2+4-5', '1+2-3+12-5', '2*2*2*2*2',
  '17/2', '--/-1-2-', '**2*', '++1++', '/2/', '10/' ]
.forEach(t=>console.log(t+' -> '+f(t)))
Your test <input id=I><button onclick="test()">-></button>
<pre id=O></pre>


Size bir byte kaydedildi: p < '0' ? ( c=='/' | c<'+' || ' ' )+c : c ;.
Kenney
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.