Keyfi hassasiyet bölünmesi uygulayın


15

divide(int a, int b, int c)Temel 10 değerini yazdıran bir işlev uygulayın a/b. herhangi kayan nokta matematik ne de kullanmadan BigInteger/ BigDecimalveya herhangi eşdeğer kütüphaneleri. Aşağıdaki 4. maddede yer alan (olası) istisna dışında c, kümesindeki en az doğru karakterler 0123456789.yazdırılmalıdır.

  1. ave bherhangi bir 32 bit tam sayı olabilir. Güncelleme: Golf amacıyla, girişin 64 bit ilkel olması iyi olur, ancak 64 bit veri aralığının tamamını desteklemeniz gerekmez.
  2. Eğer cpozitif değilse (umarım programınız çökmezse) pozitif olup olmadığını kontrol etmenize gerek yoktur.
  3. Asgari üst giden desteklenen cIS 500. Programınız cyukarıdaki değerleri desteklemiyorsa 500, aynı zamanda destekliyorsa da iyidir.
  4. Eşit olarak bölünen sayılar için, ekstra sıfır (değerine bağlı olarak c) veya hiçbir şey yazdırmamak sizin seçiminizdir .
  5. Bölümle başka görevler yapmak için işlevi kullanmanıza gerek yoktur, tek hedef yazdırmaktır.
  6. Arasındaki numaraları için -1ve 1, bir lider yazdırmak ister tercihinizdir 0. Ancak, baştaki sıfırı yazdırmanın kabul edilebilir olduğu tek senaryo budur ve böyle bir sıfırı yalnızca bir tane yazdırabilirsiniz.
  7. Son ondalık basamak için tercih ettiğiniz herhangi bir yuvarlama / zemin / tavan mantığını kullanabilirsiniz.
  8. Olumsuz bir cevap için bir satır aralığı yazdırmalısınız -. Bu dikkate alınmaz c. Yazdırmak istediğiniz Ancak, bu sizin tercihinizdir , +ya olumlu cevap vermesini şey.
  9. Tamsayı bölünmesine ve tamsayı modülüne izin verilir. Bununla birlikte, kod uzunluğuna göre sayılan kendi BigInteger/ BigDecimalkütüphanenizi uygulamayı seçmediğiniz sürece, ilkel öğelerle sınırlı olduğunuzu unutmayın .
  10. Var bolmakla uğraşmanıza gerek yok 0, ancak isterseniz yapabilirsiniz. Programınız sonsuz bir döngü girebilir veya çökebilir b=0ve cezalandırılmayacaksınız.
  11. Yorum başına hafif kural değişikliği. İken yapmak için emin Oyun alanını düzeyidir ave b32 bitlik tamsayılar olmasını garanti altına alınmıştır 64 bit uzunluğunda tamsayı kullanabilir. Seçtiğiniz dil bir ilkel olarak 64 bit tam sayıların ötesine geçiyorsa, hiçbir noktada bu işlevselliği kullanamazsınız (64 bit ile kaplanmış gibi davranabilirsiniz).
  12. Belirsiz olan başka bir nokta (mevcut geçerli cevapların hiçbirini değiştirmemelidir): cbasılı karakter sayısı veya ondalık basamaktan sonraki boşluk sayısı olarak yorumlanabilirken, programınız bir cşekilde ilgili bir şekilde kullanmalıdır. kaç karakter basılacağına karar vermek için. Başka bir deyişle, divide(2,3,2)çıktı çok daha kısa olmalıdır divide(2,3,500); 500 karaktere bakmaksızın basmak uygun değil c.
  13. Aslında işlevin adını umursamıyorum. dgolf için uygundur.

Giriş

Hem işlev çağrısı hem de okuma değeri stdinkabul edilir. Eğer okursanız stdin, kümede olmayan herhangi bir karakter [-0123456789]bağımsız değişken sınırlayıcısı olarak kabul edilir.

Çıktı

stdoutYukarıda açıklandığı gibi karakterler .

Misal

için divide(2,3,5)aşağıdakilerin tümü kabul edilebilir çıktılardır:

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

Başka bir örnek: divide(371,3,5)aşağıdakiler için tüm kabul edilebilir çıktılar:

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

Ve divide(371,-3,5)aşağıdakiler için kabul edilebilir:

-123.6
-123.7
-123.66666
-123.66667

Düzgün bir oyun alanı uğruna, kendi daha büyük uygulamanızı yuvarlamadığınız sürece kullanılabilecek (ilkel veya başka bir) belirli bir maksimum bit uzunluğu vermek akıllıca olabilir , çünkü a) bazı dillerde ilkellerin bit uzunluğu, bazı diller büyük sayı türlerinde temel mimari ve b) olan ilkel.
Jonathan Van Matre


1
Doğru rakamları nasıl sayarsınız ? Örneğinizde son argümanın gösterdiği gibi üç veya dört ama asla beş görmüyorum.
Howard

@Howard, eğer 92,3,5cevap verdiyseniz, örneğin,30.67
durron597

1
btw 370/3 = 123.333 lol
izabera

Yanıtlar:


5

Java, 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);}

Doğaçlama yapmak zorunda kaldım aya bda -2147483648 olabilir, çünkü pozitif 32 bit tamsayılar sadece 2147483647'ye sayılır, bu yüzden bir aoldu long. Olumsuz sonuçlarla baş etmenin daha iyi bir yolu olabilir, ancak hiçbirini bilmiyorum ( doublemuhtemelen bunu olduğu gibi çalışacaktı abs(a) < abs(b), -0ancak sadece tamamlayıcıların hassasiyeti koruyacağını).

Neden iki bayt sayısı? Hesaplama için 92 bayta ve baskı yardımcısı için 36 bayta ihtiyacım vardı ( System.out.printberbat; genellikle Java o kadar golfçü değil).

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

Yöntem temelde çoğumuzun istenen ondalık basamakları oluşturmak için okulda öğrendiklerini uygular.


Resmi karar: Görmezden gelmenin Integer.MIN_VALUEiyi olmadığını long, ancak girdinin iyi olduğunu söyleyebilirim .
durron597

Bu çok daha kısa. Güzel yapılmış.
durron597

@ durron597 teşekkür ederim. Hala katı yazarak ve System.outJava hantal hissediyorum yapmak ;-) Hala iyi bir duygu, zaten uzun cevaplar vardır.
Yapımcı

1
@ durron597 özellikle bir fonksiyon istediniz, bu yüzden saymayacağını düşündüm. Eğer ithalatı kullanmak zorundaysam, muhtemelen evet.
Yapımcı

1
En azından her değişkene $ yok ;-)
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;}

csonra rakamları yazdırır.

örnek çıktı:

d(2,3,5);
0.66666

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

d(24352345,31412,500);
775.25611231376543995925124156373360499172290844263338851394371577740990704189481726728638736788488475741754743410161721635043932255189099707118298739335285878008404431427479943970457150133706863618999108620909206672609193938622182605373742518782630841716541449127721889723672481854068508850120972876607665860180822615560932127849229593785814338469374761237743537501591748376416656055010823888959633261174073602444925506175983700496625493441996689163377053355405577486310963962816757926906914554947153953

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

-2147483647 için çalışmalı <= a <= 2147483647, b için aynı. idare etmek -bir acıydı.

çevrimiçi sürüm: ideone


Bu -2147483648 olmak için çalışıyor mu? Parametrelerinize hangi tamsayı türünün atandığını söyleyecek kadar c derleyicisini bilmiyorum.
TheConstructor

işaret ettiğiniz için teşekkürler. -2147483647 <= a <= 2147483647 için doğru çalışır, b için aynıdır. a = -2147483648 ve b'nin pozitif olması nedeniyle bir sorun var a=-a.
izabera

Denedim ama sonunda sizinle aynı çözümü aldım. printf("-")1 döndürdüğünü fark ederek bir karakter kaydedebilirsiniz .
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;}

Bir adım döngüsü sırasında a/ sırasının çıktısını çıkararak çalışır , geri kalan her yinelemede 10 ile çarpılır.bca

DEMO


A veya b negatif olduğunda garip sonuçlar üretir
TheConstructor

Negatif sayılar için hatayı düzelttim. Teşekkürler!
Razvan

Kodunuzun 112 sürümünü buldum: dönüş değerinefunction 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;}} bakın
TheConstructor

Teşekkürler. Hatta sürümünüzü güncelledim ve ekstra 1 bayt kazanmayı başardım.
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]

Bu çözüm belirtilen kuralların hiçbirini ihlal etmez.


2

C: 72 karakter

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

Neredeyse tamamen yapması gerekeni yapar. Bununla birlikte, buradaki diğer cevapların bazıları sakat değerler verir veya başarısız olur d(-2147483648,b,c)ve d(a,-2147483648,c)-2147483648'in mutlak değeri 32 bitlik bir kelime için sınırların dışında olduğundan.


2

Perl, aritmetik yok, 274 bayt

Bu, Euclid uzun bölümü, alışılmadık miktarda bellek tüketmesi muhtemeldir. Kayan noktalı sayılarda matematiğe en yakın olanı, ayrıştırmak için bit işlemlerini kullanmaktır.

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

Örnekler:

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

Çıktı:

-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

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

Test için çevrimiçi sürüm .

Hüner çarpmak etmektir bir sonuç kayan nokta operasyonu sadece bir tamsayı katı olan yani oldukça yüksek bir sayı ile. Daha sonra nokta ve sıfırlar, sonuçtaki dizede doğru yere yerleştirilmelidir.


Bu 350'den büyük c için işe yarıyor mu?
durron597

C = 1000 ile test ettim - kod bana bir cevap verdi, belki de gerçek sonucu kontrol etmeliyim ...
David Herrmann

2
gelmez gbüyük 64 bitten fazla olsun c? Düzenleme: Bence dolaylı olarak BigIntegerburada kullanıyorsunuz
durron597

Hata, gbir dizedir, ancak aramadan önce to_sbellekte 64 bit'ten büyük bir sayı oluşturdunuz
durron597

1
Bu anlaşılabilir - ve görevi daha zorlu (ve ilginç) yapar! Cevabı silmek veya başkalarının görevin nasıl uygulanmayacağına dair bir örnek vermesini bırakmak daha mı iyi?
David Herrmann

1

python 92 bayt:

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

biraz daha golf mümkün olduğunu düşünüyorum .....


2
gelmez ebüyük c 64 bitten fazla olsun? Edit: Bence dolaylı olarak BigIntegerburada kullanıyorsunuz .
durron597

1
@ durron597 kesinlikle bundan şüpheliyim. BigInt'e (Python'da uzun) gider, ancak 2 ** 45 48 bittir. Yeterli sunum var mı ?? Ayrıca, python hiçbir ilkelleri vardır ...
Maltysen

Eğer a=5ve c=400sonra sonra e=10**c, hex, sayı 333 basamak uzunluğundadır. Bu 8889e7dd7f43fc2f7900bc2eac756d1c4927a5b8e56bbcfc97d39bac6936e648180f47d1396bc905a47cc481617c7...64 bitten fazla başlar .
durron597

@ durron597 400 ... buna ihtiyacım var mı
Maltysen

1
Evet, kural 3 en az 500 kadar desteklemeniz gerektiğini söylüyor ... Bu (imo önemsiz) çözümü önlemeye çalışıyordum.
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);}

Python uygulamamda kullandığım aynı fikir


Çok hoş! Ancak, çöküyord(-2147483648,-1,10)
durron597
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.