Menerapkan pembagian presisi yang sewenang-wenang


15

Menerapkan fungsi divide(int a, int b, int c)yang mencetak nilai basis 10 dari a/b. tanpa menggunakan matematika floating point atau BigInteger/ BigDecimalatau perpustakaan setara apa pun. Setidaknya ckarakter yang akurat dalam himpunan 0123456789.harus dicetak, kecuali untuk pengecualian (mungkin) pada poin 4 di bawah ini.

  1. adan bbisa berupa bilangan bulat 32 bit. Pembaruan: Jika, untuk tujuan bermain golf, Anda ingin input menjadi primitif 64 bit, tidak apa-apa, tetapi Anda tidak perlu mendukung seluruh rentang data 64 bit.
  2. Anda tidak perlu memeriksa capakah positif (walaupun semoga program Anda tidak macet) jika tidak.
  3. Batas atas minimum yang didukung cadalah 500. Tidak apa-apa jika program Anda tidak mendukung nilai-nilai di catas 500, tetapi juga tidak apa-apa jika itu benar.
  4. Untuk angka yang membagi secara merata, adalah pilihan Anda untuk mencetak nol ekstra (berdasarkan nilai c) atau tidak sama sekali.
  5. Anda tidak perlu dapat menggunakan fungsi untuk melakukan tugas lebih lanjut dengan hasil bagi, satu-satunya tujuan adalah mencetak.
  6. Untuk angka di antara -1dan 1, itu adalah pilihan Anda apakah akan mencetak pemimpin 0. Namun, ini adalah satu-satunya skenario di mana pencetakan nol depan dapat diterima, dan Anda hanya dapat mencetak satu nol tersebut.
  7. Anda dapat menggunakan logika pembulatan / lantai / langit-langit yang Anda sukai untuk tempat desimal terakhir.
  8. Untuk jawaban negatif, Anda harus mencetak pemimpin -. Ini tidak diperhitungkan c. Namun, itu adalah pilihan Anda jika Anda ingin mencetak , +atau apa-apa untuk jawaban positif.
  9. Divisi integer dan modulus integer keduanya diperbolehkan. Namun, perlu diingat bahwa Anda dibatasi untuk primitif, kecuali jika Anda memilih untuk menerapkan sendiri BigInteger/ BigDecimallibrary yang penting terhadap panjang kode Anda.
  10. Anda tidak perlu menangani bmakhluk 0, meskipun Anda bisa jika mau. Program Anda dapat memasukkan loop tak terbatas, atau crash, jika b=0, dan Anda tidak akan dihukum.
  11. Perubahan aturan sedikit per komentar. Untuk memastikan lapangan bermain level, sementara adan bdijamin bilangan bulat 32 bit, Anda dapat menggunakan bilangan bulat 64 bit. Jika bahasa yang Anda pilih melampaui bilangan bulat 64 bit sebagai primitif, Anda tidak boleh menggunakan fungsi tersebut (berpura-pura dibatasi pada 64 bit).
  12. Poin lain yang tidak jelas (seharusnya tidak mengubah salah satu jawaban yang valid saat ini): sementara cdapat diartikan sebagai jumlah karakter yang dicetak atau jumlah spasi setelah desimal, program Anda harus menggunakan centah bagaimana dengan cara yang relevan untuk memutuskan berapa banyak karakter yang akan dicetak. Dengan kata lain, divide(2,3,2)output harus jauh lebih pendek daripada divide(2,3,500); tidak apa-apa untuk mencetak 500 karakter tanpa memperhatikan c.
  13. Saya sebenarnya tidak peduli dengan nama fungsinya. dboleh digunakan untuk bermain golf.

Memasukkan

Panggilan fungsi dan membaca dari stdinditerima. Jika Anda membaca dari stdin, karakter apa pun yang tidak ada dalam set [-0123456789]dianggap sebagai pembatas argumen.

Keluaran

Karakter stdoutseperti yang dijelaskan di atas.

Contoh

karena divide(2,3,5), semua yang berikut ini adalah keluaran yang dapat diterima:

0.666
0.667
.6666
.6667
 0.666
 0.667
 .6666
 .6667
+0.666
+0.667
+.6666
+.6667

Contoh lain: untuk divide(371,3,5)yang berikut ini adalah semua output yang dapat diterima:

123.6
123.7
 123.6
 123.7
+123.6
+123.7
123.66666
123.66667
 123.66666
 123.66667
+123.66666
+123.66667

Dan untuk divide(371,-3,5)yang berikut semuanya dapat diterima:

-123.6
-123.7
-123.66666
-123.66667

Demi level playing field, mungkin bijaksana untuk memberikan panjang bit maksimum tertentu yang dapat digunakan (primitif atau sebaliknya) kecuali Anda menggulung implementasi Anda sendiri yang lebih besar, karena a) dalam beberapa bahasa bit panjang primitif bervariasi tergantung pada arsitektur yang mendasari dan b) dalam beberapa bahasa tipe jumlah besar adalah primitif.
Jonathan Van Matre

@JonathanVanMatre Menambahkan aturan 11 per komentar Anda
durron597

1
Bagaimana Anda menghitung angka yang akurat ? Dalam contoh Anda, saya melihat tiga atau empat tetapi tidak pernah lima seperti yang ditunjukkan oleh argumen terakhir.
Howard

@ Howard, jika Anda melakukan 92,3,5jawabannya akan, misalnya,30.67
durron597

1
btw 370/3 = 123.333 lol
izabera

Jawaban:


5

Jawa, 92/128

void d(long a,int b,int c){if(a<0^b<0){a=-a;p('-');}for(p(a/b+".");c>0;c--)p((a=a%b*10)/b);}<T>void p(T x){System.out.print(x);}

Saya harus berimprovisasi sehingga aatau bbisa -2147483648 sebagai bilangan bulat 32-bit positif hanya dihitung menuju 2147483647, itu sebabnya amenjadi a long. Mungkin ada cara yang lebih baik untuk menangani hasil negatif, tetapi saya tahu tidak ada ( doublemungkin akan membuat ini berfungsi abs(a) < abs(b)seperti yang mereka miliki -0tetapi hanya pelengkap yang akan menjaga presisi).

Mengapa angka dua byte? Saya membutuhkan 92 byte untuk perhitungan dan 36 untuk print-helper ( System.out.printmenyebalkan; umumnya Java bukan golfy).

public class Div {

    void d(long a, int b, int c) {
        if (a < 0 ^ b < 0) {
            a = -a;
            p('-');
        }
        for (p(a / b + "."); c > 0; c--) {
            p((a = a % b * 10) / b);
        }
    }

    <T> void p(T x) {
        System.out.print(x);
    }

    public static void main(String[] args) {
        final Div div = new Div();
        div.d(12345, 234, 20);
        div.p('\n');
        div.d(-12345, 234, 20);
        div.p('\n');
        div.d(234, 234, 20);
        div.p('\n');
        div.d(-234, 234, 20);
        div.p('\n');
        div.d(234, 12345, 20);
        div.p('\n');
        div.d(234, -12345, 20);
        div.p('\n');
        div.d(-234, 12345, 20);
        div.p('\n');
        div.d(-234, -12345, 20);
        div.p('\n');
        div.d(-2147483648, 2147483647, 20);
        div.p('\n');
        div.d(2147483647, -2147483648, 20);
        div.p('\n');
    }
}

Metode ini pada dasarnya melatih apa yang sebagian besar dari kita pelajari di sekolah untuk menghasilkan angka desimal yang diminta.


Keputusan resmi: Saya akan mengatakan bahwa mengabaikan Integer.MIN_VALUEtidak baik-baik saja tetapi longsebagai input tidak masalah.
durron597

Itu jauh lebih pendek. Bagus sekali.
durron597

@ durron597 terima kasih. Masih mengetik ketat dan System.outmembuat Java terasa besar ;-) Masih perasaan yang baik, bahwa sudah ada jawaban lagi yang diposting.
TheConstructor

1
@ durron597 Anda secara khusus meminta fungsi jadi saya pikir itu tidak masuk hitungan. Jika saya harus menggunakan impor daripada mungkin ya.
TheConstructor

1
Setidaknya tidak ada $ untuk setiap variabel ;-)
TheConstructor

9

C, 98 95 89

d(a,b,c){if(a>0^b>0)a=-a,printf("-");for(printf("%d.",a/b);c--;putchar(a/b+48))a=a%b*10;}

mencetak cangka setelah.

contoh output:

d(2,3,5);
0.66666

d(-2,3,5);
-0.66666

d(24352345,31412,500);
775.25611231376543995925124156373360499172290844263338851394371577740990704189481726728638736788488475741754743410161721635043932255189099707118298739335285878008404431427479943970457150133706863618999108620909206672609193938622182605373742518782630841716541449127721889723672481854068508850120972876607665860180822615560932127849229593785814338469374761237743537501591748376416656055010823888959633261174073602444925506175983700496625493441996689163377053355405577486310963962816757926906914554947153953

d(-77,12346463,500);
-0.00000623660395693892250760399962321192717298873369644407471192356871761572524859953818352673150196943043525906974329409159530142357369879940514137530724386409289850866600418273638369142644334656816288195250736992448768525852302801215214430238036593962173620088603513411087855687900251270343579371679160258286118056645048869461642577311412993340683886551152342172814999729072204727783171585254821563066280601982932277851559592411203111368818745903178910429650985873444078680671541315111866451144752954

harus bekerja untuk -2147483647 <= a <= 2147483647, sama untuk b. menangani -itu menyakitkan.

versi online: ideone


Apakah ini berfungsi untuk menjadi -2147483648? Tidak tahu c compiler dengan cukup baik untuk mengetahui tipe integer mana yang ditugaskan pada parameter Anda.
TheConstructor

terima kasih telah menunjukkannya. itu bekerja dengan benar untuk -2147483647 <= a <= 2147483647, sama untuk b. ada masalah ketika a = -2147483648 dan b positif karena a=-a.
izabera

Saya mencoba tetapi pada dasarnya mendapat solusi yang sama seperti Anda. Anda dapat menyimpan satu karakter dengan menyadari bahwa printf("-")mengembalikan 1.
Thomas

4

PHP, 108

function d($a,$b,$c){$a*$b<0&&$a*=-print'-';for($p='.';$c--;$a.=0,print$i.$p,$p='')$a-=$b*$i=($a-$a%$b)/$b;}

Ia bekerja hanya dengan mengeluarkan hasil bagi a/ bselama satu putaran clangkah, amenjadi sisanya dikalikan dengan 10 pada setiap iterasi.

DEMO


Menghasilkan hasil aneh ketika a atau b negatif
TheConstructor

Saya memperbaiki bug untuk angka negatif. Terima kasih!
Razvan

Baru saja menemukan versi 112 kode Anda: function d($a,$b,$c){if($a*$b<0)$a*=-print'-';for($p='.';$c--;$a*=10,$p=''){$a-=$b*$i=($a-$a%$b)/$b;echo$i.$p;}}lihat nilai balik
TheConstructor

Terima kasih. Saya bahkan memperbarui versi Anda dan berhasil memenangkan 1 byte tambahan.
Razvan

2

Python 111

f=lambda a,b,c:'-'[a*b>=0:]+'%s'%reduce(lambda(d,r),c:(d%c*10,r+`d/c`+'.'[r!='':],),[abs(b)]*c,(abs(a),''))[-1]

Solusi ini tidak melanggar aturan yang disebutkan.


2

C: 72 karakter

d(a,b,c){for(printf("%d.",a/b);c--;putchar((a=abs(a)%b*10)/abs(b)+48));}

Hampir sepenuhnya melakukan apa yang seharusnya dilakukan. Namun itu karena beberapa jawaban lain di sini memberikan nilai miring atau gagal untuk d(-2147483648,b,c)dan d(a,-2147483648,c)karena nilai absolut -2147483648 di luar batas untuk kata 32-bit.


2

Perl, tanpa aritmatika, 274 byte

Ini adalah pembagian panjang Euclidean , kemungkinan untuk mengkonsumsi jumlah memori yang tidak biasa. Yang paling dekat dengan matematika pada angka floating-point adalah menggunakan operasi bit untuk menguraikannya.

sub di{($v,$i,$d,$e)=(0,@_);($s,$c,$j)=$i=~s/-//g;$s^=$d=~s/-//g;
$i=~s/\.(\d+)/$j=$1,""/e;$d=~s/\.(\d+)/$c=$1,""/e;
$z=0.x+length($c|$j);$i.=$j|$z;$d.=$c|$z;
($e,$m,$z,$t)=(1.x$e,0.x$i,0.x$d,"-"x($s&1));
for(;$e;$t.="."x!$v,$v=chop$e){$t.=$m=~s/$z//g||0;$m="$m"x10}
print"$t\n"}

Contoh:

di(-355,113,238);
di(1.13,355,239);
di(27942,19175,239);
di(1,-90.09,238);
di("--10.0","----9.801",239);
di(".01",".200",239);

Keluaran:

-3.141592920353982300884955752212389380530973451327433628318
584070796460176991150442477876106194690265486725663716814159
292035398230088495575221238938053097345132743362831858407079
646017699115044247787610619469026548672566371681415929203539

0.0031830985915492957746478873239436619718309859154929577464
788732394366197183098591549295774647887323943661971830985915
492957746478873239436619718309859154929577464788732394366197
183098591549295774647887323943661971830985915492957746478873

1.4572099087353324641460234680573663624511082138200782268578
878748370273794002607561929595827900912646675358539765319426
336375488917861799217731421121251629726205997392438070404172
099087353324641460234680573663624511082138200782268578878748

-0.011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011
100011100011100011100011100011100011100011100011100011100011

1.0203040506070809101112131415161718192021222324252627282930
313233343536373839404142434445464748495051525354555657585960
616263646566676869707172737475767778798081828384858687888990
919293949596979900010203040506070809101112131415161718192021

0.0500000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000

1

Ruby, 178

def d(a,b,c)
    n=(a<0)^(b<0)
    a=-a if n
    m=a/b-b/a
    l=m.to_s.size-1
    g=(a*10**(10+c)/b).to_s
    f=m<0?"."+"0"*(l-1)+g[0..c-l-1] : g[0..l]+"."+g[l+1..c-2]
    p n ? "-"+f : f
end

Versi online untuk pengujian.

Caranya adalah dengan mengalikan angka dengan angka yang cukup tinggi, sehingga hasilnya hanyalah kelipatan bilangan bulat dari operasi floating point. Kemudian titik dan nol harus dimasukkan di tempat yang tepat di string yang dihasilkan.


Apakah ini bekerja untuk c lebih besar dari 350?
durron597

Saya mengujinya dengan c = 1000 - kode memberi saya jawaban, mungkin saya harus memeriksa hasil yang sebenarnya meskipun ...
David Herrmann

2
tidak gmelampaui 64 bit untuk besar c? Sunting: Saya pikir Anda secara implisit menggunakan di BigIntegersini
durron597

Err, gadalah sebuah string, tetapi sebelum Anda menelepon to_sAnda telah membuat angka dalam memori yang melebihi ukuran 64 bit
durron597

1
Itu bisa dimengerti - dan membuat tugas lebih menantang (dan menarik)! Apakah lebih baik menghapus jawaban atau membiarkan orang lain memiliki contoh bagaimana tidak melaksanakan tugas?
David Herrmann

1

python 92 byte:

def d(a,b,c):c-=len(str(a/b))+1;e=10**c;a*=e;a/=b;a=str(a);x=len(a)-c;return a[:x]+'.'+a[x:]

Saya pikir lebih banyak golf mungkin .....


2
tidak ebisa melampaui 64 bit untuk c besar? Sunting: Saya pikir Anda secara implisit menggunakan di BigIntegersini.
durron597

1
@ durron597 saya sangat meragukannya. Ini masuk ke BigInt (Long di python) tetapi 2 ** 45 adalah 48 bit. Apakah itu cukup pertimbangan ?? Juga, python tidak punya primitif, jadi ...
Maltysen

Jika a=5dan c=400kemudian setelah e=10**c, dalam heks, panjangnya adalah 333 digit. Mulai 8889e7dd7f43fc2f7900bc2eac756d1c4927a5b8e56bbcfc97d39bac6936e648180f47d1396bc905a47cc481617c7...ini lebih dari 64 bit.
durron597

@ durron597 400 ... apakah saya memerlukannya
Maltysen

1
Ya aturan 3 mengatakan Anda harus mendukung setidaknya 500 ... Saya mencoba untuk mencegah solusi (imo sepele) ini.
durron597

1

C 83

d(a,b,c){printf("%d.",a/b);for(a=abs(a),b=abs(b);c--&&(a=a%b*10);)putchar(a/b+48);}

Ide yang sama yang saya gunakan dalam implementasi python saya


Sangat bagus! Namun, crash padad(-2147483648,-1,10)
durron597
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.