การกระจายตัวเลข


11

ในความท้าทายนี้คุณจะใช้ BE กระจายสินค้ามากกว่าผลบวกและความแตกต่างของตัวเลขตามที่อธิบายไว้ที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

ตัวอย่าง

  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)

สเปค

การป้อนข้อมูลจะเป็นสตริงของรูปแบบn(_), มีเพียงหนึ่งเดียวที่ไม่ได้ลงชื่อจำนวนเต็มบวกตามด้วยการแสดงออกวงเล็บn _การแสดงออกนี้_จะประกอบด้วยผลรวมและความแตกต่างของหนึ่งในคำศัพท์จำนวนเต็มบวกที่คั่นด้วย+และ-เครื่องหมาย เทอมแรกอาจมีการนำหน้าด้วย+สัญญาณ-เครื่องหมายหรือไม่มีเครื่องหมาย

ในการส่งออกจำนวนเริ่มต้นnควรจะกระจายเพื่อคูณแต่ละคำ แต่ละเทอมaควรจะถูกคูณด้วยnการสร้างการแสดงออกในวงเล็บ(n*a)และคำศัพท์ใหม่เหล่านี้ควรจะรวมกับ+และ-เครื่องหมายในลักษณะเดียวกับที่เป็นคำดั้งเดิม

อินพุตไม่ถูกต้อง

นี่เป็นตัวอย่างของอินพุตที่คุณไม่ต้องจัดการ

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

การชนะ

นี่คือดังนั้นรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


มันเกิดขึ้นกับฉันที่ regex เหมาะจริง ๆ สำหรับปัญหานี้ หากคุณไม่เห็นด้วยกับวิธีแก้ปัญหา reg-ex คุณสามารถแบนได้แม้ว่าคนอื่นอาจจะใช้งานมันแล้ว
xnor

ห้องสมุดอนุญาตหรือไม่
orlp

@orlp ในระดับหนึ่งซึ่งได้รับการกล่าวถึงในเมตา
Downgoat

กรณีที่น่าสนใจ:8(-40+18)
BrainSteel

คำตอบ:


2

Pip, 28 ไบต์

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

คำอธิบาย:

                              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 ส่วนใหญ่จะเป็นไปตามไวยากรณ์ของ Python regex แต่&รูปแบบการแทนที่ถูกยืมมาจาก sed

อ่านเพิ่มเติมเกี่ยวกับ Pip ได้ที่ที่เก็บ Github


9

JavaScript 65 ไบต์

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

สิ่งนี้จะรับอินพุต รับเครื่องหมาย + หรือ - ตามด้วยตัวเลขจากนั้นแทนที่ด้วยลำดับที่ถูกต้อง

คำอธิบาย

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

การใช้

ใช้งานได้กับ Firefox และ Safari Nightly อาจเป็น Edge หรือไม่ เพราะมันใช้คุณสมบัติ ES6 คุณสามารถเรียกใช้โดย:

var t = s => (q = s.split (/ [()] /)) [1]. แทนที่ (/ (\ 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+)เสีย นี้ล้มเหลวในการผลิต23(12+42) 1(23*2)+(23*42)
orlp

@orlp ฉันได้แก้ไขแล้ว

รหัสนี้จะใช้งานได้เฉพาะใน Firefox b / c ของฟังก์ชั่นลูกศร แต่ไม่เป็นไร
MayorMonty

@SpeedyNinja นอกจากนี้ยังทำงานใน Edge สำหรับ Chrome / Opera คุณต้องเปิดใช้งาน "คุณสมบัติ JavaScript แบบทดลอง"
rink.attendant.6

\D?สามารถใช้แทน[+-]?
edc65

6

Python 2.7 110 108 ไบต์

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

โปรแกรมรับอินพุตจาก stdin ค้นหาการจับคู่กับ - ([+-]?)(\d+)regex และสร้างสตริงเอาต์พุต
ทดสอบมัน -

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

เรติน่า 40 ไบต์

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

แต่ละบรรทัดควรไปที่ไฟล์ของตัวเอง แต่คุณสามารถเรียกใช้รหัสเป็นไฟล์เดียวที่มีการ-sตั้งค่าสถานะ เช่น:

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

สองบรรทัดแรกผลักดันตัวคูณถัดจากทุกหมายเลขในรูปแบบที่คาดไว้:

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

สองบรรทัดสุดท้ายลบส่วนต่อท้ายที่ไม่จำเป็นออก:

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

3

sed, 105 ไบต์

แค่อยากจะดูว่าสิ่งนี้สามารถทำได้กับ sed
อาจเป็นโรงเรียนเก่า แต่ก็ใช้ได้

$ 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 ไบต์

ใช้ REGXY ซึ่งเป็นภาษาที่ใช้ในการทดแทน regex

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

วิธีการที่ไม่//ทำงานหรือไม่ ฉันคิดว่ามันวนไปด้านบนจนกระทั่งสตริงเปลี่ยน แต่ฉันไม่พบในหน้า esolang ทำไม
randomra

มันเป็นการละเมิดความคลุมเครือเล็กน้อยของความคลุมเครือในสเป็คภาษา แต่ฉันได้อธิบายไว้ที่นี่: codegolf.stackexchange.com/questions/52946/ …
Jarmex

1
ฉันยังไม่เข้าใจว่าทำไมไม่//สร้างวงวนไม่สิ้นสุดเหมือนที่nothingเคยตรงกันดังนั้นเราจึงย้อนกลับไปที่บรรทัดแรกเสมอ
randomra

คุณรู้อะไรไหม จริงๆแล้วฉันไม่รู้ว่าทำไม คุณคิดถูกแล้วตอนนี้มันไม่มีเหตุผล แต่มันรวบรวมและทำงานในล่ามที่ให้มา แม้แต่การดู Perl ที่คอมไพล์มันสร้างความสับสนให้ฉันเพราะมันดูชัดเจนยิ่งขึ้นว่ามันควรจะเป็นวงไม่สิ้นสุด: pastebin.com/9q7M0tpZ
Jarmex

2

Perl, 36 ไบต์

รหัส 35 ไบต์ + บรรทัดคำสั่ง 1 ไบต์

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

การใช้งาน:

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

1

Pyth, 39 38 ไบต์

วิธีการแก้ปัญหา regex ที่น่ากลัว:

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

ฉันไม่สามารถดูเหมือนจะได้รับนี้ในการเรียกใช้ในการล่ามออนไลน์
BrainSteel

@BrainSteel มันทำงานในล่ามออฟไลน์ดูเหมือนว่าจะมีปัญหากับ heroku
orlp

@orlp ไม่ใช่ปัญหากับ heroku การนำเข้าแบบไดนามิกถูกปิดใช้งานในเซฟโหมดเพื่อลดโอกาสในการแฮ็กและโมดูลใหม่จะนำเข้าแบบไดนามิก ดังนั้นจึงไม่สามารถใช้ในเซฟโหมดรวมถึงออนไลน์ได้
isaacg


1

CJam, 50 ไบต์

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

ลองออนไลน์

CJam ไม่ได้รับการสนับสนุน regex หรือสิ่งอื่นนอกเหนือจากการค้นหาและแยกสตริงที่สะดวกในการแยกวิเคราะห์นิพจน์ มีแรงงานบางส่วนที่เกี่ยวข้องที่นี่

คำอธิบาย:

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

วุว ... ไม่ได้ทำงานกับ regexp มาสักพักแล้ว


1

Perl 5, 70 60 55 44 Bytes + 1 การลงโทษ

โซลูชัน perl ที่ใช้การแยกและการแสดงออกปกติ 1 ครั้งเท่านั้น
ยังคำนวณอินพุตอีกต่อไป

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

ทดสอบ

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

เวอร์ชันที่รับพารามิเตอร์

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

เวอร์ชันที่ใช้นิพจน์ทั่วไปเท่านั้น

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

อันนี้ทำงานผ่านกลุ่มการจับภาพภายใน lookahead บวกและจับคู่สันหลังยาว อาจเป็นไปได้ที่จะใช้ lookbehind เชิงบวกถ้า Perl 5 สนับสนุน แต่อนิจจา เอาฉันสักครู่เพื่อคิดออกว่าสิ่งนี้เป็นไปได้ด้วย regex


1
เฮ้ Luk, คุณอาจจะสามารถที่จะบันทึกตัวอักษรโดยใช้-pตัวเลือกบรรทัดคำสั่ง (ผมคิดว่านี่เป็น 1 ถ่าน VS 9 ,<>และ;print) ในขณะที่splitการทำงานจะอยู่บน$_โดยค่าเริ่มต้น (ซึ่งจะเป็นสิ่งที่อยู่ใน<>) และพิมพ์รวมอยู่ในวงด้วย ! หวังว่าจะช่วย!
Dom Hastings

1
ขอบคุณ! มันช่วยได้ ตัวเลือก -p ก็ไม่ได้ใจของฉัน อาจเป็นเพราะมันเป็นสิ่งที่ไม่ค่อยได้ใช้นอกบริบทการเล่นกอล์ฟ ทำไมคุณถึงคิดว่ามันเป็น +1 ถ่าน? ความท้าทายนี้ไม่ได้พูดถึงสิ่งใดเกี่ยวกับบทลงโทษสำหรับการใช้สวิตช์
LukStorms

ฉันไม่พบโพสต์ในขณะนี้ แต่เมตาโพสต์นี้กล่าวถึงการให้คะแนนธงของ Perl
Dom Hastings

1
ไม่ดีของฉันดูเหมือนว่าฉันมาและโพสต์โซลูชั่นที่คล้ายกันมากสำหรับคุณ โดยทั่วไปคุณไม่จำเป็นต้องจับ [+ -] เพราะคุณปล่อยให้มันอยู่ในการทดแทนอยู่ดี: codegolf.stackexchange.com/a/57117/26977
Jarmex

มันเท่ห์มาก เพราะคุณ Perl ก็ชนะแม้กระทั่งโซลูชั่น Pyth / Cjam ในความท้าทายนี้ ฉันไม่ควรสนใจเกี่ยวกับอินพุตที่ไม่ถูกต้องหลังจากแยกตัวนั้นออกแล้ว
LukStorms

1

Retina , 50 51 43 ไบต์

ฉันคิดว่านี่อาจเป็นโปรแกรม Retina ครั้งแรกของฉัน ถ้าไม่ใช่มันเป็นโปรแกรม Retina ครั้งแรกของฉันที่ซับซ้อนนี้ (ไม่ใช่แบบนั้นจริง ๆ ) แต่ละบรรทัดจะอยู่ในไฟล์ของตัวเอง

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

ฉันไม่ได้ทดสอบกับ Retina จริง ๆ ฉันทดสอบโดยใช้ตัวทดสอบ regex-replace หลายครั้ง แต่มันก็ใช้ได้

คำอธิบายสำหรับตัวอย่างแรก:

เนื่องจากมีไฟล์เป็นจำนวนเท่ากัน Retina จึงใช้โหมดแทนที่ ครั้งแรกที่เข้ามาแทนที่ (สองไฟล์แรก) เอาจำนวนที่จะกระจายและเพิ่มว่าทั้งคู่กระจายไปยังจุดสิ้นสุดให้(23*12) ที่เริ่มต้นบอก Retina ซ้ำไปซ้ำมาแทนที่จนกระทั่งรูปแบบที่ไม่ตรงและตั้งแต่นี้จะถูกจับคู่อีกครั้งรูปแบบการแทนที่นี้กับ สิ่งนี้ไม่ตรงกันอีกต่อไปดังนั้นจึงใช้ 2 ไฟล์ถัดไปสำหรับการแทนที่ครั้งต่อไป คราวนี้มันแค่เอา ใช้งานได้ดี: เนื่องจากผลิตภัณฑ์ถูกผนวกเข้ากับท้ายที่สุดฉันไม่ต้องทำอะไรแปลก ๆ ถ้าตัวเลขไม่มีสัญญาณเพราะมีเพียงผลิตภัณฑ์เดียวที่ไม่มีสัญลักษณ์คือหมายเลขแรก23(+42)(23*12)+`23()(23*12)+(23*42)23()

แก้ไข: $'ในการแทนที่หมายถึงส่วนที่เหลือของสตริงหลังการแข่งขันเพื่อให้ฉันสามารถลบ(.*)s ต่อท้าย


0

k, 98 ไบต์

ไม่ค่อยเล่นกอล์ฟมาก

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

แยกที่ไม่ใช่ตัวเลข, ลบ parens, ลบสตริงว่าง, จากนั้นเก็บxค่าคงที่เป็นสตริงแรก, รวม*กับแต่ละสตริงที่เหลือy, วงเล็บ, และย้ายเครื่องหมายไปที่จุดเริ่มต้นถ้ามี; แผ่ออกเป็นสตริงเดียว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.