Ваша задача - преобразовать десятичные дроби обратно в сумму квадратных корней целых чисел. Результат должен иметь точность не менее 6 значащих десятичных цифр.
Вход :
Число, указывающее количество квадратных корней, и десятичное число, указывающее число для аппроксимации.
Пример ввода:
2 3.414213562373095
Вывод : целые числа, разделенные пробелами, которые при квадратном корне и сложении приблизительно соответствуют исходному десятичному знаку с точностью не менее 6 значащих десятичных знаков.
Нули не допускаются в решении.
Если есть несколько решений, вам нужно распечатать только одно.
Пример вывода (в любом порядке):
4 2
Это работает, потому что Math.sqrt(4) + Math.sqrt(2) == 3.414213562373095
.
Это код гольф. Самый короткий код (с дополнительным бонусом) выигрывает!
Всегда будет решение, но -10, если ваша программа выводит «Нет», когда нет решения с целыми числами. Кроме того, -10, если ваша программа печатает все решения (разделенные символом новой строки или точкой с запятой или что-то еще) вместо одного.
Тестовые случаи:
3 7.923668178593959 --> 6 7 8
2 2.8284271247461903 --> 2 2
5 5.0 --> 1 1 1 1 1
5 13.0 --> 4 4 9 9 9 --> 81 1 1 1 1 --> 36 9 4 1 1 etc. [print any, but print all for the "all solutions bonus"]
И да, ваша программа должна завершиться за конечное время, используя ограниченную память на любой разумной машине. Это не может просто работать «в теории», вы должны быть в состоянии действительно проверить это.
источник
6 7 8
второго бонуса?Ответы:
Python 3, 90 - 10 = 80
(Мега спасибо @xnor за советы, особенно реструктуризацию цикла for)
Простая рекурсивная попытка. Он начинается с целевого числа и непрерывно вычитает квадратные корни, пока не достигнет 0 или ниже. Функция
S
может быть вызвана какS(2,3.414213562373095)
(второй аргумент считается положительным).Программа не просто распечатывает все решения, она печатает все варианты решений (немного посторонний, я знаю). Вот вывод для последнего случая: Pastebin .
Небольшая настройка дает решение 98 - 10 = 88, которое не печатает перестановки, что делает его более эффективным:
И просто для удовольствия, этот 99 - 10 = 89 один настолько эффективен, насколько это возможно (в отличие от других, он не бьет стек
S(1,1000)
:Обратите внимание, что, хотя у нас есть изменяемый аргумент по умолчанию, это никогда не вызывает проблем, если мы перезапустим функцию, поскольку создаем
n+[i]
новый список.Доказательство правильности
Чтобы попасть в бесконечный цикл, мы должны достичь некоторой точки, где x <0 и 0.1 + x 2 > 1 . Это удовлетворяет й <-0,948 ... .
Но обратите внимание, что мы начинаем с положительного значения x, а x всегда уменьшается, поэтому для достижения x <-0,948 ... у нас должно быть x '- i 0,5 <-0,948 ... для некоторых x'> -0,948 .. . Перед х и положительного целого числа я . Для запуска цикла while у нас также должно быть 0.1 + x ' 2 > i .
Переставляя, мы получаем x ' 2 + 1.897x' + 0,948 <i <0,1 + x ' 2 , внешние части подразумевают, что x' <-0,447 . Но если -0,948 <x '<-0,447 , то ни одно положительное целое число i не сможет заполнить пробел в вышеприведенном неравенстве.
Следовательно, мы никогда не попадем в бесконечный цикл.
источник
abs
сx*x<1e-12
.while
цикл работает, чтобы заменитьfor
:,while.1+x*x>i:S(x-i**.5,n+[i]);i+=1
инициализировавi=1
в параметрах функции. Идея состоит в том, чтобы избежать необходимости конвертировать вint
s. Для.1
устранения неточностей поплавка; Я думаю, что это безопасно от бесконечных петель.N
теперь, когда есть аргумент функции, стало меньше нужды возвращатьсяN-1
и проверять когда,N==0
а неlen(n)==N
..1
это безопасно; Я могу поболтать с тобой, если хочешь.Эклипс Пролог - 118 (138-20)
Я использовал следующую реализацию Пролога: http://eclipseclp.org/
Это очень наивный, экспоненциальный подход. Перечисление всех возможных решений требует времени, чтобы охватить все комбинации ( правка : диапазон посещаемых целых чисел теперь уменьшается на каждом шаге, что устраняет множество бесполезных комбинаций).
Здесь следует стенограмма тестовой сессии. По умолчанию среда пытается найти все возможные решения (-10) и выводит «Нет», если это не удается (-10).
Как правильно отметил Sp3000 в комментарии, он также печатает «Да», когда это удается. Это, безусловно, означает, что я могу снять еще 10 очков ;-)
(Изменить) Что касается производительности, то она довольно хорошая, по крайней мере, по сравнению с другими (см., Например, этот комментарий от FryAmTheEggman ). Сначала, если вы хотите распечатать все результаты, добавьте следующий предикат:
См http://pastebin.com/ugjfEHpw для (5,13.0) случая, который завершает в 0,24 секунде и найти решение (495 , но , возможно , я пропускаю какое - то решение, я не знаю).
источник
Erlang,
305-10302-10Эта функция возвращает строку «Нет» или строку со значениями, разделенными пробелами. Он (неэффективно) обрабатывает все возможные значения, кодируя их в большое целое число и начиная с более высоких значений. 0 не разрешены в решении, и закодированный 0 представляет все единицы. Ошибка в квадрате.
Пример:
Пожалуйста, будьте терпеливы, так
f(5,13.0)
как пространство поиска функции составляет 13 ^ 10. Это может быть сделано быстрее с 2 дополнительными байтами.источник
Python
32:173159 - 10 = 149Объяснение: Каждое решение имеет вид x_1 x_2 ... x_n с 1 <= x_1 <= x ^ 2, где x - целевая сумма. Поэтому мы можем закодировать каждое решение как целое число в базе x ^ 2. Цикл while перебирает все (x ^ 2) ^ n возможностей. Затем я конвертирую целое число обратно и проверяю сумму. Довольно прямо вперед.
Он находит все решения, но последний контрольный пример занимает слишком много времени.
источник
JavaScript (ES6) 162 (172 - 10)
173Редактировать Немного короче, чуть медленнее.
Как функция с 2 параметрами, вывод на консоль javascript. При этом печатаются все решения без повторений (сгенерированные кортежи решений уже отсортированы).
Я больше заботился о времени, чем о количестве символов, так что его легко протестировать в консоли браузера в течение стандартного ограничения времени javascript.
(Обновление за февраль 2016 года) Текущее время последнего тестового случая: около 1
150 секунд. Требования к памяти: незначительные.Версия ES 5 Любой браузер
Тестовый Фрагмент, который он должен запустить на любом недавнем браузере
( Изменить ) Ниже приведены результаты на моем ПК, когда я разместил этот ответ 15 месяцев назад. Я попробовал сегодня, и это в 100 раз быстрее на том же ПК, только с 64-битной альфа-версией Firefox (а Chrome сильно отстает)! - текущее время с Firefox 40 Alpha 64 bit: ~ 2 с, Chrome 48: ~ 29 с
Вывод (на моем ПК - последний номер - время выполнения в миллисекундах)
источник
Mathematica - 76 - 20 = 56
Примеры
источник
No
? Кроме того, вывод не разделен пробелом. Кроме того, вы не можете использоватьTr@
вместоPlus@@
? И вы можете быть в состоянии сохранить некоторые символы, изменивSelect
кCases
, функции в конце концов к шаблону и делаяf
неназванную чистую функцию.Haskell,
8780 - 10 = 70Это рекурсивный алгоритм, похожий на программу Python 3 @ Sp3000. Он состоит из инфиксной функции,
#
которая возвращает список всех перестановок всех решений.Со счетом
102 9992 - 10 = 82 мы можем напечатать каждое решение только один раз, отсортировав:источник
Pyth
55 5447-20 = 27Попробуйте онлайн.
Бесстыдно заимствует из комментария xnor ;)
Это исчерпает память на любом нормальном компьютере даже для значения как
5,5.0
. Определяет функцию,g
которую можно вызвать какg 3 7.923668178593959
.Эта программа на Python 3 использует, по сути, тот же алгоритм (просто не выполняет печать «Нет» в конце, что можно сделать, назначив переменную всем результатам, затем записав
print(K if K else "No")
), но использует генератор, поэтому он не Ошибка памяти (это все равно займет очень много времени, но я распечатал ее, когда нашел значения):Это дало те же самые результаты, которые получил @ Sp3000. Кроме того, это заняло несколько дней, чтобы закончить (я не рассчитывал, но около 72 часов).
источник
Питон 3 -
157174169 - 10 = 159Edit1: изменен формат вывода на разделенные пробелами целые числа вместо запятых. Спасибо за отзыв о снятии скобок (n, x).
Edit2: Спасибо за советы по игре в гольф! Я могу обрезать еще 9 символов, если я просто использую тест == вместо теста на приблизительное равенство с точностью до 1e-6, но это лишит законной силы приблизительные решения, если таковые существуют.
Использует itertools для генерации всех возможных целочисленных комбинаций, надеюсь, эффективно :)
Я не нашел способа эффективно добавить печать «Нет», всегда кажется, что требуется больше 10 дополнительных символов.
источник
n,x
.SyntaxError
s, когда я пробуюeval
линию ...from itertools import*
экономит 1, удаляя пространствоz**.5for
сохраняет 1, и удаление[]
инsum(z**.5for z in c)
сохраняет 2 и удаление()
инif(...)
сохраняет 1.n,x=input()
более компактным?Скала (397 байт - 10)
Если перестановок нет, то эта программа ничего не печатает.
источник