Đánh giá chuỗi Dotty


25

Viết chương trình lấy một chuỗi có độ dài lẻ chỉ chứa các ký tự .:. Với sự trợ giúp của ngăn xếp ban đầu trống , tạo một số từ chuỗi này như sau:

Đối với mọi ký tự c trong chuỗi (đi từ trái sang phải) ...

  • Nếu c.và ngăn xếp có ít hơn 2 phần tử, đẩy 1 trên ngăn xếp.
  • Nếu c.và ngăn xếp có 2 phần tử trở lên, hãy bật hai giá trị trên cùng ra khỏi ngăn xếp và đẩy tổng của chúng lên ngăn xếp.
  • Nếu c:và ngăn xếp có ít hơn 2 phần tử, đẩy 2 trên ngăn xếp.
  • Nếu c:và ngăn xếp có 2 phần tử trở lên, hãy bật hai giá trị trên cùng khỏi ngăn xếp và đẩy sản phẩm của chúng lên ngăn xếp.

Số kết quả là giá trị ở đầu ngăn xếp. Chương trình của bạn nên in số này ra thiết bị xuất chuẩn (với một dòng mới tùy chọn).

(Một phân tích nhỏ cho thấy chỉ còn lại một số trừ khi chuỗi có độ dài chẵn, đó là lý do tại sao chúng ta bỏ qua các số đó. Trên thực tế, ngăn xếp không bao giờ có nhiều hơn 2 phần tử.)

Ví dụ: số cho ::...:.:.là 9:

  2   1   2   2    /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9  \
: : . . . : . : .  <-- string, one character at a time

Để kiểm tra độ tỉnh táo, đây là các số cho tất cả các chuỗi có độ dài 1, 3 và 5:

. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8

Chương trình ngắn nhất tính bằng byte thắng. Tiebreaker là bài trước.

  • Bạn có thể giả sử đầu vào luôn hợp lệ, tức là một chuỗi chỉ chứa .:độ dài của nó là số lẻ.
  • Thay vì viết chương trình, bạn có thể viết một hàm lấy một chuỗi hợp lệ và in hoặc trả về số được tạo.

5
Bộ cân bằng tối giản tốt nhất bao giờ hết.
dberm22

Câu trả lời:


13

CJam, 27 24 23 22 byte

q{i]_,+~3<-"1+2* "=~}/

Khá thẳng về phía trước. Tôi sử dụng ngăn xếp của CJam như ngăn xếp được đề cập trong câu hỏi;)

Thuật toán

Trước tiên, hãy xem mã ASCII cho .:.

'.i ':ied

[46 58]

Vì trong CJam, chỉ mục bao bọc xung quanh, hãy xem liệu chúng ta có thể sử dụng trực tiếp các giá trị này để có được thao tác mong muốn không ..

'.i4% ':i4%ed

[2 2]

Vì vậy, tôi không thể đơn giản sử dụng mã ASCII trong chuỗi thao tác dài 4. Hãy thử một số giá trị khác

'.i 10% ':i 10%ed

[6 8]

mà trên một chuỗi dài 4 sôi xuống

[2 0]

Tôi có thể sử dụng thao tác mod 10 này nhưng chi phí sẽ là 2 byte. Hãy thử một cái gì đó khác

'.i5% ':i5%ed

[1 3]

Thật tuyệt!, Bây giờ chúng ta chỉ cần trừ 1 cho điều kiện kích thước ngăn xếp để lấy các chỉ mục 0, 1, 2 and 3và sử dụng một 5mảng chiều dài ( "1+2* ") làm trường hợp chuyển đổi. Không gian cuối cùng chỉ là một phụ để làm cho nó có độ dài 5. Đây chỉ là 1 byte thêm so với hoạt động sửa đổi.

q{                  }/    e# parse each input character in this loop
  i]                      e# convert '. or ': into ASCII code and wrap everything
                          e# in stack in an array
    _,+                   e# Copy the stack array, take its length and add the length to
                          e# the stack array 
       ~3<                e# unwrap the stack array and check if stack size is less than 3
                          e# 3 because either . or : is also on stack
          -               e# subtract 0 or 1 based on above condition from ASCII code
           "1+2* "        e# string containing the operation to perform
                  =~      e# chose the correct operation and evaluate it

Dùng thử trực tuyến tại đây

Lưu 1 byte nhờ cosechy


1
Không gian cho chuỗi hoạt động là gì?
Peter Taylor

@PeterTaylor giải thích trong bài.
Trình tối ưu hóa

9

> <> (Cá) , 33 byte

ib%1-i:1+?\~n;
5a*)?*+40.\b%1-0@i

Khá đơn giản với ít thủ thuật / tối ưu hóa.

Giải trình:

  • Thông tin: i= codepoint của char đầu vào tiếp theo, -1nếu kết thúc đầu vào; a= 10; b= 11; )= =>
  • imật mã của char đầu vào đầu tiên,
  • b%1- top_of_stack mod 11 - 1mặt nạ 48 ('.') , 56 (':')để1 , 2
  • i:1+?\~n; nếu kết thúc đầu vào đạt được kết quả cuối cùng và chấm dứt
  • nếu không thì:
  • b%1- mặt nạ đầu vào 1 , 2
  • 0@đẩy 0theo hai số
  • i5a*)đọc đầu vào tiếp theo và che dấu nó để 0 , 1so sánh với50
  • if 1( ':') nhân hai phần tử trên cùng tạo stack [0 sản phẩm]
  • luôn luôn thêm hai yếu tố hàng đầu tạo ngăn xếp [0 sum]hoặc[0+product=product]
  • 40.nhảy (vòng lặp) trở lại vị trí (4,0), quan điểm của chúng tôi 4,i:1+?\~n;

8

Haskell, 73 65 byte

Một giải pháp đơn giản, sử dụng thực tế là ngăn xếp không bao giờ có nhiều hơn 2 phần tử.

[x,y]#'.'=[x+y]
[x,y]#_=[x*y]
s#'.'=1:s
s#_=2:s
f=head.foldl(#)[]

5

C, 104 byte

k[2],n;f(char*c){for(n=0;*c;)k[n]=*c++-58?n>1?n=0,*k+k[1]:1:n>1?n=0,*k*k[1]:2,k[1]=n++?k[1]:0;return*k;}

Chà, cái này quá dài.


5

Bình thường, 25 24 byte

eu?]?.xGHsGtG+GhHmqd\:zY

Có một ý tưởng bằng cách nghiên cứu giải pháp của @ isaacg. Nhưng tôi đang sử dụng một ngăn xếp.

Trình diễn hoặc thử nghiệm trực tuyến

Giải trình

Điều đầu tiên tôi làm là chuyển đổi chuỗi đầu vào thành 0 và 1. A "."được chuyển đổi thành a 0, a ":"thành a 1.

mqd\:z   map each char d of input to (d == ":")

Sau đó, tôi giảm danh sách các số này:

eu?]?.xGHsGtG+GhHmqd\:zY
 u                     Y   start with the empty stack G = []
                           for each H in (list of 0s and 1s), update G:
                              G = 
    ?.xGHsG                      product of G if H != 0 else sum of G
   ]                             wrapped in a list 
  ?        tG                 if G has more than 1 element else
             +GhH                G + (H + 1)
e                         take the top element of the stack

4

JavaScript (ES6), 65

Chúng tôi chỉ sử dụng 2 ô của ngăn xếp của chúng tôi.

Bắt đầu đặt một giá trị trong s [0].
Sau đó, tại mỗi vị trí lẻ (tính từ 0) trong chuỗi đầu vào, đặt một giá trị trong s [1].
Tại mỗi vị trí chẵn, thực hiện một calc (thêm hoặc nhân) và lưu kết quả trong s [0].

Vì vậy, hãy quên stack và chỉ sử dụng 2 biến, a và b.

f=s=>[...s].map((c,i)=>(c=c>'.',i&1?b=1+c:i?c?a*=b:a+=b:a=1+c))|a

Một bài kiểm tra nhanh

for(i=0;i<128;i++)
{
  b=i.toString(2).replace(/./g,v=>'.:'[v]).slice(1)
  if(b.length&1) console.log(b,f(b))
} 

Đầu ra

"." 1
":" 2
"..." 2
"..:" 1
".:." 3
".::" 2
":.." 3
":.:" 2
"::." 4
":::" 4
"....." 3
"....:" 2
"...:." 4
"...::" 4
"..:.." 2
"..:.:" 1
"..::." 3
"..:::" 2
".:..." 4
".:..:" 3
".:.:." 5
".:.::" 6
".::.." 3
".::.:" 2
".:::." 4
".::::" 4
":...." 4
":...:" 3
":..:." 5
":..::" 6
":.:.." 3
":.:.:" 2
":.::." 4
":.:::" 4
"::..." 5
"::..:" 4
"::.:." 6
"::.::" 8
":::.." 5
":::.:" 4
"::::." 6
":::::" 8

-2:f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
nderscore

@nderscore ít nhất là trên borwser của tôi không hoạt động. for (i in s) cung cấp các thuộc tính bổ sung bên cạnh các chỉ mục
edc65

nó hoạt động với tôi trong firefox 37.0.2. Hãy thử chạy nó trong một tab trình duyệt sạch. Dường như stackexchange thêm các thuộc tính bổ sung cho chuỗi (trong stub.en.js)
nderscore

3

Bình thường, 27 byte

Jmhqd\:zu?*GhHteH+GhHctJ2hJ

Một chồng? Ai cần một chồng.

                       Implicit: z is the input string.
Jmhqd\:z               Transform the string into a list, 1 for . and 2 for :
                       Store it in J.
u            ctJ2hJ     Reduce over pairs of numbers in J, with the
                       first entry as initial value.
 ?    teH               Condition on whether the second number is 1 or 2.
  *GhH                  If 1, update running total to prior total times 1st num.
         +GhH           If 2, update running total to prior total plus 1nd num.

Trình diễn.


1
Thiên tài. Và trong khi đó tôi đã thực hiện một ngăn xếp (32 byte). :-(
Jakube

3

Võng mạc , 105 75 73 byte

Chương trình Retina đầu tiên của tôi! (Cảm ơn Martin Büttner vì đã lưu 2 byte, chưa kể đến việc phát minh ngôn ngữ ở vị trí đầu tiên.)

Mỗi dòng nên đi trong một tệp riêng biệt; hoặc, bạn có thể đặt tất cả chúng trong một tệp và sử dụng -scờ. Các <empty>ký hiệu đại diện cho một tập tin / dòng trống.

^(a+;)?\.
$1a;
^(a+;)?:
$1aa;
;(a+;)\.
$1
(a+);aa;:
$1$1;
)`;a;:
;
;
<empty>
a
1

Lấy cảm hứng từ câu trả lời của mbomb007 , nhưng tôi có một cách tiếp cận hơi khác. Một sự khác biệt chính là tôi xây dựng ngăn xếp ở phía trước chuỗi dấu chấm (với đỉnh của ngăn xếp phải đối diện). Điều này giúp dễ dàng chuyển đổi các ký hiệu thành các số tương ứng tại chỗ. Tôi cũng sử dụng athay vì 1, chỉ trao đổi nó ở cuối, để tránh phân tích sự mơ hồ trong chuỗi như thế nào $1a. Nếu một câu trả lời như aaaaaađược chấp nhận là một số đơn nguyên, hai dòng / tệp cuối cùng có thể được loại bỏ để lưu 4 byte.

Giải trình:

^(a+;)?\.
$1a;

Khớp nếu có 0 hoặc 1 mục trên ngăn xếp ( (a+;)?) theo sau là dấu chấm ( \.); nếu vậy, nó thay thế khoảng thời gian bằng a;(tức là đẩy 1).

^(a+;)?:(.*)
$1aa;$2

Khớp nếu có 0 hoặc 1 mục trên ngăn xếp theo sau là dấu hai chấm. Nếu vậy, nó thay thế dấu hai chấm bằng aa;(tức là đẩy 2).

;(a+;)\.
$1

Khớp nếu có hai mục trên ngăn xếp theo sau là dấu chấm. Xóa dấu chấm và dấu chấm phẩy giữa các mục, từ đó thêm chúng.

(a+);aa;:
$1$1;

Khớp nếu có hai mục trên ngăn xếp, trên cùng là 2, theo sau là dấu hai chấm. Xóa dấu hai chấm và 2 và lặp lại số khác hai lần, từ đó nhân nó với 2.

)`;a;:
;

Regex khớp với nếu có hai mục trên ngăn xếp, trên cùng là 1, theo sau là dấu hai chấm. Xóa dấu hai chấm và 1, giữ nguyên số khác (tức là nhân với 1).

)`chỉ ra sự kết thúc của một vòng lặp. Nếu bất kỳ thay đổi nào được thực hiện đối với chuỗi, điều khiển sẽ quay trở lại đầu chương trình và chạy lại các thay thế. Nếu chuỗi đã ngừng thay đổi, chúng tôi đã thay thế tất cả các dấu chấm và dấu hai chấm và tất cả những gì còn lại là dọn dẹp ...

;
<empty>

Xóa dấu chấm phẩy còn sót lại.

a
1

Biến đổi tất cả các a thành 1. Một lần nữa, nếu số unary được phép sử dụng bất kỳ ký hiệu nào, bước này là không cần thiết.


Là bắt đầu của vòng lặp được coi là tập tin đầu tiên, sau đó?
mbomb007

@ mbomb007 Có. Tôi đã thấy điều đó trong các tài liệu, nhưng quên cho đến khi Martin nhắc tôi về nó. ;)
DLosc

2

Rust, 170 ký tự

fn f(s:String)->i32{let(mut a,mut b)=(-1,-1);for c in s.chars(){if b!=-1{a=match c{'.'=>a+b,':'=>a*b,_=>0};b=-1}else{b=match c{'.'=>1,':'=>2,_=>0};if a==-1{a=b;b=-1}};}a}

Thêm bằng chứng cho thấy Rust hoàn toàn khủng khiếp khi chơi golf. Mã không mã hóa đầy đủ:

#[test]
fn it_works() {
    assert_eq!(dotty_ungolfed("::...:.:.".to_string()), 9);
    assert_eq!(f("::...:.:.".to_string()), 9);
}

fn dotty_ungolfed(program: String) -> i32 {
    let (mut a, mut b) = (-1, -1);
    for ch in program.chars() {
        if b != -1 {
            a = match ch { '.' => a + b, ':' => a * b, _ => panic!() };
            b = -1;
        } else {
            b = match ch { '.' => 1, ':' => 2, _ => panic!() };
            if a == -1 { a = b; b = -1; }
        }
    }
    a
}

fn f(s:String)->i32{let(mut a,mut b)=(-1,-1);for c in s.chars(){if b!=-1{a=match c{'.'=>a+b,':'=>a*b,_=>0};b=-1}else{b=match c{'.'=>1,':'=>2,_=>0};if a==-1{a=b;b=-1}};}a}

Đây là một mẹo thú vị mà tôi đã sử dụng trong phần này. Bạn có thể loại bỏ một ký tự trong câu lệnh if / other bằng cách cho chúng trả về một giá trị bị loại bỏ ngay lập tức, điều đó có nghĩa là bạn chỉ cần một dấu chấm phẩy thay vì hai.

Ví dụ,

if foo {
    a = 42;
} else {
    doSomething(b);
}

có thể thay đổi thành

if foo {
    a = 42
} else {
    doSomething(b)
};

trong đó lưu một nhân vật bằng cách cạo một dấu chấm phẩy.


2

Haskell, 88 81 79 byte

(h:t)![p,q]|h=='.'=t![p+q]|1<2=t![p*q]
(h:t)!s|h=='.'=t!(1:s)|1<2=t!(2:s)
_!s=s

Có vẻ như ai đó đã đánh bại tôi đến mức đánh dấu vào giải pháp Haskell, không chỉ vậy, giải pháp của họ ngắn hơn tôi. Điều đó thật tệ nhưng, tôi thấy không có lý do gì để không đăng những gì tôi nghĩ ra.


2

APL (50)

Tôi gặp bất lợi lớn ở đây, vì APL không phải là ngôn ngữ dựa trên ngăn xếp. Cuối cùng tôi đã phải giảm lạm dụng để rút ngắn chương trình, mặc dù.

{⊃{F←'.:'⍳⍺⋄2>⍴⍵:F,⍵⋄((⍎F⌷'+×')/2↑⍵),2↓⍵}/(⌽⍵),⊂⍬}

Hàm bên trong nhận một 'lệnh' ở bên trái và một ngăn xếp ở bên phải và áp dụng nó, trả về ngăn xếp. Hàm bên ngoài giảm nó trên chuỗi, bắt đầu với một ngăn xếp trống.

Giải trình:

  • (⌽⍵),⊂⍬: danh sách ban đầu để giảm hơn. ⊂⍬là một danh sách trống được đóng hộp, đại diện cho ngăn xếp, (⌽⍵)là mặt trái của đầu vào. (Việc giảm được áp dụng từ phải sang trái trong danh sách, do đó chuỗi sẽ được xử lý từ phải sang trái. Việc đảo ngược đầu vào trước khiến nó áp dụng các ký tự theo đúng thứ tự.)

  • {... }: chức năng bên trong. Nó nhận ngăn xếp bên phải, một ký tự bên trái và trả về ngăn xếp đã sửa đổi.

    • F←'.:'⍳⍺: chỉ mục của ký tự trong chuỗi .:, đây sẽ là 1 hoặc 2 tùy thuộc vào giá trị.
    • 2>⍴⍵:F,⍵: Nếu 2 lớn hơn kích thước ngăn xếp hiện tại, chỉ cần nối thêm giá trị hiện tại vào ngăn xếp.
    • : nếu không thì,
      • 2↓⍵: xóa hai mục trên cùng khỏi ngăn xếp
      • (... )/2↑⍵: giảm một hàm đã cho qua chúng và thêm nó vào ngăn xếp.
      • ⍎F⌷'+×': hàm là +(cộng) hoặc ×(nhân), được chọn bởi F.
  • : cuối cùng, trả lại mục trên cùng trên ngăn xếp


2

Ruby - 96 ký tự

Các mảnh thú vị ở đây là eval.

Ngoài ra, tôi đưa ra giả định rằng sau ký tự đầu tiên, ngăn xếp sẽ luôn đi 2, toán, 2, toán, .... Điều này cho phép tôi sử dụng ít mã hơn bằng cách lấy hai ký tự cùng một lúc - tôi không bao giờ phải hình ra xem một nhân vật là toán học hay số. Đó là vị trí.

x,m=$<.getc>?.?2:1
(b,f=m.split //
b=b>?.?2:1
x=f ?eval("x#{f>?.??*:?+}b"):b)while m=gets(2)
p x

Ung dung:

bottom_of_stack = $<.getc > '.' ? 2 : 1 # if the first char is ., 1, else 2
two_dots = nil
while two_dots = gets(2) do # get the next 2 chars
  number_char, math_char = two_dots.split //
  number = number_char > '.' ? 2 : 1
  if math_char
    math = math_char > '.' ? '*' : '+'
    # so bottom_of_stack = bottom_of_stack + number ...
    # or bottom_of_stack = bottom_of_stack * number
    bottom_of_stack = eval("bottom_of_stack #{math} number")
  else
    # if there's no math_char, it means that we're done and 
    # number is the top of the stack
    # we're going to print bottom_of_stack, so let's just assign it here
    bottom_of_stack = number
  end
end
p bottom_of_stack  # always a number, so no need for `puts`

2

TI-BASIC, 78 73 70 69 66 byte

Input Str1
int(e^(1=inString(Str1,":
For(A,2,length(Str1),2
Ans+sum({Ans-2,1,1,0},inString("::..:",sub(Str1,A,2
End
Ans

TI-BASIC tốt ở một lớp lót, vì đóng dấu ngoặc đơn là tùy chọn; ngược lại, đó là một ngôn ngữ kém trong đó việc lưu trữ nhiều giá trị là bắt buộc vì lưu trữ vào một biến mất từ ​​hai đến bốn byte không gian. Do đó, mục tiêu là viết càng nhiều trên mỗi dòng càng tốt. TI-BASIC cũng rất tệ (đối với ngôn ngữ được mã hóa) ở bất kỳ loại thao tác chuỗi nào; thậm chí đọc một chuỗi con là dài.

Thủ thuật bao gồm:

  • int(e^([boolean]thay vì 1+(boolean; tiết kiệm một byte
  • Tổng một phần của danh sách thay vì cắt danh sách (sẽ yêu cầu lưu trữ vào danh sách): tiết kiệm 3 byte

Bạn sẽ ổn khi lấy đầu vào từ Ans, như ".:.":prgmDOTTY, tiết kiệm 4 byte.
MI Wright

@Wright Tôi sử dụng Ans để lưu trữ số trên ngăn xếp.
lirtosiast

Ý tôi là lúc đầu-- thoát khỏi dòng 1, và đổi dòng thứ hai thành1+(":"=sub(Ans,1,1
MI Wright

1
Tôi cần sử dụng Str1 trong vòng lặp, nơi Ans được thực hiện, vì vậy tôi không thể tránh khỏi việc giữ chuỗi trong Ans. Lưu nó vào Str1 từ Ans sẽ không tiết kiệm bất kỳ khoảng trống nào.
lirtosiast

1

Đi, 129 115 112 byte

func m(s string){a,b:=0,0;for c,r:=range s{c=int(r/58);if b>0{a=a*b*c+(a+b)*(c^1);b=0}else{b,a=a,c+1}};print(a)}

(phần nào) vô danh:

func m(s string){
    // Our "stack"
    a, b := 0, 0
    // abusing the index asignment for declaring c
    for c, r := range s {
        // Ascii : -> 58, we can now use bit fiddeling
        c = int(r / 58)
        if b > 0 {
            // if r is :, c will be 1 allowing a*b to pass through, c xor 1 will be 0
            // if r is ., c xor 1 will be 1 allowing a+b to pass through
            a = a*b*c + (a+b)*(c^1)
            b = 0
        } else {
            b, a = a, c+1 // Since we already know c is 0 or 1
        }
    }
    print(a)
}

Dùng thử trực tuyến tại đây: http://play.golang.org/p/B3GZonaG-y


1

Trăn 3, 74

x,*s=[1+(c>'.')for c in input()]
while s:a,b,*s=s;x=[x*a,x+a][-b]
print(x)

Đầu tiên biến đổi danh sách đầu vào thành một chuỗi 1 và 2, lấy giá trị đầu tiên làm giá trị ban đầu x. Sau đó, tắt hai phần tử tại một thời điểm từ phía trước s, lấy số đầu tiên và thêm hoặc nhân với số hiện tại dựa trên việc số thứ hai là 1 hay 2.


1

Vâng, đây là hoạt động rất dễ dàng, tinh vi bởi op (cố ý)

nó chỉ là ...

biểu thức được ngoặc đơn được dịch thành hậu tố * / + hoạt động

Mã: C (80 byte)

int f(char*V){return*(V-1)?f(V-2)*(*V==58?*(V-1)/29:1)+(*V&4)/4**(V-1)/29:*V/29;}
  • hàm này nên được gọi từ đuôi chuỗi như thế này: f (V + 10) trong đó V = ".: ..:.: .. ::"

đầu vào

length = 2n + 1 vector V loại char '.' hoặc là ':'

Đầu ra

một số nguyên k

Chức năng

  • k = (V [1] op (V [3]) V [2]) op (V [5]) V [4] ....

  • op (x): (x = '.') -> +, (x = ':') -> *


Mô phỏng:

thử nó ở đây


Làm thế nào bạn có thể giả sử rằng byte trước chuỗi ( *(V-1)) bằng không?
nutki

Khi bạn phân bổ một vectơ mới, phần đầu của nó luôn bắt đầu từ đoạn trống, phần cuối của nó một ký tự trống
Abr001am

1

Võng mạc, 181 135 129 byte

Mỗi dòng nên ở trong một tệp riêng biệt. <empty>đại diện cho một tập tin trống. Đầu ra là trong Unary.

^\..*
$&1;
^:.*
$&11;
^.
<empty>
(`^\..*
$&1
^:.*
$&11
^.(.*?1+;1+)
$1
^(\..*);(1+)
$1$2;
;1$
;
^(:.*?)(1+).*
$1$2$2;
)`^.(.*?1+;)
$1
;
<empty>

Khi ${0}1được sử dụng, niềng răng tách biệt $0với 1, nếu không nó sẽ là $01nhóm khớp thứ 1. Tôi đã thử sử dụng $001, nhưng điều này dường như không hoạt động trong hương vị .NET của regex.

Chỉnh sửa: Tìm thấy đó $&là giống như $0.

Trong mã giả, về cơ bản, đây sẽ là một vòng lặp do-while, như được thấy dưới đây. Tôi đẩy số thứ nhất, sau đó lặp: đẩy số thứ hai, xóa thao tác (hướng dẫn), làm toán, xóa op. Tiếp tục lặp. Lưu ý rằng khi một thao tác được bật lên, thao tác này cũng sẽ xóa khoảng trống sau khi tất cả các hướng dẫn được thực hiện.

Đã bình luận:

^\..*           # Push if .
$&1;
^:.*            # Push if :
$&11;
^.              # Pop op
<empty>


(`^\..*         # Loop, Push #
$&1
^:.*
$&11
^.(.*?1+;1+)    # Pop op
$1


^(\..*);(1+)    # Add if . (move ;)
$1$2;
;1$          # If mul by 1, remove
;
^(:.*?)(1+).*   # Mul if : (double)
$1$2$2;
)`^.(.*?1+;)    # Pop op, End Loop (clean up)
$1
;               # Remove semicolon
<empty>

Điều chính tôi đang thấy khi chơi golf là các cặp mẫu / thay thế như (:)(.*)-> $1$2, điều mà tôi khá chắc chắn có thể là (:.*)-> $1(vì bạn giữ hai nhóm theo cùng một thứ tự và không làm gì khác với chúng ).
DLosc

Tôi lấy cảm hứng và đưa ra câu trả lời Retina của riêng tôi. Cảm ơn đã thúc đẩy tôi tải xuống ngôn ngữ thú vị này!
DLosc

@DLosc Tuyệt! Vâng, tôi chưa thực sự tải nó. Tôi đã sử dụng một thử nghiệm thay thế regex trực tuyến cho mỗi thay thế cá nhân.
mbomb007

0

Python 3, 122 byte

x=input()
l=[0,0]
for _ in x:
 t=len(l)-2<2
 l=[[[0,0,l[-2]*l[-1]],l+[2]][t],[[0,0,sum(l)],l+[1]][t]][_=='.']
print(l[-1])

Ung dung:

x = input()
l = []
for i in x:
    if i == '.':
        if len(l) < 2: 
            l+=[1]        #True, True = 1,1
        else:
            l=[sum(l)]    #True, True = 1,0
    else:
        if len(l)<2:
            l+=[2]        #False, True = 0,1
        else:
            l=[l[0]*l[1]] #False, False = 0,0
print (l[0])

Trong python, bạn tham chiếu chỉ mục của một danh sách như thế này:

list[index]

Bạn có thể đặt một giá trị boolean vào đó, Trueđang 1False0.

# t is True if the length is less than 2, else false.

l=[ 

  # |------- Runs if char is : -------|
  # |------- l<2 -------| |- l>=2 -|

    [ [ 0,0, l[-2]*l[-1] ], l+[2] ] [t],

                                      # |---- Runs if char is . ----| 
                                      # |--- l<2 ---|  |- l>=2 -|

                                        [ [0,0, sum(l)], l+[1] ] [t] ]
                                                                      [_=='.']

Dùng thử trực tuyến tại đây


0

Perl, 77 byte

@o=(0,'+','*');sub d{$_=shift;y/.:/12/;eval'('x s!\B(.)(.)!"$o[$2]$1)"!ge.$_}

mở rộng:

@o=(0, '+', '*');
sub d{
    $_=shift;
    y/.:/12/;
    eval '(' x s!\B(.)(.)!"$o[$2]$1)"!ge.$_
}

Các @omảng ánh xạ các chữ số cho các toán tử. Sau đó, chúng tôi thay thế các cặp chữ số bằng toán tử thích hợp, được sắp xếp lại thành infix. Regrec bắt đầu bằng \Bvì vậy chúng tôi không khớp với ký tự đầu tiên. Kết quả s///gcho chúng ta biết có bao nhiêu parens mở lúc đầu. Sau đó, khi chúng tôi tập hợp biểu thức infix đầy đủ, chúng tôi có thể đánh giá nó. (Xóa evalnếu bạn muốn xem biểu thức thay thế).

Đây là khai thác thử nghiệm tôi đã sử dụng để xác minh kết quả:

while(<>) {
    my ($a, $b) = m/(.*) (.*)/;
    print d($a), " $b\n";
}

Đầu vào là danh sách các biểu thức chấm và giá trị của chúng (được cung cấp trong câu hỏi) và đầu ra là các cặp {thực tế, dự kiến}.

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.