แปลงเศษส่วนเป็นทศนิยมซ้ำ


17

เกือบจะตรงกันข้ามขั้วถ้าความท้าทายนี้และฉันสงสัยว่ามันจะง่ายขึ้นเล็กน้อย

งานของคุณคือการใช้จำนวนเต็มสองจำนวนในรูปแบบa/b(การขึ้นรูปจำนวนตรรกยะ) แล้วส่งออกจำนวนทศนิยม

ตัวอย่างเช่นถ้าคุณป้อนข้อมูล1/3มันจะส่งออก:

0.33333333333333333

และจะเก็บในการพิมพ์ 3s จนกว่าจะสิ้นสุดของเวลากับตัวเลือกชั้นนำ 0. (คุณยังสามารถพิมพ์หนึ่งตัวอักษรต่อบรรทัดถ้าและเพียงถ้าภาษาของคุณไม่อนุญาตให้มีการพิมพ์ในบรรทัดเดียวกัน.)

พฤติกรรมของx/0จะไม่ได้กำหนด สำหรับตัวเลขที่ดูเหมือนว่ามันไม่ซ้ำ (เช่นพูด5/4) มันจะทำซ้ำจริง ๆ สองรูปแบบต่อไปนี้จะยอมรับได้สำหรับ5/4:

1.25000000000000000
1.24999999999999999

(เช่นเดียวกันกับจำนวนเต็ม1.9999999หรือ2.000000)

ส่วนที่ไม่อาจอยู่ในรูปแบบที่ง่ายและaหรือbอาจจะเป็นเชิงลบ (หมายเหตุ-a/b = -(a/b), -a/-b = a/b, a/-b = -a/bและ-.6249999ไม่ถูกต้อง แต่-0.6249999เป็นที่ยอมรับ แต่คุณยังสามารถใช้


เราใช้ Unix bcได้หรือว่าโกง?
David R Tribble

ก่อนที่ฉันจะตีกอล์ฟคำตอบของฉัน: สามารถaและ / หรือbลบ?
เดนนิส

@Dennis ใช่ แต่อย่างใดอย่างหนึ่งaหรือb(หรือทั้งสองอย่าง) อาจเป็นค่าลบ)

@ DavidRTribble ฉันคิดว่านั่นเป็นช่องโหว่มาตรฐานดังนั้นไม่

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

คำตอบ:


2

CJam, 38 37 ไบต์

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

มันทำงานอย่างไร

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)

เนื่องจากคุณใช้การแบ่งสองชั้นจะไม่แตกทั้งหมดสำหรับจำนวนมากหรือไม่
orlp

@orlp: เต็มเปา ตอนนี้ได้รับการแก้ไขแล้ว
เดนนิส

6

C, 108 79

แก้ไขดัดแปลงเพื่อทำงานกับจำนวนลบ

ข้อมูลจาก stdin สไตล์ K&R แบบเก่า

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 ไบต์

->s{a,b=s.scan(/\d+/).map &:to_i
eval(s+?r)<0&&$><<?-
$><<a/b<<?.
loop{a=a%b*10
$><<a/b}}

ใช้งานง่ายของการหารจำนวนเต็มแบบแมนนวลตามการแบ่งจำนวนเต็มของคอมพิวเตอร์

ขอบคุณ @blutorange สำหรับความช่วยเหลือในการเล่นกอล์ฟ

แก้ไข: แก้ไขโซลูชันเพื่อรวมจำนวนลบ


2
ด้วยการใช้ทางลัดบางอย่างในทับทิมคุณสามารถลดขนาดได้ถึง 66 ไบต์: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}ฉันรักสิ่งนี้เกี่ยวกับทับทิม
blutorange

ว้าวฉันเพิ่งเรียนรู้หลายสิ่งหลายอย่างขอบคุณ! ฉันจำไม่ได้ว่า?/จะแสดงถึงตัวอักษรและฉันไม่รู้เกี่ยวกับ$><<การพิมพ์หรือloopคำหลัก ขอบคุณมาก!!
rorlork

1
คุณยินดีฉันไม่ทราบเกี่ยวกับเทคนิคเหล่านี้มากมายจนบางคนชี้ให้เห็น $>สั้นสำหรับ$stdoutและ<<เป็นโอเปอเรเตอร์ คุณสามารถบันทึกอีกหนึ่งไบต์ในบรรทัดที่สองโดยเปลี่ยนเป็นc*d<0&&$><<?-; สองสามไบต์โดยการรวมบรรทัดที่ 3 / 4th $><<a/b<<?.และอีกหนึ่งโดยการลบช่องว่างหลังจาก<<ในบรรทัดสุดท้าย และนี่เป็นแนวคิดที่จะนำมาไว้ที่ 91 ไบต์: ->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

ไวยากรณ์สำหรับการ$><<a/bทำงานไม่ถูกต้องนั่นเป็นสาเหตุที่ฉันใส่ที่นั่น ที่เหลือดูดีขอบคุณมาก!
rorlork

1
หากคุณสนใจยังมีตัวอักษรเหตุผล ( Rational(2,3) == 2/3r) ตั้งแต่ทับทิม 2.1 (ที่ฉันได้เรียนรู้ประมาณ 10 นาทีที่ผ่านมา) ที่สามารถใช้เพื่อย่อบรรทัดที่สอง: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){}}

อัลกอริทึมตรงไปตรงมา; ส่วนที่ยุ่งยากก็คือการพิมพ์ให้ใช้งานได้ ในท้ายที่สุดฉันมีคอมพิวเตอร์พักหนึ่งวินาทีระหว่างแต่ละขั้นตอนเพื่อให้สามารถพิมพ์ได้

เวอร์ชันที่ขยายและรันได้

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

ในขณะที่เอาต์พุตมีปัญหาการฟลัชชิงฉันสามารถรับมันเพื่อแสดงเอาต์พุตโดยการนอนเป็นเวลา 9ms ซึ่งจะโกนสองไบต์

@Snowman มันอาจขึ้นอยู่กับฮาร์ดแวร์หรือระบบปฏิบัติการ คอมพิวเตอร์ของฉันจะไม่ทำงานด้วยเวลาน้อยกว่า 250ms
Ypnypn

2

R, 103 137 109 103

รู้สึกมีความสุขมากขึ้นในตอนนี้ การใช้การสแกนด้วยตัวคั่นบันทึกได้หลายไบต์ อาจยังมีห้องพักสำหรับการปรับปรุง แทนที่ด้วย<- =ไม่เคยโชคดีที่สุดมาก่อน แต่มันได้ผลในครั้งนี้

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

ทดสอบการทำงาน

> 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 ไบต์

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

ตรงไปตรงมาสวย:

  • ใส่ตัวเศษและส่วน
  • แสดงผลหารด้วย 1 หลักหลังจากจุดทศนิยมแล้วถอดหลักสุดท้าย (เช่น-1/3-> -0.)
  • รับค่าสัมบูรณ์ *
  • ห่วง:
    • ตัวเศษจะเหลืออยู่หลังจากหารตัวส่วน
    • ตัวคูณทวีคูณ 10
    • จำนวนผลคูณของจำนวนเต็มเป็นตัวเลขถัดไป

* (แม้ว่าการคำนวณaจะถูกย้ายภายในลูปเพื่อบันทึกสองสามไบต์)

แก้ไข:แก้ไขข้อบกพร่องด้วยเศษส่วนเชิงลบ> -1


0

Python 2.7, 209 ไบต์

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

แก้ไข:

ตอนนี้เอาต์พุตอักขระทั้งหมดในบรรทัดเดียวกันตามที่ถาม

edit2:

ตอนนี้อ่านเศษส่วนจากอาร์กิวเมนต์บรรทัดคำสั่งตามที่ร้องขอ :)


1
เคล็ดลับเล็ก ๆ น้อย ๆ : 1) การใช้mapแทนความเข้าใจในรายการจะช่วยประหยัดได้เล็กน้อย 2) ไม่จำเป็นต้องวงเล็บรอบm*aในสถานที่ของตนเช่น*, %และ/มีทั้งหมดความสำคัญเหมือนกันและเชื่อมโยงซ้าย; 3) ตรรกะ 0 หรือจุดบนบรรทัดที่ 3 สามารถทำให้ง่าย"0."[m==1]ขึ้นเนื่องจากคุณเพิ่งพิมพ์มันต่อไป 4) อาจจะบันทึกตัวอักษรเพื่อตั้งค่าo=stdout.writeและแปลงอาร์กิวเมนต์ตัวเลขเป็นสตริงด้วย backticksตามต้องการ
DLosc

1
นอกจากนี้รหัสไม่ปรากฏในการทำงานกับเชิงลบ: 1/-3ให้แทน-1.666666666 -0.333333333
DLosc
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.