Dystrybucja liczb

11

W tym wyzwaniu będziesz używać dystrybucji produktu według sum i różnic liczbowych, jak wyjaśniono tutaj .

wprowadź opis zdjęcia tutaj

Przykłady

  Input      |     Output
-------------|-------------
23(12+42)    | (23*12)+(23*42)
9(62-5)      | (9*62)-(9*5)
4(17+8-14)   | (4*17)+(4*8)-(4*14)
15(-5)       | -(15*5)
2(3)         | (2*3)
8(+18)       | +(8*18)
8(-40+18)    | -(8*40)+(8*18)

Specyfikacja

Dane wejściowe będą ciągiem postaci n(_)z pojedynczą dodatnią liczbą całkowitą bez znaku, npo której nastąpi wyrażenie w nawiasie _. To wyrażenie _będzie się składać z sum i różnicy jednego z dodatnich liczb całkowitych, oddzielonych znakami +i -. Pierwszy termin może być poprzedzony +znakiem, -znakiem lub brakiem znaku.

Na wyjściu nnależy rozdzielić początkową liczbę, aby pomnożyć każdy z warunków. Każdy termin anależy pomnożyć przez lewo, naby utworzyć wyrażenie w nawiasach (n*a), a te nowe terminy należy połączyć z znakami +i -podpisać w dokładnie taki sam sposób, jak pierwotne terminy.

Nieprawidłowe dane wejściowe

To są przykłady danych wejściowych, których nie musisz obsługiwać.

3(5 plus 3)
6(5 13)
(5+8)(6+6)
(5+3)8

Zwycięski

To jest , więc wygrywa najkrótszy kod w bajtach.

Downgoat
źródło
Przyszło mi do głowy, że wyrażenie regularne jest naprawdę odpowiednie dla tego problemu. Jeśli nie zgadzasz się z rozwiązaniami reg-ex, możesz go zablokować, chociaż ludzie mogą już nad tym pracować.
xnor
Czy biblioteki są dozwolone?
orlp
@orlp Do pewnego stopnia, który był omawiany na meta .
Downgoat
Ciekawy przypadek:8(-40+18)
BrainSteel

Odpowiedzi:

2

Pip, 28 bajtów

DQaUnxWa^'(xR`\d+`'(.n.`*&)`

Wyjaśnienie:

                              a is first cmdline arg (implicit)
DQa                           Remove (DeQueue) the closing paren from a
   UnxWa^'(                   Unify n and x with a split on open paren--Python equivalent
                                n,x=a.split("(")
                              n is thus the number to be distributed, and x is the
                                addition/subtraction expression
           xR                 In x, replace...
             `\d+`            ... regex matching numbers...
                  '(.n.`*&)`  ... with the replacement pattern (n*&), where n is the
                                appropriate number and & substitutes the complete match
                              Print result (implicit)

Obiekty Pip's Pattern przeważnie są zgodne ze składnią wyrażeń regularnych Pythona, ale &wzorzec zastępczy jest zapożyczony z sed.

Przeczytaj więcej o Pip w repozytorium Github

DLosc
źródło
9

JavaScript 65 bajtów

s=>(q=s.split(/[()]/))[1].replace(/(\D?)(\d+)/g,`$1(${q[0]}*$2)`)

To zajmie dane wejściowe. Uzyskaj znak + lub -, a następnie cyfry, a następnie zamień go we właściwej kolejności.

Wyjaśnienie

s=>   // Function with argument "s"
  (q= // Set q to...
    s.split(/[()]/) // Splits on parenthesis, returns array
  )
  [1] // Gets second match or text inside brackets
  .replace(/ // Replaces string 
     (\D?)  // Try to match a non-digit, the +-/* (group 1)
     (\d+)  // Then match one or more digits (group 2)
  /,
      // $1 is group 1 and $2 is group 2 q[0] is the text before the parenthesis 
  `$1(${q[0]}*$2)`
  ) 

Stosowanie

Działa to tylko w Firefox i Safari Nightly, może Edge? ponieważ wykorzystuje funkcje ES6. Możesz uruchomić go przez:

var t = s => (q = s.split (/ [()] /)) [1] .replace (/ (\ D?) (\ d +) / g, `$ 1 ($ {q [0]} * 2 USD) `)

t ( „5 (-6 + 7 + 3-8 + 9)” ); // - (5 * 6) + (5 * 7) + (5 * 3) - (5 * 8) + (5 * 9)

źródło
(.?)(\d+)Jest zepsuty. To się nie udaje 23(12+42), produkując 1(23*2)+(23*42).
lub
@orlp Naprawiłem to
Ten kod będzie działał tylko w przeglądarce Firefox b / c funkcji strzałki, ale to w porządku
MayorMonty
@SpeedyNinja Działa również w Edge. W przeglądarce Chrome / Opera musisz włączyć „eksperymentalne funkcje JavaScript”.
rink.attendant. 6
\D?może być użyty zamiast[+-]?
edc65
6

Python 2.7, 110 108 bajtów

import re
p=re.findall('([+-]?)(\d+)',raw_input())
print"".join("%s(%s*%s)"%(e[0],p[0][1],e[1])for e in p[1:])

Program pobiera dane wejściowe ze standardowego wejścia, wyszukuje dopasowania względem - ([+-]?)(\d+)regex i tworzy ciąg wyjściowy.
Testowanie -

<< 23(12+42)
>> (23*12)+(23*42)

<< 9(62-5)
>> (9*62)-(9*5)

<< 4(17+8-14)
>> (4*17)+(4*8)-(4*14)

<< 15(-5)
>> -(15*5)

<< 2(3)
>> (2*3)

<< 8(+18)
>> +(8*18)

<< 8(-40+18)
>> -(8*40)+(8*18)
Kamehameha
źródło
4

Siatkówka , 40 bajtów

+`(\d+)\((\D)?(\d+)
$2($1*$3)$1(
\d+..$
<empty line>

Każda linia powinna przejść do własnego pliku, ale możesz uruchomić kod jako jeden plik z -sflagą. Na przykład:

>echo -n "8(-40+18)"|retina -s distributing_numbers
-(8*40)+(8*18)

Pierwsze dwa wiersze przesuwają mnożnik obok każdej liczby w oczekiwanej formie:

8(-40+18)
-(8*40)8(+18)
-(8*40)+(8*18)8()

Ostatnie dwa wiersze usuwają niepotrzebną część końcową:

-(8*40)+(8*18)8()
-(8*40)+(8*18)
randomra
źródło
3

sed, 105 bajtów

Chciałem tylko sprawdzić, czy da się to zrobić za pomocą sed.
Może trochę stara szkoła, ale działa.

$ cat distnum.sed
s@\([0-9]*\)(\([0-9]*\)\([+-]*\)\([0-9]*\)\([+-]*\)\([0-9]*\))@(\1*\2)\3(\1*\4)\5(\1*\6)@
s@([0-9]*\*)@@g

$ cat distnum.txt
23(12+42)
9(62-5)
4(17+8-14)
15(-5)
2(3)
8(+18)
8(-40+18)

$ sed -f distnum.sed distnum.txt
(23*12)+(23*42)
(9*62)-(9*5)
(4*17)+(4*8)-(4*14)
-(15*5)
(2*3)
+(8*18)
-(8*40)+(8*18)
LukStorms
źródło
2

REGXY , 45 bajtów

Używa REGXY, języka opartego na podstawieniu wyrażenia regularnego.

/(\d+)\((\D)?(\d+)/\2(\1*\3)\1(/
//
/\d+\(.//
Jarmex
źródło
Jak //działa Przypuszczam, że zapętla się do góry, dopóki łańcuch się nie zmieni, ale nie mogę znaleźć na stronie esolang dlaczego.
randomra
To trochę bezczelne nadużycie niejasności w specyfikacji językowej, ale wyjaśniłem to tutaj: codegolf.stackexchange.com/questions/52946/...
Jarmex
1
Nadal nie rozumiem, dlaczego nie //tworzy nieskończonej pętli, ponieważ nothingzawsze będzie pasować, więc zawsze przeskakujemy z powrotem do pierwszej linii.
randomra
Wiesz co? Właściwie nie mam pojęcia dlaczego. Masz całkowitą rację, myślenie o tym teraz nie ma logicznego sensu, ale zdecydowanie kompiluje się i działa w dostarczonym tłumaczu. Nawet patrzenie na skompilowany Perl, który generuje, wprawia mnie w zakłopotanie, ponieważ wygląda jeszcze wyraźniej, że powinna to być nieskończona pętla: pastebin.com/9q7M0tpZ
Jarmex
2

Perl, 36 bajtów

Kod 35 bajtów + wiersz poleceń 1 bajt

($a,$_)=split/[()]/;s/\d+/($a*$&)/g

Stosowanie:

echo "4(17+8-14)" | perl -p entry.pl
Jarmex
źródło
1

Pyth, 39 38 bajtów

Straszne rozwiązanie wyrażenia regularnego:

P:eJcz\("([+-]?)(\d+)"X"\\1(_*\\2)"3hJ
orlp
źródło
Nie mogę tego uruchomić w tłumaczu online .
BrainSteel
@BrainSteel Działa w tłumaczu offline, wydaje się, że jest to problem z heroku.
lub
@orlp To nie jest problem z heroku. Dynamiczne importowanie jest wyłączone w trybie awaryjnym, aby zmniejszyć prawdopodobieństwo włamania, a moduł re wykonuje import dynamiczny. Dlatego nie można używać ponownie w trybie awaryjnym, w tym online.
isaacg
1

Ruby, 94 bajty

gets.scan(/(\d+)\(([[-+]?\d+]+)/){|a,b|b.scan(/([-+]?)(\d+)/).map{|c,d|$><<"#{c}(#{a}*#{d})"}}
JWT
źródło
1

CJam, 50 bajtów

l__'(#_@<'*+@@)>);'+/'-f/\ff{1$'(@@++')+L?}'-f*'+*

Wypróbuj online

CJam nie obsługuje wyrażeń regularnych ani niczego poza wyszukiwaniem i dzieleniem ciągów, co jest bardzo wygodne przy analizie wyrażeń. Jest tu więc trochę pracy.

Wyjaśnienie:

l__   Get input and push 2 copies for splitting.
'(#   Find index of '(.
_     Copy index, will be used twice.
@<    Get one copy of input to top, and slice to get first multiplier.
'*+   Append '* to first multiplier.
@@    Get another copy of input and '( index to top.
)>    Increment and slice to get everything after '(.
);    Remove trailing ').
'+/   Split at '+.
'-f/  Split each part at '-.
\     Swap first multiplier to top.
ff{   Apply block to nested list of second multipliers.
  1$    Copy term. Will use this copy as condition to skip empty second multipliers
        that result from unary + or -.
  '(    Opening parentheses.
  @@    Get first and second multiplier to top.
  ++    Concatenate it all.
  ')+   Concatenate closing parentheses.
  L     Push empty string for case where term is skipped.
  ?     Ternary if to pick term or empty string.
}     End of loop over list of second multipliers.
'-f*  Join sub-lists with '-.
'+*   Join list with '+.
Reto Koradi
źródło
1

gawk - 60 58

$0=gensub(/(.*\()?(+|-)?([0-9]+))?/,"\\2("$0+0"*\\3)","G")

Uff ... od dłuższego czasu nie współpracowałem z regexp.

Cabbie407
źródło
1

Perl 5, 70 60 55 44 Bajtów + 1 kara

Rozwiązanie perla, które wykorzystuje tylko wyrażenie rozdzielone i 1 wyrażenie regularne.
Oblicza również dłuższe dane wejściowe.

($a,$_)=split/[()]/;s/(\D?)(\d+)/$1($a*$2)/g

Test

$ echo "8(9-10+11-12+13-14)"|perl -p distnums.pl   
(8*9)-(8*10)+(8*11)-(8*12)+(8*13)-(8*14)

Wersja, która przyjmuje parametr

($a,$_)=split/[()]/,pop;s/(\D?)(\d+)/$1($a*$2)/g;print

Wersja, która używa tylko wyrażeń regularnych.

s/(\d+)\((.*)\)/$2:$1/;s/(\D?)(\d+)(?=.*:(\d+)).*?/$1($3*$2)/g;s/:.*//

Ten działa przez grupę przechwytywania z pozytywnym spojrzeniem w przód i leniwym dopasowaniem. Prawdopodobnie zastosowałby pozytywny wygląd, gdyby Perl 5 go wspierał, ale niestety. Zajęło mi trochę czasu, aby dowiedzieć się, że z regexem jest to możliwe.

LukStorms
źródło
1
Hej Luk, możesz zapisać niektóre znaki przy użyciu -popcji wiersza polecenia (myślę, że jest to +1 char vs 9 dla ,<>i ;print), ponieważ domyślnie splitbędzie działać $_(co będzie, co jest w środku <>), a druk jest również zawarty w pętli ! Mam nadzieję, że to pomaga!
Dom Hastings,
1
Dzięki! Pomogło. Opcja -p po prostu nie przyszła mi do głowy. Prawdopodobnie dlatego, że jest to coś, co rzadko jest używane poza kontekstem gry w golfa. Jak myślisz, dlaczego to +1 znak? To wyzwanie nie wspomina o karach za używanie przełączników.
LukStorms,
Nie mogę teraz znaleźć tego posta, ale ten meta post wspomina o punktacji dla flag Perla.
Dom Hastings,
1
Mój zły, wygląda na to, że wymyśliłem dla ciebie bardzo podobne rozwiązanie, które jest właściwie tylko twoją nieco bardziej golfową wersją! Zasadniczo nie musisz nawet przechwytywać [+ -], ponieważ i tak pozostawiasz je nietknięte w podstawieniu: codegolf.stackexchange.com/a/57117/26977
Jarmex
To super. Dzięki tobie Perl pokonuje nawet rozwiązania Pyth / Cjam w tym wyzwaniu. I tak nie powinienem się przejmować nieprawidłowymi danymi wejściowymi po tym, jak ten podział usunął nawiasy.
LukStorms,
1

Siatkówka , 50 51 43 bajtów

Myślę, że to może być mój pierwszy program Retina. Jeśli nie, to mój pierwszy program Retina jest tym złożonym (tak naprawdę nie tak złożonym). Każda linia przechodzi we własny plik.

+`(\d+)\((\D?)(\d+)
$1($'$2($1*$3)
.+?\)
$'

Tak naprawdę nie testowałem tego z Retiną, testowałem to wielokrotnie za pomocą testera zastępującego wyrażenie regularne, ale powinno działać.

Opis pierwszego przykładu:

Ponieważ istnieje parzysta liczba plików, Retina używa trybu zastępowania. Pierwsza zamiana (pierwsze dwa pliki) usuwa liczbę do dystrybucji i dodaje tę parę dystrybucyjną (23*12)do końca, dając 23(+42)(23*12). +`na początku każe Retinie wielokrotnie wymieniać, aż wzór się nie zgadza, a ponieważ jest to ponownie dopasowane, wzór zastępuje to 23()(23*12)+(23*42). To się już nie zgadza, więc kolejne 2 pliki są używane do następnej zamiany. Tym razem po prostu usuwa 23(). Działa to ładnie: ponieważ produkty są dołączane na końcu, nie muszę robić nic dziwnego, jeśli liczba nie ma znaku, ponieważ jedyną, która może być bez znaku, jest pierwsza liczba.

EDYCJA: $'w zamianie reprezentuje resztę ciągu po dopasowaniu, więc mogę usunąć końcowe (.*)s.

mbomb007
źródło
0

k, 98 bajtów

Niezbyt golfowy.

{,/(*x){(s#y),("*"/:(x;(s:(*y)in"+-")_y))/:$"()"}/:1_x@:&~~#:'x:((0,&~x in .Q.n)_x){x_'x?'y}/"()"}

Podziel na niecyfrowe, usuń pareny, usuń puste ciągi, a następnie zachowaj xstałą jako pierwszy ciąg, połącz *z każdym pozostałym ciągiem y, nawiasuj rozmiar i przenieś znak na początek, jeśli jest obecny; spłaszcz dane wyjściowe w pojedynczy ciąg.

Aaron Davies
źródło