Видаліть першу періодичну цифру


17

Ми всі знаємо, що щоразу, коли раціональне число записується у десятковій формі, результат або закінчується, або (зрештою) періодично. Наприклад, коли 41/42 записується у десятковій формі, результат є

0.9 761904 761904 761904 761904 761904 761904 761904 ...

з початковою послідовністю цифр, 0.9за якою послідовність 761904повторюється знову і знову. (Зручне позначення для цього - це те, 0.9(761904)коли круглі дужки оточують блок повторюваних цифр.)

Ваша мета в цьому завданні - взяти позитивне раціональне число, видалити першу цифру, що є частиною повторюваної послідовності, і повернути отримане раціональне число. Наприклад, якщо це зробити до 41/42, ми отримаємо

0.9  61904 761904 761904 761904 761904 761904 761904 ...

або 0.9(619047)коротко, що становить 101/105.

Якщо раціональне число має закінчується десяткове розширення, як 1/4 = 0.25робить, нічого не повинно статися. Ви можете думати про 1/4 як 0.250000000...або як, 0.249999999...але в будь-якому випадку, видалення першої цифри повторюваної частини залишає число незмінним.

Деталі

  • Вхід є позитивним раціональним числом або як пара натуральних чисел, що представляють чисельник і знаменник, або (якщо ваша обрана мова дозволяє і ви хочете) як якийсь об'єкт раціонального числа.
  • Вихід також є раціональним числом, також у будь-якій формі. Якщо результат є цілим числом, ви можете повернути ціле число замість раціонального числа.
  • Якщо взяти пару чисел як вхід, ви можете припустити, що вони відносно прості; якщо виводиться пара чисел як вихід, ви повинні зробити їх відносно простими.
  • Будьте уважні, що ви знайдете першу цифру, яка починає повторюваний блок. Наприклад, можна записати 41/42 як, 0.97(619047)але це не робить 2041/2100 (з десятковим розширенням 0.97(190476)) дійсною відповіддю.
  • Ви можете припустити, що у отриманому введенні перша періодична цифра знаходиться після десяткової крапки, роблячи 120/11= 10.909090909...недійсним введення: (її перша періодична цифра може вважатися 0в 10). Ви можете робити все, що завгодно, на такому вході.
  • Це : виграє найкоротше рішення.

Тестові справи

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

Чи можемо ми повернутися 2017замість 2017/1?
JungHwan Min

Так, якщо ви робите справу з раціональним числом. (Якщо ви займаєтесь цілою справою пари, тоді я не впевнений, що ще ви повернете, окрім пари (2017,1).)
Міша Лавров

Чи може введення бути зменшеним (не повністю спрощеним)? Наприклад, може 2/4статися на вході?
користувач202729

1
Якщо введення - 120/11це правильна відповідь 111/11або 210/11?
kasperd

2
@kasperd Так, я не замислювався над цим випадком ... Хочеться сказати, 111/11за винятком того, що відповідь на найвищому рівні в даний момент повертається 210/11, тому я дозволю вам вибрати, щоб уникнути недійсності існуючих відповідей.
Міша Лавров

Відповіді:


13

Мова Вольфрама (Mathematica) , 59 байт

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

Спробуйте в Інтернеті!

Пояснення

RealDigits@#

Знайдіть десяткові цифри вводу.

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

Якщо є повторювані цифри, RotateLeftїх. ( List@@#запобігає спробі коду повернути останню десяткову цифру, якщо раціональне число закінчується).

FromDigits@

Перетворити на раціональне.


Дуже розумно дійсно!
DavidC

6

Желе , 36 32 31 30 байт

-1 байт завдяки Еріку Переможнику !

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

Спробуйте в Інтернеті!

Повинно бути правильним. Неточність з плаваючою точкою додайте 3 байти для +.Ḟ.

Покладається на те, що вхід є невідводимим.


Пояснення

Це спирається на:

  • Нехай чисельник буде n/dу найпростішому вигляді. Тоді посилання, на яке ọ2,5Ṁзвертається d, дасть число неперіодичної цифри після точки радіації.

ọ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 Дякую!
користувач202729

5

Python 2 , 237 235 214 байт

-21 байт завдяки спадару 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])))

Спробуйте в Інтернеті!

Введення робиться як кортеж (numerator, denominator); вихід - fractions.Fractionоб’єкт.

Для цього використовується метод стилю тривалого поділу для отримання початкових і повторюваних цифр відповіді, потім переміщується перша повторювана цифра до кінця і використовує маніпуляцію з рядком і fraction.Fractionперетворює її назад у співвідношення.

Негольована версія:

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


2

Мова Вольфрама (Mathematica) , 70 67 байт

Завдяки цій пораді (тепер видалено) на -3 байти!

(x=10^Max@IntegerExponent[#,{2,5}];(Floor@#+Mod[10#,1])/x&[x#2/#])&

Спробуйте в Інтернеті!

Порт моєї відповіді на желе . Більше, ніж існуючий відповідь Mathematica на 8 байт ...

Функція приймає 2 входи [denominator, numerator], такі, що GCD[denominator, numerator] == 1.


1

Perl 6 , 102 байти

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

Спробуй це

Бере Раціональне число і повертає Раціональне або Інт- число.

Розширено:

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

Примітка буде обробляти знаменники до того, uint64.Range.maxщоб обробляти великі знаменники FatRat(9 x$1.chars) Спробуйте .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.