Задача
Дайте ввод r
и n
найдите первые n
натуральные числа, x
такие, что если мы повернем первую цифру в последнее место, мы получим x/r
.
Вы можете предположить, что 2 <= r <= 9
и 1 <= n <= 65535
.
Вы можете написать программу, которая принимает входные данные из аргументов stdin или командной строки; или вы можете написать функцию, которая принимает r
и в n
качестве параметров. Вывод, однако, должен быть в стандартный вывод. Выходные данные должны быть по одной строке на значение x
, отформатированные x/r=y
в порядке возрастания x
.
Ваше решение должно быть в состоянии обработать все действительные случаи в течение одной минуты на приемлемом настольном компьютере.
Контрольные примеры
Вход: 4 5
Выход:
102564/4=25641
205128/4=51282
307692/4=76923
410256/4=102564
512820/4=128205
Вход: 5 1
Выход:714285/5=142857
Это код-гольф, поэтому выигрывает минимум байтов. Победивший ответ будет принят через 4 недели (2014-09-19).
Кредиты по этому вопросу идут моему коллеге, который позволил мне разместить этот вопрос здесь :)
источник
gprof
одному входному случаю для моей программы в моем коде затрачивается не более полсекунды, но занимает около 80 секунд, что, я полагаю, должно в основном блокировать вывод.printf
.Ответы:
Хаскелл,
182179Вторая версия, возможно, в дальнейшем пригодна для игры в гольф, но на этот раз с «правильным» алгоритмом. В частности, он завершается в течение нескольких минут с помощью
r=4
иn=65535
, но опять же мой компьютер не является ни разумным, ни настольным компьютером, так что есть вероятность, что это останется в течение минуты на других машинах.Он основан на идее
x=10^k*a + m
, где его первая цифра0≤a≤9
перемещается в конец для полученияy=10*m+a
. Немного математики показывает , чтоm
может быть получено какa*(10^k-r)/(10*r-1)
, поэтому мы просто сканироватьa
более[1..9]
для каждогоk
от 0 до бесконечности, и сохранить и напечатать первыеn
результаты , для которых приведенное выше выражение дляm
является интегралом.fromIntegral
Требуется потому , чтоread
ИНГ список сn
одним из своих элементовmain
, в сочетании с использованиемn
вtake
, вынудитr
наInt
всем, что приводит к неприятным переткам с большими числами в вопросе. Я мог бы использоватьgenericTake
, но это требуетimport
.Этот код также имеет преимущество, заключающееся в том, что он почти тривиален для расширения на базы, отличные от 10.
Входные данные считываются
stdin
, два значения могут быть разделены любым пробелом.источник
r = 5; n = 65535
в течение минуты?y`mod`10
сmod y10
, что является голец корочеPure Bash (без внешних утилит), 80 байт
Обратите внимание, что bash выполняет только целочисленную арифметику, а не с плавающей запятой, поэтому мы проверяем, если
x == y * r
вместоx / r == y
. Также умножение должно быть быстрее. Тем не менее, это далеко не соответствует требованиям производительности.Выход:
источник
С 468
(Некоторые символы новой строки, не учитываемые в счетчике байтов, были добавлены выше для устранения полос прокрутки. Да, последний символ новой строки считается.)
Ожидает аргументы в командной строке и предполагает, что стандартный вывод принимает ASCII. Время выполнения - O (количество выводимых байтов) = O (n * n).
Нет, я не могу использовать
printf
. Это занимает слишком много времени и заставляет программу превышать минуты на моем рабочем столе. На самом деле, некоторые тестовые случаи занимают около 30 секунд.Алгоритм обрабатывает выходные данные как строки, а не числа, так как они быстро становятся огромными, и в выходных данных есть сильные шаблоны.
Немного не одураченный
доказательство
что программа решает проблему:
(В доказательстве принимайте все операторы и функции за реальные математические функции, а не за компьютерные операции, которые их аппроксимируют.
^
Обозначает возведение в степень, а не побитовый xor.)Для ясности я буду использовать функцию
ToDec
для описания обычного процесса записи числа в виде последовательности десятичных цифр. Его диапазон - это набор упорядоченных кортежей{0...9}
. Например,Для положительного целого числа
n
определитеL(n)
количество цифр в десятичном представленииn
; или же,Для положительного целого
k
и неотрицательного целого числаn
сL(n)<k
, определите,Rep_k(n)
чтобы быть действительным числом, полученным путем добавления нулей перед десятичными цифрамиn
, если необходимо получитьk
общее количество цифр, и затем бесконечно повторяя этиk
цифры после десятичной точки. НапримерУмножение
Rep_k(n) * 10^k
дает цифрыn
перед десятичной запятой и цифры (дополненные нулями)n
бесконечно повторяющиеся после десятичной запятой. ТакУчитывая положительное целое число
r
, предположим, чтоx
это решение проблемы, игде
x_1 != 0
иk = L(x)
.Чтобы быть решением,
x
это кратноеr
, иПрименение
Rep_k
функции дает хорошее уравнение:Используя его закрытую форму сверху,
x_1
должен быть в наборе{1 ... 9}
.r
было указано, чтобы быть в наборе{2 ... 9}
. Теперь единственный вопрос: для каких значенийk
приведенная выше формулаx
дает положительное целое число? Мы рассмотрим каждое возможное значениеr
индивидуально.Когда
r
= 2, 3, 6, 8 или 9,10r-1
это 19, 29, 59, 79 или 89 соответственно. Во всех случаях знаменательp = 10r-1
прост. В числителе, только10^k-1
может быть кратнымp
, что происходит, когдаМножество решений замкнуто при сложении и вычитании, что не приводит к отрицательному числу. Таким образом, набор содержит все кратные некоторого общего множителя, который также является наименее положительным решением для
k
.Когда
r = 4
и10r-1 = 39
; или когдаr = 7
и10r-1 = 69
знаменатель в 3 раза больше другого простого числаp=(10r-1)/3
.10^k-1
всегда кратно 3, и опять никакой другой фактор в числителе не может быть кратнымp
, поэтому снова проблема сводится ки снова все решения кратны наименьшему положительному решению для
k
.[Не закончено...]
источник
Питон -
9190Вот первый выстрел:
Изменить: Хорошо, это, вероятно, способ замедлить, чтобы удовлетворить необходимый 1-минутный лимит времени для номеров 65K.
источник
JavaScript - 145
не в гольф
источник
(5,4)
. Причина, по которой это не сработает, состоит в том, что цифры растут очень большими. а) намного больше, чем число в JS, может представлять точно, и б) слишком большое, чтобы было возможно выполнить итерацию по всем числам, чтобы попасть туда.Python 3 -
223179 байтPython-реализация решения TheSpanishInquisition:
Бег:
python3 <whatever you named it>.py
Выход:
Результаты:
https://oeis.org/A092697 является первым значением для каждого r.
Кажется, что только определенные значения k дают ответы, и этот интервал является регулярным. Например, для r = 4:
Интервалы:
Это формы https://oeis.org/A094224 .
Используя эти значения, можно построить более эффективную версию:
Однако я не могу (пока) доказать, что это продолжается математически.
Результаты для r = 5:
источник
9 65535
?unsigned long long
для этого, и сделать его многоядерным, чтобы сделать это за одну минуту.unsigned long long
64 бит, это не достаточно большой.