Chuyển một phân số thành số thập phân lặp lại


17

Gần như cực đối nghịch nếu thử thách này , và tôi nghi ngờ nó sẽ dễ dàng hơn một chút.

Nhiệm vụ của bạn là lấy hai số nguyên theo định dạng a/b(Hình thành số hữu tỷ) sau đó xuất số chính xác theo số thập phân.

Ví dụ: nếu bạn nhập dữ liệu 1/3, nó sẽ xuất:

0.33333333333333333

Và sẽ tiếp tục in 3 giây cho đến hết thời gian, với số 0 tùy chọn (Bạn cũng có thể in một ký tự trên mỗi dòng nếu và chỉ khi ngôn ngữ của bạn không cho phép in trên cùng một dòng.)

Hành vi cho x/0sẽ không được xác định. Đối với một số có vẻ như nó không lặp lại (Giống như, nói 5/4) nó thực sự lặp lại. Một trong hai hình thức sau đây sẽ được chấp nhận cho 5/4:

1.25000000000000000
1.24999999999999999

(Giống với số nguyên 1.9999999hoặc 2.000000)

Các phần có thể không ở dạng đơn giản nhất, và ahay bcó thể là tiêu cực (Lưu ý -a/b = -(a/b), -a/-b = a/b, a/-b = -a/b, và -.6249999là không hợp lệ, nhưng -0.6249999là chấp nhận được, nhưng bạn vẫn có thể sử dụng.


Chúng ta có thể sử dụng Unix bc, hay đó là gian lận?
David R Tribble

Trước khi tôi tiếp tục chơi golf câu trả lời của tôi: Có thể avà / hoặc blà tiêu cực?
Dennis

@Dennis Có, nhưng hoặc ahoặc b(hoặc cả hai) có thể âm tính)

@DavidRTribble Tôi nghĩ đó là một lỗ hổng tiêu chuẩn, nên không.

Có phải bản chỉnh sửa mới nhất của bạn nói rằng các số 0 đứng đầu đều ổn với các số dương, nhưng không phải là số âm? Nếu vậy, lý do cho điều đó là gì?
Geobits

Câu trả lời:


2

CJam, 38 37 byte

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

Làm thế nào nó hoạt động

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)

Vì bạn sử dụng phân chia kép nên điều này hoàn toàn bị phá vỡ cho số lượng lớn?
orlp

@orlp: Hoàn toàn. Bây giờ nó đã được sửa.
Dennis

6

C, 108 79

Chỉnh sửa Sửa đổi để làm việc với các số âm.

Đầu vào từ stdin. Phong cách K & R cũ.

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

Thực hiện đơn giản phân chia số nguyên thủ công dựa trên phân chia số nguyên của máy tính.

Cảm ơn @blutorange vì sự giúp đỡ trong việc chơi golf.

Chỉnh sửa: Đã sửa giải pháp để bao gồm số âm.


2
Bằng cách sử dụng một số phím tắt trong ruby, bạn có thể giảm xuống còn 66 byte: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}Tôi chỉ thích điều này về ruby.
blutorange

Wow, tôi vừa học được nhiều điều, cảm ơn bạn! Tôi không nhớ về ?/việc biểu thị các ký tự, tôi cũng không biết về $><<việc in hoặc looptừ khóa. Cảm ơn rất nhiều!!
rorlork

1
Không có gì, tôi cũng không biết về nhiều mánh khóe này cho đến khi có ai đó chỉ ra. $>là viết tắt của $stdout, và <<là một toán tử. Bạn có thể lưu thêm một byte trong dòng thứ hai bằng cách thay đổi nó thành c*d<0&&$><<?-; một vài byte bằng cách kết hợp dòng thứ 3/4 $><<a/b<<?.và một và thêm một dòng nữa bằng cách xóa khoảng trắng sau <<dòng cuối cùng. Và đây là một ý tưởng để giảm xuống còn 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

Cú pháp cho $><<a/bkhông hoạt động chính xác, đó là lý do tại sao tôi đặt không gian ở đó. Phần còn lại có vẻ tốt, cảm ơn bạn rất nhiều!
rorlork

1
Nếu bạn vẫn quan tâm, cũng có một nghĩa đen ( Rational(2,3) == 2/3r) từ ruby ​​2.1 (mà tôi đã học được khoảng 10 phút trước) có thể được sử dụng để rút ngắn dòng thứ hai:eval(s+?r)<0&&$><<?-
blutorange

2

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

Thuật toán rất đơn giản; phần khó khăn là làm cho việc in ấn hoạt động. Cuối cùng, tôi đã ngủ máy tính trong một giây giữa mỗi bước để nó có thể in.

Phiên bản mở rộng, có thể chạy được

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

Trong khi đầu ra không có vấn đề gì, tôi có thể làm cho nó hiển thị đầu ra bằng cách ngủ trong 9ms, nó sẽ cạo hai byte.

@Snowman Có lẽ nó phụ thuộc vào phần cứng hoặc HĐH; máy tính của tôi sẽ không hoạt động với ít hơn 250ms.
Ypnypn

2

R, 103 137 109 103

Bit hạnh phúc hơn với điều này bây giờ. Sử dụng quét với một dấu phân cách tiết kiệm rất nhiều byte. Có thể vẫn còn một số chỗ để cải thiện. Thay thế <-bằng =. Haven luôn luôn có may mắn nhất với điều này, nhưng nó đã làm việc lần này.

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

Chạy thử

> 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="")

Khá đơn giản:

  • Nhập tử số và mẫu số
  • Xuất ra thương số với 1 chữ số sau dấu thập phân, sau đó tắt chữ số cuối cùng (ví dụ: -1/3> -0.)
  • Lấy giá trị tuyệt đối *
  • Vòng:
    • Số là phần còn lại sau khi chia mẫu số
    • Nhân tử số với 10
    • Số nguyên đầu ra là số tiếp theo

* (Mặc dù tính toán cho ađã được di chuyển bên trong vòng lặp để lưu một vài byte.)

Chỉnh sửa: Đã sửa lỗi với phân số âm> -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

biên tập:

Bây giờ xuất ra tất cả các ký tự trên cùng một dòng, như đã hỏi.

chỉnh sửa2:

Bây giờ đọc phân số từ đối số dòng lệnh, theo yêu cầu :)


1
Một vài lời khuyên: 1) Sử dụng mapthay cho việc hiểu danh sách sẽ tiết kiệm được kha khá; 2) không cần ngoặc xung quanh m*atại các địa điểm của nó, như *, %/tất cả đều cùng độ ưu tiên và trái kết hợp; 3) logic 0 hoặc dấu chấm trên dòng 3 có thể được đơn giản hóa "0."[m==1], vì dù sao bạn cũng chỉ in nó; 4) có thể sẽ lưu ký tự để chỉ thiết lậpo=stdout.writechuyển đổi các đối số số thành chuỗi với backticks khi cần thiết.
DLosc

1
Ngoài ra, mã không xuất hiện để làm việc với phủ định: 1/-3đưa ra -1.666666666thay vì -0.333333333.
DLosc
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.