İlk periyodik rakamı sil


17

Hepimiz rasyonel bir sayı ondalık olarak yazıldığında sonucun ya sonlandığını (ya da sonunda) periyodik olduğunu biliyoruz. Örneğin, 41/42 ondalık olarak yazıldığında, sonuç

0.9 761904 761904 761904 761904 761904 761904 761904 ...

ilk basamak dizisini ve 0.9ardından 761904tekrar tekrar tekrarlanan diziyi içerir . (Bunun için uygun bir gösterim 0.9(761904), parantezlerin tekrarlayan basamak bloğunu çevrelediği yerdir.)

Bu meydan okumadaki amacınız pozitif bir rasyonel sayı almak, tekrarlanan sekansın bir parçası olan ilk haneyi silmek ve ortaya çıkan rasyonel sayıyı döndürmektir. Örneğin, bunu 41/42 olarak yaparsak,

0.9  61904 761904 761904 761904 761904 761904 761904 ...

ya da 0.9(619047)kısaca 101/105.

Rasyonel sayının 1/4 = 0.25yaptığı gibi bir sonlu ondalık genişlemesi varsa , hiçbir şey olmamalıdır. 1/4 olarak 0.250000000...ya 0.249999999...da böyle düşünebilirsiniz, ancak her iki durumda da, yinelenen parçanın ilk basamağını silmek sayıyı değiştirmeden bırakır.

ayrıntılar

  • Giriş, pay ve paydayı temsil eden bir pozitif tamsayı çifti olarak veya (seçtiğiniz diliniz izin veriyorsa ve isterseniz) bir çeşit rasyonel sayı nesnesi olarak pozitif bir rasyonel sayıdır.
  • Çıktı aynı zamanda her iki biçimde de rasyonel bir sayıdır. Sonuç bir tamsayı ise, rasyonel bir sayı yerine tamsayıyı döndürebilirsiniz.
  • Giriş olarak bir çift sayı alırsanız, bunların nispeten asal olduğunu varsayabilirsiniz; çıktı olarak bir çift sayı üretiyorsanız, bunların nispeten asal olmasını sağlamalısınız.
  • Tekrarlayan bir blok başlatan ilk rakamı bulduğunuza dikkat edin . Örneğin, 41/42 olarak yazılabilir, 0.97(619047)ancak bu 2041/2100 (ondalık genişleme ile 0.97(190476)) geçerli bir yanıt yapmaz .
  • Sen almak girişteki ilk periyodik rakamdır varsayabiliriz sonra yapım ondalık noktasının 120/11= 10.909090909...(ilk periyodik haneli düşünülebilir: geçersiz giriş 0bölgesi 10). Böyle bir girdide istediğiniz her şeyi yapabilirsiniz.
  • Bu : en kısa çözüm kazanır.

Test senaryoları

41/42 => 101/105
101/105 => 193/210
193/210 => 104/105
104/105 => 19/21
1/3 => 1/3
1/4 => 1/4
2017/1 => 2017/1
1/7 => 3/7
1/26 => 11/130
1234/9999 => 2341/9999

2017Bunun yerine geri dönebilir miyiz 2017/1?
JungHwan Min

Evet, rasyonel sayı işini yapıyorsanız. (Eğer tamsayılar çifti işini yapıyorsanız, o çift dışında başka ne döndüreceğinizden emin değilim (2017,1).)
Misha Lavrov

Girdi azaltılabilir mi (tamamen basitleştirilmemiş)? Örneğin 2/4, girdide olabilir mi?
user202729

1
Giriş ise 120/11doğru cevap 111/11veya 210/11?
kasperd

2
@kasperd Huh, bu düşünmediğim bir durum ... 111/11Şu anda en çok oylanan cevabın geri gelmesi dışında şunu söylemek isterim 210/11, bu yüzden mevcut cevapları geçersiz kılmaktan kaçınmanıza izin vereceğim.
Misha Lavrov

Yanıtlar:


13

Wolfram Dili (Mathematica) , 59 bayt

FromDigits@MapAt[RotateLeft@*List@@#&,RealDigits@#,{1,-1}]&

Çevrimiçi deneyin!

açıklama

RealDigits@#

Girişin ondalık basamağını bulun.

MapAt[RotateLeft@*List@@#&, ..., {1,-1}]

Tekrarlayan rakamlar varsa, RotateLeftbunlar. ( List@@#rasyonel sayı sonlanıyorsa kodun son ondalık basamağı döndürmeye çalışmasını önler).

FromDigits@

Rasyonel hale getirin.


Gerçekten çok zekice!
DavidC

6

Jöle , 36 32 31 30 bayt

Outgolfer Erik sayesinde -1 bayt !

ọ2,5Ṁ⁵*©×Ɠ÷µ×⁵_Ḟ$+Ḟ,®×³+.Ḟ÷g/$

Çevrimiçi deneyin!

Doğru olmalı. Kayan nokta belirsizliği için 3 bayt ekleyin +.Ḟ.

Girişin indirgenemez olmasına güvenir.


açıklama

Bu şunlara dayanır:

  • Payın n/den basit haliyle olmasına izin verin . Ardından ọ2,5Ṁuygulanan bağlantı d, sayı tabanı noktasından sonraki periyodik olmayan basamağın sayısını verecektir.

ọ2,5Ṁ⁵*©×Ɠ÷µ×⁵_Ḟ$+Ḟ,®×³+.Ḟ÷g/$     Main link (monad take d as input)

    Ṁ                              Maximum
ọ                                  order of
 2,5                               2 or 5 on d
     ⁵*                            10 power
       ©                           Store value to register ®.
        ×Ɠ                         Multiply by eval(input()) (n)
          ÷                        Divide by first argument (d).
                                   Now the current value is n÷d×®.
           µ                       With that value,
            ×⁵                     Multiply by ⁵ = 10
              _Ḟ$                  subtract floor of self
                 +Ḟ                add floor or value (above)
                                   Given 123.45678, will get 123.5678
                                   (this remove first digit after `.`)
                   ,®              Pair with ®.
                     ׳            Scale
                       +.Ḟ         Round to integer
                          ÷g/$     Simplify fraction


@EriktheOutgolfer Teşekkürler!
user202729

5

Python 2 , 237 235 214 bayt

Bay Xcoder sayesinde -21 bayt

from fractions import*
F=Fraction
n,d=input()
i=n/d
n%=d
R=[]
D=[]
while~-(n in R):R+=n,;n*=10;g=n/d;n%=d;D+=g,
x=R.index(n)
r=D[x+1:]+[D[x]]
print i+F(`r`[1::3])/F('9'*len(r))/10**x+F("0."+"".join(map(str,D[:x])))

Çevrimiçi deneyin!

Giriş bir demet olarak yapılır (numerator, denominator); çıktı bir fractions.Fractionnesnedir.

Bu, yanıtın başlangıç ​​ve yinelenen basamaklarını elde etmek için uzun bölümlü bir yöntem kullanır, ardından ilk yinelenen basamağı sonuna taşır ve dize manipülasyonunu kullanır ve fraction.Fractionbir orana geri dönüştürür.

Ungolfed sürümü:

import fractions

num, denom = input()
integer_part, num = divmod(num, denom)

remainders = []
digits = []
current_remainder = num
while current_remainder not in remainders:
    remainders.append(current_remainder)
    current_remainder *= 10
    digit, current_remainder = divmod(current_remainder, denom)
    digits.append(digit)

remainder_index = remainders.index(current_remainder)
start_digits = digits[:remainder_index]
repeated_digits = digits[remainder_index:]

repeated_digits.append(repeated_digits.pop(0))

start_digits_str = "".join(map(str, start_digits))
repeated_digits_str = "".join(map(str, repeated_digits))

print(integer_part+int(repeated_digits_str)/fractions.Fraction('9'*(len(repeated_digits_str)))/10**len(start_digits_str)+fractions.Fraction("0."+start_digits_str))



1

Perl 6 , 102 bayt

{$/=.base-repeating;(+$0//$0~0)+([~]([$1.comb].rotate)/(9 x$1.chars)*.1**(($0~~/\.<(.*/).chars)if $1)}

Dene

Bir Rasyonel sayı alır ve bir Rasyonel veya Int numarası döndürür .

Expanded:

{  # bare block lambda with implicit Rational parameter 「$_」

  $/ = .base-repeating; # store in 「$/」 the two strings '0.9' '761904'

    # handle the non-repeating part
    (
      +$0        # turn into a number
      // $0 ~ 0  # if that fails append 0 (handle cases like '0.')
    )

  +

    # handle the repeating part
    (
          [~]( [$1.comb].rotate ) # rotate the repeating part
        /
          ( 9 x $1.chars )        # use a divisor that will result in a repeating number

        *

         # offset it an appropriate amount

         .1 ** (
           ( $0 ~~ / \. <( .* / ).chars # count the characters after '.'
         )

      if $1  # only do the repeating part if there was a repeating part
    )
}

Not uint64.Range.maxdaha büyük paydaları kullanmak için kadar paydaları kullanacaktır FatRat(9 x$1.chars) Deneyin .

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.