Tạo một máy tính omnifix


16

Cảm hứng. Nghịch đảo.

Đánh giá một biểu thức omnifix nhất định.

Omnifix giống như ký hiệu trung gian của toán học thông thường, nhưng có thêm các bản sao của mỗi biểu tượng xung quanh các đối số. Các biểu tượng bên ngoài thay thế cho dấu ngoặc đơn và do đó không cần thêm dấu ngoặc đơn.

Bạn phải hỗ trợ cộng, trừ, nhân, chia và số thực dương (có thể viết số âm -0-n-) trong phạm vi hợp lý cho ngôn ngữ của bạn.

Cộng và trừ phải +-, nhưng bạn có thể sử dụng *hoặc ×cho thời gian và /hoặc ÷để phân chia. Các biểu tượng hợp lý khác sẽ được cho phép theo yêu cầu.

Brownie chỉ giải thích và các tính năng bổ sung (như các thao tác bổ sung, số âm, chuỗi, v.v.) Ngay cả khi câu trả lời của bạn không có các tính năng này, vui lòng hiển thị cách có thể.

Vui lòng cung cấp một liên kết để kiểm tra giải pháp của bạn nếu có thể.

Ví dụ

Để rõ ràng, các giải thích dưới đây sử dụng âm cao ( ¯) để chỉ ra số âm. Bạn có thể trả về số âm bằng cách sử dụng bất kỳ định dạng hợp lý.

-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.Bạn chắc chắn yêu thích APL.
Erik the Outgolfer 27/07/17

@EriktheOutgolfer Bạn có gợi ý nào tốt hơn? Ngoài ra, TI-BASIC sử dụng âm cao.
Adám

Thực tế không phải vì -s có thể bị nhầm lẫn với -s trong khi ¯s không thể bị nhầm lẫn với -s.
Erik the Outgolfer 27/07/17

Bah, tôi chỉ nhận thấy yêu cầu số thực. Quá nhiều cho giải pháp Retina số học số nguyên 290 byte của tôi ...
Neil

@Neil Tại sao bạn không đăng nó như một câu trả lời?
Adám

Câu trả lời:


4

C # (.NET Core) , 198 197 188 byte

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;}}

Hãy thử trực tuyến!

Sử dụng */.

Một hàm đệ quy. Đầu tiên, nó cố phân tích chuỗi đầu vào là a float. Nếu thất bại, nó tự gọi nó một cách đệ quy dưới dạng đối số các toán hạng thứ nhất và thứ hai và sau đó thực hiện thao tác được chọn trên các kết quả.

  • Lưu 1 byte nhờ ông Xcoder!
  • 9 byte được lưu nhờ TheLethalCoder!

IndefOf(f, 1)có thểIndexOf(f,1)
Ông Xcoder

1
Sử dụng floats thay vào đó, sử dụng mã char, khi bạn có chúng có thể rút ngắn chúng với ><ở một vài nơi.
TheLethalCoder

Bạn có thể chơi golf một byte thay đổi i+1,s.Length-i-2thành ++i,s.Length+~i.
Kevin Cruijssen

4

Python 3, 159 158 152 144 136 135 132 byte

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)))

Hãy thử trực tuyến!

Không cho phép số âm (mặc dù -0-5-hoạt động tất nhiên) và yêu cầu toán tử python.


Bạn có thể thêm một liên kết TIO?
Adám

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

1
với tất cả các trường hợp thử nghiệm: liên kết
Felipe Nardi Batista


1
if a:l[i]='(';i=t(t(i+1));l[i-1]=')'với return-~i135 byte: P
Felipe Nardi Batista

3

Võng mạc , 290 287 286 byte

\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

Hãy thử trực tuyến! Lưu ý: Chỉ có khả năng số học số nguyên, vì vậy một số trường hợp kiểm tra đã bị xóa. Chấp nhận và trả về số âm bằng cách sử dụng ¯tiền tố. Chỉnh sửa: Đã lưu 3 4 byte nhờ @Cowsquack. Giải trình:

\d+
¦$&$*

Tôi cần một số cách xử lý zero, vì vậy tôi sử dụng ¦làm tiền tố số dương. Các số sau đó được chuyển đổi thành unary.

¯¦
¯

Nhưng số âm chỉ cần một ¯tiền tố.

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

Trích dẫn +s trở nên xấu xí, vì vậy tôi biến các phép cộng thành phép trừ.

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

Nếu giá trị tuyệt đối của LHS của phép trừ nhỏ hơn RHS, hãy chuyển chúng xung quanh và phủ định cả hai mặt.

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

Ngoài ra nếu LHS của phép nhân hoặc chia là âm, phủ định cả hai mặt.

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

Ngoài ra nếu LHS của phép nhân bằng 0, thì kết quả bằng không. Ngoài ra, hai nhược điểm làm cho một cộng.

¯¦|¦¯
¯

Nhưng một điểm trừ và một điểm cộng (hoặc ngược lại) tạo ra một điểm trừ.

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

Trừ hai số cùng dấu. Làm điều này nhiều lần cho đến khi không còn phép trừ như vậy.

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

Nếu vẫn còn một phép trừ, các dấu hiệu phải khác nhau, vì vậy hãy cộng các số lại với nhau. (Nhưng chỉ làm điều này một lần, vì điều này có thể tiết lộ phép trừ hai số của cùng một dấu hiệu một lần nữa.)

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

Thực hiện phép nhân bằng phép cộng lặp lại.

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

Thực hiện phép chia số nguyên. Một trong các bước trên sẽ đơn giản hóa biểu thức, do đó lặp lại cho đến khi không còn thao tác nào nữa.

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

Chuyển đổi trở lại thập phân.


Wow, đó là - sử thi. Bài đăng Retina lớn nhất trên PPCG? Tuy nhiên, thông thường các giải pháp QuadR và Retina giống nhau. Tôi có thể truyền cảm hứng?
Adám

Trong dòng này +`-(([¯¦])1*)(1*)-\2\3-, [¯¦]có thể trở thành¯|¦
Kritixi Lithos

@Cowsquack Xảy ra ba lần trong thực tế, cảm ơn!
Neil

Có một bạn đã bỏ lỡ ([×÷]);)
Kritixi Lithos

1
@Cowsquack Bạn tốt hơn không nên tìm một cái khác, nếu không tôi sẽ phải gạch bỏ 4 ...
Neil

2

PHP , 116 114 109 byte

-5 cảm ơn Martin Ender

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

Sử dụng *để nhân và /chia. Các số âm xảy ra để làm việc mặc dù tôi không cố gắng cụ thể cho trường hợp đó.

Hãy thử trực tuyến!

Ungolfed và giải thích

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;"); 

Tôi cũng sẽ giải thích regex vì nó hơi kỳ diệu:

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


([*+/-])

Đầu tiên, chúng tôi muốn khớp bất kỳ toán tử nào trong bốn toán tử: *+/-

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

Sau đó, chúng ta cần khớp một số [\d.]+hoặc một biểu thức omnifix hợp lệ khác (?R).

\1

Sau đó, chúng tôi khớp với cùng một toán tử lúc đầu.

(?3)

Sau đó, chúng tôi làm điều tương tự chúng tôi đã làm trong nhóm 3: khớp một số hoặc biểu thức omnifix.

\1

Cuối cùng, khớp toán tử ban đầu một lần nữa.

Bất cứ điều gì phù hợp với điều này được thay thế bằng ($2). Cái này lấy phần bên trong các toán tử xung quanh và đặt nó vào trong ngoặc, vì vậy nó trông giống như ký hiệu infix thông thường.


2

QuadR , 33 32 27 byte

-1 cảm ơn Quack Quack . -5 cảm ơn Erik the Outgolfer .

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

với đối số / cờ

Hãy thử trực tuyến!

Điều này tương đương với giải pháp APL Dyalog 40 byte:

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

Hãy thử trực tuyến!

Giải trình

(văn bản được ngoặc đơn đề cập đến Dyalog APL thay vì QuadR)

(... ){2}\2 mẫu sau hai lần, và toàn bộ trận đấu hai lần quá:
  (.) bất kỳ ký tự
  [... ]+ theo sau là một hoặc nhiều bộ ký tự sau đây:
   \dd igits,
   ¯ trừ cao (dấu hiệu tiêu cực)
   \. giai đoạn

( ⎕R là R được đặt với :)

( {... } kết quả của hàm ẩn danh sau đây áp dụng cho các không gian tên ⍵ :)

⍵M ( ⍵.Match) văn bản của M atch
¯1↓ thả ký tự cuối cùng (ký hiệu + - ×hoặc ÷)
1↓ thả ký tự (ký hiệu) đầu tiên
 thực thi dưới dạng mã APL
 (  xâu chuỗi)

 ( ⍣≡) lặp lại thay thế cho đến khi không có thêm thay đổi xảy ra


Tôi nghĩ bạn có thể thả
Kritixi Lithos

@Cowsquack Bạn nói đúng về QuadR. ⎕Rkhông thể hoạt động trên dữ liệu số. Cảm ơn.
Adám


1

Haskell , 132 ký tự

(134 byte, vì ×÷lấy hai byte trong UTF-8)

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"÷"=(/)

Hãy thử trực tuyến!

fphân tích càng nhiều đầu vào càng tốt và mang lại kết quả cũng như chuỗi còn lại (trống trong các trường hợp thử nghiệm). Nếu điều đó không tuân thủ quy tắc, hãy loại bỏ chuỗi còn lại không thể chỉnh sửa bằng

Haskell , 139 ký tự

...
g=fst.f

0

Perl, 64 53 byte

Bao gồm +1cho-p

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

Vô tình cũng thực hiện ,(vứt bỏ đối số đầu tiên) và đôi khi .(nối các đối số lại với nhau). .không hoạt động rất đáng tin cậy mặc dù nó can thiệp vào dấu thập phân cả ở cấp độ phân tích cú pháp và ở cấp độ đánh giá


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.