Dizide olmayan tam sayıların bir dizisi


28

Arka fon

Aşağıdaki gibi tanımlanmış bir dizi düşünün:

  • İlk eleman 0;
  • İkinci eleman 4;
  • Üçüncü unsurdan itibaren değeri şu şekilde hesaplanabilir:
    • Tamsayılar dizisini 0'dan dizinin önceki elemanına alarak (kapsayıcı veya özel, önemli değil);
    • Daha önce göründüğü tamsayıları dizideki kümeden çıkarmak;
    • Setin kalan elemanlarını bir araya getirmek; İstediğiniz değer budur.

İlginç bir şekilde, bu dizi henüz OEIS'te görünmüyor .

Görev

Bir tamsayıdır alan bir program ya da işlev Yazın n girdi olarak alır ve çıktı olarak , n dizisinin elemanından.

Test durumları

Dizinin ilk birkaç elemanı:

  • 0
  • 4
  • 6 (1 + 2 + 3)
  • 11 (1 + 2 + 3 + 5)
  • 45 (1 + 2 + 3 + 5 + 7 + 8 + 9 + 10)
  • 969 (1 + 2 + 3 + 5 + 7… 10 + 12… 44)
  • 468930 (1 + 2 + 3 + 5 + 7… 10 + 12… 44 + 46… 968)

Açıklamalar

  • Programınız teoride keyfi idare gerekir n unboundedly büyük tamsayılar ve hafıza sınırsız miktarda erişimi olan bir dil varyantı üzerinde çalıştırırsanız. (İkizleri olmayan dillerin 468930'un çok ötesine geçmesi pek mümkün değildir, ancak bu yanıtları kodlamak için mazeret değildir.)
  • Dizi için 0 tabanlı veya 1 tabanlı dizinlemeyi seçebilirsiniz (örneğin, n = 1'in birinci öğeyi döndürmesi, n = 2'nin ikinci öğeyi döndürmesi ve benzeri); veya n = 0'ın birinci öğeyi döndürmesi size bağlıdır , n = 1 ikinci eleman vb.
  • Kullandığınız algoritmada ve verimliliğinde herhangi bir gereksinim yoktur; dizinin tanımını doğrudan uygulayabilirsiniz (gerçekten yetersiz olmasına rağmen) ve aynı sonuçlara yol açan farklı bir algoritma da uygulayabilirsiniz.

Zafer durumu

Bu , yani bayt cinsinden ölçülen en kısa doğru program kazanıyor.


1
Neden girdi almak yerine sonsuz çıktıya izin vermiyorsunuz?
John Dvorak

2
@JanDvorak: Bu, tüm programları her terim üreten algoritmaları kullanmaya zorladığından; bu soruyu yazma yöntemi, bunu yapmak isteyip istemedikleri ya da kapalı bir formülü kullanmak isteyip istemediklerine (cevap varsayarak) cevaplayıcılara bırakmaktadır. Bu yüzden sorunun çözümünde daha fazla strateji seçeneği sunar.

1
Sıralamanın orada olmadığını varsayardım, çünkü 0,4 tuhaf bir
kaymadır

1
@boboquack (0,3), (0,2), (1,4) veya benzer varyasyonlarıyla, sıralama birkaç terimden sonra sabit olur.
Dennis,

[Math] etiketi bunun için bir anlam ifade ediyor mu?
mbomb007

Yanıtlar:


10

Jelly , 13 12 9 bayt

rSạo4¥ð@¡

0 tabanlı endeksleme kullanır.

Çevrimiçi deneyin!

Nasıl çalışır

rSạo4¥ð@¡  Main link. No arguments. Implicit argument: 0

      ð    Collect everything to the left into a chain and start a new, dyadic one.
           The arity of the first chain is unknown at this point, as it isn't
           prefixed by ø, µ, or ð.
       @   Swap the arguments of the first chain. Swapping  arguments is only
           implemented for dyadic links, so this makes the chain dyadic.
        ¡  Read an integer n from STDIN and execute the chain n times. Taking the
           argument swap into account, the chain is executed first with 0 as left
           and right argument, then with the previous right argument as left
           argument and the previous return value as right argument.
           The return value of the last call is the return value of the quicklink
           and becomes the implicit output.

           Let's call the left argument x and the right argument y.
r            Range; yield [x, ..., y].
 S           Compute the sum of all integers in the range.
     ¥       Convert the two atoms to the left into a dyadic chain, and call that
             chain with arguments x and y.
   o4          Take the logical OR of x and 4, replacing a 0 with 4 and leaving
               positive integers untouched.
  ạ          Take the absolute difference of the sum to the left and the result of
             the logical OR to the right.

10

Python, 66 60 bayt

6 bayt'ı tıraş etmek için @Dennis'e teşekkürler!

f=lambda n:n>2and(f(n-1)-~f(n-2))*(f(n-1)-f(n-2))/2or(5-n)*n

Bu şimdiye kadarki en golfif kod parçası değil, fakat yaptığım bir formül kullanıyor:

görüntü tanımını buraya girin

xSağ tarafta nerede f(n - 1)ve yöyle f(n - 2).

Açıklama:

Sürekli tamsayı toplamı aiçin b(dahili) formülü ile tarif edilebilir:

amount * average

Burada amount(sayı miktarı) şöyle tanımlanır:

((a - b) - 1)

Ve average(tüm sayıların ortalaması) şöyle tanımlanır:

(a + b) / 2

Yani tam formül şimdi:

  ((a - b) - 1)(a + b) / 2
= (a - b - 1)(a + b) / 2

Biz nihai formülün içine bu formülü uygulamak yolu ikame etmektir aiçin f(n - 1), biçin f(n - 2)temelde yeni terimlerin toplamını hesaplar, hangi başka bir ekleme f(n - 1)(şimdi olduğu aönceki tüm terimlerin toplamı olan üzerine).

Bunu bir araya getirerek şunları elde ederiz:

  a + ((a - b - 1)(a + b) / 2)
= a + ((a^2 + ab - ab - b^2 - a - b) / 2)
= a + ((a^2 - b^2 - a - b) / 2)
= (a^2 - b^2 - a - b + 2a) / 2
= (a^2 - b^2 + a - b) / 2
= ((a + b)(a - b) + (a - b)) / 2
= (a + b + 1)(a - b) / 2

Değiştir aile xve bile yve hey presto, yukarıdaki formüle sahiptir.



9

Mathematica, 49 48 bayt

±2=4;±1=0;±n_:=Tr@Range@±(n-1)-Tr@Array[±#&,n-1]
(* or *)
±2=4;±1=0;±n_:=-Tr@Array[(k=±#)&,n-1]+Tr@Range@k

CP-1252 kodlamasını kullanır. Fonksiyonu tanımlar PlusMinus (±). 1 endeksli.

açıklama

±2=4;±1=0;±n_:=Tr@Range@±(n-1)-Tr@Array[±#&,n-1]

±2=4;±1=0;                                        (* Define ±1 and ±2 *)
          ±n_:=                                   (* ±n equals ... *)
               Tr@Range@±(n-1)                    (* Sum of (1, 2, ..., ±(n-1)) ... *)
                              -Tr@Array[±#&,n-1]  (* Minus the sum of previous terms *)

8

Oasis , 11 bayt

Kod:

+>bc-*2/640


Açıklama:

İlişkisini görselleştirmek için f n , örneğini ele alalım f 5 . F 5'i hesaplamak için, aşağıdaki toplama bir göz atalım:

1 + 2 + 3 + 5 + 7 + 8 + 9 + 10

Kalın kısım f 4 ile aynıdır . 7 + 8 + 9 + 10 parça aralığında olduğu [f , n-2 + 1, F , n-1 - 1] . Bu formül yapar f , n-1 + Σ [f , n-2 + 1 ... f , n-1 - 1] ( volfram bağlantı ):

f , n = 0.5 x (ön n-1 2 - f , n-2 2 + f , n-1 - f , n-2 )

Hangi için yeniden yazılabilir:

f , n = 0.5 x ((f , n-1 - f , n-2 ) (f , n-1 + f , n-2 ) + (f , n-1 - f , n-2 ))

f , n = 0.5 x ((f , n-1 - f , n-2 ) (f , n-1 + f , n-2 + 1))

Kodda kullanacağımız formül hangisi:


Kod açıklaması

640Bölüm bize baz durumlarda verir:

a(0) = 0
a(1) = 4
a(2) = 6

Yürütülecek kod ( bir (n) tanımlar ):

+>bc-*2/

+          # Add a(n + 1) and a(n + 2) implicitly
 >         # Add one to get a(n + 1) + a(n + 2) + 1
  b        # Push a(n + 1)
   c       # Push a(n + 2)
    -      # Subtract from each other
     *     # Multiply with the previous result
      2/   # Halve the result

Çevrimiçi deneyin!


3
Açıklama? Bu beni diğer cevapların çoğundan daha çok meraklandırdı.

@ ais523 Bir açıklama ekledim.
Adnan

5

Julia, 39 33 32 bayt

!n=n<3?5n-n^2:sum(!(n-2)+1:!~-n)

0 tabanlı.

@Dennis sayesinde, 6 bayt kaydedildi.

@GlenO sayesinde bir bayt kurtardı.

Çevrimiçi deneyin!

Önceki cevap 1- tabanlı:

!n=n<4?2(n>1)n:sum(!(n-2)+1:!~-n)

Çevrimiçi deneyin!

Önceki ungolfed cevap 1 tabanlı:

f(n)=n<4?n<2?0:n*2:sum(f(n-2)+1:f(n-1))

Çevrimiçi deneyin!


1
Fazladan bir bayttan tasarruf etmek için - n<3?5n-n^2:yerine n<4?2(n>1)n:0 tabanlı indeksleme kullanmaya geçtiğine dikkat edin.
Glen O

@GlenO Teşekkürler, 1 bayt kaydedildi!
rahnema1

4

JavaScript (ES6), 47 bayt

f=(n,b=4,a=6)=>n?--n?f(n,a,(a+b+1)*(a-b)/2):b:0

f(n) = sum(range(f(n-2) + 1, f(n-1) + 1))N> 2 için olan nüks ilişkisini kullanır .


4

PowerShell , 84 89 88 87 bayt

$OFS='+'
for($a=0,4;$a.Count-le($n="$args")){$a+=("$(1..$a[-1])"|iex)-("$a"|iex)}$a[$n]

Çevrimiçi deneyin!

açıklama

0 tabanlı indeksleme. Yalnızca çalışır n = 6(Windows makinemde yığın taşmasıyla çöküyor n = 7).

JungHwan Min'in cevabındakiyle aynı yöntemi kullanmak (önceki terimlerin aralık eksi toplamı).

PowerShell'de bir aralığı / diziyi toplamak uzun, bu yüzden +uzun bir ifade (gibi 1+2+3+4...etc) oluşturmak ve sonra onu iex( Invoke-Expression) göndermek için bir diziye katılma hilesi kullanıyorum .

Bunu iki kez yapmam gerektiğinden, kullanmak yerine çıktı alanı ayırıcısını gösteren -joinözel değişkeni $OFSayarlıyorum. Bir diziyi dizgileştirdiğinizde, bu elemanlara katılmak için kullanılan karakterdir; bir alana varsayılandır. Yani bunu ayarlayarak +(bir kez), şöyle bir şey yerini alabilir $a-join'+'|iexile "$a"|iex.

Basit bir fordöngü dizi sayımı giriş tamsayısından küçük veya ona eşit olana kadar devam eder, o zaman $nth elemanını döndürürüm .


@AdmBorkBork çok güzel! Bunun belirgin bir cevaba layık olduğunu düşünüyorum; Yöntem, kullanmış olsaydım kendim gibi hissetmeyecek kadar farklı.
briantist

1
@AdmBorkBork nice, +1, ve bundan bir şey öğrendim: döngüden ;sonra gerek yok for. Bunu daha önce hiç farketmedim.
briantist

3

MATL , 17 16 bayt

OKi:"tP:yX-sv]G)

1tabanlı indeksleme kullanılır. Kod çok verimsiz. İçin n = 6bunun zaten online derleyici bellek sınırını aşıyor.

Çevrimiçi deneyin!

Nasıl çalışır

O       % Push 0
K       % Push 4
i       % Input n
:"      % Do the following n times
  t     %   Push a copy of the top array (or number)
  P:    %   Range from 1 to the last element of array
  y     %   Push a copy of the second-top number/array
  X-    %   Set difference
  s     %   Sum
  v     %   Concatenate everything into a column vector
]       % End
G)      % Get n-th entry of the array. Implicity display

İçin 20 bayt aşağıdaki sürüm bellek sınırlama kaçınır. Ancak, hala veri türü sınırlaması var ( doubletür yalnızca tam sayıların doğru şekilde temsil edildiğini garanti edebilir 2^53), bu nedenle sonuçlar n = 8yalnızca en çok geçerlidir .

OKi:"t0)tQ*2/ys-v]G)

Online olarak da deneyin !


2

Haskell , 42 bayt

f 0=0
f 1=4
f 2=6
f n=sum[1+f(n-2)..f$n-1]

Çevrimiçi deneyin!

Bu, doğrudan doğruya için bu nüks uygular n>2, f(n)eşit f(n-1)artı açık aralığının toplamı f(n-2)için f(n-1)bir daha yarı açık aralığın eşittir f(n-2)için f(n-1)dahildir.

f(0) = 0
f(1) = 4
f(2) = 6 = 1+2+3
f(3) = 11 = 1+2+3+5 = 6 + 5 = 6 + sum]4,6[ = f(2)+ sum]f(1),f(2)[ = sum]f(1),f(2)]
...
f(n) = sum]f(n-2),f(n-1)] = sum[f(n-2)+1,f(n-1)]

2

Haskell, 31 bayt

m#s=m:s#sum[m+1..s]
((0:4#6)!!)

Kullanım örneği: ((0:4#6)!!) 6-> 468930. Çevrimiçi deneyin! .

mŞimdiye kadar maksimum öğeyi ve bir sonraki değeri izleyen basit özyineleme s.


Ne zaman yeni bir zorluğa
girsem

Her zaman bazı matematik zorluklarına varırım, "Hey nihayet haskell'i deneyebilirim!" Diye düşünüyorum. CMD-F 'Haskell' - oh bekle hayır, bu cevap ... bekle, ne?
Haskell

2

JavaScript, 123 119 bayt

(a,i=x=y=0)=>{r=[0,4];while(r.length<a){x++;y=0;for(i=0;i<r[x];i++){if(!r.includes(i)){y+=i;}}r.push(y)}return r[a-1];}

Çevrimiçi deneyin! Bu çözüm 1 tabanlıdır f(1) => 0.


2

Perl 6 ,  52 49 44  35 bayt

{(|(0,4 X 0),{[+](^.[0])-.[1],.[0]+.[1]}...*)[$_;0]}

Dene

{(0,(4,0),{[+](^.[0])-.[1],.[0]+.[1]}...*)[$_;0]}

Dene

{(0,(4,0),{[+](^.[0])-.[1],.sum}...*)[$_;0]}

Dene

{(0,4,6,{[+] $^a^..$^b}...*)[$_]}

Dene

Expanded:

{ # bare block lambda with implicit parameter 「$_」

  (
    # generate a sequence

    0, 4, 6,      # seed the sequence

    {             # lambda with placeholder parameters 「$a」 「$b」
      [+]         # reduce with 「&infix:<+>」
          $^a     # n-2
          ^..     # Range that excludes the first value
          $^b     # n-1
    }
    ...           # keep generating values until
    *             # never stop

  )[ $_ ]         # get the value that was asked for (0 based index)
}

2

PowerShell , 77 73 bayt

param($n)$a=0,4;1..$n|%{$a+=(0..$a[-1]|?{$_-notin$a})-join'+'|iex};$a[$n]

Çevrimiçi deneyin!

Algoritmayı tanımlandığı şekilde uygular ve 0 indekslenir. 6TIO'nun ele alması için girişi çok fazla.

$aBir dizi olarak ayarlar [0,4]. Girişten 1yukarı doğru döngüler $n. Döngüde, sayı aralığımızı sahip 0olduğumuz en büyük sayıya kadar alıyoruz $a[-1]ve yalnızca mevcut olmayan sayıları çıkarmak için bir Where-Objectcümle kullanıyoruz |?{...}. Bu sayı dizisi s -joinile birlikte girilir +ve ardından iex(kısa Invoke-Expressionve benzer şekilde eval) ile beslenir . Bu değer daha sonra dizi sonuna birleştirilir$a . Sonunda döngüden çıkarız ve $ndizideki th sayısını alırız. Bu numara boru hattında bırakılır ve çıktı gizlidir.



1

Toplu iş, 108 bayt

@if %1==0 echo 0&exit/b
@set/ab=4,a=6
@for /l %%i in (2,1,%1)do @set/ac=(a+b+1)*(a-b)/2,b=a,a=c
@echo %b%

JavaScript cevabımın limanı.


1

dc , 47 bayt

?d1-scd/4*dd[d1+*2/r-dsn+dlnlc1-dsc0<x]sxlc0<xp

Bilgisayarın bellek kapasitesine kadar istediğiniz kadar tam sayı ile çalışır.

Çevrimiçi deneyin!

0 tabanlı indeksleme, stdin'de giriş, stdout'ta çıkış. (Ayrıca, yoksayılacak stderr'de çıktı var.)

Örnek çalışır:

$ for ((j=0;j<12;j++)){ echo -n "$j ";dc -f sumseq.dc <<<"$j";echo;} 2>/dev/null
0 0

1 4

2 6

3 11

4 45

5 969

6 468930

7 109947436950

8 6044219445882138462810

9 18266294354989892462984673364511343859409730

10 166828754731567805766174036610844675771635260155825966927845486666328\
837158267993261860

11 139159167026428037700805570917048711514125048327321592278500415852500\
422178720517080334552793040951056255170819719745908378102737875659900\
61575545777065220385544711322919415

Bu, (biraz) daha okunaklı olan bash'teki aşağıdaki çözümle aynı algoritmayı kullanır:

Saf bash, 60 bayt

for((n=s=$1?4:0,k=1;k<$1;k++,s+=(n=n++*n/2-s))){ :;}
echo $n

Ancak bash programı sadece 7'ye kadar olan girişler için çalışır, çünkü bunun ötesinde tamsayı taşmasına neden olur.



0

C # - 74 bayt

int A(int f){int e=4,i=1,s=0;for(;i++<f;)e=e*-~e/2-(s+=e);return f>0?e:0;}

Ungolfed:

int A(int f)
{
    int e = 4, 
        i = 1, 
        s = 0; // e is the last element, s is the sum of all previous elements
    for (; i++ < f; ) // calculate for indexes 1 through max (don't need the index, just a correct number of loop cycles)
        e = e * -~e / 2 - (s += e); // -~e => (e + 1), higher precedence to remove parentheses
    return f > 0 ? e : 0; //handle input 0 as a special case, which is 0
}

Muhtemelen daha fazla tasarruf yapmak için bunu bir lambdaya dönüştürmenin bir yolu vardır veya .Aggregate İşlevi'ni kullanarak. Şu anda hiçbir ithalatım olmamasına rağmen, belki de dışlanıyor?


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.