Mengevaluasi Dotty Strings

25

Tulis program yang menggunakan string panjang ganjil yang hanya berisi karakter .dan :. Dengan bantuan tumpukan yang awalnya kosong , buat angka dari string ini sebagai berikut:

Untuk setiap karakter c dalam string (dari kiri ke kanan) ...

  • Jika c adalah .dan tumpukan memiliki kurang dari 2 elemen, tekan 1 pada tumpukan.
  • Jika c adalah .dan tumpukan memiliki 2 atau lebih elemen, pop dua nilai teratas dari tumpukan dan dorong jumlah mereka ke tumpukan.
  • Jika c adalah :dan tumpukan memiliki kurang dari 2 elemen, tekan 2 pada tumpukan.
  • Jika c adalah :dan tumpukan memiliki 2 elemen atau lebih, pop dua nilai teratas dari tumpukan dan dorong produk mereka ke tumpukan.

Angka yang dihasilkan adalah nilai di bagian atas tumpukan. Program Anda harus mencetak nomor ini ke stdout (dengan baris tambahan tambahan opsional).

(Analisis kecil menunjukkan bahwa hanya ada satu angka yang tersisa kecuali string memiliki panjang genap, itulah sebabnya kami mengabaikannya. Faktanya, stack tidak pernah memiliki lebih dari 2 elemen.)

Misalnya, nomor untuk ::...:.:.adalah 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

Sebagai pemeriksaan kewarasan, berikut adalah angka untuk semua string dengan panjang 1, 3, dan 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

Program terpendek dalam byte menang. Tiebreaker adalah posting sebelumnya.

  • Anda dapat mengasumsikan input selalu valid, yaitu string yang hanya berisi .dan :yang panjangnya ganjil.
  • Alih-alih menulis program, Anda dapat menulis fungsi yang mengambil string yang valid dan mencetak atau mengembalikan nomor yang dihasilkan.
Hobi Calvin
sumber
5
Equaliser minimalis terbaik yang pernah ada.
dberm22

Jawaban:

13

CJam, 27 24 23 22 byte

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

Cukup lurus ke depan. Saya menggunakan tumpukan CJam sebagai tumpukan yang disebutkan dalam pertanyaan;)

Algoritma

Pertama mari kita lihat kode ASCII untuk .dan :.

'.i ':ied

[46 58]

Karena di CJam, indeks membungkus, mari kita lihat apakah kita dapat menggunakan nilai-nilai ini secara langsung untuk mendapatkan operasi yang diinginkan ..

'.i4% ':i4%ed

[2 2]

Jadi saya tidak bisa begitu saja menggunakan kode ASCII dalam string operasi 4 panjang. Mari kita coba beberapa nilai lainnya

'.i 10% ':i 10%ed

[6 8]

yang pada string 4 panjang bermuara ke

[2 0]

Saya dapat menggunakan operasi mod 10 ini, tetapi biayanya 2 byte. Mari kita coba yang lain

'.i5% ':i5%ed

[1 3]

Bagus !, sekarang kita cukup kurangi 1 untuk kondisi ukuran tumpukan untuk mendapatkan indeks 0, 1, 2 and 3dan menggunakan 5array panjang ( "1+2* ") sebagai sakelar. Ruang terakhir hanyalah pengisi untuk membuatnya dengan panjang 5. Ini hanya 1 byte tambahan dibandingkan dengan operasi modding.

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

Cobalah online di sini

1 byte disimpan berkat cosechy

Pengoptimal
sumber
1
Untuk apa ruang dalam rangkaian operasi?
Peter Taylor
@PeterTaylor dijelaskan dalam posting.
Pengoptimal
9

> <> (Ikan) , 33 byte

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

Cukup mudah dengan sedikit trik / optimisasi.

Penjelasan:

  • Info: i= codepoint input char selanjutnya, -1jika akhir input tercapai; a= 10; b= 11; )=>
  • icodepoint input char pertama,
  • b%1- top_of_stack mod 11 - 1topeng 48 ('.') , 56 (':')untuk1 , 2
  • i:1+?\~n; jika akhir input tercapai cetak hasil terakhir dan hentikan
  • jika tidak:
  • b%1- mask input ke 1 , 2
  • 0@tekan di 0bawah dua nomor
  • i5a*)baca input selanjutnya dan tutup untuk 0 , 1dibandingkan50
  • if 1( ':') kalikan dua elemen teratas menciptakan tumpukan [0 produk]
  • selalu tambahkan dua elemen teratas yang menciptakan tumpukan baik [0 sum]atau[0+product=product]
  • 40.melompat (loop) kembali ke posisi (4,0), titik kami 4,i:1+?\~n;
randomra
sumber
8

Haskell, 73 65 byte

Solusi mudah, menggunakan fakta bahwa tumpukan tidak pernah memiliki lebih dari 2 elemen.

[x,y]#'.'=[x+y]
[x,y]#_=[x*y]
s#'.'=1:s
s#_=2:s
f=head.foldl(#)[]
alephalpha
sumber
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;}

Yah, ini terlalu panjang.

BrainSteel
sumber
5

Pyth, 25 24 byte

eu?]?.xGHsGtG+GhHmqd\:zY

Punya ide dengan mempelajari solusi @ isaacg. Tapi saya menggunakan tumpukan.

Demonstrasi Online atau Test Suite

Penjelasan

Hal pertama yang saya lakukan adalah mengubah string input menjadi 0s dan 1s. A "."akan dikonversi menjadi 0, a ":"menjadi 1.

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

Lalu saya mengurangi daftar angka ini:

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
Jakube
sumber
4

JavaScript (ES6), 65

Kami hanya menggunakan 2 sel tumpukan kami.

Mulai memasukkan nilai dalam s [0].
Kemudian, pada setiap posisi ganjil (dihitung dari 0) dalam string input, masukkan nilai dalam s [1].
Pada setiap posisi genap, jalankan calc (tambah atau kalikan) dan simpan hasil dalam s [0].

Jadi lupakan stack dan gunakan hanya 2 variabel, a dan b.

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

Tes cepat

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

Keluaran

"." 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
edc65
sumber
-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 setidaknya pada borwser saya yang tidak berfungsi. untuk (i in s) memberikan properti tambahan selain indeks
edc65
ini bekerja untuk saya di firefox 37.0.2. Coba jalankan di tab browser yang bersih. Tampaknya stackexchange menambahkan properti tambahan ke string (di stub.en.js)
nderscore
3

Pyth, 27 byte

Jmhqd\:zu?*GhHteH+GhHctJ2hJ

Tumpukan? Siapa yang butuh tumpukan.

                       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.

Demonstrasi.

isaacg
sumber
1
Jenius. Dan sementara itu saya mengimplementasikan stack (32 byte). :-(
Jakube
3

Retina , 105 75 73 byte

Program Retina pertama saya! (Terima kasih kepada Martin Büttner karena telah menghemat 2 byte, belum lagi menciptakan bahasa di tempat pertama.)

Setiap baris harus dalam file terpisah; atau, Anda bisa meletakkan semuanya dalam satu file dan menggunakan -sbendera. The <empty>notasi merupakan file kosong / line.

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

Terinspirasi oleh jawaban mbomb007 , tapi saya mengambil pendekatan yang agak berbeda. Salah satu perbedaan utama adalah bahwa saya membangun tumpukan di depan string dotty (dengan bagian atas tumpukan menghadap ke kanan). Ini membuatnya mudah untuk mengkonversi simbol ke angka yang sesuai di tempat. Saya juga menggunakan aalih-alih 1, menukar hanya di akhir, untuk menghindari penguraian ambiguitas dalam urutan seperti $1a. Jika jawaban suka aaaaaaditerima sebagai angka unary, dua baris / file terakhir dapat dihilangkan untuk menghemat 4 byte.

Penjelasan:

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

Cocok jika ada 0 atau 1 item pada stack ( (a+;)?) diikuti oleh titik ( \.); jika demikian, itu mengganti periode dengan a;(yaitu mendorong 1).

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

Cocok jika ada 0 atau 1 item pada tumpukan diikuti oleh titik dua. Jika demikian, itu menggantikan titik dua dengan aa;(yaitu mendorong 2).

;(a+;)\.
$1

Cocok jika ada dua item pada tumpukan yang diikuti oleh titik. Menghapus titik dan titik koma di antara item, sehingga menambahkannya.

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

Cocok jika ada dua item pada tumpukan, yang atasnya adalah 2, diikuti oleh titik dua. Hapus tanda titik dua dan angka 2 dan ulangi angka lainnya dua kali, dengan demikian mengalikannya dengan angka 2.

)`;a;:
;

Regex cocok jika ada dua item pada tumpukan, yang atasnya adalah 1, diikuti oleh titik dua. Menghapus titik dua dan angka 1, meninggalkan angka lainnya tidak berubah (yaitu dikalikan dengan 1).

)`menunjukkan akhir dari satu loop. Jika ada perubahan pada string, kontrol kembali ke atas program dan menjalankan substitusi lagi. Jika string telah berhenti berubah, kami telah mengganti semua periode dan titik dua, dan yang tersisa hanyalah pembersihan ...

;
<empty>

Menghapus titik koma yang tersisa.

a
1

Mengubah semua a menjadi 1's. Sekali lagi, jika nomor unary diizinkan untuk menggunakan simbol apa pun, langkah ini tidak perlu.

DLosc
sumber
Apakah awal dari loop diasumsikan sebagai file pertama?
mbomb007
@ mbomb007 Ya. Saya telah melihat itu di dokumen, tetapi lupa sampai Martin mengingatkan saya tentang hal itu. ;)
DLosc
2

Karat, 170 karakter

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}

Lebih banyak bukti bahwa Rust benar-benar mengerikan dalam bermain golf. Kode lengkap ungolfed:

#[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}

Berikut adalah trik menarik yang saya gunakan dalam hal ini. Anda dapat memotong karakter dalam pernyataan if / else dengan meminta mereka mengembalikan nilai yang segera dibuang, yang berarti Anda hanya perlu satu titik koma alih-alih dua.

Sebagai contoh,

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

dapat diubah menjadi

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

yang menyimpan karakter dengan mencukur titik koma.

Gagang pintu
sumber
2

Haskell, 88 81 79 Bytes

(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

Tampaknya seseorang mengalahkan saya sampai tandai pada solusi Haskell, tidak hanya itu, solusi mereka lebih pendek daripada milik saya. Itu buruk tapi, saya tidak melihat alasan untuk tidak memposting apa yang saya hasilkan.

ankh-morpork
sumber
2

APL (50)

Saya sangat dirugikan di sini, karena APL bukan bahasa berbasis tumpukan. Saya akhirnya harus mengurangi pengurangan untuk mempersingkat program.

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

Fungsi bagian dalam mengambil 'perintah' di sebelah kiri dan tumpukan di sebelah kanan, dan menerapkannya, mengembalikan tumpukan. Fungsi luar menguranginya di atas string, dimulai dengan tumpukan kosong.

Penjelasan:

  • (⌽⍵),⊂⍬: daftar awal untuk mengurangi. ⊂⍬adalah daftar kosong kotak, yang mewakili tumpukan, (⌽⍵)adalah kebalikan dari input. (Pengurangan diterapkan kanan-ke-kiri pada daftar, sehingga string akan diproses dari kanan ke kiri. Membalik input sebelumnya membuatnya menerapkan karakter dalam urutan yang benar.)

  • {... }: fungsi dalam. Dibutuhkan tumpukan di sebelah kanan, karakter di sebelah kiri, dan mengembalikan tumpukan yang dimodifikasi.

    • F←'.:'⍳⍺: indeks karakter dalam string .:, ini akan menjadi 1 atau 2 tergantung pada nilainya.
    • 2>⍴⍵:F,⍵: Jika 2 lebih besar dari ukuran tumpukan saat ini, tambahkan saja nilai saat ini ke tumpukan.
    • : jika tidak,
      • 2↓⍵: hapus dua item teratas dari tumpukan
      • (... )/2↑⍵: kurangi fungsi yang diberikan di atasnya, dan tambahkan ke tumpukan.
      • ⍎F⌷'+×': fungsinya adalah +(penambahan) atau ×(perkalian), dipilih oleh F.
  • : akhirnya, kembalikan item paling atas di tumpukan

marinus
sumber
2

Ruby - 96 karakter

Bagian yang agak menarik di sini adalah eval .

Selain itu, saya membuat asumsi bahwa setelah karakter pertama, tumpukan akan selalu menjadi 2, matematika, 2, matematika, .... Ini memungkinkan saya menggunakan lebih sedikit kode dengan meraih dua karakter sekaligus - saya tidak pernah harus mencari apakah karakter adalah matematika atau angka. Itu posisi.

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

Tidak Disatukan:

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`
Bukan itu Charles
sumber
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 bagus dalam satu kalimat, karena tanda kurung penutup adalah opsional; sebaliknya, itu adalah bahasa yang buruk di mana menyimpan banyak nilai diperlukan karena menyimpan ke variabel membutuhkan dua hingga empat byte ruang. Karena itu, tujuannya adalah menulis sebanyak mungkin pada setiap baris. TI-BASIC juga mengerikan (untuk bahasa yang tokenized) pada manipulasi string apa pun; bahkan membaca substring itu panjang.

Trik meliputi:

  • int(e^([boolean] dari pada 1+(boolean ; menghemat satu byte
  • Jumlah parsial daftar alih-alih daftar slicing (yang akan membutuhkan menyimpan ke dalam daftar): menyimpan 3 byte
lirtosiast
sumber
Anda harus baik-baik saja dengan mengambil input dari Ans, seperti ".:.":prgmDOTTY, menghemat 4 byte.
MI Wright
@ Benar, saya menggunakan Ans untuk menyimpan nomor di tumpukan.
lirtosiast
Maksud saya di awal-- singkirkan baris 1, dan ubah baris kedua menjadi1+(":"=sub(Ans,1,1
MI Wright
1
Saya perlu menggunakan Str1 di loop, di mana Ans diambil, jadi saya tidak bisa lolos dengan menjaga string di Ans. Menyimpannya ke Str1 dari Ans tidak akan menghemat ruang.
lirtosiast
1

Pergi, 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)}

(agak) tidak berbulu:

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

Cobalah online di sini: http://play.golang.org/p/B3GZonaG-y

Kristoffer Sall-Storgaard
sumber
1

Python 3, 74

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

Pertama mengubah daftar input menjadi urutan 1 dan 2, mengambil nilai pertama sebagai nilai awal x. Kemudian, lepaskan dua elemen sekaligus dari depan s, ambil angka pertama dan tambahkan atau gandakan dengan nomor saat ini berdasarkan apakah yang kedua adalah 1 atau 2.

Tidak
sumber
1

nah ini adalah operasi yang sangat mudah, canggih oleh op (sengaja)

hanya saja ...

ekspresi tanda kurung diterjemahkan ke dalam operasi postfixed * / +

Kode: 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;}
  • fungsi ini harus dipanggil dari string tail seperti ini: f (V + 10) di mana V = ".: ..:.: .. ::"

memasukkan

panjang = 2n + 1 vektor V dari tipe char '.' atau ':'

Keluaran

bilangan bulat k

Fungsi

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

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


Simulasi:

coba di sini

Abr001am
sumber
Bagaimana Anda bisa berasumsi bahwa byte sebelum string ( *(V-1)) adalah nol?
nutki
ketika Anda mengalokasikan vektor baru, awalnya selalu dimulai dari segmen kosong, ujungnya itu adalah karakter kosong
Abr001am
1

Retina, 181 135 129 byte

Setiap baris harus dalam file terpisah. <empty>mewakili file kosong. Outputnya di Unary.

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

Ketika ${0}1digunakan, kawat gigi terpisah $0dari 1, jika tidak $01, kelompok pencocokan 1. Saya mencoba menggunakan $001, tetapi ini tampaknya tidak berfungsi dalam .NET rasa regex.

Sunting: Ditemukan yang $&sama dengan$0 .

Dalam pseudo-code, ini pada dasarnya akan menjadi loop do-while, seperti yang terlihat di bawah ini. Saya menekan angka pertama, lalu loop: mendorong angka kedua, menghapus operasi (instruksi), melakukan matematika, menghapus op. Lanjutkan perulangan. Perhatikan bahwa ketika sebuah operasi muncul, ini juga akan menghapus ruang setelah semua instruksi dilakukan.

Berkomentar:

^\..*           # 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>
mbomb007
sumber
Hal utama yang saya lihat dari segi golf adalah pola / pasangan pengganti seperti (:)(.*)-> $1$2, yang saya yakin bisa (:.*)-> $1(karena Anda menjaga kedua grup dalam urutan yang sama dan tidak melakukan hal lain dengan mereka) ).
DLosc
Saya mendapatkan inspirasi dan membuat jawaban Retina saya sendiri. Terima kasih telah mendorong saya untuk mengunduh bahasa yang menarik ini!
DLosc
@Dosc Keren! Ya, saya belum benar-benar mengunduhnya. Saya menggunakan tester penggantian regex online untuk setiap penggantian individu.
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])

Tidak Disatukan:

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

Dengan python, Anda mereferensikan indeks daftar seperti ini:

list[index]

Anda dapat memasukkan nilai boolean ke dalamnya, Trueapakah 1dan Falsesekarang 0.

# 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] ]
                                                                      [_=='.']

Cobalah online di sini

Tim
sumber
0

Perl, 77 byte

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

diperluas:

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

The @oArray peta Angka operator. Kemudian kami mengganti pasangan digit dengan operator yang sesuai, disusun ulang untuk infiks. Regexp dimulai dengan \Bjadi kami tidak cocok dengan karakter pertama. Hasil dari s///gmemberitahukan berapa banyak paren terbuka yang kita butuhkan di awal. Kemudian, ketika kami telah mengumpulkan ekspresi infiks penuh, kami dapat mengevaluasinya. (Hapus evaljika Anda ingin melihat ekspresi sebagai gantinya).

Inilah test harness yang saya gunakan untuk memverifikasi hasil:

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

Input adalah daftar ekspresi titik dan nilainya (disediakan dalam pertanyaan) dan output adalah pasangan {aktual, diharapkan}.

Toby Speight
sumber