Hôm nay là ngày Giáng sinh nào?


27

Lời nói đầu

Trong bài hát nổi tiếng, Mười hai ngày Giáng sinh , người kể chuyện được tặng một vài món quà mỗi ngày. Bài hát được tích lũy - trong mỗi câu, một món quà mới được thêm vào, với số lượng cao hơn một món quà trước nó. Một Partridge, Hai Rùa Rùa, Ba Gà mái Pháp, v.v.

Tại bất kỳ câu nào, N , chúng ta có thể tính tổng số quà tích lũy cho đến nay trong bài hát bằng cách tìm số tứ diện thứ N , cho kết quả:

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

Ví dụ: sau câu 4, chúng ta đã có 4 * (1 partridge) , 3 * (2 bồ câu rùa) , 2 * (3 con gà mái Pháp)1 * (4 con chim kêu) . Bằng cách tóm tắt những điều này, chúng tôi nhận được 4(1) + 3(2) + 2(3) + 1(4) = 20.

Các thách thức

Nhiệm vụ của bạn là viết một chương trình hoặc hàm, với một số nguyên dương biểu thị số lượng quà tặng 364 ≥ p 1 , xác định ngày nào (câu thơ) của Giáng sinh.

Ví dụ: nếu p = 286 , chúng tôi đang ở vào ngày thứ 11 của Giáng sinh. Tuy nhiên, nếu p = 287 , thì lần tải quà tiếp theo đã bắt đầu, nghĩa là ngày thứ 12.

Về mặt toán học, đây là tìm số tứ diện tiếp theo và trả về vị trí của nó trong toàn bộ dãy số tứ diện.

Quy tắc:

  • Đây là , vì vậy giải pháp ngắn nhất (tính bằng byte) sẽ thắng.
  • Tiêu chuẩn chơi golf áp dụng.
  • Khi đến ngày, chương trình của bạn phải được lập chỉ mục 1.
  • Nội dung gửi của bạn phải là một chương trình đầy đủ hoặc một chức năng - nhưng không phải là một đoạn trích.

Các trường hợp thử nghiệm

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

5
Chỉ trong trường hợp nó giúp mọi người, các n'th số tứ diện cũng là tổng của những người đầu tiên n số tam giác.
DJMcMayhem

Điều này có thể giúp : x=>{while(x>p)p+=r+=++i;return i}, Tôi chắc chắn rằng nó có thể được rút ngắn bằng ngôn ngữ như JavaScript.
12Me21

1
Đây là thử thách Giáng sinh sớm nhất từ ​​trước đến nay, phải không? :)
insertusernamehere

Câu trả lời:


7

Thạch , 7 6 byte

-1 byte nhờ Dennis (sử dụng tối thiểu vectơ «và chỉ mục đầu tiên, i)

R+\⁺«i

Dùng thử

Làm sao?

Không phải là tất cả hiệu quả - tính toán các số tứ diện thứ 1 đến thứ n theo thứ tự trong một danh sách và trả về chỉ số dựa trên 1 của số đầu tiên bằng hoặc lớn hơn.

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)

Trước 7 byters sử dụng phạm vi hạ thấp [0,1,2,3,...,n-1]và đếm tetrahedrals ít hơn n:
Ḷ+\⁺<µS,
Ḷ+\⁺<ḅ1,
Ḷ+\⁺<ċ1, và
Ḷ+\⁺<¹S


19

Python , 27 byte

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

Hãy thử trực tuyến!

Một công thức trực tiếp với một số khớp đường cong, giống như công thức ban đầu được tìm thấy bởi Level River St.

Các phương trình thay đổi i**3-i==n*6là gần i**3==n*6với lớn i. Nó giải quyết được i=(n*6)**(1/3). Lấy sàn nhà xuống khi cần thiết, bù lại cho từng người một.

Nhưng, có 6 đầu vào trên các ranh giới trong đó lỗi sẽ đưa nó xuống dưới một số nguyên mà nó phải ở trên. Tất cả những điều này có thể được khắc phục bằng cách tăng nhẹ số mũ mà không gây ra thêm lỗi.


Python , 38 byte

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

Công thức n=i*(i+1)*(i+2)/6cho số tứ diện có thể được độc đáo hơn viết bằng i+1như n*6=(i+1)**3-(i+1). Vì vậy, chúng tôi tìm thấy thấp nhất icho mà i**3-i<n*6. Mỗi lần chúng tôi tăng ibắt đầu từ 1, các cuộc gọi đệ quy sẽ thêm 1vào đầu ra. Bắt đầu từ i=1chứ không phải i=0bù cho sự thay đổi.


Tốt đẹp. Tôi đã nghĩ về việc chơi golf theo cách này, nhưng tôi đã không làm điều đó. Tuy nhiên, tôi sẽ thử thay đổi; câu trả lời của chúng tôi sẽ vẫn khác nhau.
0WJYxW9FMN

1
Ái chà. Cái mới của bạn thật tuyệt vời
0WJYxW9FMN

1
Phiên bản 26 byte không thành công cho 364, được loại trừ khỏi phạm vi thử nghiệm. **.33359làm việc cho một byte thêm.
Dennis

@Dennis Cảm ơn. Python phạm vi độc quyền một lần nữa!
xnor

1
lambda n:n**.3336//.5501tiết kiệm một vài byte.
Dennis

10

J , 12 byte

2>.@-~3!inv]

Có thể có một cách chơi gôn để làm điều này, nhưng đây là một cơ hội đáng yêu để sử dụng chức năng đảo ngược tích hợp của J.

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Thạch , 7 byte

R‘c3<¹S

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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
Đôi khi tôi tự hỏi, Jelly không thể làm gì?
Gà Sombrero

1
Một trong những ngày này ai đó sẽ giống như "Code Golf một MMO đầy đủ tính năng" và Dennis sẽ đăng "Jelly, 29 byte" hoặc một cái gì đó ngu ngốc như thế.
corsiKa

6

JavaScript (ES6), 33 byte

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

Dựa trên công thức đệ quy:

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

Biểu thức thứ hai cũng có thể được viết là ...

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

... đó là cái mà chúng tôi đang sử dụng ở đây.

a(i - 1)được lưu trữ thực sự trong kbiến và được chuyển sang lần lặp tiếp theo cho đến khi k >= n.

Các trường hợp thử nghiệm


Đây là lén lút ngắn! Làm tốt lắm.
FlipTack

@FlipTack Nỗ lực đầu tiên của tôi dựa trên công thức bạn đã sử dụng. Tôi đã phải thay đổi kế hoạch của mình. ;-)
Arnauld

6

Ruby, 26 byte

Chỉnh sửa: phiên bản thay thế, vẫn 26 byte

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

Phiên bản gốc

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

Sử dụng thực tế T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6là rất gần với (x+1)**3/6.

Hàm chỉ đơn giản là nhân với 6, tìm thấy một phiên bản được điều chỉnh một chút của khối lập phương (có 5 vị trí thập phân được yêu cầu) và trả về kết quả bị cắt cụt thành một số nguyên.

Chương trình thử nghiệm và đầu ra

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.3336dường như làm việc cho phiên bản gốc. (Chỉnh sửa: Đừng bận tâm, Dennis chỉ ra rằng tôi đã quên khoảng 364.)
xnor

5

JavaScript, 36 33 byte

-3 byte nhờ Luke (làm cho hàm bị cong)

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

Đây là một hàm lambda chưa được đặt tên có thể được gán funcvà gọi với func(220)(), như được mô tả trong bài meta này . Chức năng ban đầu, không bị quấy rối của tôi trông như thế này:

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

Câu trả lời này sử dụng thực tế là số tứ diện thứ x có thể được tìm thấy với hàm sau:

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

Việc đệ trình hoạt động bằng cách tăng đệ quy ivà tìm kiếm tetrahedral(i), cho đến khi nó lớn hơn hoặc bằng n(số lượng quà tặng được đưa ra).

Khi được gọi với một đối số như mong đợi i = undefined, và do đó không lớn hơn n. Điều này có nghĩa f(n,-~i)là được thực thi và -~undefinedước tính 1, đặt ra đệ quy.


Đoạn kiểm tra:

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)()));


Tôi đã định đăng chính xác câu trả lời. Đánh tôi 2 phút. Làm tốt lắm!
Lu-ca

Bạn có thể lưu 3 byte bằng cách curry : n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i). Bạn sẽ gọi nó như thế nào f(2)().
Lu-ca

@Luke điểm tốt, chức năng quấy rối của tôi không quá ngắn. Bạn có chắc chắn không muốn đăng nó dưới dạng câu trả lời của riêng bạn?
FlipTack

Không, tôi sẽ làm điều đó nếu chúng tôi sử dụng một công thức khác, nhưng bây giờ các giải pháp của chúng tôi gần như giống hệt nhau. Tôi muốn giúp bạn có cùng đẳng cấp với Arnauld. ;-)
Lu-ca

3
i=>n<=iĐẹp ;-)
Sản phẩm điện tử

3

MATL , 12 11 byte

`G@H+IXn>}@

Hãy thử trực tuyến!

Giải trình

`       % 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

Toán học, 26 byte

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

Hàm không tên lấy một đối số nguyên không âm và trả về một số nguyên không âm (vâng, nó cũng hoạt động cho cả ngày 0). Chúng tôi muốn tìm số nguyên nhỏ nhất imà đầu vào #nhiều nhất i(i+1)(i+2)/6, đó là công thức cho số lượng quà tặng được đưa ra trong những ingày đầu tiên . Thông qua thủ thuật đại số nhẹ, bất đẳng thức # ≤ i(i+1)(i+2)/6tương đương với (i+1) + 6# ≤ (i+1)^3. Vì vậy, cấu trúc 0//.i_/;i+6#>i^3:>i+1bắt đầu bằng một 0và tiếp tục thêm 1miễn là thử nghiệm i+6#>i^3được thỏa mãn; sau đó (...)-1&trừ đi 1ở cuối (thay vì sử dụng byte với dấu ngoặc đơn bên trong bất đẳng thức).

Nếu chúng ta để 12 ngày Giáng sinh tiếp tục, chúng ta có thể xử lý khoảng 65536 ngày trước khi giới hạn đệ quy tích hợp để //.tạm dừng quá trình ... đó là khoảng 4,7 * 10 ^ 13 ngày, hoặc khoảng mười lần tuổi của vũ trụ cho đến nay ....


2

J , 9 byte

I.~3!2+i.

Hãy thử trực tuyến!

Điều này là không hiệu quả hơn so với việc sử dụng nghịch đảo của giai thừa nhưng xảy ra ngắn hơn.

Ví dụ: nếu số nguyên đầu vào là n = 5, hãy tạo phạm vi [2, n+1].

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

Đây là 5 số tứ diện đầu tiên. Bước tiếp theo là xác định khoảng (ngày) n thuộc về. Có n +1 = 6 khoảng.

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

Khi đó n = 5 thuộc về khoảng 3 (4, 10]và kết quả là 3.

Giải trình

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

Python, 43 byte

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

Đã lưu 5 byte nhờ @FlipTack và 3 byte khác nhờ @xnor !


Điều này cho f(220)=11, mà nên được f(220)=10.
xnor

Ồ, tôi đã sử dụng Python 2. Điều này cần Python 3 để tránh phân chia tầng, mặc dù có lẽ bạn có thể nhân lên ở phía bên kia để biến nó thành phiên bản không thể biết.
xnor

Tôi nghĩ bạn có thể làm and-~f(n,i+1)cho and f(n,i+1)or i. Thật kỳ lạ, nó thường ngắn hơn khi bạn đếm một biến đệ quy không phải trả lại nó, mà thay vào đó, tăng sản lượng theo cách đệ quy.
xnor

2

Japt , 12 byte

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

Kiểm tra nó trực tuyến! hoặc Xác minh tất cả các trường hợp thử nghiệm cùng một lúc

Làm thế nào nó hoạt động

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

Đây là một sự đơn giản hóa của công thức tứ diện mà một số câu trả lời khác đang sử dụng:

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

Bằng cách thay thế x - 1cho x, chúng ta có thể đơn giản hóa này đáng kể:

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

Do đó, kết quả đúng là một ít hơn số nguyên nhỏ nhất xsao cho (x^3 - x) / 6lớn hơn hoặc bằng đầu vào.

Giải pháp 13 byte, lấy cảm hứng từ câu trả lời của @ xnor :

p.3335 /.55 f

Một vài giải pháp nữa @ETHproductions và tôi đã chơi xung quanh với

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:ß

Kiểm tra nó ở đây .


1

SmileBASIC, 43 byte

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

Ilà ngày, Risố tam giác thứ, và Pisố tứ diện thứ (số lượng quà).

Tôi nghĩ rằng một câu trả lời tương tự trong một ngôn ngữ khác, có lẽ: x=>{while(x>p)p+=r+=++i;return i}có thể là khá tốt.


Bạn muốn ?Icuối cùng, phải không?
Nick Matteo

1

Python 3, 48 46 byte

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

@FlipTack Argh! Tôi sẽ sửa nó trong giây lát ... không ai downvote, làm ơn.
0WJYxW9FMN

6
Bạn có thể ngăn chặn bất kỳ sự hạ thấp nào bằng cách xóa câu trả lời của bạn. Sau đó, bạn vẫn có thể chỉnh sửa câu trả lời và phục hồi nó sau khi đã sửa.
Laikoni

Ngoài ra, điều này vẫn không làm những gì thách thức yêu cầu. Một đầu vào của 221nó sẽ sụp đổ nó.
FlipTack

Tôi đã thử nghiệm điều này trên TIO và nó gặp sự cố trên tất cả các đầu vào. Đây là vấn đề của tôi hay điều này xảy ra với bất cứ ai khác?

Nó làm việc cho tôi. Tôi sẽ kiểm tra lại.
0WJYxW9FMN


1

Haskell, 21 23 byte

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

Chỉnh sửa: Như xnor đã chỉ ra, giải pháp ban đầu ( floor.(/0.82).(**0.4)) không hoạt động giữa những ngày Giáng sinh


Điều này đưa ra câu trả lời sai trên nhiều đầu vào, ví dụ: 221.
xnor

0

Mẻ, 69 byte

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

Tự tính toán các số tứ diện.



0

R, 19 ký tự

floor((n*6)^.33359)

dựa trên câu trả lời của xnor trong Python.


0

QBIC , 19 byte

Điều này đánh cắp công thức của @xnor:

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

Tôi đã thử quay số độ phân giải xuống .3336 để lưu một byte, nhưng điều đó không thành công trên bản thử nghiệm cuối cùng.


0

Bash + bc, 44 byte

bc -l <<< "f=e(.33359*l($1*6));scale=0;f/1"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.