Який день Різдва це?


27

Передмова

У добре відомій колядці «Дванадцять днів Різдва» оповідачеві подають кілька подарунків щодня. Пісня є кумулятивною - у кожному вірші додається новий подарунок, на кількість на один більший, ніж подарунок перед ним. Один Партрідж, Два Голуби-черепахи, Три французькі кури тощо.

У будь-якому даному вірші, N , ми можемо обчислити кумулятивну суму подарунків на даний момент у пісні, знайшовши N -те тетраедричне число , яке дає результати:

Verse 1: 1
Verse 2: 4
Verse 3: 10
Verse 4: 20
Verse 5: 35
Verse 6: 56
Verse 7: 84
Verse 8: 120
Verse 9: 165
Verse 10: 220
Verse 11: 286
Verse 12: 364

Наприклад, після вірша 4 у нас було 4 * (1 куріпка) , 3 * (2 голуби-черепахи) , 2 * (3 французькі кури) та 1 * (4 птахи, що кличуть) . Підсумовуючи ці, ми отримуємо 4(1) + 3(2) + 2(3) + 1(4) = 20.

Змагання

Ваше завдання - написати програму або функцію, яка за заданим цілим числом, що представляє кількість подарунків 364 ≥ p ≥ 1 , визначає, який день (вірш) Різдва це.

Наприклад, якщо p = 286 , ми на 11 день Різдва. Однак якщо p = 287 , то наступне навантаження подарунків розпочалося, тобто це 12 день.

Математично це знаходження наступного тетраедрального числа та повернення його положення у всій послідовності тетраедричних чисел.

Правила:

  • Це , тому найкоротше рішення (в байтах) виграє.
  • Застосовуються стандартні лазівки для гольфу.
  • Що стосується днів, то ваша програма повинна бути індексованою 1.
  • Подання має бути повноцінною програмою або функцією, але не фрагментом.

Випробування

1   ->  1
5   ->  3
75  ->  7
100 ->  8
220 ->  10
221 ->  11
364 ->  12

5
На всякий випадок, коли це комусь допомагає, n-е чотиригранне число - це також сума перших n трикутних чисел.
— DJMcMayhem

Це може допомогти: x=>{while(x>p)p+=r+=++i;return i}я впевнений, що його можна скоротити такою мовою, як JavaScript.
— 12Me21

1
Це найдавніший різдвяний виклик будь-коли, правда? :)
— вставити користувач туди

Відповіді:


7

Желе , 7 6 байт

-1 байт завдяки Деннісу (використовуйте векторизований мінімум «та перший індекс i)

R+\⁺«i

TryItOnline

Як?

Не все так ефективно - обчислює числа від 1-го до n-го тетраедричних чисел у порядку у списку та повертає 1-заснований індекс першого, який дорівнює або більший.

R+\⁺«i - main link: n
R      - range                          [1,2,3,4,...,n]
 +\    - cumulative reduce by addition  [1,3,6,10,...,sum([1,2,3,4,...n])] i.e. triangle numbers
   ⁺   - duplicate previous link - another cumulative reduce by addition
                                        [1,4,10,20,...,nth tetrahedral]
    «  - min(that, n)                   [1,4,10,20,...,n,n,n]
     i - first index of n (e.g. if n=12:[1,4,10,12,12,12,12,12,12,12,12,12] -> 4)

Попередній 7 byters з використанням зниженого діапазону [0,1,2,3,...,n-1]і підрахунком tetrahedrals менше п:
Ḷ+\⁺<µS,
Ḷ+\⁺<ḅ1,
Ḷ+\⁺<ċ1, і
Ḷ+\⁺<¹S


19

Пітон , 27 байт

lambda n:int((n*6)**.33359)

Спробуйте в Інтернеті!

Пряма формула з деяким приляганням кривих, така сама, як і оригінальна, знайдена рівнем River St.

Зсунене рівняння i**3-i==n*6близьке до i**3==n*6великого i. Це вирішує i=(n*6)**(1/3). Знімаючи підлогу вниз, за ​​необхідності, компенсуючи вимикання.

Але є 6 входів на межі, де помилка приймає її нижче цілого числа, яке повинно бути вище. Все це можна виправити, трохи збільшивши показник, не вводячи подальших помилок.


Пітон , 38 байт

f=lambda n,i=1:i**3-i<n*6and-~f(n,i+1)

Формула n=i*(i+1)*(i+2)/6для чотиригранних чисел може бути красивіше записана i+1як n*6=(i+1)**3-(i+1). Отже, ми знаходимо найнижчу iдля якої i**3-i<n*6. Кожен раз, коли ми збільшуємо, iпочинаючи з 1, рекурсивні дзвінки додають 1до результату. Починаючи з, i=1а не i=0компенсуючи зміну.


Приємно. Я думав про те, щоб пройти шахту для гольфу таким чином, але цього не зробив. Тим не менш, я спробую змінити; наші відповіді все одно будуть іншими.
— 0WJYxW9FMN

1
Вуа. Ваш новий дивовижний.
— 0WJYxW9FMN

1
26-байтна версія не відповідає 364, що виключається з тестового діапазону. **.33359працює на один зайвий байт.
— Денніс

@ Денніс Дякую Ексклюзивні діапазони Python знову вражають!
— xnor

1
lambda n:n**.3336//.5501економить кілька байт.
— Денніс

10

J , 12 байт

2>.@-~3!inv]

Можливо, це є спосіб, коли це можна зробити, але це прекрасна можливість використовувати вбудовану функцію інверсії J.

Спробуйте в Інтернеті!

Як це працює

2>.@-~3!inv]  Monadic verb. Argument: n

           ]  Right argument; yield n.
      3       Yield 3.
       !inv   Apply the inverse of the ! verb to n and 3. This yields a real number.
              x!y computes Π(y)/(Π(y-x)Π(x)), where Π is the extnsion of the 
              factorial function to the real numbers. When x and y are non-negative
              integers, this equals yCx, the x-combinations of a set of order y.
 >.@-~        Combine the ceil verb (>.) atop (@) the subtraction verb (-) with
              swapped arguments (~).
2             Call it the combined verbs on the previous result and 2.


7

Желе , 7 байт

R‘c3<¹S

Спробуйте в Інтернеті!

Як це працює

R‘c3<¹S  Main link. Argument: n

R        Range; yield [1, ..., n].
 ‘       Increment; yield [2, ..., n+1].
  c3     Combinations; yield [C(2,3), ..., C(n+1,3)].
    <¹   Yield [C(2,3) < n, ..., C(n+1,3) < n].
      S  Sum; count the non-negative values of k for which C(k+2,3) < n.

2
Іноді я замислююся, що желі не може зробити?
— Курка Сомбреро

1
Днями хтось стане схожим на "Code Golf - повнофункціональний MMO", і Денніс збирається розмістити "Желе, 29 байт" або щось таке дурне.
— corsiKa

6

JavaScript (ES6), 33 байти

n=>(F=k=>k<n?F(k+3*k/i++):i)(i=1)

На основі рекурсивної формули:

a(1) = 1
a(i) = (i + 3) * a(i - 1) / i

Другий вираз також можна записати як ...

a(i) = a(i - 1) + 3 * a(i - 1) / i

... що саме ми тут використовуємо.

a(i - 1)насправді зберігається у kзмінній і передається до наступної ітерації до k >= n.

Тестові справи


Це підступно коротко! Хороша робота.
— FlipTack

@FlipTack Моя перша спроба була заснована на використаній вами формулі. Мені довелося змінити свої плани. ;-)
— Арнольд

6

Рубін, 26 байт

Редагувати: альтернативна версія, ще 26 байт

->n{(n**0.3333*1.82).to_i}

Оригінальна версія

->n{((n*6)**0.33355).to_i}

Використовує той факт, T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6що дуже близький (x+1)**3/6.

Функція просто множиться на 6, знаходить злегка підправлену версію кореня куба (так, потрібно 5 знаків після коми) і повертає результат, урізаний у ціле число.

Тестова програма та вихід

f=->n{((n*6)**0.33355).to_i}
[1,4,10,20,35,56,84,120,165,220,286,364].map{|i|p [i,f[i],f[i+1]]}

[1, 1, 2]
[4, 2, 3]
[10, 3, 4]
[20, 4, 5]
[35, 5, 6]
[56, 6, 7]
[84, 7, 8]
[120, 8, 9]
[165, 9, 10]
[220, 10, 11]
[286, 11, 12]
[364, 12, 13]

0.3336здається, працює для оригінальної версії. (Редагувати: Неважливо, Денніс зазначає, що я забував про 364.)
— xnor

5

JavaScript, 36 33 байт

-3 байти завдяки Лука (що робить функцію викривленою)

n=>f=i=>n<=i/6*-~i*(i+2)?i:f(-~i)

Це неназвана лямбда-функція, якій можна призначити funcта викликати func(220)(), як описано в цьому мета-пості . Моя оригінальна функція, яка не має вибору, виглядає так:

f=(n,i)=>n<=-~i*i/6*(i+2)?i:f(n,-~i)

У цій відповіді використовується той факт, що x- й чотиригранний номер можна знайти за допомогою наступної функції:

f (x) = x / 6 (x + 1) (x + 2)

Подання працює шляхом рекурсивного збільшення iі знаходження tetrahedral(i), поки воно не буде більшим або рівним n(кількість подарункових подарунків).

Коли викликається з одним аргументом, як очікувалося i = undefined, а тому не більше, ніж n. Цей засіб f(n,-~i)виконується і -~undefinedоцінюється 1, що запускає рекурсію.


Фрагмент тесту:

func = n=>f=i=>n<=i/6*-~i*(i+2)?i:f(-~i)

var tests = [1, 5, 75, 100, 220, 221, 364];
tests.forEach(n => console.log(n + ' => ' + func(n)()));


Я збирався розмістити таку саму відповідь. Бийте мене на 2 хвилини. Хороша робота!
— Лука

Ви можете зберегти 3 байта від вичинки: n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i). Ви б так називали f(2)().
— Лука

@Luke гарне місце, моя вибаглива функція була не така коротка. Ви впевнені, що не хочете розмістити це як власну відповідь?
— FlipTack

Ні, я би зробив це, якби ми використовували іншу формулу, але зараз наші рішення майже однакові. Я вважаю за краще допомогти вам стати на тому ж рівні, що і Арнольд. ;-)
— Лука

3
i=>n<=iКрасиво ;-)
— ETHproductions

3

MATL , 12 11 байт

`G@H+IXn>}@

Спробуйте в Інтернеті!

Пояснення

`       % Do...while
  G     %   Push input, n
  @     %   Push iteration index (1-based), say m
  H     %   Push 2
  +     %   Add
  I     %   Push 3
  Xn    %   Binomial coefficient with inputs m+2, 3
  >     %   Is n greater than the binomial coefficient? If so: next iteration
}       %   Finally (execute after last iteration, before exiting the loop)
  @     %   Push last iteration index. This is the desired result
        % End (implicit)
        % Display (implicit)



2

Математика, 26 байт

(0//.i_/;i+6#>i^3:>i+1)-1&

Безіменна функція, яка приймає невід'ємний цілий аргумент і повертає негативне ціле число (так, воно працює і за день 0). Ми хочемо знайти найменше ціле число, iдля якого вхід #не більше i(i+1)(i+2)/6, що є формулою кількості подарунків, поданих у перші iдні. Через легку алгебраїчну хитрість нерівність # ≤ i(i+1)(i+2)/6еквівалентна (i+1) + 6# ≤ (i+1)^3. Таким чином, структура 0//.i_/;i+6#>i^3:>i+1починається з а 0і продовжує додавати 1, доки тест i+6#>i^3буде задоволений; потім(...)-1& віднімаємо 1в кінці (а не витрачаємо байти з дужками всередині нерівності).

Якщо ми продовжимо тривалість Різдва 12, ми можемо обробити приблизно 65536 днів до вбудованого обмеження рекурсії для //.зупинки процесу ... це приблизно 4,7 * 10 ^ 13 днів, або приблизно в десять разів перевищує вік Всесвіту до цих пір ….


2

J , 9 байт

I.~3!2+i.

Спробуйте в Інтернеті!

Це неефективніше, ніж використання зворотного факторного, але, здається, коротше.

Наприклад, якщо вхідне ціле число n = 5, зробіть діапазон [2, n+1].

2 3 4 5 6 choose 3
0 1 4 10 20

Це перші 5 тетраедричних чисел. Наступним кроком є ​​визначення, до якого інтервалу (дня) належить n . Є n +1 = 6 інтервалів.

0 (-∞, 0]
1 (0, 1]
2 (1, 4]
3 (4, 10]
4 (10, 20]
5 (20, ∞)

Тоді n = 5 належить до інтервалу 3, який є(4, 10] а результат 3.

Пояснення

I.~3!2+i.  Input: integer n
       i.  Range [0, n)
     2+    Add 2 to each
   3!      Combinations nCr with r = 3
I.~        Interval index of n

2

Пітон, 43 байти

f=lambda n,i=0:n*6>-~i*i*(i+2)and-~f(n,i+1)

Збережено 5 байт завдяки @FlipTack та ще 3 завдяки @xnor !


Це дає f(220)=11, що має бути f(220)=10.
— xnor

О, я використовував Python 2. Для цього потрібно Python 3, щоб уникнути поділу підлоги, хоча, можливо, ви можете помножити на іншій стороні замість цього, щоб зробити його версійно-агностичним.
— xnor

Я думаю , що ви можете зробити and-~f(n,i+1)для and f(n,i+1)or i. Як не дивно, це зазвичай коротше, коли ви підраховуєте змінну рекурсивно не для її повернення, а для того, щоб натомість збільшувати вихід рекурсивно.
— xnor

2

Japt , 12 байт

1n@*6§X³-X}a

Перевірте це в Інтернеті! або Перевірте всі тестові випадки одразу

Як це працює

1n@*6§X³-X}a  // Implicit: U = input integer
  @       }a  // Find the smallest non-negative integer X which satisfies this condition:
      X³-X    //   (X ^ 3) - X
     §        //   is greater than or equal to
   *6         //   U * 6.
1n            // Subtract 1 from the result.
              // Implicit: output result of last expression

Це спрощення тетраедричної формули, яку використовують кілька інших відповідей:

f(x) = (x)(x + 1)(x + 2)/6

Підставляючи x - 1в x, ми можемо спростити це значно:

f(x) = (x - 1)(x)(x + 1) / 6
f(x) = (x - 1)(x + 1)(x) / 6
f(x) = (x^2 - 1)(x) / 6
f(x) = (x^3 - x) / 6

Тому правильний результат на один менший, ніж найменше ціле число, xтаке(x^3 - x) / 6 більше або дорівнює вхідному.

13-байтовое рішення, натхнена @ XNOR в відповіді :

p.3335 /.55 f

Ще кілька рішень @ETHproductions, і я розігрувався

J+@*6§X³-X}a 
@*6§X³-X}a -1
@§X/6*°X*°X}a 
_³-V /6¨U}a -1
§(°V nV³ /6?´V:ß
§(°VV³-V /6?´V:ß

Перевірте це тут .


1

SmileBASIC, 43 байти

INPUT X
WHILE X>P
I=I+1
R=R+I
P=P+R
WEND?I

I- це день, Rє iтретім трикутним числом і Pє iчетвертим чотиригранним числом (кількість подарунків).

Я думаю, схожа відповідь на іншій мові, мабуть: x=>{while(x>p)p+=r+=++i;return i}могла б бути досить хорошою.


Ти хочеш ?Iнаприкінці, чи не так?
— Нік Маттео

1

Python 3, 48 46 байт

f=lambda x,i=1:f(x,i+1)if(i+3)*i+2<x/i*6else i

@FlipTack Argh! Я виправлю це через секунду ... нікого не зволікайте, будь ласка.
— 0WJYxW9FMN

6
Ви можете попередити будь-яке запозичення, видаливши свою відповідь. Потім ви все ще зможете відредагувати відповідь та відновити її після її виправлення.
— Лайконі

Крім того, це все ще не робить те, що задається завданням. Вхід 221волі розбить його.
— FlipTack

Я перевірив це на TIO, і він виходить з ладу на всіх входах. Це моя проблема чи це трапляється з кимось іншим?

Це працювало для мене. Я тестую його ще раз.
— 0WJYxW9FMN


1

Haskell, 21 23 байт

floor.(**(1/3)).(*6.03)

Редагувати: Як зазначав xnor, оригінальне рішення ( floor.(/0.82).(**0.4)) не працювало між різдвяними днями


Це дає неправильну відповідь на багато входів, наприклад 221.
— xnor

0

Пакет, 69 байт

@set/an=d=t=0
:l
@set/at+=d+=n+=1
@if %t% lss %1 goto l
@echo %n%

Вручну обчислює чотиригранні числа.




0

QBIC , 19 байт

Це краде формулу @xnor:

:?int((a*6)^.33359)

Я спробував набрати роздільну здатність до .3336, щоб зберегти байт, але це не вдається на остаточному тесті.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.