Kesiri tekrarlanan ondalık sayıya dönüştürme


17

Bu meydan okuma neredeyse kutup ters ve biraz daha kolay olacağını düşünüyorum.

Senin görevin biçiminde iki tamsayı almak a/b(rasyonel bir sayı oluşturma) sonra sayı tam olarak ondalık sayı olarak çıktı.

Örneğin, giriş 1/3yapacak olsaydınız:

0.33333333333333333

Ve isteğe bağlı bir baştaki 0 ​​ile 3s zaman sonuna kadar yazdırmaya devam eder. ( Yalnızca diliniz aynı satırda yazdırmaya izin vermiyorsa, satır başına bir karakter de yazdırabilirsiniz .)

İçin davranışı x/0tanımsız olacaktır. Tekrar etmeyen gibi görünen bir sayı için (örneğin, diyelim 5/4) aslında tekrar eder. Aşağıdaki iki formdan herhangi biri aşağıdakiler için kabul edilebilir 5/4:

1.25000000000000000
1.24999999999999999

(Tam sayılarla aynı 1.9999999veya 2.000000)

Fraksiyonu en basit şeklinde olabilir, ve aya da bnegatif olabilir (Not -a/b = -(a/b), -a/-b = a/b, a/-b = -a/bve -.6249999geçersiz fakat -0.6249999kabul edilebilir, ama yine de kullanabilir.


Unix kullanabilir miyiz bc, yoksa bu hile mi?
David R Tribble

Golf oynamaya devam etmeden önce cevabım: a/ veya bnegatif olabilir mi?
Dennis

@Dennis Evet, ancak aveya b(veya her ikisi birden) negatif olabilir)

@DavidRTribble Bence bu standart bir boşluk, yani hayır.

En son düzenlemeniz, baştaki sıfırların pozitif sayılarla iyi olduğunu, ancak negatif sayıların olmadığını söylüyor mu? Eğer öyleyse, bunun nedeni nedir?
Geobits

Yanıtlar:


2

CJam, 38 37 bayt

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

Nasıl çalışır

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)

Çift bölme kullandığınız için bu büyük sayılar için tamamen kırılmış değil mi?
orlp

@orlp: Tamamen. Şimdi düzeltildi.
Dennis

6

C, 108 79

Düzenle Negatif sayılarla çalışmak için değiştirildi.

Stdin'den girdi. Eski K & R tarzı.

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

Yakut, 83 69 102 91 89 bayt

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

Bilgisayarın tamsayı bölümüne göre manuel tamsayı bölümünün basit uygulanması.

Golfteki yardım için @blutorange'a teşekkürler.

Düzenle: Negatif sayılar içerecek şekilde çözüm düzeltildi.


2
Ruby'deki bazı kısayolları kullanarak, bunu 66 bayta düşürebilirsiniz: ->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}Bunu ruby ​​ile ilgili seviyorum.
blutorange

Vay canına, çok şey öğrendim, teşekkürler! ?/Karakterleri belirtmeyi hatırlamadım , ne de $><<yazdırmayı veya loopanahtar kelimeyi bilmiyordum . Çok teşekkürler!!
rorlork

1
Birisi işaret edene kadar bu hilelerin çoğunu bilmiyordum. $>kısa $stdoutve <<operatördür. İkinci satıra bir bayt daha kaydederek c*d<0&&$><<?-; 3. / 4. satırı birleştirerek birkaç bayt ve son satırdan $><<a/b<<?.sonraki boşluğu kaldırarak bir kaç bayt <<. Ve işte 91 bayta düşürmek için bir fikir: ->s{a,b=s.scan(/\d+/).map &:to_i;1==s.count(?-)&&$><<?-;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}(yakut 2.2.0)
blutorange

Sözdizimi $><<a/bdüzgün çalışmadı, bu yüzden boşluğu oraya koydum. Gerisi iyi görünüyor, çok teşekkür ederim!
rorlork

1
Hala ilgileniyorsanız, ikinci satırı kısaltmak için kullanılabilecek yakut 2.1'den beri (yaklaşık 10 dakika önce öğrendiğim) rasyonel bir literal ( Rational(2,3) == 2/3r) var: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){}}

Algoritma basittir; zor kısmı baskı işine başlamıştı. Sonunda, yazdırmak için her adım arasında bir saniye bilgisayar uyku vardı.

Genişletilmiş, çalıştırılabilir sürüm

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

Çıktının bir yıkama problemi olsa da, iki bayt tıraş edecek 9ms için uyuyarak çıktıyı göstermeyi başardım.

@Büyük olasılıkla donanıma veya işletim sistemine bağlıdır; bilgisayarım 250ms veya daha kısa bir sürede çalışmaz.
Ypnypn

2

R 103 137 109 103

Bununla biraz daha mutlu. Bir ayırıcı ile taramayı kullanarak çok fazla bayt kaydedin. Hala iyileştirilmesi gereken bir yer olabilir. Değiştirilen <-ile =. Bununla her zaman iyi şanslar olmadı, ama bu sefer işe yaradı.

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

Test çalıştırmaları

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

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

Oldukça basit:

  • Pay ve paydayı girin
  • Ondalık noktadan sonra 1 basamaklı bölümü girin, ardından son basamağı çıkarın (örn. -1/3-> -0.)
  • Mutlak değerleri al *
  • Döngü:
    • Payda paylaştırıldıktan sonra pay kaldı
    • Payı 10 ile çarp
    • Sonraki basamak olarak çıktı tamsayı bölümü

* (Hesaplama abirkaç bayt kaydetmek için döngü içinde taşınmasına rağmen )

Düzenleme: Negatif kesirler> -1 ile düzeltildi.


0

Python 2.7, 209 bayt

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

Düzenle:

Şimdi istendiği gibi aynı satırdaki tüm karakterleri çıktılar.

edit2:

Şimdi, istendiği gibi komut satırı bağımsız değişkeninden kesri okur :)


1
Birkaç ipucu: 1) mapListe anlamak yerine kullanmak biraz tasarruf sağlar; 2) parantez içine gerekmez m*a, onun konumların hiçbirinde olarak *, %ve /hepsi aynı önceliğe ve sola birleşim vardır; 3) 3. satırdaki 0 ​​veya nokta mantığına sadeleştirilebilir "0."[m==1], çünkü yine de yazdırıyorsunuz; 4) muhtemelen sayısal argümanları gerektiğinde backticks ile dizeye ayarlamak o=stdout.writeve dönüştürmek için karakterleri kaydeder .
DLosc

1
Ayrıca, kod negatiflerle çalışmıyor gibi görünüyor: yerine 1/-3verir . -1.666666666-0.333333333
DLosc
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.