ใช้การแบ่งความแม่นยำโดยพลการ


15

ใช้ฟังก์ชั่นdivide(int a, int b, int c)ที่พิมพ์ค่าฐาน 10 a/bเป็น โดยไม่ต้องใช้ใด ๆ ทางคณิตศาสตร์จุดลอยมิได้BigInteger/ BigDecimalหรือเทียบเท่าห้องสมุดใด ๆ อย่างน้อยcอักขระที่แม่นยำภายในชุด0123456789.ต้องพิมพ์ยกเว้นข้อยกเว้น (เป็นไปได้) ในจุดที่ 4 ด้านล่าง

  1. aและbอาจเป็นจำนวนเต็ม 32 บิต อัปเดต:หากเพื่อวัตถุประสงค์ในการเล่นกอล์ฟคุณต้องการให้อินพุตเป็นแบบดั้งเดิม 64 บิตที่ใช้ได้ แต่คุณไม่จำเป็นต้องสนับสนุนช่วงข้อมูล 64 บิตทั้งหมด
  2. คุณไม่จำเป็นต้องตรวจสอบว่าcเป็นไปในเชิงบวก (แต่หวังว่าโปรแกรมของคุณจะไม่เกิดปัญหา) หากไม่ใช่
  3. ขั้นต่ำในการสนับสนุนที่ถูกผูกไว้บนสำหรับมีc 500มันก็โอเคถ้าโปรแกรมของคุณไม่รองรับค่าcข้างต้น500แต่มันก็โอเคถ้ามันทำ
  4. สำหรับตัวเลขที่แบ่งเท่า ๆ กันมันเป็นทางเลือกของคุณว่าจะพิมพ์เลขศูนย์พิเศษ (ตามค่าc) หรือไม่มีอะไร
  5. คุณไม่จำเป็นต้องใช้ฟังก์ชั่นเพื่อทำงานเพิ่มเติมใด ๆ กับความฉลาดทางเป้าหมายเดียวคือการพิมพ์
  6. สำหรับตัวเลขระหว่าง-1และมันเป็นสิ่งที่คุณเลือกว่าจะพิมพ์ชั้นนำ1 0อย่างไรก็ตามนี่เป็นสถานการณ์จำลองเดียวที่ยอมรับการพิมพ์ศูนย์นำหน้าและคุณสามารถพิมพ์หนึ่งในศูนย์ดังกล่าวได้
  7. คุณสามารถใช้ตรรกะการปัดเศษ / พื้น / เพดานที่คุณต้องการสำหรับทศนิยมตำแหน่งสุดท้าย
  8. -สำหรับคำตอบเชิงลบคุณจะต้องพิมพ์ชั้นนำ cนี้ไม่นับรวม แต่ก็เป็นทางเลือกของคุณถ้าคุณต้องการพิมพ์, +หรืออะไรหาคำตอบในเชิงบวก
  9. อนุญาตการหารทั้งจำนวนและโมดูลัสจำนวนเต็ม อย่างไรก็ตามโปรดจำไว้ว่าคุณถูก จำกัด ให้ใช้แบบดั้งเดิมยกเว้นว่าคุณเลือกที่จะใช้งานBigInteger/ BigDecimalไลบรารีของคุณเองซึ่งนับรวมกับความยาวโค้ดของคุณ
  10. คุณไม่จำเป็นต้องจัดการกับสิ่งbมีชีวิต0แม้ว่าคุณจะทำได้ถ้าคุณต้องการ โปรแกรมของคุณอาจเข้าสู่วงวนไม่สิ้นสุดหรือผิดพลาดหากb=0และคุณจะไม่ถูกลงโทษ
  11. การเปลี่ยนแปลงกฎเล็กน้อยต่อความคิดเห็น เพื่อให้แน่ใจว่าระดับการเล่นอยู่ในระดับขณะที่aและbรับประกันว่าจะเป็นจำนวนเต็ม 32 บิตคุณสามารถใช้จำนวนเต็มแบบยาว 64 บิต หากภาษาที่คุณเลือกมีจำนวนเต็มมากกว่า 64 บิตเป็นภาษาดั้งเดิมคุณไม่สามารถใช้ฟังก์ชันนั้นได้ (อ้างว่าเป็น 64 บิต)
  12. อีกจุดที่ไม่ชัดเจน (แต่ไม่ควรเปลี่ยนคำตอบที่ถูกต้องในปัจจุบัน): ในขณะที่cอาจถูกตีความว่าเป็นจำนวนตัวอักษรที่พิมพ์ออกมาหรือจำนวนช่องว่างหลังจุดทศนิยมโปรแกรมของคุณจะต้องใช้cวิธีใดวิธีหนึ่งที่เกี่ยวข้อง เพื่อตัดสินใจจำนวนอักขระที่จะพิมพ์ กล่าวอีกนัยหนึ่งdivide(2,3,2)ควรสั้นกว่าเอาท์พุทdivide(2,3,500); มันไม่โอเคที่จะพิมพ์ 500 cตัวอักษรโดยไม่คำนึงถึง
  13. ฉันไม่สนใจชื่อของฟังก์ชั่น dโอเคสำหรับการเล่นกอล์ฟ

อินพุต

ทั้งฟังก์ชั่นการโทรและการอ่านจากstdinได้รับการยอมรับ หากคุณอ่านstdinตัวอักษรใด ๆ ที่ไม่ได้อยู่ในชุด[-0123456789]จะถือว่าเป็นตัวคั่นอาร์กิวเมนต์

เอาท์พุต

อักขระstdoutตามที่อธิบายไว้ข้างต้น

ตัวอย่าง

สำหรับdivide(2,3,5)ทั้งหมดต่อไปนี้เป็นผลลัพธ์ที่ยอมรับได้:

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

อีกตัวอย่าง: สำหรับdivide(371,3,5)สิ่งต่อไปนี้เป็นผลลัพธ์ที่ยอมรับได้ทั้งหมด:

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

และสำหรับdivide(371,-3,5)สิ่งต่อไปนี้ล้วนเป็นสิ่งที่ยอมรับได้:

-123.6
-123.7
-123.66666
-123.66667

เพื่อประโยชน์ของสนามเด็กเล่นระดับคุณควรใช้ความยาวบิตสูงสุดเฉพาะที่สามารถนำมาใช้ (ดั้งเดิมหรืออย่างอื่น) เว้นแต่คุณจะเลื่อนการใช้งานที่ใหญ่กว่าของคุณเองเนื่องจากก) ในบางภาษาความยาวบิตดั้งเดิมนั้นแตกต่างกันไป สถาปัตยกรรมพื้นฐานและ b) ในบางภาษาจำนวนมากเป็นชนิดดั้งเดิม
Jonathan Van Matre

@JonathanVanMatre เพิ่มกฎ 11 ต่อความคิดเห็นของคุณ
durron597

1
คุณจะนับตัวเลขที่ถูกต้องได้อย่างไร ในตัวอย่างของคุณฉันเห็นสามหรือสี่ แต่ไม่เคยห้าเป็นอาร์กิวเมนต์สุดท้ายระบุ
Howard

@Howard ถ้าคุณทำ92,3,5คำตอบจะเป็นเช่นนั้น30.67
durron597

1
btw 370/3 = 123.333 lol
izabera

คำตอบ:


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

ผมต้องโพล่งเพื่อให้aหรือbอาจจะ -2147483648 เป็นบวกจำนวนเต็ม 32 บิตเท่านั้นนับรวม 2147483647 ว่าทำไมกลายเป็นa longอาจมีวิธีที่ดีกว่าในการจัดการกับผลลัพธ์เชิงลบ แต่ฉันรู้ว่าไม่มี ( doubleอาจจะได้รับสิ่งนี้เพื่อการทำงานabs(a) < abs(b)ตามที่พวกเขามี-0แต่เพียงส่วนเสริมเท่านั้นที่จะรักษาความแม่นยำ)

ทำไมต้องเป็นเลขสองไบต์ ฉันต้องการ 92 ไบต์สำหรับการคำนวณและ 36 สำหรับผู้ช่วยเหลือการพิมพ์ ( System.out.printแย่; โดยทั่วไป Java ไม่ได้เป็นกอล์ฟ)

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

วิธีการดังกล่าวเป็นแบบฝึกหัดที่พวกเราส่วนใหญ่เรียนที่โรงเรียนเพื่อสร้างตัวเลขทศนิยมตามที่ร้องขอ


การพิจารณาคดีอย่างเป็นทางการ: ฉันจะบอกว่าการเพิกเฉยInteger.MIN_VALUEไม่ได้เป็นเรื่องปกติ แต่longเป็นข้อมูลที่ดี
durron597

สั้นกว่ามาก ทำได้ดีมาก
durron597

@ durron597 ขอบคุณ ยังคงมีการพิมพ์ที่เข้มงวดและSystem.outทำให้ Java รู้สึกใหญ่ ;-) ยังเป็นความรู้สึกที่ดีว่ามีคำตอบอีกต่อไปแล้ว
TheConstructor

1
@ durron597 คุณขอฟังก์ชั่นโดยเฉพาะฉันเลยคิดว่ามันจะไม่นับ ถ้าฉันต้องใช้การนำเข้ามากกว่าอาจจะใช่
TheConstructor

1
อย่างน้อยก็ไม่มีตัวแปร $ สำหรับทุก ๆ ตัวแปร ;-)
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;}

พิมพ์cตัวเลขหลังจาก.

เอาท์พุทตัวอย่าง:

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 <= a <= 2147483647 เหมือนกันสำหรับ b การจัดการกับ-ความเจ็บปวด

รุ่นออนไลน์: ideone


สิ่งนี้ใช้ได้กับสิ่งมีชีวิต -2147483648 หรือไม่ ไม่ทราบว่าคอมไพเลอร์ c ดีพอที่จะบอกได้ว่าชนิดจำนวนเต็มใดถูกกำหนดให้กับพารามิเตอร์ของคุณ
TheConstructor

ขอบคุณที่ชี้นำ ทำงานอย่างถูกต้องสำหรับ -2147483647 <= a <= 2147483647 เหมือนกันสำหรับ b มีปัญหาเมื่อ = -2147483648 และ B a=-aเป็นบวกเนื่องจาก
izabera

ฉันพยายาม แต่ในที่สุดก็มีทางออกเดียวกับคุณ คุณสามารถบันทึกหนึ่งตัวละครโดยตระหนักว่าprintf("-")ผลตอบแทนที่ 1
โทมัส

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

มันทำงานโดยเพียงแค่แสดงผลหารของa/ bระหว่างวนรอบของcขั้นตอนaกลายเป็นส่วนที่เหลือคูณด้วย 10 ในแต่ละรอบซ้ำ

การสาธิต


สร้างผลลัพธ์แปลก ๆ เมื่อ a หรือ b เป็นค่าลบ
TheConstructor

ฉันแก้ไขข้อผิดพลาดสำหรับจำนวนลบ ขอบคุณ!
รัซวาน

เพิ่งพบโค้ด 112 เวอร์ชันของคุณ: 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;}}ดูค่าที่ส่งคืน
TheConstructor

ขอบคุณ ฉันยังอัปเดตเวอร์ชันของคุณและจัดการเพื่อชนะเพิ่ม 1 ไบต์
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]

วิธีนี้ไม่ได้ละเมิดกฎที่ระบุไว้


2

C: 72 ตัวอักษร

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

มันเกือบทั้งหมดทำในสิ่งที่ควรจะทำ อย่างไรก็ตามมันจะเป็นบางส่วนของคำตอบอื่น ๆ ที่นี่ให้คุณค่าหรือไม่แพงd(-2147483648,b,c)และd(a,-2147483648,c)เนื่องจากค่าสัมบูรณ์ของ -2147483648 อยู่นอกขอบเขตสำหรับคำแบบ 32 บิต


2

Perl, ไม่มีเลขคณิต, 274 ไบต์

นี่คือยุคลิดยาวส่วนที่มีแนวโน้มที่จะบริโภคในปริมาณที่ผิดปกติของหน่วยความจำ สิ่งที่ใกล้เคียงที่สุดในการคำนวณเลขทศนิยมคือการใช้การดำเนินการบิตเพื่อแยกวิเคราะห์

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

ตัวอย่าง:

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

เอาท์พุท:

-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

ทับทิม, 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

เวอร์ชั่นออนไลน์สำหรับการทดสอบ

เคล็ดลับคือการคูณaด้วยจำนวนที่ค่อนข้างสูงดังนั้นผลลัพธ์จึงเป็นจำนวนเต็มจำนวนเต็มของการดำเนินการจุดลอยตัว จากนั้นให้ใส่จุดและศูนย์ในตำแหน่งที่ถูกต้องในสตริงผลลัพธ์


ใช้งานได้กับ c มากกว่า 350 หรือไม่
durron597

ผมทดสอบกับ c = 1000 - รหัสให้ฉันคำตอบบางทีฉันควรตรวจสอบผลที่เกิดขึ้นจริง แต่ ...
เดวิดมานน์

2
จะgได้รับเกิน 64 บิตสำหรับขนาดใหญ่c? แก้ไข: ฉันคิดว่าคุณกำลังใช้BigIntegerที่นี่โดยปริยาย
durron597

ข้อผิดพลาดgเป็นสตริง แต่ก่อนที่คุณจะโทรหาto_sคุณได้สร้างตัวเลขในหน่วยความจำที่เกิน 64 บิต
durron597

1
นั่นเป็นที่เข้าใจ - และทำให้งานมีความท้าทายมากขึ้น (และน่าสนใจ)! ดีกว่าที่จะลบคำตอบหรือปล่อยให้คนอื่นมีตัวอย่างว่าจะไม่ใช้งานได้อย่างไร?
David Herrmann

1

หลาม 92 ไบต์:

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

ฉันคิดว่าการเล่นกอล์ฟบางอย่างเป็นไปได้มากขึ้น .....


2
จะeได้รับเกิน 64 บิตสำหรับ c ขนาดใหญ่? แก้ไข: ฉันคิดว่าคุณใช้BigIntegerที่นี่โดยปริยาย
durron597

1
@ durron597 ฉันสงสัยอย่างมากว่า มันไปที่ BigInt (Long in python) แต่ 2 ** 45 คือ 48 บิต นั่นเป็นสิ่งที่เพียงพอหรือไม่? ยิ่งกว่านั้นไพ ธ อนไม่มีสิ่งพื้นฐานดังนั้น ...
Maltysen

ถ้าa=5และc=400แล้วหลังจากที่e=10**cในฐานสิบหกจำนวน 333 ตัวเลขยาว มันเริ่มต้น8889e7dd7f43fc2f7900bc2eac756d1c4927a5b8e56bbcfc97d39bac6936e648180f47d1396bc905a47cc481617c7...นี้มากกว่า 64 บิต
durron597

@ durron597 400 ... ฉันต้องการมัน
ไหม

1
ใช่กฎข้อที่ 3 บอกว่าคุณต้องสนับสนุนอย่างน้อย 500 คน ... ฉันพยายามป้องกันวิธีการแก้ปัญหานี้
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);}

แนวคิดแบบเดียวกันกับที่ฉันใช้ในการนำไปใช้ของหลาม


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