ตัวเลขผสมกับเศษส่วนที่ไม่เหมาะสม


19

ตัวเลขผสมกับเศษส่วนที่ไม่เหมาะสม

ในการท้าทายนี้คุณจะแปลงตัวเลขผสมให้เป็นเศษส่วนที่ไม่เหมาะสม

เนื่องจากเศษส่วนที่ไม่เหมาะสมใช้จำนวนน้อยรหัสของคุณจะต้องสั้นที่สุด


ตัวอย่าง

4 1/2
9/2

12 2/4
50/4

0 0/2
0/2

11 23/44
507/44

สเปค

คุณอาจคิดว่าตัวส่วนของอินพุตจะไม่เป็น 0 อินพุตจะอยู่ในรูปแบบx y/zที่ x, y, z เป็นจำนวนเต็มแบบไม่ติดลบเสมอ คุณไม่จำเป็นต้องทำให้เอาต์พุตง่ายขึ้น


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


5
คุณควรเพิ่มแท็ก "การแยกวิเคราะห์" ฉันแน่ใจว่าคำตอบส่วนใหญ่จะใช้เวลามากขึ้นในการแยกวิเคราะห์อินพุตและจัดรูปแบบผลลัพธ์มากกว่าการคำนวณทางคณิตศาสตร์
nimi

3
เอาต์พุตสามารถเป็นชนิดจำนวนตรรกยะหรือต้องเป็นสตริง?
Martin Ender

2
@AlexA .: ... แต่ความท้าทายส่วนใหญ่ ตามคำอธิบายมันควรใช้แท็กในกรณีเช่นนี้
nimi

7
สามารถx, yและzเป็นเชิงลบได้อย่างไร
เดนนิส

2
ขึ้นอยู่กับความท้าทายที่ฉันสมมติว่ามันเป็น แต่รูปแบบอินพุต "xy / z" จำเป็นหรือพื้นที่สามารถเป็นบรรทัดใหม่และ / หรือx,y,zอินพุตแยกกันได้หรือไม่ คำตอบส่วนใหญ่สมมติว่ารูปแบบการป้อนข้อมูลนั้นจำเป็นจริง ๆx y/zแต่บางคำตอบไม่ได้ดังนั้นคำถามนี้จึงมีคำตอบที่ชัดเจน
Kevin Cruijssen

คำตอบ:


1

Japt, 10 ไบต์

Woohoo กำลังเต้น CJam!

U*W+V+'/+W

ลองออนไลน์!

มันทำงานอย่างไร

       // Implicit: [U,V,W] = eval(input). This automatically discards the slash.
U*W+V  // Calculate the new numerator: (whole part * denominator) + numerator.
+'/+W  // Add the slash and the denominator.
       // Implicit: output last expression

ฉันใช้เวลาพอสมควรเมื่อวานนี้พยายามหาวิธีที่ฉันได้รับ 15 ตัวแทนออกจากคำตอบจนกระทั่งฉันตระหนัก: เครื่องหมายถูกสีเขียวครั้งแรกของฉัน! \ o /
ETHproductions


7

CJam, 16 15 14 ไบต์

l'/']er~:Xb'/X

หรือ

l'/']er~_@b'/@

ทดสอบที่นี่

คำอธิบาย

l      e# Read input.
'/']er e# Replace the "/" with a "]".
~      e# Evaluate the string as code. If the input was "i n/d", this pushes [i n] d.
:X     e# Store the denominator in X.
b      e# Treat [i n] as base-d digits. This effectively computes i*d + n.
'/     e# Push a slash.
X      e# Push the denominator.

รุ่นอื่นหลีกเลี่ยงการใช้ตัวแปรโดยใช้การเลื่อนสแต็กอีกเล็กน้อย


ฉันต้องเริ่มใช้การแปลงฐานใน CJam มากขึ้นจริงๆ
แยกผลไม้

รุ่นอื่น: '//~\S/1$b'/@นี่คือ 13 ไบต์ แก้ไข : lโอ้ฉันลืมการป้อนข้อมูล
Chromium

4

Mathematica, 58 ไบต์

ToExpression@StringReplace[#," "->"+"]~ToString~InputForm&

ส่งคืนผลลัพธ์ที่ง่าย หากการส่งออกจำนวนตรรกยะแทนสตริงเป็นเรื่องปกติเราสามารถบันทึก 19 ไบต์:

ToExpression@StringReplace[#," "->"+"]&

4

PowerShell, 47 44 42 ไบต์

ข้ามไป 44 ยังคงเป็นปกติ 44; (

$l,$n,$d=$args-split'\D';"$(+$l*$d+$n)/$d"

แข็งแรงเล่นกอล์ฟไบต์คู่โดยใช้ -splitregex Golfed อีกสองสามขอบคุณ TessellatingHecklerโดยการแลกเปลี่ยน regex

การ$args-split'\D'โต้แย้งของเรานำเข้าและแยกตัวอักษรที่ไม่ใช่ตัวเลข ที่นี่มันทำการแยกสองแบบอันหนึ่งบนช่องว่างอีกช่องหนึ่งบน/อักขระ ผลลัพธ์จะถูกเก็บไว้ในตัวแปรสามตัวโดยใช้การกำหนดพร้อมกัน จากนั้นเราจะกำหนดเอาท์พุทสตริงเป็น ( $lหมายเลข eft $dคูณตัว$nดำเนินการบวกตัวดำเนินการ) ดำเนินการเป็นบล็อคโค้ด/สแลชจากนั้นจึงกำหนด$dอีกครั้ง


สวัสดีฉันคิดว่าคุณสามารถทำได้-split ' |/'เพื่อบันทึกอักขระหนึ่งตัวด้วย "จับคู่อย่างนี้ | หรือ" regex หรือใช้-split '\D'เพื่อแยกสิ่งที่ไม่ใช่ตัวเลขและ s (h) มีอักขระสองตัว หาก @Downgoat ยินดีที่จะยืดหยุ่นเล็กน้อยในรูปแบบเอาต์พุต'{0}*{2}+{1};{2}'-f($args-split'\D')|iexคือ 40 ไบต์และมีเอาต์พุตที่เย็นกว่ามากเนื่องจากตัวเลขนั้นอยู่เหนือตัวเลขอื่น!
TessellatingHeckler

1
@TessellatingHeckler ขอบคุณสำหรับความช่วยเหลือ regex ฉันขอให้ป้อนข้อมูล Downgoat แต่$l,$n,$d=$args-split'\D';+$l*$d+$n;$dสั้นกว่าที่อายุ 37 และใช้รูปแบบเดียวกันตามเหตุผล
AdmBorkBork

โอ้ใช่แค่คณิตศาสตร์! (นั่นคงเพียงพอที่จะเอาชนะคำตอบ Perl ได้เช่นกัน)
TessellatingHeckler

3

Java พร้อมเสาเลเซอร์สิบฟุต 1.03, 79 + 25 (อิมพอร์ต) = 104 ไบต์

ต้องใช้ import sj224.tflp.math.*;

String m(String[]a){return ""+new BigRational(a[0]).add(new BigRational(a[1]));}

สิ่งนี้จะใช้งานได้กับ 1.04 เช่นกัน แต่จนถึงตอนนี้ฉันเพิ่งทดสอบด้วย 1.03 เท่านั้นเพราะฉันได้ตั้งค่าโปรเจ็กต์ java ด้วย 1.03 ในพา ธ บิลด์แล้ว


3

JavaScript (ES6), 44 41 ไบต์

m=>([x,y,z]=m.match(/\d+/g),+y+x*z+"/"+z)

บันทึก 3 ไบต์ด้วย@ETHproductions !

คำอธิบาย

ง่ายมาก.

m=>
  ([x,y,z]=m.match(/\d+/g), // x, y and z = numbers from input
    +y+x*z                  // numerator
    +"/"+z                  // denominator
  )

ทดสอบ

การทดสอบไม่มีการมอบหมายการทำลายโครงสร้างให้ทำงานในเบราว์เซอร์ส่วนใหญ่


ดี! คุณสามารถใช้[p,q,r]=ในสถานที่ของp=แล้วแทนที่p[0], p[1]และp[2]ด้วยp, qและrตามลำดับ หลังจากการเปลี่ยนแปลงนี้ฉันจะได้รับ 41:m=>([p,q,r]=m.match(/\d+/g),+q+p*r+"/"+r)
ETHproductions

@ ETHproductions ขอบคุณสำหรับเคล็ดลับ! จริง ๆ แล้วฉันได้พิจารณาใช้การมอบหมายการทำลายล้าง แต่พวกเขาไม่ทำงานใน Chrome และฉันไม่มี Firefox ในมือเพื่อทดสอบ : P
user81655

ข้ามครั้งแรกของฉัน 44! : D
user81655

คุณสามารถใช้m.split(/\W/g)แทนบันทึกไบต์
Kritixi Lithos

2

Julia 58 58ไบต์

s->eval(parse((r=replace)(r(s," ","+"),"/","//")))

นี่คือฟังก์ชันที่ไม่ระบุชื่อที่ยอมรับสตริงและส่งคืนRationalวัตถุชนิด หากต้องการเรียกใช้ให้ตั้งชื่อเช่นf=s->...เรียกว่าให้มันชื่อเช่น

เราสามารถใช้ประโยชน์จากข้อเท็จจริงที่ว่าข้อมูลนั้นสามารถถูกจัดการได้เล็กน้อยเพื่อให้เป็นนิพจน์ที่ประเมินว่ามีเหตุผล โดยเฉพาะอย่างยิ่งจำนวนเต็มบวกเหตุผลคือเหตุผลและปันส่วนจะแสดงด้วยเครื่องหมายทับสองครั้ง ดังนั้นถ้าเราเปิด4 1/2เข้าไปในผลการประเมินจะได้รับ4+1//29//2

Ungolfed:

function f(s::AbstractString)
    # Replace the space in the input with a plus
    r1 = replace(s, " ", "+")

    # Replace the / with //
    r2 = replace(r1, "/", "//")

    # Parse the resulting expression as a rational
    return eval(parse(r2))
end

2

Smalltalk - 76 ตัวอักษร

อินพุตตรงกับตัวคั่นอาร์เรย์และการแทนเศษส่วนโดยธรรมชาติของ Smalltalk ถ้ามันไม่ได้ verbose มันอาจเป็นคู่แข่งที่ร้ายแรง!

Compiler evaluate:'|p|p:=0.#(',FileStream stdin nextLine,')do:[:q|p:=p+q].p'

การทำให้เข้าใจง่ายแย่เกินไปไม่ใช่ข้อกำหนด, Smalltalk ทำโดยอัตโนมัติ!


2

Bash + coreutils, 28

dc<<<${@/\// }sarla*+n47Plap

$@ขยายไปยังพารามิเตอร์บรรทัดคำสั่งทั้งหมดดังนั้นจึง${@/\// }ขยายไปยังพารามิเตอร์บรรทัดคำสั่งทั้งหมดด้วยการ/แทนที่ด้วยซึ่งวางอยู่บนdcสแต็กของ ส่วนที่เหลือเป็นการจัดการกองซ้อนและเลขคณิตอย่างง่าย


2

Haskell , 74 67 63 ไบต์

r=read
f x|(a,(c,s:d):_)<-lex<$>lex x!!0=show(r a*r d+r c)++s:d

ลองออนไลน์!

คำอธิบาย

ในฐานะH.PWizคิดออกเราสามารถใช้ lexer ของ Haskell ที่นี่เพื่อแยกสตริงออกเป็นส่วนต่างๆ (ก่อนหน้านี้ผมใช้span(>'/')) และ Laikoni ชี้ให้เห็นว่า<$>การทำงานเช่นเดียวmapSndจากData.Tupleจาก

lexยามรูปแบบการแบ่งรหัสของเราในสามตัวเลขที่เราต้องการใช้ lexเรียกใช้ lexer ของ haskell เพื่อแยกโทเค็นแรก มันจะส่งกลับรายการที่มีองค์ประกอบที่เป็นวิธีที่เป็นไปได้ในการแยกสตริง องค์ประกอบเหล่านี้เป็นสิ่งอันดับที่องค์ประกอบแรกเป็นโทเค็นแรกและส่วนที่เหลือของสตริงเป็นองค์ประกอบที่สอง ตอนนี้เนื่องจากรูปแบบอินพุตเป็นปกติมากเราจะมีการแยกวิเคราะห์เพียงหนึ่งครั้งเท่านั้นดังนั้นเราจึงสามารถใช้รูปแบบแรกได้เสมอ สิ่งแรกที่เราทำคือเรียกใช้lexอินพุต

lex x

จากนั้นเราก็แกะมันออกจากรายการซึ่งให้ 2-tuple

lex x!!0

โทเค็นแรกจะเป็นส่วนทั้งหมดของเศษส่วนผสมที่ออกจากส่วนที่จัดทำขึ้นโดยเว้นวรรคเพื่อแยกวิเคราะห์ จากนั้นเนื่องจากสิ่งอันดับFunctorsเราสามารถใช้(<$>)นามแฝงสำหรับfmapการสมัครlexไปกับองค์ประกอบที่สองของสิ่งอันดับ

lex<$>lex x!!0

นี่กินผ่านอวกาศและแยกโทเค็นถัดไปเป็นตัวเศษของเศษส่วนของเรา <-ตอนนี้เราผูกนี้ให้ตรงกับรูปแบบการใช้ รูปแบบของเราคือ

(a,(c,s:d):_)

aหยิบเศษส่วนทั้งหมดเป็นโทเค็นแรกของเรา :_unwraps lexรายการที่เกิดจากการที่สองของเรา cจับโทเค็นที่สองที่เราอ่านอยู่นั่นคือตัวเศษของเศษส่วน ทุกสิ่งที่ยังคงมีอยู่จะถูกs:dแยกออกเป็นอักขระตัวแรกโดยรับประกันว่ารูปแบบจะเป็น/และส่วนที่เหลือซึ่งจะเป็นตัวส่วน

ตอนนี้เราได้แยกวิเคราะห์อินพุตที่เราทำการคำนวณจริง:

show(r a*r d+r c)++s:d

ที่ไหน rเป็นฟังก์ชั่นการอ่านที่เราผูกไว้ก่อนหน้านี้

มันเป็นสิ่งสำคัญที่จะต้องทราบว่าlexจะส่งคืนรายการว่างเปล่าถ้ามันล้มเหลวและไม่ว่างเปล่าถ้ามันประสบความสำเร็จ ทำไมนี่ไม่ใช่Maybeฉันไม่รู้



@ H.PWiz นั่นคือการใช้งานที่ดีของ lex
ข้าวสาลีตัวช่วยสร้าง


2
คุณน่าจะประหยัดอีก 2 คนโดยจับคู่กับ/
H.PWiz


1

Javascript ES6, 62 ไบต์

p=prompt;b=p(a=+p()).split`/`;alert((+b[1]*a+ +b[0])+"/"+b[1])

1
ค่อนข้างดี! เคล็ดลับ: คุณสามารถใช้[b,c]=ในสถานที่ของb=แล้วใช้bในสถานที่ของb[0]และในสถานที่ของc b[1]นอกจากนี้คุณสามารถจัดเรียงสมการใหม่ได้ดังนั้นคุณไม่จำเป็นต้องใส่วงเล็บเลย: p=prompt;[b,c]=p(a=+p()).split/;alert(+b+c*a+"/"+c)
ETHproductions

1

Perl, 82 61 38 ไบต์

#!perl -paF/\D/
$_=$F[0]*$F[2]+$F[1]."/$F[2]"

นี่อาจเป็นเรื่องของกอล์ฟมากกว่า

การเปลี่ยนแปลง

  • บันทึก 16 ไบต์โดยใช้ regex splitและ 5 โดยใช้<>แทน<STDIN>.
  • บันทึกอีก 16 ไบต์ด้วย Dennis

ด้วย shebang #!perl -paF/\D/(9 bytes) $_=$F[0]*$F[2]+$F[1]."/$F[2]"คุณสามารถใช้
เดนนิส

@Dennis ฉันได้เพิ่มสิ่งต่อไปนี้แล้วขอบคุณ!
ASCIIThenANSI

#!perlส่วนหนึ่งของ shebang และเลื่อนบรรทัดไม่นับ นี่เป็นเพียง 38 ไบต์
เดนนิส

@Dennis Oh, OK. I'll correct it now. (On the bright side I think this is the second-shortest non-esoteric answer)
ASCIIThenANSI

1

Mathematica, 51 bytes

Interpreter["ComputedNumber"]@#~ToString~InputForm&

Interestingly, Mathematica supports this with a built-in. If outputting a number is allowed, than we only need 28 bytes:

Interpreter@"ComputedNumber"

1

Java, 159 148 142 120 110 bytes

String m(String[]a){Long b=new Long(a[0]),d=new Long((a=a[1].split("/"))[1]);return b*d+new Long(a[0])+"/"+d;}

Saved a bunch of bytes thanks to FlagAsSpam.


@FlagAsSpam Done.
SuperJedi224

@FlagAsSpam But then the variables will be left undeclared!
SuperJedi224

Disregard all of what I just said - a short way doing what you're doing is Long b=new Long(a[0]),c=new Long((a=a[1].split("/"))[0]),d=new Long(a[1]);
Addison Crump


1

05AB1E, 17 15 bytes

#`'/¡R`Š©*+®'/ý

-2 bytes thanks to @MagicOctopusUrn.

Try it online or verify all test cases.

Explanation:

#`         # Split input by spaces and push all items to the stack
           #  i.e. "4 1/2" → "4" and "1/2"
  '/¡      # Push the second item by "/"
           #  i.e. "1/2" → [1,2]
     R`    # Revert the list, and also push all items to the stack
           #  i.e. [1,2] → [2,1] → 2 and 1
Š          # Triple-swap the stack
           #  [4,2,1] → [1,4,2]
 ©         # Store the 2 in the register
  *        # Multiple the top two items
           #  4 and 2 → 8
   +       # Add the top two items
           #  1 and 8 → 9
®          # Push the 2 from the register to the stack again
 '/ý       # Join the two items by "/"
           #  9 and 2 → "9/2"

With flexible input- and output-format, taking the integers in the order x,z,y and outputting the nominator and denominator on separated lines it would be 4 bytes (which is why I added the -tag to the challenge..):

*+²»

Try it online or verify all test cases.

Explanation:

*        # Multiply the first two inputs (x and z)
         #  i.e. 4 and 2 → 8
 +       # Add the third input (y)
         #  i.e. 8 and 1 → 9
  ²      # Take the second input again (z)
   »     # Join the stack by newlines and implicitly print it

@MagicOctopusUrn Thanks, but the input-format is different than in the challenge description. Apparently the format (as single string) 4 1/2 is mandatory for this particular challenge. Otherwise I would have used my 4-byte version (or if output was mandatory, but input flexible I would use this 6-byter: *+'/²J)
Kevin Cruijssen


@MagicOctopusUrn Oh, didn't even knew about "Push all the items of a into the stack".. o.Ô Exactly what I needed for this challenge! And smart with the join by "/". Thanks! :)
Kevin Cruijssen

I hate using the "Push all items of a into the stack" command because it's "`" and it can't be tamed by inline code-tags.
Magic Octopus Urn

@MagicOctopusUrn yeah, it's also a bit annoying in comments (which is why I quoted "Push all the items of a into the stack" instead of using '`'..
Kevin Cruijssen


1

Stax, 1 byte

+

Run and debug it (although there's not much to debug)

The challenge specification says "You do not need to simplify the output." Assuming it's allowed to simplify, then there's a built-in instruction in stax to do this. The input is implicitly interpreted as an integer and a rational number. The + instruction widens both to rationals, adds, and simplifies. The result is implicitly printed.


1

Perl 5 with -la -Mfeature=say, 32 bytes 25 bytes

m|/|;say$_*$'+$F[1],"/$'"

Try it online!

(-7 bytes thanks to Dom Hastings)

$_ is the whole input x y/z, which evaluates the value of x in numeric contexts (like the * here). $' is the regex post-match string, which here contains whatever comes after / - so, z. To get the y value, we use the -a flag which splits the input on spaces and places them in the @F array. So here, @F = ("x", "y/z"), which means $F[1]="y/z" which evaluates in y in numeric contexts (since y is the initial contiguous sequence of digits with $F[1]).


You do not have to count the -p flag in your byte count; instead you count the language as Perl 5 with -p flag, 32 bytes. See this meta post for the current consensus.
Giuseppe

Nice approach! I just had a little go at this and managed to make a 25 byte version: Try it online!. Using $' was the only real difference there really!
Dom Hastings

The combination of using both regex-$' and -a-$F[n] to get parts of the string is a pretty good idea, I have to remember that! Thanks, updated the post.
sundar - Reinstate Monica


0

Milky Way 1.6.0, 31 bytes

'" "\="/"\=>;<A;A;:>*;A+"/"+<+!

Ended up being much longer than I thought it would be.


Explanation

'" "\="/"\=>;<A;A;:>*;A+"/"+<+!

'                                # read input from the command line
 " "  "/"               "/"      # push a string to the stack
    \    \                       # split the STOS at the TOS
     =    =                      # dump the TOS to the stack
           >       >             # rotate the stack rightward
            ;  ; ;   ;           # swap the TOS and STOS
             <              <    # rotate the stack leftward
              A A     A          # push the integer representation of the TOS
                  :              # duplicate the TOS
                    *            # multiply the STOS by the TOS
                       +   + +   # add the TOS and STOS
                              !  # output the TOS

Usage

./mw <path-to-code> -i <input>



0

Check, 120 bytes

>]+>:>32r#v
#d@0+\)  ##:>4;:>5'=:>48-\R-?
dd)R>32-#v
#>15-#v  #?
47r@>@   #v
#dd#v #?
r@>@     #v
    #\d@\: @*@+pd"/"op

Try it online!

I might be able to save some bytes by not trying to reuse the parsing loop (the second line). That way I could make the loop more specific, avoid the huge mess of conditionals, and I could use the register for other things.



0

C#, 112 bytes

s=>{string[]a=s.Split(),b=a[1].Split('/');int o=int.Parse(b[1]);return int.Parse(a[0])*o+int.Parse(b[0])+"/"+o;}

Full/Formatted Version:

namespace System.Linq
{
    class P
    {
        static void Main()
        {
            Func<string, string> f = s =>
            {
                string[] a = s.Split(), b = a[1].Split('/');
                int o = int.Parse(b[1]);
                return int.Parse(a[0]) * o + int.Parse(b[0]) + "/" + o;
            };

            Console.WriteLine(f("4 1/2"));
            Console.WriteLine(f("12 2/4"));
            Console.WriteLine(f("0 0/2"));
            Console.WriteLine(f("11 23/44"));

            Console.ReadLine();
        }
    }
}


0

PHP, 65 Bytes

Try it online

Code

<?=(($a=preg_split("/[\s,\/]/",$argv))[0]*$a[2]+$a[1])."/".$a[2];

Explanation

$a=preg_split("/[\s,\/]/",$argv); # Split the string on "/" and " "
(($a)[0]*$a[2]+$a[1]) # as always denominator*whole number + numerator 
."/"                  # echo an slash
.$a[2];               # echo de denominator

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