Distribuire i numeri


11

In questa sfida utilizzerai la distribuzione di un prodotto su somme e differenze di numeri, come spiegato qui .

inserisci qui la descrizione dell'immagine

Esempi

  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)

specificazione

L'input sarà una stringa del modulo n(_), con un singolo intero senza segno positivo nseguito da un'espressione tra parentesi _. Questa espressione _consisterà in somme e differenze di uno dei termini più positivi-interi separati da +e -segni. Il primo termine può essere preceduto da un +segno, un -segno o nessun segno.

Nell'output, il numero iniziale ndeve essere distribuito per moltiplicare ciascuno dei termini. Ogni termine di adovrebbe essere lasciato moltiplicato per nper produrre l'espressione tra parentesi (n*a), e questi nuovi termini dovrebbero essere combinati con +e -segni esattamente allo stesso modo dei termini originali.

Ingressi non validi

Questi sono esempi di input che non devi gestire.

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

vincente

Questo è , quindi vince il codice più breve in byte.


Mi viene in mente che regex è davvero adatto a questo problema. Se non stai bene con le soluzioni reg-ex, potresti vietarlo, anche se le persone potrebbero già lavorarci.
— xnor

Sono consentite le biblioteche?
— orlp,

@orlp In una certa misura che è stato discusso su meta .
— Downgoat,

Caso interessante:8(-40+18)
— BrainSteel,

Risposte:


2

Pip, 28 byte

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

Spiegazione:

                              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)

Gli oggetti Pattern di Pip seguono principalmente la sintassi della regex di Python, ma il &pattern di sostituzione viene preso in prestito da sed.

Maggiori informazioni su Pip nel repository Github


9

JavaScript 65 byte

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

Questo richiederà l'input. Prendi il + o -, quindi le cifre, quindi sostituiscilo nell'ordine corretto.

Spiegazione

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

uso

Funziona solo con Firefox e Safari Nightly, forse Edge? perché utilizza le funzionalità ES6. Puoi eseguirlo da:

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

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

(.?)(\d+)è rotto. Questo fallisce 23(12+42), producendo 1(23*2)+(23*42).
— orlp,

@orlp L'ho risolto

Questo codice funzionerà solo in Firefox b / c della funzione freccia, ma va bene
— MayorMonty

@SpeedyNinja Funziona anche in Edge. Per Chrome / Opera devi abilitare le "funzionalità JavaScript sperimentali".
— rink.attendant.6

\D?potrebbe essere usato al posto di[+-]?
— edc65,

6

Python 2.7, 110 108 byte

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

Il programma prende input da stdin, cerca corrispondenze contro - ([+-]?)(\d+)regex e crea la stringa di output.
Testarlo -

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

4

Retina , 40 byte

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

Ogni riga dovrebbe andare al proprio file ma è possibile eseguire il codice come un file con il -sflag. Per esempio:

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

Le prime due righe spingono il moltiplicatore accanto a ogni numero nella forma prevista:

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

Le ultime due righe rimuovono la parte finale non necessaria:

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

3

sed, 105 byte

Volevo solo vedere se questo può essere fatto con sed.
Forse un po 'vecchia scuola, ma funziona.

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


2

REGXY , 45 byte

Utilizza REGXY, un linguaggio basato sulla sostituzione regex.

/(\d+)\((\D)?(\d+)/\2(\1*\3)\1(/
//
/\d+\(.//

Come //funziona? Suppongo che si giri in alto fino a quando la stringa non cambia, ma non riesco a trovare il perché nella pagina di esolang.
— randomra,

È un po 'un sfacciato abuso della vaghezza nelle specifiche della lingua, ma l'ho spiegato qui: codegolf.stackexchange.com/questions/52946/…
— Jarmex,

1
Non riesco ancora a capire perché non //crei un loop infinito perché nothingcorrisponderà sempre, quindi torniamo sempre alla prima riga.
— randomra,

Sai una cosa? In realtà non ho idea del perché. Hai assolutamente ragione, pensarci ora non ha alcun senso logico, ma sicuramente si compila e funziona nell'interprete fornito. Anche guardando il Perl compilato che genera mi confonde, perché sembra ancora più chiaro che dovrebbe essere un ciclo infinito: pastebin.com/9q7M0tpZ
— Jarmex,

2

Perl, 36 byte

Codice 35 byte + riga comandi 1 byte

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

Uso:

echo "4(17+8-14)" | perl -p entry.pl

1

Pyth, 39 38 byte

Una terribile soluzione regex:

P:eJcz\("([+-]?)(\d+)"X"\\1(_*\\2)"3hJ

Non riesco a farlo funzionare nell'interprete online .
— BrainSteel,

@BrainSteel Funziona nell'interprete offline, sembra essere un problema con heroku.
— orlp,

@orlp Non è un problema con heroku. Le importazioni dinamiche sono disabilitate in modalità provvisoria, per ridurre la probabilità di un hack e il modulo re esegue un'importazione dinamica. Quindi re non può essere utilizzato in modalità provvisoria, anche online.
— isaacg,

1

Rubino, 94 byte

gets.scan(/(\d+)\(([[-+]?\d+]+)/){|a,b|b.scan(/([-+]?)(\d+)/).map{|c,d|$><<"#{c}(#{a}*#{d})"}}

1

CJam, 50 byte

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

Provalo online

CJam non ha il supporto regex o qualsiasi cosa oltre alla ricerca e alla divisione delle stringhe che sia molto conveniente per analizzare le espressioni. Quindi c'è del lavoro qui coinvolto.

Spiegazione:

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 '+.

1

gawk - 60 58

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

Accidenti ... non ho lavorato con regexp da un po 'di tempo.


1

Perl 5, 70 60 55 44 byte + 1 penalità

Una soluzione perl che utilizza solo split e 1 espressione regolare.
Calcola anche gli input più lunghi.

($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)

Una versione che accetta un parametro

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

Una versione che utilizza solo espressioni regolari.

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

Questo funziona tramite un gruppo di acquisizione all'interno di un lookahead positivo e una corrispondenza pigra. Probabilmente avrebbe usato un aspetto positivo se Perl 5 lo avesse supportato, ma purtroppo. Mi ci è voluto un po 'per capire che questo genere di cose è possibile con regex.


1
Ehi Luk, potresti essere in grado di salvare alcuni caratteri usando l' -popzione della riga di comando (penso che questo sia +1 carattere vs 9 per ,<>e ;print) come splitfunzionerà $_di default (che sarà qualsiasi cosa sia dentro <>) e la stampa è inclusa anche nel ciclo ! Spero possa aiutare!
— Dom Hastings,

1
Grazie! Ha aiutato. L'opzione -p semplicemente non mi è passata per la testa. Probabilmente dal momento che è qualcosa che viene usato raramente al di fuori di un contesto golfistico. Perché pensi che sia +1 carattere? Questa sfida non menziona nulla di una penalità per l'utilizzo di switch.
— LukStorms,

Non riesco a trovare il post ora, ma questo meta post menziona il punteggio per le bandiere di Perl.
— Dom Hastings,

1
Mio cattivo, sembra che sia arrivato e abbia pubblicato una soluzione molto simile a te, che in effetti è solo una tua versione leggermente più giocosa! Fondamentalmente non hai nemmeno bisogno di catturare il [+ -] perché li lasci comunque intatti nella sostituzione: codegolf.stackexchange.com/a/57117/26977
— Jarmex,

Questo è figo. Grazie a te, Perl batte anche le soluzioni Pyth / Cjam in questa sfida. Non avrei dovuto preoccuparmi degli input non validi comunque dopo che quella divisione aveva rimosso le parentesi.
— LukStorms,

1

Retina , 50 51 43 byte

Penso che questo potrebbe essere il mio primo programma Retina. Altrimenti, è il mio primo programma Retina che è così complesso (non così complesso, davvero.) Ogni riga va nel suo file.

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

In realtà non l'ho testato con Retina, l'ho testato usando un tester regex-sostituzione più volte, ma dovrebbe funzionare.

Descrizione per il primo esempio:

Poiché esiste un numero pari di file, Retina utilizza la modalità di sostituzione. Il primo rimpiazzo (primi due file) rimuove un numero da distribuire e aggiunge quella coppia di distribuzione (23*12)alla fine, dando 23(+42)(23*12). +`all'inizio dice a Retina di sostituire ripetutamente fino a quando il modello non corrisponde, e poiché questo viene nuovamente abbinato, il modello sostituisce questo con 23()(23*12)+(23*42). Questo non corrisponde più, quindi i successivi 2 file vengono utilizzati per il prossimo rimpiazzo. Questa volta, rimuove semplicemente il file 23(). Funziona bene: poiché i prodotti vengono aggiunti alla fine, non devo fare nulla di strano se un numero non ha un segno, poiché l'unico che può essere senza segno è il primo numero.

EDIT: $'in sostituzione rappresenta il resto della stringa dopo la corrispondenza, quindi posso rimuovere i messaggi finali (.*).


0

k, 98 byte

Non molto golf.

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

Dividi su non cifre, rimuovi parentesi, rimuove stringhe vuote, quindi mantieni xcostante come prima stringa, combina *con ogni stringa rimanente y, parentesi e sposta il segno all'inizio, se presente; appiattire l'output in una singola stringa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.