Этот вопрос не нужно применять только к конечным десятичным знакам - повторяющиеся десятичные дроби также можно преобразовать в дроби с помощью алгоритма.
Ваша задача состоит в том, чтобы создать программу, которая будет принимать повторяющиеся десятичные числа в качестве входных данных, и выводить соответствующий числитель и знаменатель (в самых низких терминах), который производит это десятичное расширение. Фракции больше 1 должны быть представлены как неправильные дроби, такие как 9/5
. Вы можете предположить, что вход будет положительным.
Повторное десятичное число будет дано в этом формате:
5.3.87
со всем после повторения второй точки, например так:
5.3878787878787...
Ваша программа выведет два целых числа, представляющих числитель и знаменатель, разделенные косой чертой (или эквивалентную форму на вашем языке, если вы не выводите простой текст):
889/165
Обратите внимание, что после второй точки после десятичной запятой ничего не будет, а между двумя точками после десятичной точки без неповторяющейся десятичной части ничего не будет.
Контрольные примеры
Эти контрольные примеры охватывают все необходимые угловые случаи:
0..3 = 1/3
0.0.3 = 1/30
0.00.3 = 1/300
0.6875. = 11/16
1.8. = 9/5
2.. = 2/1
5..09 = 56/11
0.1.6 = 1/6
2..142857 = 15/7
0.01041.6 = 1/96
0.2.283950617 = 37/162
0.000000.1 = 1/9000000
0..9 = 1/1
0.0.9 = 1/10
0.24.9 = 1/4
Если вы хотите, вы также можете предположить, что дроби без целочисленных частей не имеют ничего слева от первой точки. Вы можете проверить это с помощью этих дополнительных тестовых случаев:
.25. = 1/4
.1.6 = 1/6
..09 = 1/11
.. = 0/1
источник
9/99
?(in lowest terms)
т.е. дробь должна быть упрощена.13
вместо13/1
?1.9999...
и вывод2/1
1.9999.
это19999/10000
, чтобы получить2/1
вам нужно1..9
, не так ли?Ответы:
Dyalog APL (
75736968 знаков)Вот еще одна и пятая попытка (скорее всего, моя последняя); Я потратил весь день на то, чтобы написать какой-нибудь фрагмент кода длиной менее 80 символов и полностью соответствовать правилам. Этот вызов сделал мой день!
Я наконец-то получил строку APL, состоящую из 75 символов, работающую с Dyalog APL (но не на странице онлайн-переводчика, так как использует функцию
⍎
execute ), которая выглядит следующим образом:Конечно, я мог бы сделать это немного короче, но в особых случаях, когда одно, два или три поля отсутствуют. Мой код может даже обрабатывать
..
случай ввода.Я знаю, что APL трудно читать, и поскольку людям нравится понимать, как на самом деле работает фрагмент кода, вот некоторые объяснения. По сути, я вычисляю последний знаменатель в переменной D и последний числитель в переменной N.
APL анализируется справа налево.
I←
).P←'.'=
). Например, '1.2.3' будет отображено на 0 1 0 1 0.10⊥
); сейчас «1.2.3» составляет 1010.1-⍨
либо с¯1+
, здесь я выбрал второе). Теперь «1.2.3» - это 1009.⍕
), удаляются две начальные цифры (2↓
), что составляет 09 из нашего первоначального примера 1.2.3; строка перевернута (⌽
).'0',
но я сделал это, чтобы избежать ошибки, когда второе и третье поля пусты. Строка преобразуется обратно в число (⍎
) и сохраняется в D, который является знаменателем, за исключением случаев, когда оба последних поля пусты, потому что в этом случае D равно 0.D←D+0=
Кусок кода множества D 1 , если она в настоящее время нулевой, а теперь D содержит знаменатель (до НОД разделения однако).×
) на содержание исходной строки I до второй точки, с(⍎'0',I/⍨2>+\P)
которой снова начинается с P (0 1 0 1 0 в моем примере), добавляет последовательные числа, накапливая их (что составляет 0 1 1 2 2 в моем примере), проверьте, какие значения меньше 2 (делая логический вектор 1 1 1 0 0), и принимая соответствующие символы в I; еще один 0 добавляется перед строкой для предотвращения другой ловушки (если два начальных поля пусты), и все преобразуется в число.(⍎'0',1↓I/⍨2=+\P)
, которая снова принимает P, добавляет путем кумуляции снова, проверяет, какие значения равны 2 (см. Предыдущее объяснение), берет символы-символы, удаляет первый, который является точкой , добавляет начальный нулевой символ и преобразует в число.изменить: вот исправление для 73 символов:
Идея этого взлома состоит в том, чтобы сначала вычислить случай, когда накопленное сложение имеет значения, равные 2, сохранить их для последующего использования и инвертировать эту побитовую маску для получения первого случая; таким образом, для вычисления следующего случая требуется меньше символов.
редактировать: вот еще одно исправление для 69 символов:
Идея этого взлома состоит в том, чтобы встроить наиболее сложный частный случай в виде кода APL в строку, которая должна быть оценена (на этапе преобразования строки в число).
редактировать: вот еще одно исправление для 68 символов:
Идея этого хака состоит в том, чтобы заменить добавление -1 к значению для вычитания 1 к этому значению операцией, вычтя это значение к 1, а затем удалить вначале еще один символ в начале (что будет знаком минус).
изменить: косметическое изменение:
Нет улучшения в размере, но более удовлетворен, чтобы получить максимальную функцию из кода, подлежащего оценке.
источник
INVALID TOKEN
. Ты знаешь почему?I
): см. эту постоянную ссылкуPerl 6 (
93101100806866 байт)Размер был увеличен, чтобы ничего не обрабатывать, а не просто потерпеть неудачу. Mouq предложил использовать
$/
, так что теперь он используется, а код на 20 байт короче. Айико предложил заменить/
на, поэтому код стал еще короче (на 12 байт). Затем Mouq предложил заменить
chars
наcomb
(в числовом контексте они идентичны, поскольку список символов после преобразования в число равен числу символов).Пример вывода:
источник
0..09
возвращается1/11
, но0.0.09
возвращается1/110
.0.1 + 0.2 == 0.3
в Perl 6.$/=split ".",get;say join "/",($0+($1+$2/(9 x chars $2 or 1))/10**$1.chars).nude
:)J (
859089 символов)Моя первоначальная функция, которая была на 5 символов короче второй, содержала пару ошибок: она не выводила целые числа как «n / 1» и дала неправильный ответ на числа, содержащие более дюжины или около того цифр. Вот исправленная функция в J, которая также включает предложение Eelvex о сохранении символа:
Он получает строку и возвращает строку. Вот пример сеанса:
источник
0/1
и3/1
inf первых двух тестовых случаев, см. Этот комментарий('0','x',~])
и сохраните байт.С 171
Довольно долго. Может быть дополнительно уменьшено. Нет
scanf
, который действительно не может справиться с этим, если между точками нет чисел. Нетstrtol
. Просто хруст номера:Тест:
источник
DC (не полностью общий, сокращен до 76 символов)
Не совсем общее, но, пожалуйста, учтите, что я сделал это с одной из самых старых вещей в мире:
Редактировать: я редактирую свое решение; это не более общее, но немного короче:
Используйте это как:
Первое поле не обязательно:
все в порядке.
Второе и жаждущее поля требуют как минимум одну цифру
источник
Javascript, 203
Слишком долго, но все равно весело. Новые строки, потому что точки с запятой не читаются.
источник
889/NaN
когда я бегу5.3.87
... Я делаю что-то не так?"889/165"
в консоль. Как ты это делаешь? @rafaelcastrocoutob=1
деталь внутрьprompt()
.f=(P(10,s[2].length)-1)*P(10,l),f=f?f:1
=>f=(P(10,s[2].length)-1)*P(10,l)||1
J (другой метод)
Другое решение, основанное на совершенно другом методе; на этот раз оно полностью общее; пропущен только один знаменатель, когда передается целое число:
источник
GolfScript (67 символов)
NB Это поддерживает пустые целочисленные части.
Если строка имеет вид,
'n.p.q'
то значение - этоn + p/E + q/(DE) = ((nD + p)E + q)/DE
гдеD = 10^(len p)
иE = 10^(len q) - 1
, кроме случаев, когдаlen q = 0
и в этом случаеE = 1
(чтобы избежать деления на 0).Вскрытие:
Онлайн-демонстрация, которая имитирует запуск программы с каждым из тестовых входов, по одному.
источник
0.1.
питон
Нет библиотек - 156 символов
Использование
fractions
- 127 символовисточник
fractions
версии печатает такие вещи , как «фракции (7, 5)» вместо «7/5», не так ли?_=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b),
ValueError: need more than 1 value to unpack
print
использует,str
когда доступно, нетrepr
. Это вывод с моей стороны: puu.sh/7w64w.png_=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b),(10**len(c)-bool(c))*10**len(b);f=_(d,e);print'%i/%i'%(d/f,e/f)
должен идти все в одну строку.Математика, 143
Как обычно, Mathematica предлагает множество высокоуровневых функций для выполнения работы, но дает им подробные имена.
Пример вывода будет добавлен позже, когда у меня будет время.
источник
n/1
уменьшить доn
? Я добавлю дополнительные ~ 50 байтов для преобразования целых чисел позже.FromDigits
поэтому я решил опубликовать его тоже.Рубин - 112
Это мой первый эксперимент с ruby, поэтому не стесняйтесь предлагать улучшения.
источник
If you wish
. Я не желаю, поэтому я не поддерживаю дроби без 1-й или 3-й группы цифр. Однако я поддерживаю дроби, в которых отсутствует вторая группа цифр, что соответствует спецификации.С, 164
Это похоже на решение С orion, хотя я сделал это с нуля. Признаюсь, однако, украл ряд его оптимизаций. Это не намного короче, но это обрабатывает .25. = 1/4 и 0,000000,1 = 1/9000000.
источник
Два ответа Python без использования библиотек. Сначала обрабатывает необязательный ввод без цифры перед первым. и составляет 162 символа
Second не обрабатывает ничего до первой цифры, но правильно обрабатывает все необходимые входы и составляет 150 символов
источник
Haskell
источник
span
реализовать s, добавить короткие псевдонимы для функций, удалить пространство, где это возможно.import Data.Ratio v=span(/='.');w=tail;l=length;f n=(r x)%1+(r y)%p+(r z)%((10^t-1)*p)where{(x,b)=v n;(y,d)=v(w b);z=w d;p=10^(l y);r""=0;r n=read n;t=if null z then 9 else l z}
- 178 символов, по сравнению с 321. NBTrue
является синонимомotherwise
,null z
этоlength z==0
JavaScript (ECMASCript 6)
180175Хотя это не явный победитель для награды 300 ... это самое короткое, что я могу придумать:
P
функции Power путем изменения ее+("1e"+a)
вместоMath.pow(10,a)
сохранения нескольких символов ...источник
Mathematica 175
Большая часть рутины идет на массаж ввода. Примерно 50 символов ушло на обработку целых чисел.
Примеры
Больше примеров:
Как это обычно достигается в Mathematica
FromDigits
можно получить дробь непосредственно из повторяющегося десятичного числа при условии, что входные данные имеют определенную форму. Целые числа отображаются как целые числа.источник
J (96 знаков)
Я не использую символ косой черты в качестве разделителя (но решение в Mathematica также не используется, поскольку оно использует графическое представление, которое в любом случае лучше); на языке J фракция отображается
r
вместо/
:источник
APL (не полностью общий)
Не полностью общий (как мое решение для DC); работает с Dyalog APL (но не с онлайн-версией Dyalog APL, не знаю почему):
Первое поле является необязательным, но для обоих остальных полей требуется как минимум одна цифра.
источник
JavaScript (189)
Пример:
Входные данные:
Выход:
источник
C (420 символов, как написано; меньше после удаления ненужных пробелов)
Обратите внимание, что это предполагает 64-битный
long
(например, 64-битный Linux); это не удастся для тестового случая0.2.283950617
на системах, использующих 32-битныйlong
. Это можно исправить за счет некоторых символов, изменив тип наlong long
и соответственно изменивprintf
строку формата.источник
'0'
на48
.switch
заявление какif(c==46) n[++i]=1; else d[i]=10*d[i]+c-48,n[i]*=10;
.БРГ , 81
пример
источник
GTB
ссылке выше, если вы мне не верите. Вы получите сжатый материал для проприетарной программы, затем поищете эту программу и обнаружите, что сайт, который утверждает, что предоставляет загрузку, говорит, что он недоступен. Так как мы это скомпилируем?