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.