Thực hiện phân chia chính xác tùy ý


15

Thực hiện một chức năng divide(int a, int b, int c)in giá trị cơ sở 10 của a/b. không sử dụng bất kỳ thư viện dấu phẩy động cũng như BigInteger/ BigDecimalhoặc thư viện tương đương nào. Ít nhất ccác ký tự chính xác trong bộ 0123456789.phải được in, ngoại trừ ngoại lệ (có thể) ở điểm 4 bên dưới.

  1. abcó thể là bất kỳ số nguyên 32 bit nào. Cập nhật: Nếu, cho mục đích chơi gôn, bạn muốn có đầu vào là 64 bit nguyên thủy thì không sao, nhưng bạn không cần phải hỗ trợ toàn bộ phạm vi dữ liệu 64 bit.
  2. Bạn không cần kiểm tra xem điều đó ccó tích cực không (mặc dù hy vọng chương trình của bạn không gặp sự cố) nếu không.
  3. Giới hạn trên được hỗ trợ tối thiểu c500. Không sao nếu chương trình của bạn không hỗ trợ các giá trị cở trên 500, nhưng cũng không sao nếu có.
  4. Đối với các số chia đều, lựa chọn của bạn là in các số 0 bổ sung (dựa trên giá trị của c) hoặc không có gì.
  5. Bạn không cần phải có khả năng sử dụng chức năng để thực hiện bất kỳ nhiệm vụ nào nữa với thương số, mục tiêu duy nhất là in ấn.
  6. Đối với các số giữa -11, bạn có nên chọn hàng đầu hay không 0. Tuy nhiên, đây là tình huống duy nhất mà việc in số 0 đứng đầu được chấp nhận và bạn chỉ có thể in một số không như vậy.
  7. Bạn có thể sử dụng bất kỳ logic làm tròn / sàn / trần nào bạn thích cho vị trí thập phân cuối cùng.
  8. Đối với một câu trả lời tiêu cực, bạn phải in một hàng đầu -. Điều này không được tính vào c. Tuy nhiên, nó là sự lựa chọn của bạn nếu bạn muốn in , +hoặc không có gì cho một câu trả lời tích cực.
  9. Phân chia số nguyên và mô đun số nguyên đều được cho phép. Tuy nhiên, hãy nhớ rằng bạn bị hạn chế đối với các nguyên thủy, trừ khi bạn chọn triển khai thư viện BigInteger/ BigDecimalthư viện riêng của mình , tính theo chiều dài mã của bạn.
  10. Bạn không cần phải xử lý b0, mặc dù bạn có thể nếu bạn muốn. Chương trình của bạn có thể nhập một vòng lặp vô hạn hoặc sự cố, nếu b=0, và bạn sẽ không bị phạt.
  11. Thay đổi quy tắc nhẹ trên mỗi bình luận. Để đảm bảo sân chơi bình đẳng, trong khi ab được đảm bảo là số nguyên 32 bit, bạn có thể sử dụng số nguyên dài 64 bit. Nếu ngôn ngữ được chọn của bạn vượt quá số nguyên 64 bit dưới dạng nguyên thủy, thì tại bất kỳ thời điểm nào bạn cũng không thể sử dụng chức năng đó (giả sử ngôn ngữ đó được giới hạn ở mức 64 bit).
  12. Tuy nhiên, một điểm khác không rõ ràng (không nên thay đổi bất kỳ câu trả lời hợp lệ hiện tại nào): mặc dù ccó thể được hiểu là số lượng ký tự được in hoặc số khoảng trắng sau dấu thập phân, chương trình của bạn phải sử dụng ccách nào đó theo cách phù hợp để quyết định có bao nhiêu ký tự để in. Nói cách khác, divide(2,3,2)nên đầu ra ngắn hơn nhiều so với divide(2,3,500); Không thể in 500 ký tự mà không quan tâm đến c.
  13. Tôi thực sự không quan tâm đến tên của chức năng. dlà ổn cho mục đích chơi golf.

Đầu vào

Cả một cuộc gọi chức năng và đọc từ stdinđược chấp nhận. Nếu bạn đọc từ stdin, bất kỳ ký tự nào không có trong bộ [-0123456789]đều được coi là dấu phân cách đối số.

Đầu ra

Nhân vật stdoutnhư được mô tả ở trên.

Thí dụ

cho divide(2,3,5), tất cả những điều sau đây là đầu ra chấp nhận được:

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

Một ví dụ khác: cho divide(371,3,5)các mục sau đây là tất cả các đầu ra có thể chấp nhận:

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

Và đối với divide(371,-3,5)những điều sau đây đều được chấp nhận:

-123.6
-123.7
-123.66666
-123.66667

Vì lợi ích của một sân chơi bình đẳng, có thể là khôn ngoan khi đưa ra độ dài bit tối đa cụ thể có thể được sử dụng (nguyên thủy hoặc theo cách khác) trừ khi bạn thực hiện triển khai lớn hơn của riêng mình, bởi vì a) trong một số ngôn ngữ, độ dài bit nguyên thủy thay đổi tùy thuộc vào kiến trúc cơ bản và b) trong một số ngôn ngữ loại số lớn nguyên thủy.
Jonathan Van Matre

@JonathanVanMatre Đã thêm quy tắc 11 cho mỗi bình luận của bạn
durron597

1
Làm thế nào để bạn đếm chữ số chính xác ? Trong ví dụ của bạn, tôi thấy ba hoặc bốn nhưng không bao giờ năm như đối số cuối cùng chỉ ra.
Howard

@Howard, nếu bạn đã 92,3,5trả lời, chẳng hạn,30.67
durron597

1
btw 370/3 = 123.333 lol
izabera

Câu trả lời:


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

Tôi đã phải ứng biến để ahoặc bcó thể là -2147483648 vì số nguyên 32 bit dương chỉ được tính vào 2147483647, đó là lý do tại sao atrở thành a long. Có thể có một cách tốt hơn để xử lý các kết quả tiêu cực, nhưng tôi biết không ai doublecó thể làm điều này hoạt động abs(a) < abs(b)như họ có -0nhưng chỉ có phần bổ sung mới giữ được độ chính xác).

Tại sao hai số byte? Tôi cần 92 byte cho phép tính toán và 36 byte cho trình trợ giúp in ( System.out.printhút; nói chung Java không phải là golf).

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

Phương pháp này về cơ bản thực hiện những gì hầu hết chúng ta đã học ở trường để tạo ra các chữ số thập phân được yêu cầu.


Phán quyết chính thức: Tôi sẽ nói rằng bỏ qua Integer.MIN_VALUElà không ổn nhưng đó longlà đầu vào là tốt.
durron597

Nó ngắn hơn rất nhiều. Hoàn thành tốt
durron597

@ durron597 cảm ơn bạn. Vẫn là kiểu gõ nghiêm ngặt và System.outlàm cho Java cảm thấy cồng kềnh ;-) Vẫn là một cảm giác tốt, rằng đã có câu trả lời dài hơn được đăng.
TheConstructor

1
@ durron597 bạn đặc biệt yêu cầu một chức năng vì vậy tôi nghĩ rằng nó sẽ không được tính. Nếu tôi phải sử dụng nhập khẩu hơn có lẽ có.
TheConstructor

1
Ít nhất là không có $ cho mỗi biến số ;-)
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;}

in các cchữ số sau.

đầu ra ví dụ:

d(2,3,5);
0.66666

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

d(24352345,31412,500);
775.25611231376543995925124156373360499172290844263338851394371577740990704189481726728638736788488475741754743410161721635043932255189099707118298739335285878008404431427479943970457150133706863618999108620909206672609193938622182605373742518782630841716541449127721889723672481854068508850120972876607665860180822615560932127849229593785814338469374761237743537501591748376416656055010823888959633261174073602444925506175983700496625493441996689163377053355405577486310963962816757926906914554947153953

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

nên hoạt động cho -2147483647 <= a <= 2147483647, tương tự cho b. xử lý -là một nỗi đau.

phiên bản trực tuyến: ideone


Điều này có hoạt động cho một -2147483648 không? Không biết trình biên dịch c đủ tốt để cho biết loại số nguyên nào được gán cho tham số của bạn.
TheConstructor

Cảm ơn đã chỉ ra điều đó. nó hoạt động chính xác cho -2147483647 <= a <= 2147483647, tương tự cho b. có vấn đề khi a = -2147483648 và b dương do a=-a.
izabera

Tôi đã cố gắng nhưng cuối cùng cũng có giải pháp tương tự như bạn. Bạn có thể lưu một ký tự bằng cách nhận ra rằng printf("-")trả về 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;}

Nó hoạt động bằng cách đơn giản xuất ra thương số của a/ btrong một vòng các cbước, atrở thành phần còn lại nhân với 10 ở mỗi lần lặp.

BẢN GIỚI THIỆU


Tạo ra kết quả lạ khi a hoặc b âm tính
TheConstructor

Tôi đã sửa lỗi cho số âm. Cảm ơn!
Razvan

Chỉ tìm thấy một phiên bản 112 của mã của bạn: 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;}}xem giá trị trả về
TheConstructor

Cảm ơn. Tôi thậm chí đã cập nhật phiên bản của bạn và quản lý để giành thêm 1 byte.
Razvan

2

Con trăn 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]

Giải pháp này không vi phạm bất kỳ quy tắc đã nêu.


2

C: 72 ký tự

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

Nó gần như hoàn toàn làm những gì nó phải làm. Tuy nhiên, như một số câu trả lời khác ở đây đưa ra các giá trị thắng hoặc thất bại d(-2147483648,b,c)d(a,-2147483648,c)vì giá trị tuyệt đối của -2147483648 nằm ngoài giới hạn cho một từ 32 bit.


2

Perl, không có số học, 274 byte

Đây là sự phân chia dài của Euclide , có khả năng tiêu thụ một lượng bộ nhớ bất thường. Cách gần nhất để toán học về các số có dấu phẩy động là sử dụng các phép toán bit để phân tích chúng.

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

Ví dụ:

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

Đầu ra:

-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

Hồng ngọc, 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

Phiên bản trực tuyến để thử nghiệm.

Thủ thuật là nhân a với số khá cao, do đó, kết quả chỉ là bội số nguyên của phép toán dấu phẩy động. Sau đó, điểm và các số không phải được chèn vào đúng vị trí trong chuỗi kết quả.


Điều này có làm việc cho c lớn hơn 350 không?
durron597

Tôi đã thử nghiệm nó với c = 1000 - mã đã cho tôi một câu trả lời, có lẽ tôi nên kiểm tra kết quả thực tế mặc dù ...
David Herrmann

2
không gvượt quá 64 bit cho lớn c? Chỉnh sửa: Tôi nghĩ rằng bạn đang ngầm sử dụng BigIntegerở đây
durron597

Err, glà một chuỗi, nhưng trước khi bạn gọi, to_sbạn đã tạo một số trong bộ nhớ có kích thước vượt quá 64 bit
durron597

1
Đó là điều dễ hiểu - và làm cho nhiệm vụ trở nên thách thức hơn (và thú vị)! Là tốt hơn để xóa câu trả lời hoặc để lại cho người khác để có một ví dụ về cách không thực hiện nhiệm vụ?
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:]

tôi nghĩ rằng có thể chơi gôn nhiều hơn .....


2
không evượt quá 64 bit cho c lớn? Chỉnh sửa: Tôi nghĩ rằng bạn đang ngầm sử dụng BigIntegerở đây.
durron597

1
@ durron597 tôi rất nghi ngờ điều đó. Nó đi đến BigInt (Long in python) nhưng 2 ** 45 là 48 bit. Như vậy là đủ? Ngoài ra, trăn KHÔNG có người nguyên thủy nên ...
Maltysen

Nếu a=5c=400sau đó e=10**c, trong hex, số dài 333 chữ số. Nó bắt đầu 8889e7dd7f43fc2f7900bc2eac756d1c4927a5b8e56bbcfc97d39bac6936e648180f47d1396bc905a47cc481617c7...này là hơn 64 bit.
durron597

@ durron597 400 ... tôi có cần điều đó không
Maltysen

1
Có quy tắc 3 nói rằng bạn cần hỗ trợ tối thiểu 500 ... Tôi đã cố gắng ngăn chặn giải pháp (tầm thường) này.
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);}

Cùng một ý tưởng mà tôi đã sử dụng trong việc thực hiện python của mình


Rất đẹp! Tuy nhiên, nó gặp sự cốd(-2147483648,-1,10)
durron597
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.