Który to dzień Bożego Narodzenia?


27

Przedmowa

W znanej kolędie Dwanaście dni świąt Bożego Narodzenia narrator otrzymuje codziennie kilka prezentów. Piosenka jest kumulatywna - w każdym wersecie dodawany jest nowy prezent, o jeden wyższy od prezentu przed nim. Jedna kuropatwa, dwie gołębie żółwiowe, trzy francuskie kury i tak dalej.

W dowolnym wierszu N możemy obliczyć łączną sumę prezentów do tej pory w piosence, znajdując N- tą liczbę czworościenną , która daje wyniki:

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

Na przykład po wersecie 4 mieliśmy 4 * (1 kuropatwa) , 3 * (2 turkawki) , 2 * (3 kury francuskie) i 1 * (4 wzywające ptaki) . Sumując je, otrzymujemy 4(1) + 3(2) + 2(3) + 1(4) = 20.

Wyzwanie

Twoim zadaniem jest napisanie programu lub funkcji, która przy dodatniej liczbie całkowitej reprezentującej liczbę prezentów 364 ≥ p ≥ 1 , określa, który dzień (wiersz) Bożego Narodzenia jest.

Na przykład, jeśli p = 286 , jesteśmy w 11. dniu świąt Bożego Narodzenia. Jeśli jednak p = 287 , rozpoczęło się kolejne ładowanie prezentów, co oznacza, że ​​jest to 12 dzień.

Matematycznie znajduje to kolejną liczbę czworościenną i zwraca jej pozycję w całej sekwencji liczb czworościennych.

Zasady:

  • To jest , więc wygrywa najkrótsze rozwiązanie (w bajtach).
  • Obowiązują standardowe luki w grze w golfa.
  • Jeśli chodzi o dni, twój program musi mieć indeks 1.
  • Twoje zgłoszenie musi być pełnym programem lub funkcją - ale nie fragmentem kodu.

Przypadki testowe

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

5
Na wypadek, gdyby komukolwiek to pomogło, n-ta czworościenna liczba jest również sumą pierwszych n liczb trójkątnych.
— DJMcMayhem

Może to pomóc: x=>{while(x>p)p+=r+=++i;return i}jestem pewien, że można go skrócić w języku takim jak JavaScript.
— 12Me21

1
To najwcześniejsze świąteczne wyzwanie, prawda? :)
— inserttusernamehere

Odpowiedzi:


7

Galaretka , 7 6 bajtów

-1 bajt dzięki Dennisowi (użyj minimum wektorowego «i pierwszego indeksu i)

R+\⁺«i

TryItOnline

W jaki sposób?

Nie wszystko tak wydajne - oblicza od 1 do n-tej liczby czworościennej w kolejności na liście i zwraca indeks oparty na 1 pierwszej, która jest równa lub większa.

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)

Poprzednia 7 byters użyciem obniżony zakres [0,1,2,3,...,n-1]mniej i liczenia tetrahedrals niż n:
Ḷ+\⁺<µS,
Ḷ+\⁺<ḅ1,
Ḷ+\⁺<ċ1i
Ḷ+\⁺<¹S


19

Python , 27 bajtów

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

Wypróbuj online!

Bezpośrednia formuła z pewnym dopasowaniem krzywej, taka sama jak oryginalna znaleziona przez Level River St.

Przesunięte równanie i**3-i==n*6jest zbliżone do i**3==n*6dużego i. To rozwiązuje i=(n*6)**(1/3). W razie potrzeby zabiera głos w dół, kompensując efekt off-by-one.

Ale istnieje 6 danych wejściowych na granicach, gdzie błąd umieszcza go poniżej liczby całkowitej, którą powinien być powyżej. Wszystkie te można naprawić poprzez nieznaczne zwiększenie wykładnika bez wprowadzania dalszych błędów.


Python , 38 bajtów

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

Wzór n=i*(i+1)*(i+2)/6na liczby czworościenne można ładniej zapisać i+1jako n*6=(i+1)**3-(i+1). Tak więc znajdujemy najniższą idla której i**3-i<n*6. Za każdym razem, gdy zwiększamy iod 1, rekurencyjne wywołania zwiększają 1wynik. Zaczynając od, i=1zamiast i=0kompensować zmianę.


Miły. Tak myślałem o grze w golfa, ale tego nie zrobiłem. Niemniej jednak spróbuję się zmienić; nasze odpowiedzi wciąż będą inne.
— 0WJYxW9FMN

1
Łał Twój nowy jest niesamowity.
— 0WJYxW9FMN

1
Wersja 26-bajtowa kończy się niepowodzeniem dla 364, co jest wykluczone z zakresu testowego. **.33359działa na jeden dodatkowy bajt.
— Dennis

@Dennis Thanks. Ekskluzywne zakresy Pythona znów uderzają!
— xnor

1
lambda n:n**.3336//.5501oszczędza kilka bajtów.
— Dennis

10

J , 12 bajtów

2>.@-~3!inv]

Może to być bardziej golfowy sposób, ale jest to świetna okazja, aby użyć wbudowanej funkcji inwersji J.

Wypróbuj online!

Jak to działa

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

Galaretka , 7 bajtów

R‘c3<¹S

Wypróbuj online!

Jak to działa

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
Czasami zastanawiam się, czego nie może zrobić Jelly ?
— Sombrero Chicken

1
Któregoś dnia ktoś będzie taki jak „Code Golf w pełni funkcjonalny MMO”, a Dennis zamieści „Jelly, 29 bajtów” lub coś w tym rodzaju głupiego.
— corsiKa

6

JavaScript (ES6), 33 bajty

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

Na podstawie rekurencyjnej formuły:

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

Drugie wyrażenie można również zapisać jako ...

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

... którego tu używamy.

a(i - 1)jest faktycznie przechowywany w kzmiennej i przekazywany do następnej iteracji do k >= n.

Przypadki testowe


To jest podstępnie krótkie! Dobra robota.
— FlipTack

@FlipTack Moja pierwsza próba była oparta na użytej formule. Musiałem zmienić swoje plany. ;-)
— Arnauld

6

Rubinowy, 26 bajtów

Edycja: wersja alternatywna, wciąż 26 bajtów

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

Orginalna wersja

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

Wykorzystuje to, T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6co jest bardzo blisko (x+1)**3/6.

Funkcja po prostu mnoży przez 6, znajduje nieco ulepszoną wersję pierwiastka kostki (tak, wymagane jest 5 miejsc po przecinku) i zwraca wynik obcięty do liczby całkowitej.

Program testowy i wyjście

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.3336wydaje się działać w oryginalnej wersji. (Edytuj: Nieważne, Dennis zaznacza, że ​​zapomniałem o 364.)
— xnor

5

JavaScript, 36 33 bajtów

-3 bajty dzięki Lukeowi (funkcja curry)

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

Jest to nienazwana funkcja lambda, którą można przypisać funci wywołać func(220)()zgodnie z opisem w tym poście . Moja oryginalna funkcja bez curry wygląda następująco:

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

Ta odpowiedź wykorzystuje fakt, że x- ta liczba czworościenna może być znaleziona za pomocą następującej funkcji:

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

Przesyłanie polega na rekurencyjnym zwiększaniu ii znajdowaniu tetrahedral(i), aż będzie większe lub równe n(podanej liczbie prezentów).

Po wywołaniu z jednym argumentem zgodnie z oczekiwaniami i = undefined, a zatem nie jest większy niż n. Oznacza to, że f(n,-~i)jest wykonywany i -~undefinedocenia 1, co uruchamia rekurencję.


Fragment testowy:

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


Właśnie miałem opublikować tę samą odpowiedź. Pokonaj mnie o 2 minuty. Dobra robota!
— Łukasza

Można zapisać 3 bajty przez zmiękczania: n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i). Nazwałbyś to tak f(2)().
— Łukasz

@Luke dobre miejsce, moja funkcja curry nie była taka krótka. Czy na pewno nie chcesz opublikować tego jako własnej odpowiedzi?
— FlipTack

Nie, zrobiłbym to, gdybyśmy używali innej formuły, ale teraz nasze rozwiązania są prawie identyczne. Wolę pomóc ci wejść na ten sam poziom co Arnauld. ;-)
— Łukasz

3
i=>n<=iPiękny ;-)
— ETHprodukcje

3

MATL , 12 11 bajtów

`G@H+IXn>}@

Wypróbuj online!

Wyjaśnienie

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

05AB1E , 10 bajtów

XµNÌ3c¹‹_½

Wypróbuj online!

Wyjaśnienie

Xµ          # loop until counter equals 1
  NÌ3c      # binomial_coefficient(iteration_index+2,3)
      ¹     # push input
       ‹_   # not less than
         ½  # if true, increment counter
            # output last iteration index

1
Wow, binom jest znacznie mądrzejszy niż [N2Ý+P6÷¹Q#N>miły.
— Magic Octopus Urn


2

Mathematica, 26 bajtów

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

Nienazwana funkcja przyjmująca nieujemną liczbę całkowitą i zwracająca nieujemną liczbę całkowitą (tak, działa również na dzień 0). Chcemy znaleźć najmniejszą liczbę całkowitą, idla której dane wejściowe #są co najwyżej i(i+1)(i+2)/6, czyli wzór na liczbę prezentów podanych w pierwszych idniach. Poprzez łagodną algebraiczną sztuczkę nierówność # ≤ i(i+1)(i+2)/6jest równoważna (i+1) + 6# ≤ (i+1)^3. Struktura 0//.i_/;i+6#>i^3:>i+1zaczyna się od a 0i dodaje, 1dopóki test i+6#>i^3jest spełniony; następnie (...)-1&odejmuje 1na końcu (zamiast wydawać bajty z nawiasami wewnątrz nierówności).

Jeśli pozwolimy, aby 12 Dni Świąt Bożego Narodzenia trwało dalej, możemy obsłużyć około 65536 dni przed wbudowanym limitem rekurencji, aby //.zatrzymać proces ... to około 4,7 * 10 ^ 13 dni lub około dziesięciokrotnie wiek wszechświata do tej pory ....


2

J , 9 bajtów

I.~3!2+i.

Wypróbuj online!

Jest to bardziej nieefektywne niż użycie odwrotności silni, ale zdarza się, że jest krótsze.

Na przykład, jeśli wejściowa liczba całkowita wynosi n = 5, określ zakres [2, n+1].

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

Są to pierwsze 5 liczb czworościennych. Następnym krokiem jest określenie, do którego przedziału (dnia) n należy. Istnieje n +1 = 6 przedziałów.

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

Zatem n = 5 należy do przedziału 3, który jest, (4, 10]a wynikiem jest 3.

Wyjaśnienie

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 bajty

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

Zaoszczędź 5 bajtów dzięki @FlipTack i kolejne 3 dzięki @xnor !


To daje f(220)=11, co powinno być f(220)=10.
— xnor

Och, używałem Pythona 2. To wymaga Pythona 3, aby uniknąć podziału podłogi, ale być może możesz zamiast tego pomnożyć po drugiej stronie, aby był niezależny od wersji.
— xnor

Myślę, że można to zrobić and-~f(n,i+1)za and f(n,i+1)or i. O dziwo, zwykle jest krótszy, gdy rekurencyjnie zliczasz zmienną, aby jej nie zwrócić, ale zamiast tego rekurencyjnie zwiększać wynik.
— xnor

2

Japt , 12 bajtów

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

Przetestuj online! lub Zweryfikuj wszystkie przypadki testowe jednocześnie

Jak to dział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

Jest to uproszczenie formuły czworościennej, z której korzysta kilka innych odpowiedzi:

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

Podstawiając x - 1do x, możemy znacznie uprościć ten:

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

Dlatego poprawny wynik jest o jeden mniejszy od najmniejszej liczby całkowitej xtakiej, która (x^3 - x) / 6jest większa lub równa wartości wejściowej.

Roztwór 13-bajtowy, zainspirowany @ XNOR za odpowiedź :

p.3335 /.55 f

Jeszcze kilka rozwiązań @ETHproductions i bawiłem się

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

Sprawdź to tutaj .


1

SmileBASIC, 43 bajty

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

Ijest dniem, Rjest itrzecią liczbą trójkątną i Pjest iczwartą liczbą czworościenną (liczbą prezentów).

Myślę, że podobna odpowiedź x=>{while(x>p)p+=r+=++i;return i}może być w innym języku: może być całkiem dobra.


Chcesz ?Ina końcu, prawda?
— Nick Matteo

1

Python 3, 48 46 bajtów

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

@FlipTack Argh! Naprawię to za chwilę ... proszę, niech nikt nie przegłosuje.
— 0WJYxW9FMN

6
Możesz zapobiec głosowaniu, usuwając odpowiedź. Nadal będziesz mógł edytować odpowiedź i cofnąć jej usunięcie, gdy zostanie naprawiona.
— Laikoni

Ponadto nadal nie spełnia wymagań stawianych przez wyzwanie. Wejście 221spowoduje awarię.
— FlipTack

Przetestowałem to na TIO i zawiesza się na wszystkich wejściach. Czy to mój problem, czy dzieje się to z kimś innym?

To zadziałało dla mnie. Przetestuję to jeszcze raz.
— 0WJYxW9FMN


1

Haskell, 21 23 bajtów

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

Edycja: Jak wskazał xnor, oryginalne rozwiązanie ( floor.(/0.82).(**0.4)) nie działało między świętami Bożego Narodzenia


Daje to błędną odpowiedź na wiele danych wejściowych, na przykład 221.
— xnor

0

Partia, 69 bajtów

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

Ręcznie oblicza liczby czworościanów.




0

QBIC , 19 bajtów

To kradnie formułę @xnor:

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

Próbowałem obniżyć rozdzielczość do .3336, aby zapisać bajt, ale to nie powiedzie się na końcowym przypadku testowym.


0

Bash + bc, 44 bajty

bc -l <<< "f=e(.33359*l($1*6));scale=0;f/1"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.