Mendistribusikan Angka

11

Dalam tantangan ini Anda akan menggunakan mendistribusikan produk melebihi jumlah dan perbedaan angka, seperti yang dijelaskan di sini .

masukkan deskripsi gambar di sini

Contohnya

  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)

Spesifikasi

Input akan berupa string formulir n(_), dengan satu bilangan bulat unsigned positif ndiikuti oleh ekspresi yang diurung _. Ungkapan ini _akan terdiri dari jumlah dan perbedaan dari salah satu istilah bilangan bulat positif yang dipisahkan oleh +dan -tanda. Istilah pertama dapat didahului dengan +tanda, -tanda, atau tanpa tanda.

Dalam output, angka awal nharus didistribusikan untuk melipatgandakan setiap persyaratan. Setiap istilah aharus dikalikan dengan nuntuk menghasilkan ekspresi yang dipasteurisasi (n*a), dan istilah-istilah baru ini harus digabungkan dengan +dan -menandatanganinya dengan cara yang persis sama seperti istilah aslinya.

Input tidak valid

Ini adalah contoh input yang tidak harus Anda tangani.

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

Kemenangan

Ini adalah , jadi kode terpendek dalam byte menang.

Downgoat
sumber
Terpikir oleh saya bahwa regex sangat cocok untuk masalah ini. Jika Anda tidak setuju dengan solusi reg-ex, Anda dapat mencekalnya, meskipun orang mungkin sudah mengerjakannya.
xnor
Apakah perpustakaan diizinkan?
orlp
@orlp Sampai batas tertentu yang telah dibahas pada meta .
Downgoat
Kasus yang menarik:8(-40+18)
BrainSteel

Jawaban:

2

Pip, 28 byte

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

Penjelasan:

                              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)

Objek Pola Pip sebagian besar mengikuti sintaks Python regex, tetapi &pola penggantian dipinjam dari sed.

Baca lebih lanjut tentang Pip di repositori Github

DLosc
sumber
9

JavaScript 65 byte

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

Ini akan mengambil input. Dapatkan + atau -, lalu digit, lalu ganti dengan urutan yang benar.

Penjelasan

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

Pemakaian

Ini hanya berfungsi di Firefox dan Safari Nightly mungkin Edge? karena menggunakan fitur ES6. Anda dapat menjalankannya dengan:

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)

sumber
(.?)(\d+)rusak. Ini gagal 23(12+42), menghasilkan 1(23*2)+(23*42).
orlp
@ orlp Saya telah memperbaikinya
Kode ini hanya akan berfungsi di Firefox b / c dari fungsi panah, tapi tidak apa-apa
MayorMonty
@SpeedyNinja Ini juga berfungsi di Edge. Untuk Chrome / Opera Anda harus mengaktifkan "fitur JavaScript eksperimental".
rink.attendant.6
\D?bisa digunakan sebagai ganti[+-]?
edc65
6

Python 2.7, 110 108 Bytes

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 ini mengambil input dari stdin, mencari kecocokan melawan - ([+-]?)(\d+)regex dan membuat string keluaran.
Mengujinya -

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

Retina , 40 byte

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

Setiap baris harus menuju ke file sendiri tetapi Anda dapat menjalankan kode sebagai satu file dengan -sbendera. Misalnya:

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

Dua baris pertama mendorong pengali di sebelah setiap angka dalam bentuk yang diharapkan:

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

Dua baris terakhir menghapus bagian trailing yang tidak perlu:

-(8*40)+(8*18)8()
-(8*40)+(8*18)
randomra
sumber
3

sed, 105 byte

Hanya ingin melihat apakah ini bisa dilakukan dengan sed.
Mungkin sekolah yang agak tua, tetapi berhasil.

$ 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
sumber
2

rs , 77 byte

$$d=(?<!\))([+-]?)(\d+)
+$d\($d([+-])/\3(\1\2*\4)\5\1\2(
$d\($d\)/\3(\1\2*\4)

Demo langsung dan semua kasus uji.

Ini adalah pertama kalinya macro rs benar-benar digunakan!

kirbyfan64sos
sumber
2

REGXY , 45 byte

Menggunakan REGXY, bahasa berbasis pengganti regex.

/(\d+)\((\D)?(\d+)/\2(\1*\3)\1(/
//
/\d+\(.//
Jarmex
sumber
Bagaimana cara //kerjanya? Saya kira itu loop ke atas sampai string berubah tetapi saya tidak dapat menemukan di halaman esolang mengapa.
randomra
Ini adalah sedikit penyalahgunaan ketidakjelasan dalam spesifikasi bahasa, tapi saya sudah menjelaskannya di sini: codegolf.stackexchange.com/questions/52946/…
Jarmex
1
Saya masih belum mengerti mengapa tidak //membuat loop tak terbatas seperti yang nothingakan selalu cocok jadi kami selalu melompat kembali ke baris pertama.
randomra
Kamu tahu apa Saya sebenarnya tidak tahu kenapa. Anda benar sekali, memikirkannya sekarang tidak masuk akal, tetapi pasti mengkompilasi dan menjalankan penerjemah yang disediakan. Bahkan melihat Perl yang dikompilasi itu menghasilkan membingungkan saya, karena itu terlihat lebih jelas bahwa itu harus menjadi infinite loop: pastebin.com/9q7M0tpZ
Jarmex
2

Perl, 36 byte

35 byte kode + 1 byte baris perintah

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

Pemakaian:

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

Pyth, 39 38 byte

Solusi regex yang mengerikan:

P:eJcz\("([+-]?)(\d+)"X"\\1(_*\\2)"3hJ
orlp
sumber
Sepertinya saya tidak bisa menjalankannya dengan penerjemah online .
BrainSteel
@BrainSteel Berhasil dalam penerjemah offline, sepertinya ada masalah dengan heroku.
orlp
@ Atlp Ini bukan masalah dengan heroku. Impor dinamis dinonaktifkan dalam mode aman, untuk mengurangi kemungkinan peretasan, dan modul ulang melakukan impor dinamis. Jadi kembali tidak dapat digunakan dalam mode aman, termasuk online.
isaacg
1

Ruby, 94 byte

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

CJam, 50 byte

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

Cobalah online

CJam tidak memiliki dukungan regex, atau apa pun di luar pencarian dan pemisahan string yang sangat nyaman untuk ekspresi parsing. Jadi ada beberapa tenaga kerja yang terlibat di sini.

Penjelasan:

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
sumber
1

gawk - 60 58

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

Fiuh ... sudah lama tidak bekerja dengan regexp.

Cabbie407
sumber
1

Perl 5, 70 60 55 44 Bytes + 1 penalti

Solusi perl yang hanya menggunakan split dan 1 ekspresi reguler.
Juga menghitung input yang lebih panjang.

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

Uji

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

Versi yang mengambil parameter

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

Versi yang hanya menggunakan ekspresi reguler.

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

Yang ini bekerja melalui grup tangkap dalam tampilan positif dan pencocokan malas. Mungkin akan menggunakan tampilan positif di belakang jika Perl 5 mendukungnya, tetapi sayangnya. Butuh beberapa saat untuk mencari tahu bahwa ini agak mungkin dengan regex.

LukStorms
sumber
1
Hai Luk, Anda mungkin dapat menyimpan beberapa karakter menggunakan -popsi baris perintah (saya pikir ini adalah +1 char vs 9 untuk ,<>dan ;print) karena splitakan berfungsi $_secara default (yang akan menjadi apa pun yang ada di dalamnya <>) dan hasil cetak termasuk dalam loop juga ! Semoga itu bisa membantu!
Dom Hastings
1
Terima kasih! Itu membantu. Opsi -p sama sekali tidak terlintas di benak saya. Mungkin karena itu adalah sesuatu yang jarang digunakan di luar konteks golf. Menurut Anda mengapa ini +1 char? Tantangan ini tidak menyebutkan apa pun tentang penalti untuk menggunakan sakelar.
LukStorms
Saya tidak dapat menemukan pos sekarang, tetapi pos meta ini menyebutkan skor untuk bendera Perl.
Dom Hastings
1
Buruk saya, sepertinya saya datang dan memposting solusi yang sangat mirip dengan Anda, yang secara efektif hanya versi yang sedikit lebih golf dari Anda! Pada dasarnya Anda bahkan tidak perlu menangkap [+ -] karena Anda membiarkannya tetap di substitusi: codegolf.stackexchange.com/a/57117/26977
Jarmex
Itu keren. Karena Anda, Perl mengalahkan bahkan solusi Pyth / Cjam dalam tantangan ini. Saya seharusnya tidak memedulikan input yang tidak valid setelah perpecahan menghapus tanda kurung.
LukStorms
1

Retina , 50 51 43 byte

Saya pikir ini mungkin program Retina pertama saya. Jika tidak, ini adalah program Retina pertamaku yang kompleks ini (tidak terlalu rumit, sungguh.) Setiap baris masuk dalam file sendiri.

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

Saya tidak benar-benar menguji ini dengan Retina, saya mengujinya menggunakan tester regex-replace beberapa kali, tetapi seharusnya berhasil.

Deskripsi untuk contoh pertama:

Karena ada sejumlah file, Retina menggunakan mode ganti. Ganti pertama (dua file pertama) menghapus nomor yang akan didistribusikan dan menambahkan pasangan distribusi (23*12)ke akhir, memberi 23(+42)(23*12). +`pada awalnya memberitahu Retina untuk berulang kali mengganti sampai polanya tidak cocok, dan karena ini cocok lagi, polanya menggantikan ini dengan 23()(23*12)+(23*42). Ini tidak cocok lagi, jadi 2 file berikutnya digunakan untuk penggantian berikutnya. Kali ini, itu hanya menghapus 23(). Ini bekerja dengan baik: karena produk ditambahkan sampai akhir, saya tidak perlu melakukan sesuatu yang aneh jika nomor tidak memiliki tanda, karena satu-satunya yang bisa tanpa tanda adalah nomor pertama.

EDIT: $'in replacement mewakili sisa string setelah pertandingan, jadi saya bisa menghapus trailing (.*)s.

mbomb007
sumber
0

k, 98 byte

Tidak terlalu bermain golf.

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

Membagi pada non-digit, menghapus parens, menghapus string kosong, lalu memegang xkonstan sebagai string pertama, bergabung *dengan setiap string yang tersisa y, tanda kurung, dan pindahkan tanda ke awal jika ada; ratakan output menjadi string tunggal.

Aaron Davies
sumber