Noel hangi gün?


27

önsöz

Tanınmış şarkıcı Noel'de On İki Gün'de, anlatıcıya her gün birkaç hediye verilir. Şarkı kümülatiftir - her ayette, ondan önceki hediyeden daha yüksek bir miktarla yeni bir hediye eklenir. Bir Keklik, İki Kaplumbağa Güvercini, Üç Fransız Tavuk, vb.

Herhangi bir ayet anda, N , biz bularak şarkıda şu ana kadar hediye kümülatif toplamını hesaplayabilirsiniz v- inci tetrahedral numara sonuçları verir:

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

Örneğin, 4. ayetin ardından 4 * (1 keklik) , 3 * (2 kaplumbağa güvercini) , 2 * (3 Fransız tavuk) ve 1 * (4 çağıran kuş) yaşadık . Bunları toplayarak anlıyoruz 4(1) + 3(2) + 2(3) + 1(4) = 20.

Meydan okuma

Göreviniz, 364 ≥ p ≥ 1 hediye sayısını temsil eden pozitif bir tamsayı verildiğinde , Noel'in hangi gün (ayet) olduğunu belirleyen bir program veya işlev yazmaktır .

Örneğin, eğer p = 286 ise , Noel'in 11. gününde. Ancak, eğer p = 287 ise , bir sonraki hediye yükü başladı, yani 12. gün.

Matematiksel olarak, bu sonraki tetrahedral sayıyı bulmak ve tüm tetrahedral sayı sırasındaki konumunu döndürmektir.

Kurallar:

  • Bu , yani en kısa çözüm (bayt cinsinden) kazanır.
  • Standart golf boşlukları geçerlidir.
  • Günlere gelince, programınız 1 indeksli olmalıdır.
  • Gönderiminiz tam bir program veya işlev olmalı - ancak snippet değil.

Test Kılıfları

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

5
Herkesin yardım etmesi durumunda, n. Dördüncü katedral sayısı da ilk n üçgen sayıların toplamıdır .
DJMcMayhem

Bu yardımcı olabilir:, x=>{while(x>p)p+=r+=++i;return i}eminim JavaScript gibi bir dilde kısaltılabilir.
12Me21

1
Bu şimdiye kadarki en eski Noel mücadelesi, değil mi? :)
insertusernamehere

Yanıtlar:


7

Jöle , 7 6 bayt

Dennis sayesinde -1 bayt (minimum vektörlü «ve ilk dizini kullanın i)

R+\⁺«i

TryItOnline

Nasıl?

Tüm bu verimli değil - bir listede sırayla 1. ila 1. tetrahedral sayılarını hesaplar ve ilkine eşit veya daha büyük olan 1 tabanlı dizini döndürür.

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)

Alçaltılmış aralığı kullanılarak Önceki 7 byters [0,1,2,3,...,n-1]n daha az tetrahedrals ve sayım:
Ḷ+\⁺<µS,
Ḷ+\⁺<ḅ1,
Ḷ+\⁺<ċ1ve
Ḷ+\⁺<¹S


19

Python , 27 bayt

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

Çevrimiçi deneyin!

Level River St. tarafından bulunan orijinal ile aynı, bazı eğri uydurma ile doğrudan bir formül

Kaymış denklem büyük için i**3-i==n*6yakındır . İçin çözer . Zemini gerektiği gibi aşağı indirerek, bir-bir için telafi ediyor.i**3==n*6ii=(n*6)**(1/3)

Ancak, hatanın yukarıda olması gereken bir tamsayı altına aldığı sınırlar üzerinde 6 girdi vardır. Bunların tümü, başka hatalar vermeden üssü hafifçe artırarak düzeltilebilir.


Python , 38 bayt

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

Formül n=i*(i+1)*(i+2)/6tetrahedral numaralar için daha güzel yazılabilir i+1olarak n*6=(i+1)**3-(i+1). Yani en düşük iolanı bulduk i**3-i<n*6. i1'den başlayarak her artış yaptığımızda , özyinelemeli çağrılar 1çıktıya ekler . Vardiyayı telafi etmek i=1yerine başlıyor i=0.


Güzel. Bu şekilde golf oynamayı düşündüm, ama yapmadım. Yine de, değişmeyi deneyeceğim; Cevaplarımız hala farklı olacak.
0WJYxW9FMN

1
Woah. Yeni olan harika.
0WJYxW9FMN

1
26 baytlık sürüm test aralığının dışında bırakılan 364 sürümünde başarısız oluyor. **.33359bir ekstra bayt için çalışır.
Dennis

@Dennis Teşekkürler. Özel Python aralıkları tekrar grev!
xnor

1
lambda n:n**.3336//.5501birkaç bayt kaydeder.
Dennis

10

J , 12 bayt

2>.@-~3!inv]

Bunu yapmanın daha kolay bir yolu olabilir, ancak bu J'nin yerleşik fonksiyon inversiyonunu kullanmak için güzel bir fırsat.

Çevrimiçi deneyin!

Nasıl çalışır

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

Jöle , 7 bayt

R‘c3<¹S

Çevrimiçi deneyin!

Nasıl çalışır

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
Bazen merak ediyorum, Jelly ne yapamaz?
Sombrero Tavuğu,

1
Bu günlerden biri birileri "Code Golf tam özellikli bir MMO" gibi olacak ve Dennis "Jelly, 29 bayt" veya bunun gibi aptalca bir şey gönderecek.
corsiKa,

6

JavaScript (ES6), 33 bayt

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

Özyinelemeli formüle göre:

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

İkinci ifade aynı zamanda ...

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

... burada kullandığımız şey.

a(i - 1)Aslında kdeğişkende saklanır ve bir sonraki yinelemeye kadar geçirilir k >= n.

Test durumları


Bu sinsi kısa! Aferin.
FlipTack

@FlipTack İlk denemem, kullandığınız formüle dayanıyordu. Planlarımı değiştirmek zorunda kaldım. ;-)
Arnauld

6

Ruby, 26 bayt

Düzenleme: alternatif sürüm, hala 26 bayt

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

Orijinal versiyon

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

T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6Çok yakın olanı kullanır (x+1)**3/6.

Fonksiyon basitçe 6 ile çarpılır, küp kökünün hafifçe ince ayarlı bir versiyonunu bulur (evet 5 ondalık basamak gereklidir) ve sonucu bir tamsayıya döndürür.

Test programı ve çıktı

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.3336Orijinal sürüm için çalışıyor gibi görünüyor. (Düzenleme: Boşver, Dennis 364'ü unuttuğumu işaret eder.)
xnor

5

JavaScript, 36 33 bayt

Luke sayesinde -3 bayt (işlevi körleştirerek)

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

Bu, bu meta gönderimde açıklandığı gibi atanabilen funcve çağrılabilen adsız bir lambda işlevidir . Orijinal, körensiz işlevim şöyle görünür:func(220)()

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

Bu cevap, x. Tetrahedral sayının aşağıdaki işlevle bulunabileceği gerçeğini kullanır :

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

Teslim, tekrarlanan bir şekilde artarak ive tetrahedral(i)buna eşit veya daha büyük n(verilen hediye sayısı) olana kadar bulma yoluyla çalışır .

Beklendiği gibi bir argüman ile çağrıldığında i = undefined, ve bu nedenle daha büyük değildir n. Bu , özyinelemeyi başlatan f(n,-~i), uygulandığı ve -~undefineddeğerlendirildiği anlamına gelir 1.


Test Parçacığı:

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


Aynı cevabı göndermek üzereydim. Beni 2 dakika geç. Aferin!
Luke

Sen-işlemden tarafından 3 bayt kaydedebilirsiniz: n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i). Sen buna benzersin f(2)().
Luke

@Luke iyi nokta, benim curried fonksiyonum çok kısa değildi. Bunu kendi cevabın olarak göndermek istemediğine emin misin?
FlipTack

Hayır, farklı bir formül kullanıyor olsaydık yapardım, ama şimdi çözümlerimiz neredeyse aynı. Arnauld ile aynı seviyede olmana yardım etmeyi tercih ederim. ;-)
Luke

3
i=>n<=iGüzel ;-)
ETHproductions

3

MATL , 12 11 bayt

`G@H+IXn>}@

Çevrimiçi deneyin!

açıklama

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

XµNÌ3c¹‹_½

Çevrimiçi deneyin!

açıklama

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
Vay be, binom çok daha zekidir [N2Ý+P6÷¹Q#N>, güzel olandan .
Magic Octopus Urn

2

Pyke, 11 bayt

#3RL+B6f)lt

Burada dene!

#3RL+B6f)   -  while rtn <= input as i:
 3RL+       -     i+j for j in range(3)
     B      -    product(^)
      6f    -   ^/6
         lt - len(^)-1

2

Mathematica, 26 bayt

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

Adsız işlev, negatif olmayan bir tamsayı argümanı alarak ve negatif olmayan bir tamsayı döndürür (evet, o da gün boyu çalışır 0). İlk günlerde verilen hediye sayısının formülü iolan, girdinin #en fazla olduğu en küçük tam sayıyı bulmak istiyoruz . Hafif cebirsel kandırmaca sayesinde, eşitsizlik eşiti(i+1)(i+2)/6i# ≤ i(i+1)(i+2)/6(i+1) + 6# ≤ (i+1)^3 . Böylece yapı a ile 0//.i_/;i+6#>i^3:>i+1başlar 0ve 1test i+6#>i^3karşılandığı sürece eklemeye devam eder ; sonra sonunda (...)-1&çıkarır 1(eşitsizlik içindeki parantezli baytları harcamak yerine).

12 Günün Noel'in devam etmesine izin verirsek, yerleşik yineleme sınırından yaklaşık 65536 gün önce //. , işlemin durması için işlem yapabiliriz. Bu, yaklaşık 4.7 * 10 ^ 13 gün veya evrenin yaşının yaklaşık on katı ....


2

J , 9 bayt

I.~3!2+i.

Çevrimiçi deneyin!

Bu faktöriyelin tersini kullanmaktan daha yetersizdir, ancak daha kısa olur.

Örneğin, giriş tamsayısı n = 5 ise, aralığı yapın [2, n+1].

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

Bunlar ilk 5 tetrahedral sayılarıdır. Bir sonraki adım, n'nin hangi aralığa (gün) ait olduğunu belirlemektir. Orada n 1 = 6 aralıkları.

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

Daha sonra n = 5, aralık 3'e aittir (4, 10]ve sonuç 3'tür.

açıklama

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 bayt

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

Kaydedilen 5 sayesinde bayt @FlipTack ve başka 3 sayesinde @xnor !


f(220)=11Olması gereken bu verir f(220)=10.
xnor

Oh, Python 2'yi kullanıyordum. Bu, kat bölünmesini önlemek için Python 3'e ihtiyaç duyuyor, ancak belki de diğer tarafla çarparak sürüm agnostik hale getirebilirsiniz.
Xnor

Ne yapabilirim düşünüyorum and-~f(n,i+1)için and f(n,i+1)or i. Garip bir şekilde, bir değişkeni geri döndürmek için değil, bunun yerine çıktıyı özyinelemeli olarak arttırmak için özyinelemeli saydığınız zaman daha kısadır.
xnor

2

Japt , 12 bayt

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

Çevrimiçi test edin! veya Tüm test durumlarını bir kerede doğrulayın

Nasıl çalışır

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

Bu, tetrahedral formülün basitleştirilmesidir ve diğer bazı cevapların kullanılması:

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

İkame ederek x - 1için x, biz oldukça bu kolaylaştırabilirsiniz:

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

Bu nedenle, doğru sonuçları tam sayı küçük bir eksiktir xşekilde (x^3 - x) / 6girişe eşit ya da daha büyüktür.

@ Xnor'ın cevabından ilham alan 13 baytlık çözüm :

p.3335 /.55 f

Birkaç çözüm daha @ETHproductions ve ben oynadım

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

Burada test et .


1

SmileBASIC, 43 bayt

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

Igün olduğunu Rise iinci üçgen numarası ve Pbiri inci yüzlü numarası (sunar sayısı).

Sanırım başka bir dilde benzer bir cevap, belki de: x=>{while(x>p)p+=r+=++i;return i}oldukça iyi olabilir.


?ISonunda istiyorsun , değil mi?
Nick Matteo,

1

Python 3, 48 46 bayt

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

@FlipTack Argh! Bir saniye içinde tamir edeceğim ... kimse oy kullanmadı, lütfen.
0WJYxW9FMN

6
Cevabınızı silerek herhangi bir aşağı oy vermeyi önleyebilirsiniz. Daha sonra hala cevabı düzenleyebilecek ve düzeltildikten sonra geri almayı başarabileceksiniz.
Laikoni

Ayrıca, bu hala istediği şeyi yapmaz. Bir girişi 221onu çökertecek.
FlipTack

Bunu TIO'da test ettim ve tüm girişlerde çöküyor. Bu benim sorunum mu, yoksa bu başkasına mı oluyor?

Benim için çalıştı. Tekrar test edeceğim.
0WJYxW9FMN


1

Haskell, 21 23 bayt

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

Düzenleme: Xnor'ın işaret ettiği gibi, orijinal çözüm ( floor.(/0.82).(**0.4)) Noel günleri arasında işe yaramadı


Bu, birçok
girdideki

0

Toplu, 69 bayt

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

Tetrahedronal sayıları elle hesaplar.




0

QBIC , 19 bayt

Bu @xnor formülünü çaldı:

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

Bir bayttan tasarruf etmek için çözünürlüğü 0,3336 olarak çevirmeyi denedim, ancak bu son test durumunda başarısız oldu.


0

Bash + bc, 44 bayt

bc -l <<< "f=e(.33359*l($1*6));scale=0;f/1"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.