Ocena ciągów Dotty

25

Napisz program, który przyjmuje ciąg nieparzystej długości zawierający tylko znaki .i :. Za pomocą początkowo pustego stosu wygeneruj liczbę z tego ciągu w następujący sposób:

Dla każdego znaku c w ciągu (od lewej do prawej) ...

  • Jeśli c jest, .a stos zawiera mniej niż 2 elementy, wciśnij 1 na stosie.
  • Jeśli c jest, .a stos zawiera 2 lub więcej elementów, usuń dwie górne wartości ze stosu i wypchnij ich sumę na stos.
  • Jeśli c jest, :a stos zawiera mniej niż 2 elementy, wciśnij 2 na stosie.
  • Jeśli c jest, :a stos zawiera 2 lub więcej elementów, usuń dwie najwyższe wartości ze stosu i wepchnij ich produkt na stos.

Wynikowa liczba to wartość na górze stosu. Twój program powinien wydrukować ten numer na standardowe wyjście (z opcjonalnym końcowym znakiem nowej linii).

(Mała analiza pokazuje, że pozostała tylko jedna liczba, chyba że łańcuch ma równą długość, dlatego je ignorujemy. W rzeczywistości stos nigdy nie ma więcej niż 2 elementy.)

Na przykład liczba ::...:.:.to 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

Jako kontrolę poczytalności, oto liczby dla wszystkich ciągów długości 1, 3 i 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

Najkrótszy program w bajtach wygrywa. Tiebreaker jest wcześniejszym postem.

  • Możesz założyć, że dane wejściowe są zawsze prawidłowe, tzn. Ciąg zawierający tylko .i :którego długość jest nieparzysta.
  • Zamiast pisać program, możesz napisać funkcję, która pobiera prawidłowy ciąg i wypisuje lub zwraca wygenerowaną liczbę.
Hobby Calvina
źródło
5
Najlepszy minimalistyczny korektor w historii.
dberm22

Odpowiedzi:

13

CJam, 27 24 23 22 bajtów

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

Całkiem prosto. Używam stosu CJam jako stosu wspomnianego w pytaniu;)

Algorytm

Najpierw spójrzmy na kod ASCII dla .i :.

'.i ':ied

[46 58]

Ponieważ w CJam indeks się zawija, zobaczmy, czy możemy użyć tych wartości bezpośrednio, aby uzyskać żądaną operację.

'.i4% ':i4%ed

[2 2]

Nie mogę więc po prostu użyć kodów ASCII w ciągu operacji o długości 4. Spróbujmy innych wartości

'.i 10% ':i 10%ed

[6 8]

który na sznurku o długości 4 sprowadza się do

[2 0]

Mogę użyć tej operacji mod 10, ale będzie to kosztować 2 bajty. Spróbujmy czegoś innego

'.i5% ':i5%ed

[1 3]

Fajnie !, teraz odejmujemy 1 dla warunku rozmiaru stosu, aby uzyskać indeksy 0, 1, 2 and 3i użyć 5tablicy length ( "1+2* ") jako przypadku przełącznika. Ostatnia spacja to tylko wypełniacz, aby uzyskać długość 5. To tylko 1 dodatkowy bajt w porównaniu z operacją modowania.

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

Wypróbuj online tutaj

1 bajt zapisany dzięki cosechy

Optymalizator
źródło
1
Jaka jest przestrzeń w ciągu operacji?
Peter Taylor,
@PeterTaylor wyjaśnił w poście.
Optymalizator
9

> <> (Ryba) , 33 bajty

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

Dość proste z małymi sztuczkami / optymalizacjami.

Wyjaśnienie:

  • Info: i= punkt kodowy następnego znaku wejściowego, -1jeśli osiągnięto koniec wejścia; a= 10; b= 11; )=>
  • ipunkt kodowy pierwszego wejścia char,
  • b%1- top_of_stack mod 11 - 1maski 48 ('.') , 56 (':')do1 , 2
  • i:1+?\~n; jeśli osiągnięty został koniec danych wejściowych, wydrukuj ostatni wynik i zakończ
  • Inaczej:
  • b%1- wejście maski do 1 , 2
  • 0@wciśnij 0pod dwoma numerami
  • i5a*)przeczytaj następny wpis i zamaskuj go do 0 , 1porównania50
  • if 1( ':') pomnóż dwa górne elementy, tworząc stos [0 produkt]
  • zawsze dodawaj dwa górne elementy tworząc stos albo [0 sum]albo[0+product=product]
  • 40.przeskocz (pętla) z powrotem do pozycji (4,0), nasz punkt 4,i:1+?\~n;
randomra
źródło
8

Haskell, 73 65 bajtów

Proste rozwiązanie, wykorzystujące fakt, że stos nigdy nie ma więcej niż 2 elementy.

[x,y]#'.'=[x+y]
[x,y]#_=[x*y]
s#'.'=1:s
s#_=2:s
f=head.foldl(#)[]
alephalpha
źródło
5

C, 104 bajty

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

To jest za długie.

BrainSteel
źródło
5

Pyth, 25 24 bajtów

eu?]?.xGHsGtG+GhHmqd\:zY

Wpadłem na pomysł studiując rozwiązanie @ isaacg. Ale używam stosu.

Demonstracja online lub pakiet testowy

Wyjaśnienie

Pierwszą rzeczą, którą robię, jest konwersja ciągu wejściowego na 0 i 1. A "."przekształca się w 0, a ":"w 1.

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

Następnie zmniejszam tę listę liczb:

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
źródło
4

JavaScript (ES6), 65

Używamy tylko 2 komórek naszego stosu.

Zacznij wpisywać wartość ws [0].
Następnie na każdej nieparzystej pozycji (licząc od 0) w ciągu wejściowym wprowadź wartość w s [1].
Na każdej parzystej pozycji wykonaj oblicz (dodaj lub pomnóż) i zapisz wynik w s [0].

Więc zapomnij o stosie i użyj tylko 2 zmiennych, a i b.

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

Szybki test

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

Wydajność

"." 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
źródło
-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 przynajmniej na mojej przeglądarce, która nie działa. for (i in) daje dodatkowe właściwości oprócz indeksów
edc65
działa dla mnie w Firefox 37.0.2. Spróbuj uruchomić go na czystej karcie przeglądarki. Wygląda na to, że stackexchange dodaje dodatkowe właściwości do ciągów znaków (w stub.en.js)
nderscore 26.04.15
3

Pyth, 27 bajtów

Jmhqd\:zu?*GhHteH+GhHctJ2hJ

Stos? Kto potrzebuje stosu.

                       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.

Demonstracja.

isaacg
źródło
1
Geniusz. W międzyczasie zaimplementowałem stos (32 bajty). :-(
Jakube
3

Siatkówka , 105 75 73 bajtów

Mój pierwszy program Retina! (Podziękowania dla Martina Büttnera za zapisanie 2 bajtów, nie mówiąc już o wymyśleniu języka.)

Każda linia powinna znajdować się w osobnym pliku; lub możesz umieścić je wszystkie w jednym pliku i użyć -sflagi. The<empty>Notacja reprezentuje pusty plik / linię.

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

Zainspirowany odpowiedzią mbomb007 , ale podchodzę nieco inaczej. Jedną z głównych różnic jest to, że buduję stos przed kropkowanym łańcuchem (górą stosu jest skierowana w prawo). Ułatwia to konwersję symboli na odpowiednie liczby w miejscu. Używam również azamiast 1zamiany tylko na końcu, aby uniknąć parsowania dwuznaczności w podobnych sekwencjach$1a . Jeśli odpowiedź typu „tak” aaaaaajest akceptowalna jako liczba jednoargumentowa, ostatnie dwa wiersze / pliki można wyeliminować, aby zaoszczędzić 4 bajty.

Wyjaśnienie:

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

Dopasowuje, jeśli na stosie (0 (a+;)?) znajduje się 0 lub 1 elementów, po których następuje kropka ( \.); jeśli tak, to zastępuje kropkę a;(tj. wypycha 1).

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

Dopasowuje, jeśli na stosie znajduje się 0 lub 1 przedmiotów, a następnie dwukropek. Jeśli tak, zastępuje dwukropek aa;(tj. Wypycha 2).

;(a+;)\.
$1

Dopasowuje, jeśli na stosie znajdują się dwa przedmioty, po których następuje kropka. Usuwa kropkę i średnik między elementami, tym samym dodając je.

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

Pasuje, jeśli na stosie znajdują się dwa przedmioty, których szczyt to 2, a następnie dwukropek. Usuwa dwukropek i 2 i powtarza drugą liczbę dwa razy, mnożąc ją przez 2.

)`;a;:
;

Wyrażenie regularne pasuje, jeśli na stosie znajdują się dwa przedmioty, których górna część to 1, a następnie dwukropek. Usuwa dwukropek i 1, pozostawiając drugą liczbę bez zmian (tj. Pomnożoną przez 1).

)`wskazuje koniec pętli. Jeśli w łańcuchu zostaną wprowadzone jakiekolwiek zmiany, formant powróci na początek programu i ponownie uruchomi podstawienia. Jeśli ciąg przestał się zmieniać, zastąpiliśmy wszystkie kropki i dwukropki, a wszystko, co pozostało, to czyszczenie ...

;
<empty>

Usuwa resztkowy średnik.

a
1

Przekształca wszystkie a w 1. Ponownie, jeśli jednostkowym liczbom wolno używać dowolnego symbolu, ten krok jest niepotrzebny.

DLosc
źródło
Czy zatem zakłada się, że początek pętli jest pierwszym plikiem?
mbomb007
@ mbomb007 Tak. Widziałem to w dokumentacji, ale zapomniałem, dopóki Martin mi o tym nie przypomniał. ;)
DLosc
2

Rdza, 170 znaków

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}

Kolejny dowód, że Rust jest absolutnie okropny w golfie. Pełny nieoznaczony kod:

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

Oto interesująca sztuczka, której użyłem w tym. Możesz ogolić znak w instrukcji if / else, zwracając mu wartość, która jest natychmiast odrzucana, co oznacza, że ​​potrzebujesz tylko jednego średnika zamiast dwóch.

Na przykład,

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

można zmienić na

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

który ocala postać, goląc średnik.

Klamka
źródło
2

Haskell, 88 81 79 bajtów

(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

Wygląda na to, że ktoś pobił mnie do kresu na rozwiązaniu Haskell, nie tylko to, że jego rozwiązanie jest krótsze niż moje. To źle, ale nie widzę powodu, aby nie publikować tego, co wymyśliłem.

ankh-morpork
źródło
2

APL (50)

Jestem tutaj w bardzo niekorzystnej sytuacji, ponieważ APL nie jest językiem stosowym. W końcu jednak musiałem ograniczyć nadużycia, aby skrócić program.

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

Funkcja wewnętrzna pobiera „polecenie” po lewej stronie i stos po prawej stronie i stosuje je, zwracając stos. Funkcja zewnętrzna zmniejsza ją w ciągu, zaczynając od pustego stosu.

Wyjaśnienie:

  • (⌽⍵),⊂⍬: początkowa lista do zmniejszenia. ⊂⍬pusta lista w ramkach, która reprezentuje stos, (⌽⍵)jest odwrotnością danych wejściowych. (Redukcję stosuje się od prawej do lewej nad listą, więc ciąg będzie przetwarzany od prawej do lewej. Wcześniejsze odwrócenie danych wejściowych powoduje, że znaki zostaną zastosowane we właściwej kolejności.)

  • {... }: funkcja wewnętrzna. Bierze stos po prawej stronie, postać po lewej i zwraca zmodyfikowany stos.

    • F←'.:'⍳⍺: indeks znaku w ciągu .:, będzie wynosił 1 lub 2 w zależności od wartości.
    • 2>⍴⍵:F,⍵: Jeśli 2 jest większy niż bieżący rozmiar stosu, wystarczy dołączyć bieżącą wartość do stosu.
    • : Inaczej,
      • 2↓⍵: usuń dwa górne elementy ze stosu
      • (... )/2↑⍵: zredukuj nad nimi daną funkcję i dodaj ją do stosu.
      • ⍎F⌷'+×': funkcją jest +(dodawanie) lub ×(mnożenie), wybrane przez F.
  • : w końcu zwróć najwyższy przedmiot ze stosu

marinus
źródło
2

Rubin - 96 znaków

Ten interesujący kawałek jest tutaj eval .

Poza tym zakładam, że po pierwszym znaku stos będzie zawsze wynosił 2, matematyka, 2, matematyka ... To pozwala mi używać mniej kodu, chwytając dwa znaki jednocześnie - nigdy nie muszę myśleć czy postać jest matematyką czy liczbą. To jest pozycyjne.

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

Nie golfowany:

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`
Nie ten Charles
źródło
2

TI-BASIC, 78 73 70 69 66 bajtów

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 jest dobry w liniach jednowarstwowych, ponieważ nawiasy zamykające są opcjonalne; i odwrotnie, jest to słaby język, w którym wymagane jest przechowywanie wielu wartości, ponieważ przechowywanie w zmiennej zajmuje dwa do czterech bajtów miejsca. Dlatego celem jest napisanie jak największej liczby wierszy. TI-BASIC jest także okropny (jak na język tokenizowany) przy manipulowaniu ciągami dowolnego rodzaju; nawet czytanie podciągów jest długotrwałe.

Sztuczki obejmują:

  • int(e^([boolean]zamiast 1+(boolean; oszczędza jeden bajt
  • Częściowa suma listy zamiast podziału na listy (co wymagałoby zapisania na liście): zapisuje 3 bajty
lirtosiast
źródło
Powinieneś być w porządku, biorąc dane wejściowe z Ans, na przykład ".:.":prgmDOTTYoszczędzając 4 bajty.
MI Wright,
@Wright Używam Ans do przechowywania numeru na stosie.
lirtosiast
Na początku miałem na myśli - pozbyć się linii 1 i zmienić drugą linię na1+(":"=sub(Ans,1,1
MI Wright
1
Muszę użyć Str1 w pętli, w której pobierany jest Ans, więc nie mogę uciec od trzymania łańcucha w Ans. Przechowywanie go w Str1 z Ans nie pozwoli zaoszczędzić miejsca.
lirtosiast
1

Udać się, 129 115 112 bajtów

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

(nieco) niespokojny:

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

Wypróbuj online tutaj: http://play.golang.org/p/B3GZonaG-y

Kristoffer Sall-Storgaard
źródło
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)

Najpierw przekształca listę wejściową w ciąg 1 i 2, przyjmując pierwszą wartość jako wartość początkową x. Następnie usuwa dwa elementy naraz s, biorąc pierwszy numer i albo dodając, albo mnożąc bieżący numer, w zależności od tego, czy drugi to 1, czy 2.

xnor
źródło
1

to jest tak łatwa obsługa, wyrafinowana przez op (celowo)

to jest po prostu ...

wyrażenie w nawiasach przetłumaczone na postfiks * * / +

Kod: C (80 bajtów)

int f(char*V){return*(V-1)?f(V-2)*(*V==58?*(V-1)/29:1)+(*V&4)/4**(V-1)/29:*V/29;}
  • tę funkcję należy wywołać z końca łańcucha w następujący sposób: f (V + 10) gdzie V = ".: ..:. .. .."

wkład

długość = 2n + 1 wektor V typu char '. ” lub „:”

Wydajność

liczba całkowita k

Funkcjonować

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

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


Symulacja:

spróbuj tutaj

Abr001am
źródło
Jak możesz założyć, że bajt przed string ( *(V-1)) ma wartość zero?
nutki
kiedy przydzielasz nowy wektor, jego początek zawsze zaczyna się od pustego segmentu, jego koniec JEST pustą postacią
Abr001am
1

Retina, 181 135 129 bajtów

Każda linia powinna znajdować się w osobnym pliku. <empty>reprezentuje pusty plik. Dane wyjściowe są w Unary.

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

Gdy ${0}1jest używany, nawiasy klamrowe oddzielają się $0od 1, w przeciwnym razie byłaby to $01pierwsza pasująca grupa. Próbowałem użyć $001, ale wydaje się, że nie działa w smaku regex .NET.

Edycja: Znaleziono $&to samo co $0.

W pseudokodzie jest to w zasadzie pętla „do-while”, jak pokazano poniżej. Naciskam pierwszy numer, a następnie zapętlam: wciskam drugi numer, usuwam operację (instrukcję), wykonuję matematykę, usuwam op. Kontynuuj zapętlanie. Zauważ, że kiedy operacja zostanie wyświetlona, ​​spowoduje to również usunięcie spacji po wykonaniu wszystkich instrukcji.

Skomentowano:

^\..*           # 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
źródło
Najważniejsze, co widzę pod względem golfowym, to pary wzór / wymiana, takie jak (:)(.*)-> $1$2jestem pewien, że może to być po prostu (:.*)-> $1(ponieważ utrzymujesz obie grupy w tej samej kolejności i nie robisz z nimi nic innego ).
DLosc
Zainspirowałem się i odpowiedziałem na własną odpowiedź Retina. Dzięki za nakłonienie mnie do pobrania tego interesującego języka!
DLosc
@DLosc Cool! Tak, właściwie go nie pobrałem. Użyłem testera wymiany wyrażeń regularnych online dla każdej pojedynczej wymiany.
mbomb007
0

Python 3, 122 bajty

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

Nie golfowany:

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

W Pythonie odwołujesz się do indeksu takiej listy:

list[index]

Możesz w to wstawić wartość boolowską, Truejest 1i Falsejest 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] ]
                                                                      [_=='.']

Wypróbuj online tutaj

Tim
źródło
0

Perl, 77 bajtów

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

rozszerzony:

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

@oTablica odwzorowuje cyfry operatorów. Następnie zastępujemy pary cyfr odpowiednim operatorem, zamienionym na infix. Wyrażenie regularne zaczyna się od, \Bwięc nie dopasowujemy pierwszej postaci. Wynik s///gmówi nam, ile otwartych parenów potrzebujemy na początku. Następnie, po skompletowaniu wyrażenia pełnej poprawki, możemy go ocenić. (Usuń, evaljeśli chcesz zobaczyć wyrażenie).

Oto uprząż testowa, której użyłem do weryfikacji wyników:

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

Dane wejściowe to lista wyrażeń kropkowych i ich wartości (podanych w pytaniu), a dane wyjściowe to pary {faktyczne, oczekiwane}.

Toby Speight
źródło