Sayıları Dağıtma


11

Bu zorlukta, bir ürünü burada açıklandığı gibi toplamlar ve sayı farkları üzerinden dağıtmak için kullanacaksınız .

resim açıklamasını buraya girin

Örnekler

  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)

Şartname

Giriş, formun bir dizesi olacak ve n(_)tek bir pozitif imzasız tam sayı ve nardından parantez içine alınmış bir ifade olacaktır _. Bu ifade _, toplamlar +ve -işaretlerle ayrılmış daha pozitif tamsayı terimlerinden birinin toplamından ve farkından oluşacaktır . İlk terimden önce bir +işaret, bir -işaret veya hiçbir işaret olmayabilir .

Çıktıda, nterimlerin her birini çarpmak için ilk sayı dağıtılmalıdır. Parantez içindeki ifadeyi üretmek için her terim asol ile çarpılmalıdır ve bu yeni terimler orijinal terimlerle aynı şekilde birleştirilmeli ve imzalanmalıdır.n(n*a)+-

Geçersiz Girdiler

Bunlar işlemek zorunda olmadığınız girdilere örnektir.

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

Kazanan

Bu , bayt en kısa kod kazanır.


Regex'in bu sorun için gerçekten uygun olduğu bana geliyor. Reg-ex çözümlerinde sorun yoksa, insanlar zaten üzerinde çalışıyor olsa da yasaklayabilirsiniz.
xnor

Kütüphanelere izin veriliyor mu?
orlp

@orlp Belli bir dereceye kadar meta üzerinde tartışıldı .
Downgoat

İlginç vaka:8(-40+18)
BrainSteel

Yanıtlar:


2

Pip, 28 bayt

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

Açıklama:

                              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)

Pip'in Pattern nesneleri çoğunlukla Python regex sözdizimini takip eder, ancak &yedek desen sed'den ödünç alınır.

Pip at the Github repository hakkında devamını oku


9

JavaScript 65 bayt

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

Bu girdiyi alacaktır. + Veya -, ardından rakamları alın, ardından doğru sırayla değiştirin.

açıklama

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

kullanım

Bu sadece Firefox ve Safari Nightly belki Edge çalışır? çünkü ES6 özelliklerini kullanıyor. Bunu şu şekilde çalıştırabilirsiniz:

var t = s => (q = s.split (/ [()] /)) [1]. değiştirin (/ (\ 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+)kırılmış, bozulmuş. Bu başarısız oluyor 23(12+42), üretiyor 1(23*2)+(23*42).
orlp

@orlp Bunu düzelttim

Bu kod yalnızca ok işlevinin Firefox b / c
öğesinde

@SpeedyNinja Edge'de de çalışır. Chrome / Opera için "deneysel JavaScript özelliklerini" etkinleştirmeniz gerekir.
rink.attendant.6

\D?yerine kullanılabilir[+-]?
edc65

6

Python 2.7, 110 108 Bayt

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 stdin'den girdi alır, regex'e karşı eşleşmeleri arar ([+-]?)(\d+)ve çıktı dizesini oluşturur.
Test ediliyor -

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

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

Her satır kendi dosyasına gitmelidir ancak kodu -sbayraklı tek bir dosya olarak çalıştırabilirsiniz . Örneğin:

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

İlk iki satır çarpanı beklenen biçimde her sayının yanına iter:

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

Son iki satır, gereksiz arka kısmı kaldırır:

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

3

sed, 105 bayt

Sadece sed ile yapılıp yapılamayacağını görmek istedim.
Belki biraz eski okul, ama işe yarıyor.

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

Normal ifade yerine koyma tabanlı bir dil olan REGXY'yi kullanır.

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

Nasıl //çalışır? Dize değişene kadar üst döngüler varsayalım ama neden esolang sayfasında bulamıyorum.
randomra

Bu, dil spesifikasyonundaki belirsizliğin arsız bir tacizidir
Jarmex

1
Hala neden her zaman eşleşeceği //gibi sonsuz bir döngü oluşturmuyor anlamıyorum, nothingbu yüzden her zaman ilk satıra geri atlıyoruz.
randomra

Biliyor musun? Aslında neden olduğu hakkında hiçbir fikrim yok. Kesinlikle haklısın, şimdi düşünmek mantıklı değil, ama kesinlikle sağlanan yorumlayıcıda derleniyor ve çalışıyor. Derlenmiş Perl'e baktığımda bile beni karıştırıyor, çünkü sonsuz bir döngü olması daha da net görünüyor: pastebin.com/9q7M0tpZ
Jarmex

2

Perl, 36 bayt

35 bayt kodu + 1 bayt komut satırı

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

Kullanımı:

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

1

Pyth, 39 38 bayt

Korkunç bir regex çözümü:

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


@BrainSteel Çevrimdışı yorumlayıcıda çalışır, heroku ile ilgili bir sorun gibi görünüyor.
orlp

@orlp Heroku ile ilgili bir sorun değil. Dinamik alma, saldırı olasılığını azaltmak için güvenli modda devre dışı bırakılır ve re modülü dinamik bir içe aktarma yapar. Dolayısıyla, çevrimiçi dahil güvenli modda yeniden kullanılamaz.
isaacg

1

Ruby, 94 bayt

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

1

CJam, 50 bayt

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

Çevrimiçi deneyin

CJam'in normal ifade desteği veya ifadeleri ayrıştırmak için çok uygun olan string arama ve bölmenin ötesinde herhangi bir şeyi yoktur. Yani burada işgücü var.

Açıklama:

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

Vay be ... uzun süredir regexp ile çalışmadı.


1

Perl 5, 70 60 55 44 Bayt + 1 penaltı

Yalnızca split ve 1 normal ifade kullanan bir perl çözümü.
Ayrıca daha uzun girişleri de hesaplar.

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

Ölçek

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

Parametre alan bir sürüm

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

Yalnızca normal ifadeler kullanan bir sürüm.

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

Bu, pozitif bir ileri ve tembel eşleme içinde bir yakalama grubu aracılığıyla çalışır. Muhtemelen Perl 5 bunu destekleseydi olumlu bir bakış açısı kullanırdı, ama ne yazık ki. Bu tür bir şeyin regex ile mümkün olduğunu anlamaya zaman ayırdım.


1
Hey Luk, -pKomut satırı seçeneğini kullanarak bazı karakterleri kaydedebilirsiniz (bunun +1 char vs 9 olduğunu düşünüyorum ) ,<>ve varsayılan ;printolarak splitçalışacağı gibi $_(içinde ne olursa olsun <>) ve baskı da döngüye dahil edilir ! Umarım yardımcı olur!
Dom Hastings

1
Teşekkürler! Yardımcı oldu. -P seçeneği aklımdan geçmedi. Muhtemelen bir golf bağlamının dışında nadiren kullanılan bir şey olduğu için. Neden +1 karakter olduğunu düşünüyorsun? Bu meydan okuma, anahtarları kullanma cezalarından bahsetmiyor.
LukStorms

Gönderiyi şimdi bulamıyorum, ancak bu meta gönderi Perl'in bayrakları için puanlamadan bahsediyor.
Dom Hastings

1
Kötü, görünüşe göre seninkine çok benzer bir çözüm yayınladım, ki bu seninkinden biraz daha golfçü bir versiyon! Temel olarak [+ -] yakalamanıza bile gerek yok, çünkü onları yine de ikame halinde olduğu gibi bırakıyorsunuz: codegolf.stackexchange.com/a/57117/26977
Jarmex

Çok havalı. Senin sayende, Perl bu meydan okumada Pyth / Cjam çözümlerini bile yener. Bu ayrık parantez kaldırıldıktan sonra geçersiz girişleri yine de önemsememeliydim.
LukStorms

1

Retina , 50 51 43 bayt

Bunu düşünmek olabilir benim ilk Retina program. Değilse, bu karmaşık olan ilk Retina programım (bu karmaşık değil, gerçekten.) Her satır kendi dosyasına gider.

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

Aslında bunu Retina ile test etmedim, birçok kez bir regex-yedek test cihazı kullanarak test ettim, ama işe yaramalı.

İlk örnek için açıklama:

Çift sayıda dosya olduğundan, Retina değiştirme modunu kullanır. İlk değiştirme (ilk iki dosya) dağıtılacak sayıyı kaldırır ve bu dağıtım çiftini (23*12)sonuna ekleyerek verir 23(+42)(23*12). +`başlangıçta Retina'ya kalıp eşleşmeyene kadar tekrar tekrar değişmesini söyler ve bu yeniden eşleştiğinden kalıp bunun yerine geçer 23()(23*12)+(23*42). Bu artık eşleşmiyor, bu nedenle sonraki 2 dosya bir sonraki değiştirme için kullanılıyor. Bu kez, sadece kaldırır 23(). Bu güzel çalışıyor: ürünler sonuna eklendiğinden, bir sayının işareti yoksa garip bir şey yapmak zorunda değilim, çünkü bir işaret olmadan olabilecek tek şey ilk sayıdır.

EDIT: $'yerine maçtan sonra dizenin geri kalanını temsil eder, böylece sonları (.*)s kaldırabilirsiniz .


0

k, 98 bayt

Çok golf değil.

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

Rakamsız olarak bölün, parensleri kaldırın, boş dizeleri kaldırın, ardından xilk dize olarak sabit tutun , *kalan her dize ile birleştirin y, parantez içine alın ve varsa işareti başlangıca taşıyın; çıktıyı tek bir dizeye yasla.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.