Nomor Campuran ke Fraksi yang Tidak Benar


19

Nomor Campuran ke Fraksi yang Tidak Benar

Dalam tantangan ini, Anda akan mengonversi angka campuran menjadi fraksi yang tidak tepat.

Karena pecahan yang tidak tepat menggunakan angka lebih sedikit, kode Anda harus sesingkat mungkin.


Contohnya

4 1/2
9/2

12 2/4
50/4

0 0/2
0/2

11 23/44
507/44

Spesifikasi

Anda dapat menganggap penyebut input tidak akan pernah menjadi 0. Input akan selalu dalam format di x y/zmana x, y, z adalah bilangan bulat non-negatif yang berubah-ubah. Anda tidak perlu menyederhanakan output.


Ini adalah sehingga kode terpendek dalam byte menang.


5
Anda harus menambahkan tag "parsing". Saya yakin sebagian besar jawaban akan menghabiskan lebih banyak byte untuk mem-parsing input dan memformat output daripada melakukan matematika.
nimi

3
Dapatkah output menjadi tipe angka rasional atau harus berupa string?
Martin Ender

2
@AlexA .: ... tapi sebagian besar tantangan. Menurut keterangannya, tag harus digunakan dalam kasus seperti itu.
nimi

7
Bisakah x, ydan zmenjadi negatif?
Dennis

2
Berdasarkan tantangan yang saya asumsikan, tetapi apakah format input "xy / z" wajib, atau dapatkah ruang menjadi baris baru, dan / atau x,y,zinput yang dipisahkan? Sebagian besar jawaban menganggap format input memang wajib x y/z, tetapi beberapa tidak, maka pertanyaan ini memiliki jawaban yang pasti.
Kevin Cruijssen

Jawaban:


1

Japt, 10 byte

Woohoo, saat ini mengalahkan CJam!

U*W+V+'/+W

Cobalah online!

Bagaimana itu bekerja

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

Saya menghabiskan sedikit waktu kemarin mencoba untuk mencari tahu bagaimana saya mendapatkan 15 rep dari jawaban, sampai saya menyadari: tanda centang hijau pertama saya! \ o /
ETHproduk


7

CJam, 16 15 14 byte

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

atau

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

Uji di sini.

Penjelasan

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.

Versi lain menghindari penggunaan variabel dengan menggunakan sedikit lebih banyak perpindahan tumpukan.


Saya benar-benar harus mulai menggunakan konversi basis di CJam lebih banyak.
Buah Esolanging

Versi alternatif:, '//~\S/1$b'/@ini adalah 13 byte. Sunting : oh saya lupa input l.
Chromium

4

Mathematica, 58 byte

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

Ini mengembalikan hasil yang disederhanakan. Jika mengeluarkan bilangan rasional alih-alih string baik-baik saja, kita dapat menyimpan 19 byte:

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

4

PowerShell, 47 44 42 Bytes

Dicoret 44 masih teratur 44; (

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

Golf beberapa byte dengan menggunakan regex -split. Golf beberapa lagi berkat TessellatingHeckler dengan menukar regex.

The $args-split'\D'mengambil argumen masukan dan membagi pada karakter non-digit. Di sini ia melakukan dua pemisahan, satu di spasi, yang lain pada /karakter. Hasilnya kemudian disimpan dalam tiga variabel menggunakan tugas simultan. Kami kemudian merumuskan output string sebagai ( $ljumlah eft kali $denominator ditambah $numerator) dieksekusi sebagai blok kode, /slash, dan kemudian $denominator lagi.


Hai, saya pikir Anda dapat melakukan -split ' |/'untuk menyimpan satu karakter dengan regex "cocokkan ini | atau itu", atau gunakan -split '\D'untuk membagi pada apa pun yang bukan digit dan s (h) ave dua karakter. Jika @Downgoat bersedia sedikit fleksibel pada format output, '{0}*{2}+{1};{2}'-f($args-split'\D')|iexadalah 40 byte dan memiliki output yang lebih keren karena angkanya bahkan satu di atas yang lain!
TessellatingHeckler

1
@TessellatingHeckler Terima kasih atas bantuan regex. Saya sudah meminta masukan Downgoat. Tetapi $l,$n,$d=$args-split'\D';+$l*$d+$n;$dlebih pendek lagi di 37, dan secara logis mengikuti pola yang sama seperti di sini.
AdmBorkBork

Oh ya, hanya matematika! (Itu akan cukup untuk mengalahkan jawaban Perl, juga)
TessellatingHeckler

3

Java dengan Ten Foot Laser Pole 1.03, 79 + 25 (import) = 104 bytes

Membutuhkan import sj224.tflp.math.*;

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

Ini hampir pasti akan bekerja dengan 1.04 juga, tetapi sejauh ini saya hanya mengujinya dengan 1.03 karena saya sudah memiliki proyek java yang diatur dengan 1.03 di jalur build.


3

JavaScript (ES6), 44 41 byte

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

Disimpan 3 byte berkat @ETHproductions !

Penjelasan

Sangat sederhana.

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

Uji

Tes tanpa merusak penugasan untuk bekerja di sebagian besar browser.


Bagus! Anda dapat menggunakan [p,q,r]=di tempat p=, kemudian ganti p[0], p[1]dan p[2]dengan p, q, dan rmasing-masing. Setelah perubahan ini, saya mendapatkan 41:m=>([p,q,r]=m.match(/\d+/g),+q+p*r+"/"+r)
ETHproduksi

@ ETHproduk Terima kasih atas tipnya! Saya benar-benar mempertimbangkan untuk menggunakan penugasan perusakan tetapi mereka tidak bekerja di Chrome dan saya tidak memiliki Firefox untuk mengujinya. : P
user81655

Saya pertama mencoret 44! : D
user81655

Anda dapat menggunakan m.split(/\W/g)sebagai gantinya untuk menyimpan byte
Kritixi Lithos

2

Julia, 58 50 byte

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

Ini adalah fungsi anonim yang menerima string dan mengembalikan Rationalobjek tipe. Untuk menyebutnya, berikan nama, mis f=s->....

Kita dapat mengambil keuntungan dari kenyataan bahwa input dapat sedikit dimanipulasi untuk menjadi ekspresi yang dievaluasi menjadi rasional. Secara khusus, bilangan bulat ditambah rasional adalah rasional, dan rasional dilambangkan dengan garis miring ganda. Jadi jika kita berubah 4 1/2menjadi 4+1//2, hasil yang dievaluasi akan menjadi 9//2.

Tidak Disatukan:

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 karakter

Masukan persis cocok dengan pembatas array dan representasi fraksi yang melekat dari Smalltalk. Kalau saja tidak begitu bertele-tele, itu bisa menjadi pesaing serius!

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

Penyederhanaan yang terlalu buruk bukanlah keharusan, Smalltalk melakukannya secara otomatis!


2

Bash + coreutils, 28

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

$@mengembang ke semua parameter baris perintah, jadi ${@/\// }mengembang ke semua parameter baris perintah dengan /diganti dengan , yang diletakkan di dcatas tumpukan. Sisanya adalah manipulasi tumpukan dan aritmatika sederhana.


2

Haskell , 74 67 63 byte

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

Cobalah online!

Penjelasan

Seperti yang diketahui oleh H.PWiz , kita dapat menggunakan lexer Haskell di sini untuk memecah string menjadi bagian-bagiannya. (Sebelumnya saya menggunakan span(>'/')) Dan Laikoni menunjukkan bahwa itu <$>berfungsi seperti mapSnddari Data.Tuple.

Pengawal pola memecah kode kami menjadi tiga angka yang ingin kita gunakan lex. lexmemanggil haskell's lexer untuk memutus token pertama. Ini mengembalikan daftar dengan masing-masing elemen yang mewakili cara yang mungkin untuk mengurai string. Elemen-elemen ini adalah tupel dengan elemen pertama menjadi token pertama dan sisanya dari string menjadi elemen kedua. Sekarang karena format input sangat teratur, kami hanya akan memiliki satu parse, jadi kami selalu dapat mengambil yang pertama. Hal pertama yang kita lakukan adalah memanggil lexinput

lex x

Lalu kami membuka bungkusnya dari daftar itu memberi kami 2-tuple

lex x!!0

Token pertama akan menjadi seluruh bagian dari fraksi campuran yang meninggalkan fraksi yang didahului oleh spasi untuk tetap diuraikan. Kemudian karena tupel Functorskita dapat menggunakan (<$>)alias untuk fmapmenerapkan lexke elemen kedua tupel.

lex<$>lex x!!0

Ini memakan ruang dan memutuskan token berikutnya, pembilang dari fraksi kami. Sekarang kita ikat ini ke pencocokan pola menggunakan <-. Pola kita adalah

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

ameraih seluruh bagian dari fraksi, token pertama kami. :_membuka daftar yang dihasilkan dari yang kedua lex. cmeraih token kedua yang kami lexed, yaitu pembilang dari pecahan. Segala sesuatu yang tersisa terikat pada s:dyang membaginya menjadi karakter pertama, dijamin oleh format menjadi /dan sisanya yang akan menjadi penyebutnya.

Sekarang kita telah mem-parsing input, kita melakukan perhitungan yang sebenarnya:

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

Di mana rfungsi baca yang kita ikat sebelumnya.

Penting untuk dicatat bahwa lexmengembalikan daftar kosong jika gagal dan tidak kosong jika berhasil. Kenapa ini bukan Maybesaya tidak tahu.



@ H.PWiz Itu adalah penggunaan lex yang bagus.
Wheat Wizard


2
Anda harus dapat menyimpan 2 lainnya dengan mencocokkan pada/
H.PWiz


1

Javascript ES6, 62 byte

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

1
Cukup bagus! Beberapa tips: Anda dapat menggunakan [b,c]=di tempat b=, lalu menggunakan bdi tempat b[0]dan cdi tempat b[1]. Selain itu, Anda dapat mengatur ulang persamaan sehingga Anda tidak memerlukan tanda kurung sama sekali: p=prompt;[b,c]=p(a=+p()).split/;alert(+b+c*a+"/"+c)
ETHproduksi

1

Perl, 82 61 38 byte

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

Ini mungkin bisa lebih banyak golf.

Perubahan

  • Disimpan 16 byte dengan menggunakan regex split, dan 5 dengan menggunakan <>bukan <STDIN>.
  • Disimpan 16 byte lagi berkat Dennis.

Dengan shebang #!perl -paF/\D/(9 byte), Anda dapat menggunakan $_=$F[0]*$F[2]+$F[1]."/$F[2]".
Dennis

@ Dennis saya telah menambahkan itu. Terima kasih!
ASCIIThenANSI

Bagian #!perldari shebang dan linefeed tidak masuk hitungan. Ini hanya 38 byte.
Dennis

@ Dennis Oh, baiklah. Saya akan memperbaikinya sekarang. (Sisi baiknya, saya pikir ini adalah jawaban non-esoterik terpendek kedua)
ASCIIThenANSI

1

Mathematica, 51 byte

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

Menariknya, Mathematica mendukung ini dengan built-in. Jika mengeluarkan nomor diperbolehkan, maka kita hanya perlu 28 byte:

Interpreter@"ComputedNumber"

1

Jawa, 159 148 142 120 110 byte

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

Menyimpan banyak byte berkat FlagAsSpam.


@FlagAsSpam Selesai.
SuperJedi224

@ FlagAsSpam Tapi kemudian variabel akan dideklarasikan!
SuperJedi224

Abaikan semua yang baru saja saya katakan - cara singkat melakukan apa yang Anda lakukan adalahLong b=new Long(a[0]),c=new Long((a=a[1].split("/"))[0]),d=new Long(a[1]);
Addison Crump


1

05AB1E , 17 15 byte

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

-2 byte terima kasih kepada @MagicOctopusUrn .

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

#`         # 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"

Dengan input-dan output-format yang fleksibel, mengambil bilangan bulat dalam urutan x,z,ydan mengeluarkan nominator dan penyebut pada garis yang terpisah itu akan menjadi 4 byte (itulah sebabnya saya menambahkan -tag ke tantangan ..):

*+²»

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

*        # 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 Terima kasih, tetapi format input berbeda dari pada deskripsi tantangan. Rupanya format (sebagai string tunggal) 4 1/2wajib untuk tantangan khusus ini. Jika tidak saya akan menggunakan saya versi 4-byte (atau jika keluaran adalah wajib, tapi masukan fleksibel saya akan menggunakan ini 6-byter: *+'/²J)
Kevin Cruijssen


@MagicOctopusUrn Oh, bahkan tidak tahu tentang " Dorong semua item ake dalam tumpukan " .. o.Ô Persis apa yang saya butuhkan untuk tantangan ini! Dan cerdas dengan bergabung dengan "/". Terima kasih! :)
Kevin Cruijssen

Saya benci menggunakan perintah "Dorong semua item ke dalam tumpukan" karena ini "` "dan tidak dapat dijinakkan dengan tag-inline kode.
Magic Gurita Guci

@ MagicOctopusUrn ya, itu juga agak mengganggu dalam komentar (itulah sebabnya saya kutip " Dorong semua item ake dalam tumpukan " daripada menggunakan '`'..
Kevin Cruijssen


1

Stax , 1 byte

+

Jalankan dan debug itu (meskipun tidak banyak yang bisa di-debug)

Spesifikasi tantangan mengatakan, "Anda tidak perlu menyederhanakan output." Dengan asumsi itu diizinkan untuk disederhanakan, maka ada instruksi bawaan untuk melakukan ini. Masukan secara implisit ditafsirkan sebagai bilangan bulat dan bilangan rasional. The +instruksi melebar baik untuk rasional, menambahkan, dan menyederhanakan. Hasilnya dicetak secara implisit.


1

Perl 5 dengan -la -Mfeature = katakanlah, 32 byte 25 byte

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

Cobalah online!

(-7 byte terima kasih kepada Dom Hastings)

$_adalah seluruh input x y/z, yang mengevaluasi nilai xdalam konteks numerik (seperti di *sini). $'adalah string pasca-pertandingan regex, yang di sini berisi apa pun yang muncul setelah /- jadi z,. Untuk mendapatkan ynilai, kami menggunakan -aflag yang membagi input pada spasi dan menempatkannya dalam @Farray. Jadi di sini,, @F = ("x", "y/z")yang berarti $F[1]="y/z"yang mengevaluasi dalam ykonteks numerik (karena yadalah urutan awal angka yang berdekatan $F[1]).


Anda tidak harus menghitung -pbendera dalam hitungan byte Anda; alih-alih Anda menghitung bahasa sebagai Perl 5 with -p flag, 32 bytes. Lihat meta ini untuk konsensus saat ini.
Giuseppe

Pendekatan yang bagus! Saya baru saja mencoba dan berhasil membuat versi 25 byte: Cobalah online! . Menggunakan $'adalah satu-satunya perbedaan nyata di sana!
Dom Hastings

Kombinasi menggunakan regex- $'dan -a- $F[n]untuk mendapatkan bagian dari string adalah ide yang cukup bagus, saya harus ingat itu! Terima kasih, perbarui posnya.
sundar - Reinstate Monica

0

Lua, 123 Bytes

m=io.read()z=string x=z.find c=z.sub b=tonumber s=x(m," ")f=x(m,"/")d=c(m,f+1)print(b(c(m,1,s))*b(d)+b(c(m,s,f-1)).."/"..d)

0

Bima Sakti 1.6.0 , 31 byte

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

Akhirnya menjadi lebih lama dari yang saya kira.


Penjelasan

'" "\="/"\=>;<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

Pemakaian

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

0

Python 2.7, 88 Bytes

a = input (). split ('/'); cetak int (a [-1]) * int (a [0] .split () [0]) + int (a [0] .split () [1 ]), '/', a [1]

Cobalah online !

Anda harus mengetikkan input dalam tanda kutip.

Mungkin bukan yang terbaik ...



0

C, 64

main(i,d,n){scanf("%d %d/%d",&i,&n,&d);printf("%d/%d",i*d+n,d);}

Membaca input dari STDIN. Cukup jelas, saya kira.


0

Periksa , 120 byte

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

Cobalah online!

Saya mungkin dapat menyimpan beberapa byte dengan tidak mencoba menggunakan kembali parsing loop (baris kedua). Dengan begitu saya bisa membuat loop lebih spesifik, menghindari kekacauan besar kondisional, dan saya bisa menggunakan register untuk hal-hal lain.



0

C #, 112 byte

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

Versi Lengkap / Diformat:

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

Cobalah online

Kode

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

Penjelasan

$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

0

Java 10, 87 byte

Seekor lambda dari Stringke String.

s->{var p=s.split(" |/");return new Long(p[0])*new Long(p[2])+new Long(p[1])+"/"+p[2];}

Cobalah secara Online

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.