Elimina la prima cifra periodica


17

Sappiamo tutti che ogni volta che un numero razionale è scritto in decimale, il risultato è terminato o (eventualmente) periodico. Ad esempio, quando 41/42 è scritto in decimale, il risultato è

0.9 761904 761904 761904 761904 761904 761904 761904 ...

con una sequenza iniziale di cifre 0.9seguita dalla sequenza 761904ripetuta più volte. (Una nota utile per questo è 0.9(761904)dove le parentesi circondano il blocco di cifre ripetute.)

Il tuo obiettivo in questa sfida è prendere un numero razionale positivo, eliminare la prima cifra che fa parte della sequenza ripetuta e restituire il numero razionale risultante. Ad esempio, se facciamo questo al 41/42, otteniamo

0.9  61904 761904 761904 761904 761904 761904 761904 ...

o 0.9(619047)in breve, che è 101/105.

Se il numero razionale ha un'espansione decimale finale, come 1/4 = 0.25, non dovrebbe succedere nulla. Puoi pensare a 1/4 come 0.250000000...o come 0.249999999...ma in entrambi i casi, l'eliminazione della prima cifra della parte ripetuta lascia invariato il numero.

Dettagli

  • L'input è un numero razionale positivo, o come una coppia di numeri interi positivi che rappresentano il numeratore e il denominatore, oppure (se la tua lingua preferita lo consente e vuoi farlo) come una sorta di oggetto di numero razionale.
  • L'output è anche un numero razionale, anche in entrambe le forme. Se il risultato è un numero intero, è possibile restituire il numero intero anziché un numero razionale.
  • Se prendi una coppia di numeri come input, puoi presumere che siano relativamente primi; se produci una coppia di numeri come output, devi renderli relativamente primi.
  • Fai attenzione a trovare la prima cifra che inizia un blocco ripetuto. Ad esempio, si potrebbe scrivere 41/42 come 0.97(619047)ma ciò non rende 2041/2100 (con l'espansione decimale 0.97(190476)) una risposta valida.
  • Si può presumere che nell'input che si ottiene, la prima cifra periodica sia dopo il punto decimale, rendendo 120/11= 10.909090909...input non valido: (la sua prima cifra periodica può essere considerata 0in 10). Puoi fare tutto ciò che ti piace su tale input.
  • Questo è : vince la soluzione più breve.

Casi test

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

Possiamo tornare 2017invece di 2017/1?
JungHwan Min

Sì, se stai facendo la cosa del numero razionale. (Se stai facendo la cosa della coppia di numeri interi, allora non sono sicuro di cos'altro torneresti tranne la coppia (2017,1).)
Misha Lavrov,

L'ingresso può essere riducibile (non completamente semplificato)? Ad esempio, può 2/4succedere nell'input?
user202729

1
Se input è 120/11la risposta corretta 111/11o 210/11?
Kasperd,

2
@kasperd Huh, è un caso a cui non avevo pensato ... vorrei dire, 111/11tranne che la risposta più votata al momento ritorna 210/11, quindi ti lascerò scegliere per evitare di invalidare le risposte esistenti.
Misha Lavrov,

Risposte:


13

Wolfram Language (Mathematica) , 59 byte

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

Provalo online!

Spiegazione

RealDigits@#

Trova le cifre decimali dell'input.

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

Se ci sono cifre ripetute, RotateLeftloro. (List@@# impedisce al codice di tentare di ruotare l'ultima cifra decimale se il numero razionale sta terminando).

FromDigits@

Converti in razionale.


Davvero molto intelligente!
DavidC

6

Gelatina , 36 32 31 30 byte

-1 byte grazie a Erik the Outgolfer !

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

Provalo online!

Dovrebbe essere corretto L'imprecisione in virgola mobile aggiunge 3 byte per+.Ḟ .

Si basa sul fatto che l'input è irriducibile.


Spiegazione

Questo si basa su:

  • Lascia che il numeratore sia n/dnella sua forma più semplice. Quindi il collegamento ọ2,5Ṁapplicato dfornirà il numero di cifre non periodiche dopo il punto di radice.

ọ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 Grazie!
user202729

5

Python 2 , 237 235 214 byte

-21 byte grazie a Mr. Xcoder

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

Provalo online!

L'input viene eseguito come tupla (numerator, denominator); l'output è un fractions.Fractionoggetto.

Questo utilizza un metodo a divisione lunga per ottenere le cifre iniziali e ripetute della risposta, quindi sposta la prima cifra ripetuta fino alla fine e utilizza la manipolazione delle stringhe fraction.Fractionper riconvertirla in un rapporto.

Versione non golfata:

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 byte

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

Provalo

Prende un numero Rational e restituisce un numero Rational o Int .

Allargato:

{  # 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
    )
}

Nota gestirà denominatori fino uint64.Range.maxa gestire denominatori più grandi usare FatRat(9 x$1.chars) Provalo .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.