Ubah pecahan menjadi desimal berulang


17

Hampir kutub berlawanan jika tantangan ini , dan saya kira itu akan sedikit lebih mudah.

Tugas Anda adalah mengambil dua bilangan bulat dalam format a/b(Membentuk bilangan rasional), lalu mengeluarkan bilangan desimal dengan tepat.

Misalnya, jika Anda memasukkan 1/3, itu akan menghasilkan:

0.33333333333333333

Dan akan terus mencetak 3s hingga akhir waktu, dengan awalan 0 opsional (Anda juga dapat mencetak satu karakter per baris jika dan hanya jika bahasa Anda tidak mengizinkan pencetakan pada baris yang sama.)

Perilaku untuk x/0tidak akan ditentukan. Untuk nomor yang terlihat seperti itu tidak mengulangi (Seperti, katakan 5/4) itu benar-benar berulang. Salah satu dari dua bentuk berikut ini dapat diterima untuk 5/4:

1.25000000000000000
1.24999999999999999

(Sama dengan bilangan bulat, 1.9999999atau 2.000000)

Fraksi mungkin tidak dalam bentuk yang paling sederhana, dan aatau bmungkin negatif (Catatan -a/b = -(a/b), -a/-b = a/b, a/-b = -a/b, dan -.6249999tidak valid, tetapi -0.6249999dapat diterima, namun Anda masih bisa menggunakan.


Bisakah kita menggunakan Unix bc, atau apakah itu curang?
David R Tribble

Sebelum saya terus bermain golf jawaban saya: Bisakah adan / atau bmenjadi negatif?
Dennis

@ Dennis Ya, tetapi salah satu aatau b(atau keduanya) bisa negatif)

@ DavidTribble Saya pikir itu celah standar, jadi tidak.

Apakah hasil edit terakhir Anda mengatakan bahwa angka nol di depan boleh saja dengan angka positif, tetapi bukan angka negatif? Jika demikian, apa alasannya?
Geobits

Jawaban:


2

CJam, 38 37 byte

l'/%:i2*~*0<'-*o:Dmd\zo'.{oA*Dmd\z1}g

Bagaimana itu bekerja

l     e# Read line from STDIN.            STACK '17/-13'
'/%   e# Split at '/'.                    STACK ['17' '-13']
:i    e# Cast each element to int.        STACK [17 -13]
2*~   e# Duplicate and dump the array.    STACK 17 -13 17 -13
*     e# Multiply.                        STACK 17 -13 -221
0<    e# Compare with zero.               STACK 17 -13 1
'-*o  e# Print '-' that many times.       STACK 17 -13
:D    e# Save the topmost integer in D.   STACK 17 -13
md    e# Perform modular division.        STACK -1 4
\z    e# Swap and take absolute value.    STACK 4 1
o'.   e# Print and push '.'.              STACK 4 '.'
{     e# do:
  o   e#   Print.                         STACK 4
  A*  e#   Multiply by 10.                STACK 40
  Dmd e#   Divide modulo D.               STACK -3 1
  \z  e#   Swap and take absolute value.  STACK 1 3
  o   e#   Print.                         STACK 1
1}g   e# while(1)

Karena Anda menggunakan pembagian ganda bukankah ini benar-benar rusak untuk angka besar?
orlp

@ orlp: Benar-benar. Sudah diperbaiki sekarang.
Dennis

6

C, 108 79

Edit Dimodifikasi untuk bekerja dengan angka negatif.

Masukan dari stdin. Gaya K&R lama.

main(a,b){char*s="-%d.";scanf("%d/%d",&a,&b);for(a*b<0?(a<0?a=-a:(b=-b)):++s;printf(s,a/b);s="%d")a=a%b*10;}

4

Ruby, 83 69 102 91 89 byte

->s{a,b=s.scan(/\d+/).map &:to_i
eval(s+?r)<0&&$><<?-
$><<a/b<<?.
loop{a=a%b*10
$><<a/b}}

Implementasi sederhana divisi integer manual berdasarkan divisi integer komputer.

Terima kasih kepada @blutorange untuk bantuan dalam bermain golf.

Sunting: Memperbaiki solusi untuk memasukkan angka negatif.


2
Dengan memanfaatkan beberapa pintasan di ruby, Anda dapat menurunkannya menjadi 66 byte: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}Saya suka ini tentang ruby.
blutorange

Wow, saya baru belajar banyak hal, terima kasih! Saya tidak ingat ?/untuk menunjukkan karakter, saya juga tidak tahu tentang $><<mencetak atau loopkata kunci. Terima kasih banyak!!
rorlork

1
Sama-sama, saya tidak tahu banyak dari trik ini sampai seseorang menunjukkannya. $>kependekan dari $stdout, dan <<merupakan operator. Anda dapat menyimpan satu byte lagi di baris kedua dengan mengubahnya ke c*d<0&&$><<?-; beberapa byte dengan menggabungkan baris ke-3 / ke-4 $><<a/b<<?., dan satu lagi dengan menghapus spasi setelah <<di baris terakhir. Dan inilah ide untuk membawanya ke 91 byte: ->s{a,b=s.scan(/\d+/).map &:to_i;1==s.count(?-)&&$><<?-;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}(ruby 2.2.0)
blutorange

Sintaks untuk $><<a/btidak berfungsi dengan benar, itu sebabnya saya menempatkan spasi di sana. Kelihatannya bagus, terima kasih banyak!
rorlork

1
Jika Anda masih tertarik, ada juga literal rasional ( Rational(2,3) == 2/3r) sejak ruby ​​2.1 (yang saya pelajari sekitar 10 menit yang lalu) yang dapat digunakan untuk mempersingkat baris kedua:eval(s+?r)<0&&$><<?-
blutorange

2

Jawa, 177 176 170

s->{try{int x=new Integer(s.split("/")[0]),y=new Integer(s.split("/")[1]),z=1;for(;;x=x%y*10,Thread.sleep(999))System.out.print(x/y+(z-->0?".":""));}catch(Exception e){}}

Algoritma ini sangat mudah; bagian yang sulit adalah membuat pencetakan bekerja. Pada akhirnya, saya memiliki komputer tidur selama satu detik di antara setiap langkah sehingga bisa mencetak.

Versi diperluas dan dapat dijalankan

public class RepeatedDecimal {
    public static void main(String[] args) {
        java.util.function.Consumer<String> f = s -> {
                try {
                    int x = new Integer(s.split("/")[0]),
                        y = new Integer(s.split("/")[1]),
                        z = 1;
                    for (;; x = x % y * 10, Thread.sleep(999)) {
                        System.out.print(x / y + (z-- > 0 ? "." : ""));
                    }
                } catch (Exception e) { }
                };

        f.accept("5/7");
    }
}

Sementara output memang memiliki masalah pembilasan, saya bisa membuatnya menampilkan output dengan tidur selama 9ms yang akan mencukur dua byte.

@Snowman Mungkin tergantung pada perangkat keras atau OS; komputer saya tidak akan bekerja dengan kurang dari 250 ms atau lebih.
Ypnypn

2

R, 103 137 109 103

Agak lebih senang dengan ini sekarang. Menggunakan pemindaian dengan pemisah menghemat banyak byte. Mungkin masih ada ruang untuk perbaikan. Diganti <-dengan =. Tidak selalu beruntung dalam hal ini, tetapi berhasil kali ini.

cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)

Tes berjalan

> cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)
1: -1/3
3: 
Read 2 items
-0.33333333333333333333...
> cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)
1: -5/-4
3: 
Read 2 items
1.250000000000000000000...

1

Python 3, 107 115 byte

a,b=map(int,input().split("/"))
print(("%.1f"%(a/b))[:-1],end="")
b=abs(b)
while 1:a=abs(a)%b*10;print(a//b,end="")

Cukup mudah:

  • Masukkan pembilang dan penyebut
  • Keluarkan hasil bagi dengan 1 digit setelah titik desimal, lalu lepas digit terakhir (misalnya -1/3-> -0.)
  • Ambil nilai absolut *
  • Loop:
    • Numerator adalah sisa setelah membagi penyebut
    • Kalikan pembilang dengan 10
    • Hasil bagi integer output sebagai digit berikutnya

* (Meskipun perhitungan untuk adipindahkan di dalam loop untuk menyimpan beberapa byte.)

Sunting: Fixed bug dengan pecahan negatif> -1.


0

Python 2.7, 209 byte

from sys import*;m,o=1,lambda x:stdout.write(str(x));a,b=[int(x)for x in argv[1].split('/')]
o(str(a*b)[0]);a,b=abs(a),abs(b);o('0'*(b>a))
while 1:
 while not((m*a)/b):o('0.'[m==1]);m*=10
 o((m*a)/b);a=(m*a)%b

edit:

Sekarang menampilkan semua karakter pada baris yang sama, seperti yang diminta.

edit2:

Sekarang membaca fraksi dari argumen commandline, seperti yang diminta :)


1
Beberapa tips: 1) Menggunakan mapalih-alih pemahaman daftar menghemat sedikit; 2) tidak perlu tanda kurung di sekitar m*adi salah satu lokasi, seperti *, %, dan /semua prioritas yang sama dan kiri-asosiatif; 3) logika 0-atau-dot pada baris 3 dapat disederhanakan "0."[m==1], karena Anda hanya mencetaknya saja; 4) mungkin akan menghemat karakter hanya untuk mengatur o=stdout.writedan mengkonversi argumen numerik ke string dengan backticks sesuai kebutuhan.
DLosc

1
Selain itu, kode tersebut tampaknya tidak berfungsi dengan negatif: 1/-3memberi -1.666666666alih-alih -0.333333333.
DLosc
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.