Üssünüzü 1-2-3-Tribonacci üssü


19

Arka fon

1-2-3-Tribonacci Dizisi

Bir saniye için standart iterasyon formülünü aşağıdaki ile değiştirerek bir fibonacci dizisi yapabileceğinizi düşünün:

tribonacci

Temel olarak, bir sonrakini almak için son ikisini toplamak yerine, son üçünü toplarsınız. 1-2-3-Tribonacci dizisinin temeli budur.

Brown'un Kriteri

Brown'un Ölçütü, bir dizinin üyelerinin toplamı olarak herhangi bir tamsayı değerini temsil edebileceğinizi belirtir:

  1. x alt n eşittir 1

  2. Tüm için n1 'den büyük,x alt n 2'den az x alt n - 1

Bu meydan okuma için ne anlama geliyor?

Herhangi bir pozitif tamsayıyı, aşağıdaki başlangıç ​​koşullarından oluşan 1-2-3-Tribonacci dizisinin üyelerinin toplamı olarak tanımlayabilirsiniz:

başlangıç ​​koşulları

Bu, bu dizideki her değer için, terimler arasındaki oran asla 2'den büyük değildir (oranın ortalama 1.839'da olduğu).

Bu sayısal gösterim sistemine nasıl yazılır

Diyelim ki biraz endian bir temsili kullanıyorsunuz. Dizinin üyelerini şu şekilde sıralayın:

1  2  3  6 11 20 37 68

Daha sonra, numaranızı temsil edersiniz (testlerimiz için diyelim ki 63) ve verilen 1-2-3-Tribonacci'nin değerlerini (toplamda en büyük değerleri kullanarak!) 63 olarak bulursunuz . Sayı toplamın bir parçasıysa, altına 1, değilse 0 yazın.

1  2  3  6 11 20 37 68
0  0  0  1  0  1  1  0

Bunu herhangi bir tamsayı için yapabilirsiniz - önce verilen girdinin altındaki en büyük değerleri kullandığınızı doğrulamanız yeterlidir!

Tanım (sonunda)

n1 ile dilinizin maksimum değeri arasında bazı pozitif tamsayı girişleri (herhangi bir standart temelde yazılmış) verildiğinde aşağıdakileri yapacak bir program veya işlev yazın :

  1. Değeri tanımlanan 1-2-3-Tribonacci'nin sayısal gösterimine dönüştürün.
  2. Bu ikili benzeri gösterimi kullanarak ve sanki ikiliymiş gibi okuyun. Bu, rakamların aynı kaldığı, ancak ne anlama geldiklerinin değiştiği anlamına gelir.
  3. Bu ikili sayıyı alın ve orijinal sayının tabanına dönüştürün.
  4. Bu yeni numarayı girin veya gönderin.

Ancak, çıktı geçerli olduğu sürece, bu adımları izlemenize gerek yoktur. Sihirli olarak daha kısa (ve matematiksel olarak eşdeğer) bir formül bulursanız, kullanmaktan çekinmeyin.

Örnekler

İşlevin ftanım tarafından tanımlanan işlev olmasına izin verin ve []atılan adımları temsil etsin (küçük endian olarak, önemli olmamasına rağmen) (bu işlemi izlemenize gerek yoktur, bu sadece açıklanan işlemdir):

>>> f(1)
[1]
[1]
[1]
1

>>> f(5)
[5]
[0, 1, 1]
[6]
6

>>> f(63)
[63]
[0, 0, 0, 1, 0, 1, 1]
[104]
104

Kısa bir süre olmasa da soruyu daha hızlı çözecek ayrı bir program gönderebilir miyim? log (log (n)) + n zaman log (n) + n zaman yerine. Gidip Nth güç matrisi.
fəˈnɛtɪk

@LliwTelracs Çözümlerinizi göndermenizi engelleyemiyorum. Sadece doğru alanda rekabet ettiğinizden emin olmak için bu çözüm yöntemi hedefini bilginize kısa ve öz yapın.
Addison Crump

En azından bunu yapmayacaksın. Bu matrisin hızlı
üslenmesi

2
@LliwTelracs Belki sadece mevcut yayınınıza ek olarak ekleyebilirsiniz.
Jonathan Allan

meydan okumanız görüntüleri gösteremeyenler için okunaksız.
Mindwin

Yanıtlar:


7

Javascript 117111 bayt

@Theonlygusti'ye 5 bayt golf için yardım ettiği için teşekkürler

x=>{r=0;a=[1,2,3];i=1;while(a[++i]<x)a[i+1]=a[i]+a[i-1]+a[i-2];for(;x;i--)if(x>=a[i]){r+=1<<i;x-=a[i]}return r}

Nasıl çalışır

İlk olarak, fonksiyon girdiden bir tane daha bulana kadar tüm tribonacci sayılarını üretir

a=[1,2,3];i=1;for(;a[++i]<x;)a[i+1]=a[i]+a[i-1]+a[i-2];

Daha sonra, sayı listesini tersine arar. Bir sayı girişten küçükse, dönüş değerine 2 ^ (o sayının dizini) ekler ve girişi bu sayı kadar azaltır.

for(;x;i--)if(x>=a[i]){r+=1<<i;x-=a[i]}

Sonunda sonucu döndürür.

Çevrimiçi Deneyin


1
a[++i]<xbir bayt kaydetmek için koşul içinde ne olacak ?
theonlygusti

1
Ayrıca, x>0ile değiştirebilirsiniz x. Başka bir 2 bayt kaydedin.
theonlygusti

Bu oldukça iyi bir algoritma. oo
Addison Crump

7

Piton 2 , 110 102 bayt

Rod sayesinde -3 bayt ( ibir int'e boolean dökümü için temiz hile +iböylece repr `+i`çalışır)

n=input()
x=[3,2,1]
r=''
while x[0]<n:x=[sum(x[:3])]+x
for v in x:i=n>=v;n-=v*i;r+=`+i`
print int(r,2)

Çevrimiçi deneyin!


1
Eğer yerine '01'[i]birlikte`+i`
Rod

iint bir boolean değil. Düzenle - Ohhh +i, temiz.
Jonathan Allan

3
@Rod Python 2 ipuçları ve püf noktaları bu hile mi?
Addison Crump

@VoteToClose Sanmıyorum
Rod

7

JavaScript (ES6), 97 93 bayt

Burada reduce()özyinelemeli bir işlev kullanıyoruz. Çıktının 31 bit (JS'nin zaten bitsel işlemler için kolayca çalışabileceği en büyük işaretsiz miktar) olduğunu varsayıyoruz.

n=>[...Array(x=31)].reduce(p=>(c=(F=k=>k<4?k:F(--k)+F(--k)+F(--k))(x--))>n?p:(n-=c,p|1<<x),0)

Performans açısından, bu çok verimli değil.

Meraklı için:

  • F()N + 1 reduce()yinelemeleri ile N yinelemeleri arasındaki çağrı sayısı arasındaki oran hızla Tribonacci Sabiti'ne yaklaşmaktadır (≈ 1.83929). Bu nedenle, çıktıdaki her ek bit bir öncekinden yaklaşık iki kat daha fazla zaman alır.
  • 31 bit ile F()fonksiyona 124 milyon kez iyi denir.

Ölçek

Not: Bu işlemin tamamlanması 1 veya 2 saniye sürebilir.


Vay canına, kullandığımda tarayıcım gecikiyor. xD
Addison Crump

@VoteToClose Performans akıllıca, bu korkunç derecede verimsiz. :-) Ancak test kodu çok uzun süre kalmamalıdır. Kutumda, Firefox'ta yaklaşık 600ms ve Chrome'da 900ms olsun. Senin tarafında çok mu yavaş?
Arnauld

5 saniye gibi. xD
Addison Crump

@VoteToClose Şimdi biraz daha hızlı olmalı. 32. yineleme anlamsız, bu yüzden çıktı işaretsiz bir 31-bit tam sayı ile sınırlı ettik.
Arnauld

6

Mathematica, 78 74 bayt

Fold[#+##&,#~NumberDecompose~Reverse@LinearRecurrence[{1,1,1},{1,2,3},#]]&

LinearRecurrence[{1,1,1},{1,2,3},#]1-2-3 tribonacci sayılarının girişine eşit uzunlukta bir liste oluşturur. ( İlk değerler {1,1,1}, önceki üç terimin toplamını temsil eder {1,2,3}.) Ardından #~NumberDecompose~, girdiyi listenin öğelerinin toplamı olarak yazmanın en kolay yolunu bulur (bu, parasal bir tutarı mevcut para birimleri). Son olarak, Fold[#+##&,...]sonuçta oluşan ikili listeyi (base-10) tamsayıya dönüştürür.

Önceki gönderim:

Fold[#+##&,#~NumberDecompose~Reverse@Array[If[#<4,#,Tr[#0/@(#-Range@3)]]&,#]]&

Çoğu zaman olduğu gibi (yukarıda olmasa da), bu golf edilmiş sürüm 20'den büyük girişlerde süper yavaştır, çünkü uzunluğu optimize edilmiş olan triblerin bir listesini oluşturur (optimize edilmemiş özyineleme ile); finali #daha makul bir sınırla değiştirmek Round[2Log@#+1]çok daha iyi performans sağlar.


Whaat? Mathematica'da 123Tribonacci[]yerleşik yok mu?
palsch

1
Tam olarak değil, bir yerleşik kullanmanın biraz yardımcı olduğu ortaya çıkıyor.
Greg Martin

5

Haskell, 95 bayt

(a!b)c=a:(b!c)(a+b+c)
e#(r,c)|c-e<0=(2*r,c)|1<2=(2*r+1,c-e)
f n=fst$foldr(#)(0,n)$take n$(1!2)3

Kullanım örneği: f 63->104 . Çevrimiçi deneyin! .

Nasıl çalışır: !1-2-3-Tribonacci dizisini oluşturur. Verilen 1, 2ve 3başlangıç parametreleri gibi, biz ilk almak ndizinin elemanlarını. Sonra sağ işlevinden kat #sonraki eleman çıkarır egelen nve dönüş değeri biti ayarlayarak reğer egerekli veya bit belirli olmayan z sağlar. Bit ayarı iki katına çıkarılıyor rve ekleniyor 1, ayarsız bırakılması sadece iki katına çıkıyor.


4

Jöle , 31 bayt

S=³
3RUµḣ3S;µ<³Ạµ¿µŒPÇÐfṀe@ЀµḄ

Çevrimiçi deneyin!

Jelly'de bunu başarmanın çok daha kısa bir yolu olduğundan neredeyse eminim.

Nasıl?

S=³ - Link 1, compare sum to input: list
S   - sum
  ³ - 3rd command line argument which is 1st program argument.
 =  - equal?

3RUµḣ3S;µ<³Ạµ¿µŒPÇÐfṀe@ЀµḄ - Main link: n
3RU                         - range(3) upended -> [3,2,1]
   µ    µ   µ¿              - while
         <³                 - less than input (vectorises)
           Ạ                - all?
    ḣ3S;                    -     head(3), sum, and concatenate
                                  [3,2,1] -> [6,3,2,1] -> [11,6,3,2,1] -> ...
              µ             - monadic chain separation, call the result x
               ŒP           - power set of x - e.g. for [6,3,2,1] -> [[],[6],[3],[2],[1],[6,3],[6,2],[6,1],[3,2],[3,1],[2,1],[6,3,2],[6,3,1],[6,2,1],[3,2,1],[6,3,2,1]]
                  Ðf        - filter keep
                 Ç          -     last link (1) as a monad (those that sum to the input)
                    Ṁ       - maximum (e.g. an input of 63 would yield [[37,20,6],[37,20,3,2,1]], the maximum of which is [37,20,6], the one with the largest numbers used)
                         µ  - monadic chain separation (to have x as the right argument below)
                     e@Ѐ   - exists in with reversed arguments mapped over x (e.g. [37,20,6] with x = [68,37,20,11,6,3,2,1] yields [0,1,1,0,1,0,0,0])
                          Ḅ - convert from binary to integer.        

4

Perl 6 , 93 91 bayt

B2gills sayesinde -2 bayt

{my@f=1,2,3,*+*+*...*>$^n;sum @f».&{$_~~any first *.sum==$n,@f.combinations}Z*(2 X**^∞)}

Nasıl çalışır

  • İlk olarak, girişten daha büyük ilk elemana kadar 1-2-3-Tribonacci dizisini üretir:

    my @f = 1, 2, 3, *+*+* ... * > $^n;
  • Buna dayanarak, girdiye eklenen dizinin alt kümesini bulur:

    first *.sum==$n, @f.combinations
  • Buna dayanarak, dizinin her elemanının toplamın bir parçası olup olmadığını belirten bir booleans listesi oluşturur:

    @f».&{$_~~any ...}
  • Ve son olarak True = 1, False = 0 değerleri listesini base 2 olarak yorumlar ve bunu (base 10) numarası olarak döndürür:

    sum ... Z* (2 X** ^∞)

1
Sen kullanarak bu kısaltabilirsiniz *>$^nve .sum==$n. Ayrıca uzay arasında gerekli değildir myve@f
Brad Gilbert b2gills

3

JavaScript (ES6), 61 60 bayt

n=>(g=(x,y,z)=>(n>x&&g(y,z,x+y+z)*2)+!(n<x||![n-=x]))(1,2,3)

1-2-3-Tribonacci sayılarını orijinal sayıya ulaşana kadar hesaplar, daha sonra özyineleme çözülürken, her birini sırayla çıkarmaya çalışır ve sonucu giderken ikiye katlar.

Düzenleme: @Arnauld sayesinde 1 bayt kaydedildi.


Vaov! Çok hoş. Could n=>(g=(x,y,z)=>(n>x&&g(y,z,x+y+z)*2)+!(n<x||![n-=x]))(1,2,3)bir byte kaydetmek?
Arnauld

@Bir şey kullanarak bir şey arıyordum n<x||ama bu ![]sadece dahiydi.
Neil

2

Toplu, 151 148 145 bayt

@set/ar=0,n=%1
@call:c 3 2 1
@echo %r%
@exit/b
:c
@set/as=%1+%2+%3
@if %n% gtr %3 call:c %s% %*
@set/ar*=2
@if %n% geq %3 set/an-=%3,r+=1

JavaScript yanıtımın bağlantı noktası. Düzenleme: Alt bayt argümanlarımı ters sırada geçirerek 3 bayt ve @yerine her satırda tek tek s kullanarak 3 bayt kaydedildi @echo off.


2

Jöle , 19 18 17 bayt

Ḣx3+
BÇL¡2ị
²Ç€»ċ

Çevrimiçi deneyin!

Arka fon

Bir tamsayıyı 1,2,3-Tribonacci tabanına, daha sonra ikili sayıdan tam sayıya dönüştürmek yerine, tam tersini yapacağız: tam sayıları ikiliye, sonra 1,2,3-Trionacci tabanından tam sayıya dönüştürün ve geri dönün girişle eşleşen en yüksek değer. Bu kolayca yapılabilir.

Giriş 63 için işlemi , özellikle 104'ün test edildiği adımı örneklendireceğiz . İkili olarak, en anlamlıdan en az anlamlı basamağa, 104 eşittir

 1  1  0  1  0  0  0
37 20 11  6  3  2  1

burada ikinci satır, bu rakamların konumsal değerlerini temsil eder.

Eklenen rakamların aynı özyinelemeli formüle uyduğunu gözlemleyerek 1,2,3-Tribonacci dizisini sağa doğru genişletebiliriz. Üç mre basamak için bu

 1  1  0  1  0  0  0  0  0  0
37 20 11  6  3  2  1  0  1  0

Şimdi, baz 1,2,3-Tribonacci sayısının değerini hesaplamak için, özyinelemeli formülü kullanabiliriz. Her sayı sağındaki üç sayının toplamı olduğundan (yukarıdaki tabloda), ilk basamağı kaldırabilir ve bunu kalan dizinin ilk üç basamağına ekleyebiliriz. 104 ikili basamak sayısına eşit olan 7 adımdan sonra , sadece üç basamakla nadiren ayrıldık.

 1  1  0  1  0  0  0  0  0  0
37 20 11  6  3  2  1  0  1  0

    2  1  2  0  0  0  0  0  0
   20 11  6  3  2  1  0  1  0

       3  4  2  0  0  0  0  0
      11  6  3  2  1  0  1  0

          7  5  3  0  0  0  0
          6  3  2  1  0  1  0

            12 10  7  0  0  0
             3  2  1  0  1  0

               22 19 12  0  0
                2  1  0  1  0

                  41 34 22  0
                   1  0  1  0

                     75 63 41
                      0  1  0

Şimdi, ilk ve son kalan basamak her ikisinin de konum değeri 0 olduğundan, sonuç orta basamaktır, yani 63 .

Nasıl çalışır

²Ç€»ċ   Main link. Argument: n

²       Yield n². Since 1.839² = 3.381921 > 2, the range [1, ..., n²] will contain
        the answer. Better bounds, at the cost of additional bytes are possible.
 Ç€     Map the the second helper link over [1, ..., n²].
   »    Take the maximum of n and each result.
    ċ   Count the occurrences of n.


BÇL¡2ị  Second helper link. Left argument: k. Right argument: n

B       Convert k to binary. Let's call the result A.
  L     Length; count the number of binary digits. Let's call the result l.
 Ç ¡    Apply the first helper link l times to A.
    2ị  Retrieve the second element.


Ḣ×3+    First helper link. Argument: A (array)

Ḣ       Head; pop and yield the first element of A.
 x3     Repeat it thrice.
   +    Add the result, component by component, to the beheaded A.

2

Jöle ( çatal ), 17 16 bayt

ḣ3S;µ¡
3RṚdzæFṪḄ

@ Çalışmadan bile golf @Dennis sayesinde 1 bayt kaydedildi.

Bu, hayal kırıklığı yaratan hala verimli bir Frobenius çözme atomu uygulamak için çalıştığım bir Jelly çatalına dayanıyor. İlgilenenler için, Mathematica'nın hızını eşleştirmek istiyorum FrobeniusSolveve neyse ki Daniel Lichtblau'nun "Değişiklik Yapma ve Yeniden Yapılandırma: Bir Sırt Çantası Dengeleme" makalesinde yöntemlerinin bir açıklaması var .

açıklama

ḣ3S;µ¡  Helper link. Input: a list
    µ   Create monadic chain
ḣ3        Take the first 3 items
  S       Sum
   ;      Prepend to the list
     ¡  Repeat it n (initial argument from main) times

3RṚdzæFṪḄ  Main link. Input: integer n
3          The constant 3
 R         Range. Makes [1, 2, 3]
  Ṛ        Reverse. Makes [3, 2, 1]
   Ç       Call the helper link on that list.
           Generates the first (n+3) 123-Tribonacci values in reverse
    ³      Get n
     æF    Frobenius solve for n using the first n 123-Tribonacci values in reverse
       Ṫ   Tail. Take the last value. The results of Frobenius solve are ordered
           where the last result uses the least
        Ḅ  Unbinary. Convert digits from base 2 to base 10

3
Süper esolangs çatallarını kullanırken golf kodunun derinliklerine girdiğinizi biliyorsunuz.
Addison Crump

Çalışır mıydı ḣ3S;µ¡¶3RṚdzæFṪḄ? Çatalın takılı değil, bu yüzden test edemiyorum.
Dennis

@Dennis Bu, argümanlardan değil stdin'den girdi alıyor, değil mi? Argümanları kullanırken sorun yaşıyordum ve bunun başka şekilde çalıştığını fark ettim.
mil

Hayır, bu hala argümanlar olmalı. ³ilk argümana atıfta bulunur.
Dennis

@Dennis Nvm, argümanlarla çalışıyor, jelly.pybu son taahhütten sonra başka şeyler de vardı.
mil

1

DC , 110 102 bayt

?se1sa2sb3sc_1sf[laddSdlbdsalcdsb++sclf1+sfle>y]dsyx0sk[lk2lf^+skler-se]sr[Lddle!<rlf1-dsf0!>z]dszxlkp

Büyük beyinler gibi Eh, görünüyor do benzer düşünüyoruz. Görünüşe göre, dcsınırlarını aşmak için bulduğum algoritma tesadüfen @ LliwTelrac'ın cevabında kullanılanla aynı. İlginç.

Çevrimiçi deneyin!



1

bash + BSD yardımcı programları (OS X vb.), 53 bayt

jot $[2#$1**4]|egrep -v '[2-9]|11(1|$)'|sed $[2#$1]!d

bash + GNU yardımcı programları (ayrıca BSD altında çalışır), 59 bayt

seq -f2o%.fp $[2#$1**2]|dc|egrep -v '11(1|$)'|sed $[2#$1]!d

Yukarıdakilerin her ikisinde de giriş ve çıkış ikili.


TIO'daki GNU sürümünü deneyin. (Örnekle bağlantılı örnek, ikili dosyada 63 olan 111111 girdisini ve ikili dosyada 104 olan 1101000 çıktısını gösterir.)

TIO'nun bir BSD seçeneği sunduğunu düşünmüyorum, ancak kullanılabilir bir Mac'iniz varsa, ikisini de deneyebilirsiniz. (59 baytlık program 53 baytlık programdan çok daha hızlıdır.)


Ne yazık ki, seqyerine BSD çözümüne bırakılamaz jot, çünkü çıkış biçimi seq999999'un üzerindeki çıkışlar için farklıdır. (32 ^ 4> 1000000'den beri 32 civarında girişler için bir sorun olmaya başlar.)

Bunu GNU yardımcı programlarıyla çalışmak için jotyukarıdakilerle değiştirebilirsiniz seq -f%.f, ancak aynı 59 bayt için yukarıdaki GNU çözümünü kullanabilirsiniz, bu da çok daha hızlıdır.

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.