Máy tính hoạt động số nguyên đơn giản


28

Thực hiện một máy tính kịch bản số nguyên hoạt động đơn giản.

Khái niệm

Bộ tích lũy bắt đầu từ 0 và có các thao tác được thực hiện trên nó. Vào cuối chương trình đầu ra giá trị của bộ tích lũy.

Hoạt động:

  • +thêm 1vào bộ tích lũy
  • -trừ 1từ tích lũy
  • * nhân số tích lũy bằng 2
  • / chia tích lũy cho 2

Kịch bản mẫu

Đầu vào ++**--/sẽ cho đầu ra 3.

Ví dụ thực hiện

def calc(s)
    i = 0
    s.chars.each do |o|
        case o
            when '+'
                i += 1
            when '-'
                i -= 1
            when '*'
                i *= 2
            when '/'
                i /= 2
        end
    end
    return i
end

Quy tắc

  • Đây là , vì vậy câu trả lời thấp nhất trong byte thắng, nhưng không được chọn.
  • Triển khai sáng tạo được khuyến khích.
  • Sơ hở tiêu chuẩn bị cấm.
  • Bạn nhận được chương trình thông qua stdin hoặc đối số và bạn có thể xuất câu trả lời qua giá trị trả về hoặc thiết bị xuất chuẩn.
  • Chúc vui vẻ.
  • Phân chia cắt xuống vì nó là phân chia số nguyên.
  • Chương trình -/trở lại -1.

Các trường hợp thử nghiệm

*///*-*+-+
-1
/*+/*+++/*///*/+-+//*+-+-/----*-*-+++*+**+/*--///+*-/+//*//-+++--++/-**--/+--/*-/+*//*+-*-*/*+*+/+*-
-17 
+++-+--/-*/---++/-+*-//+/++-*--+*+/*/*/++--++-+//++--*/***-*+++--+-*//-*/+*/+-*++**+--*/*//-*--**-/-*+**-/*-**/*+*-*/--+/+/+//-+*/---///+**////-*//+-+-/+--/**///*+//+++/+*++**++//**+**+-*/+/*/*++-/+**+--+*++++/-*-/*+--/++*/-++/-**++++/-/+/--*/-/+---**//*///-//*+-*----+//--/-/+*/-+++-+*-*+*+-/-//*-//+/*-+//+/+/*-/-/+//+**/-****/-**-//+/+-+/*-+*++*/-/++*/-//*--+*--/-+-+/+/**/-***+/-/++-++*+*-+*+*-+-//+/-++*+/*//*-+/+*/-+/-/*/-/-+*+**/*//*+/+---+*+++*+/+-**/-+-/+*---/-*+/-++*//*/-+-*+--**/-////*/--/*--//-**/*++*+/*+/-+/--**/*-+*+/+-*+*+--*///+-++/+//+*/-+/**--//*/+++/*+*////+-*-//--*+/*/-+**/*//+*+-//+--+*-+/-**-*/+//*+---*+//*/+**/*--/--+/*-*+*++--*+//+*+-++--+-*-*-+--**+/+*-/+*+-/---+-*+-+-/++/+*///*/*-+-*//-+-++/++/*/-++/**--+-////-//+/*//+**/*+-+/+/+///*+*///*-/+/*/-//-*-**//-/-+--+/-*--+-++**++//*--/*++--*-/-///-+/+//--+*//-**-/*-*/+*/-*-*//--++*//-*/++//+/-++-+-*/*-+++**-/-*++++**+-+++-+-***-+//+-/**-+/*+****-*+++*/-*-/***/-/*+/*****++*+/-/-**-+-*-*-++**/*+-/*-+*++-/+/-++*-/*-****-*
18773342

2
Vì vậy, ... nó không hoàn toàn là số nguyên, vì /có thể mang lại số nguyên.
Conor O'Brien

2
Sau đó, bạn nên xác định rõ điều này.
Conor O'Brien

5
Nên -/trả lại cái gì?
Dennis

4
Tôi không thể không chú ý rằng đoạn mã được nêu trên trang chủ của rỉ sét đã giải quyết thách thức này.
Zwei

4
Vui lòng thêm nhiều trường hợp thử nghiệm.
Martin Ender

Câu trả lời:


28

Python 2, 48 byte

i=0
for c in input():exec"i=i%s2&-2"%c
print i/2

Liệu +2, -2, *2, hoặc /2. Bằng cách làm +2-2hơn là +1-1 , chúng tôi đang làm việc trong các đơn vị nhân đôi, do đó, sản lượng cuối cùng cần phải giảm đi một nửa. Ngoại trừ, phân chia sàn /bây giờ cần làm tròn xuống bội số của 2, được thực hiện với &-2.


Thật là tuyệt vời! Nếu bạn muốn tự gửi cho mình một cổng CJam thì điều này hiện đang dẫn đến thách thức: 0q{2\~-2&}/2/( 2\~tránh người vận hành với toán hạng thứ hai 2, -2&là bitwise AND, 2/là phép chia cuối cùng cho hai. q{...}/Là một thông báo cho đầu vào và 0chỉ là lần đầu tiên giá trị.)
Martin Ender

Bạn có thể đăng nó, tôi không biết CJam.
xnor

Thực sự thông minh! Được chuyển sang ES6, điều này sẽ dễ dàng vượt qua câu trả lời của tôi
edc65

Sử dụng rực rỡ của trăn. Đã học được điều gì đó mới từ điều này.
Jacobr365

12

Haskell, 51 byte

x#'+'=x+1
x#'-'=x-1
x#'*'=x*2
x#_=div x 2 
foldl(#)0

Ví dụ sử dụng: foldl(#)0 $ "++**--/"-> 3.


12

Thạch , 18 17 byte

‘

’

:2
Ḥ
O0;ṛĿ/

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

Làm thế nào nó hoạt động

Sáu dòng đầu tiên xác định các liên kết của trình trợ giúp với các chỉ số từ 1 đến 6 ; họ tăng, không làm gì, giảm, không làm gì, giảm một nửa (sàn) và gấp đôi.

Liên kết chính - O0;ṛĿ/- chuyển đổi các ký tự đầu vào thành các điểm mã của chúng ( O), thêm 0 (giá trị ban đầu) vào mảng các điểm mã 0;, sau đó giảm mảng được tạo như sau.

Giá trị ban đầu là phần tử đầu tiên của mảng, tức là 0 được chuẩn bị trước . Quicklink ṛĿđược gọi cho mọi phần tử sau trong mảng, với giá trị trả về cuối cùng là đối số bên trái và phần tử hiện tại là phần tử bên phải. Nó kiểm tra đối số đúng của nó ( ) và đánh giá liên kết với chỉ mục Ŀđó một cách đơn điệu ( ), do đó áp dụng thao tác mong muốn.


10
Điều này trông giống như câu trả lời thạch với những dòng mới nhất
Conor O'Brien

10

Python 2, 54 byte

i=0
for c in input():exec"i=i"+c+`~ord(c)%5%3`
print i

Đầu vào được thực hiện dưới dạng một chuỗi ký tự. ~ord(c)%5%3ánh xạ các toán tử đến các toán hạng bên phải tương ứng.

Trước đây, tôi đã sử dụng hash(c)%55%3không mang lại kết quả nhất quán giữa các phiên bản Python khác nhau. Điều này khuyến khích tôi khám phá các công thức khác.


dường như không hoạt động ...
Lemon phá hủy

55,3 và 65,4 là hai đoạn ngắn nhất cho mod băm kép trong python 2
Jonathan Allan

@DeststallibleWateriwi dành cho tôi: ideone
Jonathan Allan

Tôi nghĩ hashlà phiên bản Python cụ thể - ideone sử dụng 2.7.10, cung cấp [1, 1, 2, 2]bốn bản đồ, trong khi tại địa phương vào ngày 2.7.12 tôi nhận được[2, 0, 1, 0]
Sp3000

1
nó hoạt động trên ideone, nhưng không phải trên python máy tính của tôi. Có lẽ phụ thuộc vào phiên bản, trong trường hợp phiên bản nào cần lưu ý EDIT: ninja'd: /
Lemon

10

Silos , 133 211 byte

:s
def : lbl G GOTO
readIO
i-46
if i a
i+2
if i b
i+2
if i c
i+1
if i d
G e
:a
G v
:p
a-1
a/2
G o
:v
a+1
if a p
a-1
j=a
j/2
k=j
k*2
k-a
a/2
if k t
G o
:t
a-1
:o
G s
:b
a-1
G s
:c
a+1
G s
:d
a*2
G s
:e
printInt a

Lấy mã ASCII của các nhà khai thác.

Dùng thử trực tuyến với các trường hợp thử nghiệm:
-/
++**--/
*///*-*+-+


loadLine golfier?
Rohan Jhunjhunwala

OP làm rõ; -/nên trả về -1 , không phải 0 .
Dennis

@Dennis đã sửa. Đã thêm rất nhiều byte mặc dù: /
betseg

9

Máy Turing - 23 trạng thái (684 byte)

Hãy thử nó ở đây - permalink

0 * * r 0
0 _ . l 1
1 * * l 1
1 _ * l 2
2 * 0 r 3
3 _ * r 3
3 + _ l +
3 - _ l -
3 x _ l x
3 / _ l /
+ _ * l +
+ * * * 4
4 - * l 5
4 _ 1 r 6
4 0 1 l 7
4 1 0 l 4
- _ * l -
- * * * 5
5 - * l 4
5 _ * r 8
5 0 1 l 5
5 1 0 l 7
x * * l x
x 1 0 l 9
x 0 0 l a
9 _ 1 r 6
9 1 1 l 9
9 0 1 l a
a _ _ r 6
a 1 0 l 9
a 0 0 l a
/ _ * l /
/ * * l b
b * * l b
b _ * r c
c 0 0 r d
c 1 0 r e
d * * l 7 
d 0 0 r d
d 1 0 r e
e _ * l 7
e - * l 4
e 0 1 r d
e 1 1 r e
8 * * r 8
8 - _ r 3
8 _ - r 3
7 * * l 7
7 _ * r f
f 0 _ r f
f 1 * r 6
f * _ l g
g * 0 r 6
6 * * r 6
6 _ * r 3
3 . _ l h
h _ * l h
h - _ l i
h * * l halt
i * * l i
i _ - r halt

Đầu vào không được chứa bất kỳ '*' nào vì đây là ký tự đặc biệt trong mã máy Turing. Sử dụng 'x' thay thế. Đưa ra câu trả lời trong nhị phân.

Mã không cố định

init2 * * r init2
init2 _ . l init0
init0 * * l init0
init0 _ * l init1
init1 * 0 r readop
readop _ * r readop
readop + _ l +
readop - _ l -
readop x _ l x
readop / _ l /
+ _ * l +
+ * * * inc
inc - * l dec
inc _ 1 r return
inc 0 1 l zero
inc 1 0 l inc
- _ * l -
- * * * dec
dec - * l inc
dec _ * r neg
dec 0 1 l dec
dec 1 0 l zero
x * * l x
x 1 0 l x1
x 0 0 l x0
x1 _ 1 r return
x1 1 1 l x1
x1 0 1 l x0
x0 _ _ r return
x0 1 0 l x1
x0 0 0 l x0
/ _ * l /
/ * * l //
// * * l //
// _ * r div
div 0 0 r div0
div 1 0 r div1
div0 * * l zero 
div0 0 0 r div0
div0 1 0 r div1
div1 _ * l zero
div1 - * l inc
div1 0 1 r div0
div1 1 1 r div1
neg * * r neg
neg - _ r readop
neg _ - r readop
zero * * l zero
zero _ * r zero1
zero1 0 _ r zero1
zero1 1 * r return
zero1 * _ l zero2
zero2 * 0 r return
return * * r return
return _ * r readop
readop . _ l fin
fin _ * l fin
fin - _ l min
fin * * l halt
min * * l min
min _ - r halt

Giải thích về các trạng thái:

Khởi tạo:
Các trạng thái này được truy cập một lần vào đầu mỗi lần chạy, bắt đầu bằng init2

  • init2: Di chuyển tất cả các bên phải và đặt một '.'. Bằng cách đó, TM biết khi nào nên dừng lại. Thay đổi thành 'init0'.
  • init0: Di chuyển tất cả trở lại bên trái cho đến khi đầu đọc một khoảng trắng. Sau đó di chuyển một ô sang trái. Thay đổi thành 'init1'.
  • init1: Đặt số 0 và di chuyển một ô sang bên phải và thay đổi thành 'readop'.

Hướng dẫn đọc:
Những trạng thái này sẽ được truy cập nhiều lần trong suốt chương trình

  • readop: Di chuyển tất cả các bên phải cho đến khi nó đọc một toán tử hoặc '.'. Nếu nó chạm một toán tử, thay đổi sang trạng thái tương ứng (+, -, x, /). Nếu nó chạm '.', Hãy đổi sang trạng thái 'vây'.

  • return: Trả đầu về khoảng trống giữa tổng số đang chạy và các toán tử. Sau đó thay đổi thành 'readop'.

Hoạt động:
Những hoạt động này làm công việc bẩn thực tế

  • +: Di chuyển sang trái cho đến khi đầu đọc bất kỳ ký tự không phải khoảng trắng nào. Nếu ký tự này là '-', di chuyển sang trái và thay đổi thành 'dec'. Nếu không, hãy đổi thành 'inc'.

  • -: Tương tự như '+', ngoại trừ thay đổi thành 'inc' nếu có '-' và 'dec' nếu không.

  • inc: Nếu chữ số dưới đầu là 0 (hoặc khoảng trắng), thay đổi nó thành 1 và thay đổi thành 'zero'. Nếu chữ số là 1, thay đổi thành 0, sau đó lặp lại trên chữ số tiếp theo.

  • dec: Tương tự như inc, ngoại trừ 1 chuyển sang 0, 0 chuyển sang 1 và nếu đầu đọc khoảng trắng, hãy đổi thành 'neg'.

  • x, x0, x1: Bẻ số một sang trái. Thay đổi thành 'trở lại'.

  • /, //, div, div0, div1: Di chuyển tất cả các bên phải của số, sau đó bẻ khóa một bên phải. Nếu có '-', hãy đổi thành 'inc'. Điều này mô phỏng làm tròn số âm. Nếu không, thay đổi thành 'không'

  • neg: Đặt dấu '-' sau số rồi đổi thành 'readop'

  • zero, zero1, zero2: Xóa các số 0 đứng đầu và thay đổi thành 'readop'

Dọn dẹp: Làm cho đầu ra có thể trình bày

  • vây, tối thiểu: Di chuyển '-' trước số nếu cần. Tạm dừng lại.

1
Nghĩ rằng đọc mã này là rất rất mát mẻ. Vì vậy, cảm ơn vì đã làm sáng ngày của tôi.
Jacobr365

8

Perl 6 , 53  52 byte

{([Ro] %(<+ - * />Z=>*+1,*-1,* *2,*div 2){.comb})(0)}

{[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}

Giải trình:

# bare block lambda that has one implicit parameter 「$_」
{
  (
    # reduce the code refs using ring operator 「∘」 in reverse 「R」
    [R[o]]

      # produce a hash from:
      %(

        # list of pairs of "operator" to code ref
        # ( similar to 「'+' => { $^a + 1 }」 )

          # keys
          < + - * / >

        # keys and values joined using infix zip operator 「Z」
        # combined with the infix Pair constructor operator 「=>」
        Z[=>]

          # values (Whatever lambdas)
          * + 1,
          * - 1,
          * × 2, # same as 「* * 2」
          * div 2,

      ){

        # split the block's argument into chars
        # and use them as keys to the hash
        # which will result in a list of code refs
        .comb

      }

  # call composed code ref with 0
  )(0)
}

Sử dụng:

my $input = '++**--/'
my $output = {[Ro](%(<+ - * />Z=>*+1,*-1,*×2,*div 2){.comb})(0)}.( $input );
say $output; # 3
say $output.^name; # Int


6

05AB1E , 20 byte

Cảm ơn Enigma đã sửa lỗi-/ bọ!

Đối với 16 byte nếu nó không phải là phép chia số nguyên : Î"+-*/""><·;"‡.V.

Î…+-*"><·"‡'/"2÷":.V

Giải trình:

Î                      # Push 0, which is our starting variable, and input
 …+-*                  # Push the string "+-*"
     "><·"             # Push the string "><·"
          ‡            # Transliterate. The following changes:
                           "+" -> ">"
                           "-" -> "<"
                           "*" -> "·"
           '/"2÷":     # Replace "/" by "2÷"
                  .V   # Evaluate the code as 05AB1E code...
                           '>' is increment by 1
                           '<' is decrement by 1
                           '·' is multiply by 2
                           '2÷' is integer divide by two
                       # Implicitly output the result

Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến!


OP làm rõ; -/nên trả về -1 , không phải 0 .
Dennis

Vấn đề phân chia số âm có thể được khắc phục với Î…+-*"><·"‡'/"2÷":.Vcùng một số byte.
Emigna

@Dennis Đã sửa lỗi.
Ad Nam

@Emigna Cảm ơn :)
Adnan

5

JavaScript ES6, 80 68 byte

k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}‌​[o],0)

Đã tiết kiệm được 12 byte nhờ Neil!


Câu trả lời thứ hai sẽ dễ đọc hơn nếu bạn xóa "c"+và viết, "c+1 c-1 c*2 c/2|0".splitv.v.
Neil

Đối với câu trả lời đầu tiên, tại sao không viết o=>c=[c+1,c-1,c*2,c/2|0]["+-*/".indexOf(o)]hoặc tôi nghĩ bạn có thể tiếp tục lưu byte bằng cách sử dụng o=>c={"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o].
Neil

k=>[...k].reduce((c,o)=>+{"+":c+1,"-":c-1,"*":c*2,"/":c/2|0}[o],0)có thể làm việc thậm chí còn ngắn hơn, nhưng tôi đã mất hết ...
Neil

@Neil Ah, vâng, tôi đã quên điều này
Conor O'Brien

1
Bạn bằng cách nào đó có các ký tự có độ rộng bằng không giữa }[o], vì vậy đây thực sự chỉ dài 66 byte. Ngoài ra, OP làm rõ; -/nên trả về -1 , không phải 0 .
Dennis

5

Ruby, 48 44 42 + 1 = 43 byte

+1 byte cho -ncờ. Đưa đầu vào vào STDIN.

i=0
gsub(/./){i=i.send$&,"+-"[$&]?1:2}
p i

Xem nó trên ideone (sử dụng $_vì ideone không lấy cờ dòng lệnh): http://ideone.com/3udQ3H



4

Con trăn 2 58 56 byte

-2 byte nhờ @Lynn

r=0
for c in input():exec'r=r'+c+`2-ord(c)%11%3`
print r

Các ordinals của các nhân vật +-*/43,45,42,47modulo 11 đây là những 10,1,9,3modulo 3 đó là những 1,1,0,0, 2 ít những được 1,1,2,2đưa ra số tiền chúng ta cần cho mỗi hoạt động: r=r+1, r=r-1, r=r*2, vàr=r/2


Trước:

r=0
for c in input():exec'r=r'+c+`(ord(c)%5==2)+1`
print r

Thế còn 2-ord(c)%11%3?
Lynn

@Lynn Tôi sẽ lấy nó nếu nó ổn với bạn? (nhưng thực sự nghĩ rằng nó đủ để thay đổi bạn có thể đăng nó)
Jonathan Allan

2
Hãy tiếp tục :) ----
Lynn

4

Toán học, 83 73 70 byte

10 byte được lưu do @MartinEnder .

(#/*##2&@@#/.Thread[{"+","-","*","/"}->{#+1&,#-1&,2#&,⌊#/2⌋&}])@0&

Chức năng ẩn danh. Lấy danh sách các ký tự làm đầu vào và trả về một số làm đầu ra. Gợi ý chơi golf chào mừng.


4

Silos , 175 164 byte

loadLine
a=256
o=get a
lbla
a+1
o-42
p=o
p-1
p/p
p-1
r-p
s=o
s-3
s/s
s-1
r+s
m=o
m/m
m-2
m|
r*m
t=r
t%2
d=o
d-5
d/d
d-1
t*d
d-1
d|
r-t
r/d
o=get a
if o a
printInt r

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

Phương pháp nhập liệu lành mạnh. Phân chia số nguyên đúng (tròn về phía-vô cực).


4

C #, 87 81 byte

int f(string s){int i=0;foreach(var c in s)i=c<43?i*2:c<46?i+44-c:i>>1;return i;}

Ung dung:

int f(string s)
{
    int i = 0;

    foreach (var c in s)
        i = c < 43 ? i * 2
          : c < 46 ? i + 44 - c
          : i >> 1;

    return i;
}

Đầu vào được coi là hợp lệ. Việc chia hai được thực hiện bằng cách dịch chuyển đúng một bit, bởi vì phép chia thông thường luôn làm tròn về 0 và bit dịch chuyển luôn làm tròn xuống. Tăng và giảm sử dụng thuận tiện khoảng cách 1 giữa các mã ASCII cho +-.


Một số tình yêu cho cú pháp C # 6 mới và phương pháp tổng hợp của Linq? int f(string s)=>s.Aggregate(0,(i,c)=>c<43?i*2:c<46?i+44-c:i>>1);(65 byte)
Cyril Gandon

@CyrilGandon theo như tôi biết rằng sẽ phải bao gồm "sử dụng System.Linq;", làm cho nó dài hơn 19 và đặt nó ở mức 84 byte. Đó là lý do tại sao tôi đã không làm điều đó.
Scepheo

4

Javascript (ES6), 57 byte (mảng) / 60 byte (số nguyên)

Trả về một mảng của tất cả các kết quả trung gian:

o=>[...o].map(c=>x=[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],x=0)

Ví dụ, đầu ra cho "++**--/"sẽ là [1, 2, 4, 8, 7, 6, 3].

Chỉ trả về kết quả cuối cùng:

o=>[...o].reduce((x,c)=>[x>>1,x+1,x*2,x-1][eval(2+c+3)&3],0)

Làm thế nào nó hoạt động

Cả hai giải pháp đều dựa trên cùng một ý tưởng: sử dụng hàm băm hoàn hảo eval(2+c+3)&3để ánh xạ các ký tự toán tử khác nhau cvào [0, 3].

 operator | eval(2+c+3)  | eval(2+c+3)&3
----------+--------------+---------------
    +     |  2+3 = 5     |    5 & 3 = 1
    -     |  2-3 = -1    |   -1 & 3 = 3
    *     |  2*3 = 6     |    6 & 3 = 2
    /     |  2/3 ~= 0.67 | 0.67 & 3 = 0

3

JavaScript (ES6), 57

a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a

Lưu ý: giá trị ban đầu cho bộ tích lũy là chuỗi chương trình, sử dụng các phép toán bit (~, >>, <<, |), nó được chuyển đổi thành 0 ở lần sử dụng đầu tiên.

Lưu ý phụ, câu trả lời thông minh của @xnor sẽ đạt 40 điểm được chuyển sang javascript:

a=>[...a].map(c=>a=eval(~~a+c+2))&&a>>1

(nếu bạn thích điều này, hãy bỏ phiếu cho anh ấy)

Kiểm tra

f=a=>[...a].map(c=>a=c<'+'?a<<1:c<'-'?-~a:c<'/'?~-a:a>>1)|a

function update() {
  O.textContent = f(I.value);
}

update()
<input value='++**--/' id=I oninput='update()'><pre id=O></pre>


3

Java, 77 byte

int f(String s){return s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);}

Sử dụng java 8 luồng.


1
Câu trả lời tốt đẹp, và chào mừng đến với trang web! Tôi không biết gì về java, nhưng bạn có thể thay đổi r >> 1để r>>1và tiết kiệm 2 byte?
DJMcMayhem

Bạn hoàn toàn chính xác, cảm ơn @DJMcMayhem
primodemus

1
Tuyệt vời, rất vui vì tôi có thể giúp! Thêm một lưu ý nữa, tôi đang đếm 77 byte. Bạn đã tình cờ bao gồm dòng mới trong số byte của bạn? Bạn có thể mất thêm một byte vì điều đó không cần thiết.
DJMcMayhem

Đúng một lần nữa @DJMcMayhem, aparently wc đếm byte kết thúc null hoặc một cái gì đó ...
primodemus

1
như bạn đang sử dụng java8, tại sao không xác định hàm bằng cách sử dụng lambda, s->s.chars().reduce(0,(r,c)->c<43?r*2:c<46?r+44-c:r>>1);nó sẽ cung cấp cho bạn 56 byte
user902383

3

GNU sed, 65 59 57 byte

Chỉnh sửa: ngắn hơn 2 byte nhờ nhận xét của Toby Speight

s/[+-]/1&/g
s/*/2&/g
s:/:d0>@2&:g
s/.*/dc -e"0[1-]s@&p"/e

Chạy:

sed -f simple_calculator.sed <<< "*///*-*+-+"

Đầu ra:

-1

Các sedkịch bản chuẩn bị đầu vào cho các dccuộc gọi vỏ ở cuối, sau này chấp nhận đầu vào trong ký hiệu Xếp Ba Lan . Khi chia, nếu số là âm ( d0>), [1-]lệnh giảm được lưu trong thanh ghi @được gọi. Ví dụ chuyển đổi: + - * /-> 1+ 1- 2* d0>@2/.


Bạn không cần các trích dẫn xung quanh đối số thành dc, nếu không có khoảng trắng và không có tệp nào khớp với [1-]mẫu ...
Toby Speight

@TobySpeight Trong suy nghĩ của tôi, tôi đã chuyển ý nghĩa của svới S. Tôi quên rằng nó không thay thế ngăn xếp của registry, nó đẩy lên nó, có tác dụng ngược lại với những gì tôi muốn (vì tôi đã sử dụng nó cho mọi thứ /). Các trích dẫn vẫn cần thiết bởi vì bạn có /các ký hiệu trong đó làm cho chuỗi được hiểu là đường dẫn tệp :) Tôi đã cạo thêm 1 byte bằng cách xóa khoảng trắng sau dấu -e.
seshoumara

1
Tôi sẽ không tranh luận về -etên tập tin, vì vậy bạn không cần trích dẫn cho /- hãy thử! Tôi nghĩ rằng đó là hợp lý cho một golf-code yêu cầu rằng thư mục làm việc hiện tại không chứa bất kỳ tệp nào bắt đầu bằng 01s@hoặc 0-s@.
Toby Speight

@TobySpeight bạn đã đúng về -evấn đề này /, tuy nhiên các trích dẫn vẫn được yêu cầu như tôi vừa thấy bây giờ. Các >được giải thích trực tiếp bằng vỏ như một nhà điều hành chuyển hướng tôi nghĩ, vì tôi đã nhận lỗi này:cannot create @2/d0: Directory nonexistent
seshoumara

À, vâng, tôi đã không xem xét >. Bạn cần báo giá, sau khi tất cả. Xin lỗi vì (cố gắng) đánh lạc hướng! Và, mặc dù việc thêm dấu gạch chéo ngược trông giống như một ký tự, nó cần được nhân đôi trong một s///thay thế, vì vậy không có lợi ích gì ở đó ...
Toby Speight

3

PHP, 75 byte

Điều này sử dụng một phiên bản sửa đổi của câu trả lời của Jörg Hülsermann .

eval(preg_replace('~.~','$s=($s\0(2-ord("\0")%11%3))|0;',$argv[1]));echo$s;

Nó chủ yếu dựa vào thay thế chuỗi, sử dụng biểu thức chính quy đơn giản ( ~.~).

Biến $sđược gán lại với giá trị mới cho mỗi ký tự. Cuối cùng, nó đưa ra kết quả.


Lưu ý : Điều này có nghĩa là được thực hiện bằng cách sử dụng -rcờ.


Hãy thử nó ở đây:

http://sandbox.onlinephpfifts.com/code/7d2adc2a500268c011222d8d953d9b837f2312aa

Sự khác biệt:

  • Thay vì echo$s , tôi đang sử dụng sprintf($s). Cả hai thực hiện cùng một hành động về số. Vì đây chỉ là để thử nghiệm, nó là tốt.
  • Trong trường hợp không có đối số được thông qua, nó sẽ chạy như thể bạn đã vượt qua ++*+làm đối số đầu tiên, sẽ hiển thị 5.

Yay! Công cụ esửa đổi đã trở lại! : D
Tít

@Titus Tôi không hiểu. Bạn có thể xây dựng một chút?
Ismael Miguel

PHP trước phiên bản 7 có một bộ sửa đổi mẫue , được thay thế bởi preg_replace_callbackvà có thể bị lạm dụng để ... nhưng đây không phải là điều đó.
Tít

@Titus Công cụ sửa đổi cha đã được sử dụng để nói rằng đầu ra sẽ là mã PHP thực tế và để cố gắng giữ đúng cú pháp. Điều này ở đây, không sử dụng nó, nhưng thay thế mỗi ký tự bằng một đoạn mã để thực thi, bất kể cú pháp của nó là gì. Đầu vào xấu sẽ gây ra vấn đề bảo mật nghiêm trọng.
Ismael Miguel

Tôi biết. Nhưng nó giống.
Tít

2

Mẻ, 61 byte

@set n=
@for %%a in (%*)do @set/an=n%%a2^&-2
@cmd/cset/an/2

Bản dịch câu trả lời Python tuyệt vời của @ xnor.



2

PHP, 104 102 82 byte

Phiên bản đầu tiên với eval:

$i=0;while($c<9999)eval('$i'.['+'=>'++','-'=>'--','*'=>'*=2','/'=>'>>=1'][$argv[1]{$c++}].';');echo$i;

Phiên bản thứ hai với các nhà khai thác ternary:

while($o=ord($argv[1]{$c++}))$i=$o<43?$i*2:($o<44?$i+1:($o<46?$i-1:$i>>1));echo$i;

Lấy chuỗi đầu vào làm đối số đầu tiên từ dòng lệnh.

"Chỉ" này hoạt động cho các chuỗi đầu vào ngắn hơn 10.000 ký tự - rất nhiều. Đã thử nghiệm với tất cả các trường hợp thử nghiệm, thật không may, không thể lưu vào phần khởi tạo ngay từ đầu.Phiên bản thứ hai hoạt động với các chuỗi có độ dài bất kỳ và không cần khởi tạo. :-)

Phần tử chính là hàm eval thao tác $idựa trên bản đồ các phép toán số học, khá đơn giản ngoại trừ phép chia. PHP trả về một float khi sử dụng /intdivcó quá nhiều byte, vì vậy chúng tôi thực hiện dịch chuyển sang phải .

Cập nhật

  1. Đã lưu 2 byte bằng cách rút ngắn $i=$i>>1để $i>>=1phân chia số nguyên.
  2. Đã ném ra eval ủng hộ các nhà khai thác ternary.

2

Trăn 3, 98 66 60 byte

Cảm ơn Tukkax!

Không phải là golf như câu trả lời khác, nhưng tôi không thể cạnh tranh với họ mà không đạo văn.

i=0
for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4]
print(i)

Ngoài ra, tôi cũng có một giải pháp lambda đệ quy

73 67 byte (được cải thiện!)

s=lambda x,z=0:s(x[1:],z+[1,-z//2,-1,z][ord(x[0])%23%4])if x else z

Bằng cách áp dụng một phần giải pháp đệ quy của bạn cho phiên bản thủ tục: 60 byte : i=0 for c in input():i+=[1,-i//2,-1,i][ord(c)%23%4] print(i). (tất nhiên không được định dạng đúng). Ngoài ra tôi nghĩ bạn nên đề cập rằng bạn đang sử dụng Python3. Trong Python2, input()sẽ đánh giá int(raw_input()).
Yytsi

@TuukkaX không hoạt động với z = 0 ( +-hiện 1)
Lemon phá hủy

oh vâng, sai lầm của tôi
Yytsi

1
Thêm tiêu đề Python3.
Yytsi

2

R, 201 byte

Chơi gôn

p=.Primitive;"-"="+"=function(x)p("+")(x,1);body(`-`)[[1]]=p("-");"*"="/"=function(x)p("*")(x,2);body(`/`)[[1]]=p("%/%");Reduce(function(f, ...)f(...),rev(mget(strsplit(scan(stdin(),""),"")[[1]])),0,T)

Đã bình luận

p = .Primitive                       # Redefine
"-" = "+" = function(x)p("+")(x,1)   # Define - and +
body(`-`)[[1]] = p("-")              # Change the body, what we do to save a byte
"*" = "/" = function(x)p("*")(x,2)   # Same as above
body(`/`)[[1]] = p("%/%")            # Same as above
Reduce(function(f, ...)f(...),       # Function wrapper to evaluate list of func.  
  rev(mget(strsplit(scan(stdin(),""),"")[[1]])), # Strsplit input into list of functions
  init = 0,                                      # Starting Arg = 1
  right = T)                                     # Right to left = True 

Chiến lược là để tinh chỉnh +, -, % nhà khai thác. Tách chuỗi sau đó phân tích chuỗi thành một danh sách dài các hàm, được đưa vàoReduce()'s tích lũy.

Không thể đánh gôn được nữa. Nếu ai đó có thể đi b=body<-làm, có thể có một vài byte tiết kiệm (tinh chỉnh mọi chức năng với bsau "-"="+"="/"="*"). Ban đầu đã cố gắng thay thế và phân tích eval, nhưng thứ tự các thao tác và dấu ngoặc đơn thật đáng sợ.


Đây là một năm sau đó, nhưng tôi cố gắng làm cho nó giảm 10 byte bằng cách trao đổi cách tiếp cận của bạn một chút - bạn có thể thả 8 byte bằng cách loại bỏ các khoảng trống giữa f, ...trong định nghĩa của các Reducechức năng và loại bỏ stdin()trong scannhưng tôi chỉ cố gắng một ngây thơ Cách tiếp cận đã giảm thêm hai byte bằng cách định nghĩa các hàm khác nhau một chút. tio.run/##XcvLCsMgEAXQrwnO6Gge29B/ khăn
Giuseppe

1

Lex + C, 78 , 74 , 73 byte

Nhân vật đầu tiên là một không gian.

 c;F(){yylex(c=0);return c;}
%%
\+ c++;
- c--;
\* c*=2;
\/ c=floor(c/2.);

Đọc từ stdin, trả về kết quả.

Biên dịch với lex golfed.l && cc lex.yy.c main.c -lm -lfl, kiểm tra chính:

int main() { printf("%d\n", F()); }

1

Javascript (ES5), 127 byte

function(b){for(a=c=0;a<b.length;++a)switch(b[a]){case"+":++c;break;case"-":--c;break;case"*":c*=2;break;case"/":c/=2}return c}

Ung dung:

function c(a){
  c=0;
  for(var i=0;i<a.length;++i){
    switch(a[i]){
      case "+":++c;break;
      case "-":--c;break;
      case "*":c*=2;break;
      case "/":c/=2;break;
    }
  }
  return c;
}

1

Bình thường, 23 byte

FNQ=Z.v%".&%sZ2_2"N;/Z2

Một chương trình đầy đủ lấy đầu vào là một chuỗi và in kết quả.

Đây là một cổng của câu trả lời Python của @ xnor .

Dùng thử trực tuyến

Làm thế nào nó hoạt động

FNQ=Z.v%".&%sZ2_2"N;/Z2   Program. Input: Q. Z initialised as 0
FNQ                       For. For N in Q:
        ".&%sZ2_2"         String. Literal string ".&%sZ2_2"
       %          N        String format. Replace %s with the current operator N
           %sZ2            Operator. Yield Z*2, Z//2, Z+2, Z-2 as appropriate
         .&    _2          Bitwise and. Result of above & -2
     .v                    Evaluate. Yield the result of the expression
   =Z                      Assignment. Assign result of above to Z
                   ;      End. End for loop
                    /Z2   Integer division. Yield Z//2
                          Print. Print the above implicitly 

1
Chuyển đổi Python thành Pyth chủ yếu là một ý tưởng tồi. u@[yGhG0tG0/G2)CHQ019 byte
Jakube

@Jakube Cảm ơn - Tôi rất mới với Pyth, vì vậy mọi lời khuyên đều được đánh giá cao. Hãy đăng bài đó như một câu trả lời riêng biệt, vì đó là một cách tiếp cận khác.
Đi xe đạp

1

PHP, 79 byte

<?$i=0;switch($_POST['a']){case"+":$i+1;case"-":$i-1;case"/":$i/2;case"*":$i*2}

2
Bao gồm bytecount trong tiêu đề của bạn, loại bỏ khoảng trắng không chính thức và sử dụng tên biến 1 ký tự.
Thiền lập

Đây có phải là golf không?! :-D
YetiCGN

@ TùxCräftîñg Tôi đã làm nó.
Winnie The Pooh

Bạn chia và nhân cho 1; bạn cần chia và nhân cho2
Thiền vào

@ TùxCräftîñg Tôi đã làm nó.
Winnie The Pooh
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.