Математика, 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 * (kj) . Інтуїтивна причина цього полягає в тому, що максимум у розкладанні зростає на 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, і ми не повинні були видаляти що багато значень в першу чергу). Таким чином , всякий раз , коли ми додамо одне значення, ми гарантовано перевищить п , тому що ми пішли нижче п , видаляючи менше значення. Отже, ми знаємо, що верхній кінець суми зростає на 1 кожен другий крок. Ми знаємо початкове значення цього верхнього кінця (це найменше m таке, щоT m > n ). Тепер нам просто потрібно розібратися в цьому верхньому кінці, як тільки ми досягнемо остаточної суми. Тоді кількість кроків просто вдвічі більше (плюс 1).
Для цього ми доводимо (4), що підсумкова сума - це завжди розкладання n на якомога більше цілих чисел, або розкладання, де максимум у цьому розкладі мінімальний (тобто це найшвидший можливий розпад). Ми знову зробимо це протиріччям (формулювання в цій частині може бути трохи більш суворим, але я вже витратив занадто багато часу на це ...).
Скажіть, що найбільш раннє / найдовше можливе розкладання n є деяким a + (a + 1) + ... (b-1) + b , a ≤ b , і скажімо, що алгоритм пропускає його. Це означає, що в момент, коли b додається, a більше не повинно бути частиною суми. Якби a була частиною суми s , тоді ми мали б n ≤ s у той момент. Отже, або сума містить лише значення від a до b , що дорівнює n, і ми зупиняємось (отже, ми не пропустили це розкладання), або є принаймні одне значення менше а в сумі, виграємо в якому випадку n <sі це значення буде видалено, поки ми не потрапимо в точну суму (знову ж таки, розкладання не було пропущено). Таким чином, нам доведеться позбутися a, перш ніж додавати b . Але це означає, що нам доведеться дійти до ситуації, коли а є найменшою складовою суми, а найбільшою ще не є b . Однак у цей момент ми не можемо видалити 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 за пару секунд, але це насправді не показує додаткових відомостей):
Це може бути цікаво розглянути варіанти цих дуже прямих ліній, але це я залишу комусь іншому ...