Mathematica, 79 байтов
Min[2#/(d=Divisors@#~Cases~_?OddQ)+d]-2⌊(2#)^.5+.5⌋+⌈Sqrt[8#+1]~Mod~1⌉&
объяснение
Я не мог потрудиться реализовать алгоритм в задаче, поэтому я хотел найти кратчайший путь к решению. Хотя я нашел один, к сожалению, он не побеждает ответ Mathematica, который реализует алгоритм. Тем не менее, я уверен, что это еще не оптимально, и могут быть другие языки, которые могут извлечь выгоду из этого подхода или некоторых идей, полученных в процессе.
Поэтому я утверждаю, что последовательность, которую мы должны вычислить:
f (n) = 2 * ( A212652 (n) - A002024 (n)) + 1 + A023532 (n-1)
В качестве альтернативы, это f (n) = 1, если n - треугольное число и f (n) = 2 * ( A212652 (n) - A002024 (n) + 1) в противном случае.
В первом выражении A023532 просто кодирует эти два разных случая. Две другие последовательности (плюс 1) представляют собой разницу между наибольшим целым числом k в самом длинном разложении n на последовательные целые числа (k-i + 1) + (k-i + 2) + ... + k = n и наибольшее целое число j, так что 1 + 2 + ... + j <n .
В нескольких простых словах, вот как мы находим ответ на нетреугольные числа: первое, найти наибольший треугольное число T J , который меньше , чем п . Тогда j - предпоследнее целое число, которое добавляется на шаге 1 (потому что после добавления j + 1 мы превысим n ). Затем разложите n на как можно больше (или как можно меньше) последовательных целых чисел и назовите максимум среди этих чисел k . Результат просто 2 * (кДж) . Интуитивно понятная причина этого заключается в том, что максимум разложения растет на 1 через каждый шаг, и мы останавливаемся, когда достигаемк .
Нам нужно показать четыре вещи, чтобы доказать, что это работает:
- f (n) = 1 для треугольных чисел. Это тривиально, потому что первый шаг просто перебирает все треугольные числа. Если мы нажмем n точно во время этого процесса, мы закончим и оставался только один шаг для вычисления.
- Для всех остальных чисел мы всегда заканчиваем после шага удаления, а не после шага вставки. Это означает, что все остальные f (n) четны.
- На каждом шаге вставки после первого мы добавляем только один номер. Это гарантирует, что мы достигнем разложения, включающего k после kj пар шагов.
- Окончательная декомпозиция n, которую мы получаем, всегда является самой длинной из возможных декомпозиций n на последовательные целые числа, или, другими словами, это всегда декомпозиция n с наименьшим максимумом среди суммируемых чисел. Другими словами, последнее число, которое мы добавляем к сумме, всегда A212652 (n) .
Мы уже показали, почему (1) верно. Далее мы докажем, что мы не можем закончить на шаге вставки, кроме начального (что не происходит для нетреугольных чисел).
Предположим, что мы закончили на шаге вставки, достигнув n после добавления значения p к сумме. Это означает, что перед этим шагом вставки значение было np ( или меньше, если мы добавили несколько значений одновременно). Но этому этапу вставки предшествовал этап удаления (поскольку мы не могли нажать n на шаге 1). Последнее значение q, которое мы удалили на этом шаге удаления, было обязательно меньше p из-за того, как работает алгоритм. Но это означает, что до того, как мы удалили q, у нас было n-p + q ( или меньше ), которое меньше n, Но это противоречие, потому что нам пришлось бы прекратить удалять целые числа, когда мы нажимаем n-p + q вместо удаления другого q . Это доказывает пункт (2) выше. Итак, теперь мы знаем, что мы всегда заканчиваем этапом удаления и что поэтому все нетреугольные числа имеют четные выходные данные.
Далее мы докажем (3), что каждый шаг вставки может вставить только одно значение. Это по существу следствие (2). Мы показали, что после добавления одного значения мы не можем точно указать n , а поскольку при проверке использовалось неравенство, мы также не можем оказаться ниже n (поскольку тогда n-p + q все равно будет меньше n, и мы не должны были удалять что много ценностей в первую очередь). Поэтому всякий раз, когда мы добавляем одно значение, мы гарантированно превышаем n, потому что мы опустились ниже n , удалив меньшее значение. Следовательно, мы знаем, что верхний конец суммы увеличивается на 1 при каждом следующем шаге. Мы знаем начальное значение этого верхнего конца (это наименьшее м такое, чтоT m > n ). Теперь нам просто нужно выяснить этот верхний предел, как только мы достигнем окончательной суммы. Тогда количество шагов просто вдвое больше разницы (плюс 1).
Для этого мы докажем (4), что окончательная сумма - это всегда разложение n на максимально возможное число целых чисел или разложение, где максимум в этом разложении минимален (т. Е. Это самое раннее возможное разложение). Мы снова сделаем это из-за противоречия (формулировка в этой части может быть немного более строгой, но я уже потратил слишком много времени на это ...).
Скажем, самое раннее / самое длинное из возможных разложений n - это некоторое a + (a + 1) + ... (b-1) + b , a ≤ b , и скажите, что алгоритм его пропускает. Это означает, что в момент добавления b a больше не должен быть частью суммы. Если бы a было частью суммы s , то у нас было бы n ≤ s в этот момент. Таким образом, либо сумма содержит только значения от a до b , что равно n, и мы останавливаемся (следовательно, мы не пропустили эту декомпозицию), либо в сумме есть хотя бы одно значение меньше, чем a, в этом случае выигрыш n <sи это значение будет удалено, пока мы не достигнем точной суммы (опять же, декомпозиция не была пропущена). Таким образом, мы должны избавиться от а, прежде чем добавить б . Но это означает, что нам придется столкнуться с ситуацией, в которой а является наименьшим компонентом суммы, а наибольшая - еще не б . Однако в этот момент мы не можем удалить a , потому что сумма явно меньше n (так как b отсутствует), поэтому мы должны сначала добавить значения, пока мы не добавим b и точно не достигнем n . Это доказывает (4).
Итак, взяв эти вещи вместе: мы знаем, что первая пара шагов дает нам максимальное значение A002024 (n) . Мы знаем, что максимальное значение окончательного разложения составляет A212652 (n) . И мы знаем, что этот максимум увеличивается один раз за каждую пару шагов. Следовательно, окончательное выражение равно 2 * ( A212652 (n) - A002024 (n) + 1) . Эта формула почти работает для треугольных чисел, за исключением того, что для них нам нужен только 1 шаг вместо 2, поэтому мы корректируем результат с помощью индикаторной функции треугольных чисел (или ее обратной, в зависимости от того, что удобнее).
Наконец, что касается реализации. Для первой последовательности я использую формулу MIN (нечетное d | n; n / d + (d-1) / 2) из OEIS. Получается сэкономить несколько байтов, если мы возьмем в это выражение множитель 2, чтобы получить MIN (нечетное d | n; 2n / d + d-1) , потому что это -1 затем отменяется с +1 в моей первой версии из f (n), который непосредственно кодирует два случая для треугольных и нетреугольных чисел. В коде это:
Min[2#/(d=Divisors@#~Cases~_?OddQ)+d]
Для последней последовательности ( 1, 2, 2, 3, 3, 3, ...
) мы можем использовать простую замкнутую форму:
⌊(2#)^.5+.5⌋
И, наконец, обратная индикаторная функция треугольных чисел равна 0, если 8n + 1 - идеальный квадрат. Это может быть выражено в Mathematica как
⌈Sqrt[8#+1]~Mod~1⌉
Есть много способов выразить эти последние две последовательности и сместить некоторое постоянное смещение между ними, поэтому я уверен, что это еще не оптимальная реализация, но я надеюсь, что это может дать другим отправную точку для изучения новых подходов в свои собственные языки.
Поскольку я пошел на все эти проблемы, вот график последовательности до n = 1000 (я мог бы также вычислить 100k за пару секунд, но на самом деле он не показывает никаких дополнительных сведений):
Может быть интересно взглянуть на вариации этих очень прямых линий, но я оставлю это кому-то еще ...