A190810'u hesaplayın


27

Göreviniz oldukça basit, A190810'un n. Öğesini hesaplayın .

A190810'un elemanları bu kurallara göre hesaplanır:

  1. İlk eleman 1
  2. Dizi artıyor
  3. Eğer xdaha sonra sırayla oluşan 2x+1ve 3x-1aynı zamanda yapmak

1 veya 0 tabanlı endeksleme kullanabilirsiniz, ancak 0 tabanlı endeksleme kullanıyorsanız, lütfen cevabınızı söyleyin.

Test durumları

a(1) = 1
a(2) = 2
a(3) = 3
a(4) = 5
a(5) = 7
a(10) = 17
a(20) = 50
a(30) = 95
a(55) = 255

Bu kod golf olduğu için, bayt cinsinden en kısa cevap kazanır!


2
Daha büyük test senaryoları eklemelisiniz.
mbomb007

7
Bunu biraz daha açıklayabilir misiniz? Ben anadili İngilizce olan ve ne bilmiyorum "... ve eğer x bir 2x + 1 ve 3x-1 ise" dır. olması gerekiyordu.
kedi,

1
@ cat x ϵ A → (2*x) + 1 ϵ Ave x ϵ A → (3*x)-1 ϵ A, ϵ"anlamına gelir" anlamına gelir ve "ima" olarak anlaşılabilir.
Steven H.

3
Belirtilen durum: Sıralama, diğer kurallar tarafından gerekli olmayan numaralar içermez. (Aksi takdirde $ a (i) = i $ geçerli bir dizi olur)
Stig Hemmer

1
Ve :) başlamak ücretsiz Mathematica ve Haskell cevap almak
Dur zarar Monica

Yanıtlar:


9

Jöle , 16 bayt

×3’;Ḥ‘$;
1Ç¡ṢQ³ị

Çok verimsiz. Çevrimiçi deneyin!

Nasıl çalışır

1Ç¡ṢQ³ị   Main link. Argument: n (integer)

1         Set the return value to 1.
 Ç¡       Execute the helper link n times.
   Ṣ      Sort the resulting array.
    Q     Unique; deduplicate the sorted array.
     ³ị   Retrieve its n-th element.


×3’;Ḥ‘$;  Helper link. Argument: A (array)

×3        Multiply all elements of A by 3.
  ’       Decrement the resulting products.
      $   Combine the two links to the left into a monadic chain.
    Ḥ     Unhalve; multiply all elements of A by 2.
     ‘    Increment the resulting products.
   ;      Concatenate 3A-1 and 2A+1.
       ;  Concatenate the result with A.

1
Bu 16 karakter olabilir , ancak bunu 30 bayttan daha az gösteren herhangi bir kodlamayı bilmiyorum .
Zengin remer

18
Jelly, bu karakterlerin her birinin 1 byte olmasını sağlayan kendi kod sayfasına sahiptir.

15

Python 2, 88 83 72 bayt

Bu cevaptaki programları tersine sırayla okumak isteyebilirsiniz ...

Dennis sayesinde daha yavaş ve daha kısa:

L=1,;exec'L+=2*L[0]+1,3*L[0]-1;L=sorted(set(L))[1:];'*input()
print L[0]

Çevrimiçi deneyin


Bu hızlı bir şekilde çalışmaz, ancak daha kısadır ( 83 bayt .) Her yinelemeyi çoğaltarak ve silerken, ilk öğeyi kaldırırken, bir dizine olan ihtiyacı da listeye kaldırırım. Sonuç, nyinelemelerden sonra ilk öğedir .

Dışarıda golf oynamış olabilirim Dennis. : D

L=[1]
n=input()
while n:L+=[2*L[0]+1,3*L[0]-1];n-=1;L=sorted(set(L))[1:]
print L[0]

Çevrimiçi deneyin


Aşağıdaki bu sürüm ( 88 byte ), 500000'inci elemanı yaklaşık iki saniyede bularak gerçekten hızlı çalışıyor.

Bu oldukça basit. Listenin öğelerini, öğelerin üç katından daha fazlasına kadar hesaplayın n, çünkü eklenen her öğe en fazla 2 benzersiz öğe ekleyebilir. Ardından kopyaları kaldırın, sıralayın ve nth öğesini yazdırın (sıfır dizinli)

L=[1]
i=0
n=input()
while len(L)<3*n:L+=[2*L[i]+1,3*L[i]-1];i+=1
print sorted(set(L))[n]

Çevrimiçi deneyin


8

Python 2, 59 bayt

t={1}
exec'm=min(t);t=t-{m}|{2*m+1,3*m-1};'*input()
print m

@ Mbomb007'nin Python cevabı dayanarak . İdeone üzerinde test et .


"Biri Dennis'i aşılamaz" ... Keşke set edebiyatı kullanmayı düşünebilseydim. Şimdi çok açık görünüyor. Bir dizgiyi yürütmekten asıl koda dönüştürürseniz, bu cevap benim "hızlı" programımdan daha hızlı mı?
mbomb007

Hayır! Daha yavaş. Set işlemleri daha pahalıdır.
mbomb007

Evet, minbir O (n) liste indeksleme iken O (1) , bu çözüm en azından yani O (n²) ...
Dennis

8

Haskell, 76 73 69 bayt

a#b=mod a b<1&&t(div a b)
t x=x<2||(x-1)#2||(x+1)#3
(filter t[1..]!!)

0 tabanlı bir dizin kullanır. Kullanım örneği: (filter t[1..]!!) 54-> 255.

Listeyi tekrar tekrar ekleyerek 2x+1ve 3x-1çoğu diğer cevapta görüldüğü gibi oluşturmak yerine, tüm tamsayıları okuyup 1tekrar tekrar uygulayarak (x-1) / 2(x+1) / 3yoksa bölünebilir mi olduğunu kontrol edip edemeyeceğimi kontrol ediyorum .


Bu gerçekten bir işlevi veya geçerli bir kod parçacığını tanımlamıyor, değil mi?
Zeta

@Zeta Son satır adsız bir işlevi değerlendirir.
Zgarb

@Zgarb Bir Haskell dosyasında bir hata olan ve tercüman yok bu tür bir özelliği desteklediğini biliyorum. Yani, Enlighten ben, nasıl bir kullanıcı bu kullanmak gerekiyordu lütfen olmadan herhangi bir şekilde yukarıdaki kodu değiştirerek? Yoksa beni bu tür kodlara izin veren bir meta gönderiye yönlendirir misiniz?
Zeta

2
@Zgarb Son satır için onu bir bağlayıcıya (gibi f=filter t[1..]!!) atadım , çünkü bunun doğru olduğunu sanmıyorum.
TuxCrafting 15:16

1
@TùxCräftîñg Bu Meta yayında , bu durumda ek yardımcı işlevlerin varsayılan olarak kabul edilebilir olduğu belirlenmiştir. Bu aynı zamanda Haskell cevaplarını burada gördüğüm biçimdir. Tabii ki, meydan okuma yazarı olarak son yetkilisin.
Zgarb

7

Haskell, 77 74 bayt

import Data.List
i=insert
f(x:y)=x:f(i(2*x+1)$i(3*x-1)y)
a=(!!)(nub$f[1])

Bu a, n. Giriş için bir işlev sunar . Sıfır endeksli. Alternatif olarak, a=nub$f[1]tüm listeyi oluşturacaktır (tembelce).

Reinhard Zumkeller'in Setkodunun bir listesi .


İki bayt kaydetmek yyerine neden olmasın xs? Ayrıca, son çizgiyi, bunun gibi birşeye göre kesebileceğinize inanıyorum(!!)$nub.f[1]
Michael Klein

@MichaelKlein: Ben sadece çok alışkınım (x:xs), tamamen unutmuşum, teşekkürler.
Zeta

6

Python 2, 88 84 bayt

g=lambda k:g(k%2*k/2)|g(k%3/2*-~k/3)if k>1else k
f=lambda n,k=1:n and-~f(n-g(k),k+1)

İdeone üzerinde test et .


13
Basit bir şeyi okunamayan bir şeye çevirme konusunda uzmansın.
mbomb007


5

Brachylog , 45 bayt

:1-I,?:?*:1ydo:Im.
1.|:1-:1&I(:3*:1-.;I*:1+.)

Makinemde N = 1000yaklaşık 6 saniye içinde hesaplar .

Bu 1 indeksli, örneğin

run_from_file('code.brachylog',1000,Z).
Z = 13961 .

açıklama

  • Ana tahmin:

    :1-I,               I = Input - 1
         ?:?*           Square the Input
             :1y        Find the first Input*Input valid outputs of predicate 1
                do      Remove duplicates and order
                  :Im.  Output is the Ith element
    
  • Tahmin 1:

    1.                  Input = Output = 1
    |                   Or
    :1-:1&I             I is the output of predicate 1 called with Input - 1 as input
           (            
             :3*:1-.      Output is 3*I-1
           ;            Or
             I*:1+.       Output is 2*I+1
           )
    

Aradığımızda 1'i tahmin etmek için herhangi bir girişi geçmediğimizi not edebilirsiniz y - Yield. Kısıtlama yayılımı nedeniyle 1., doğru girdi değerlerini dağıtacak olan maddeye bir kez ulaşan doğru girişi bulur .


4

MATL, 19, 18 17 bayt

1w:"tEQy3*qvSu]G)

Bu son derece yetersiz bir algoritmadır. Çevrimiçi tercüman 13'ten büyük girişler için belleği yetersiz.

Bir bayt kurtarıldı, Luis Mendo sayesinde!

Çevrimiçi deneyin!

Bu sürüm daha uzun, ancak daha verimli (21 bayt)

1`tEQy3*qvSutnG3*<]G)

Çevrimiçi deneyin

Açıklama:

Bunu yapmanın mantıklı yolu, diziyi, öğeyi kapacak kadar uzun olana kadar eleman eklemektir. Verimli olan böyle çalışır. Bunu yapmak için golfy (ve verimsiz) yol, sadece i sayısını dizi boyutunu arttırmaktır .

Yani ilk biz başlangıç dizisini tanımlar: 1. Sonra üst iki elemanı değiştiririz, böylece giriş üstte olur. w. Şimdi, girişi ile birlikte dönüyoruz :". Yani ben kere:

t             %Duplicate our starting (or current) array.
 EQ           %Double it and increment
   y          %Push our starting array again
    3*q       %Multiply by 3 and decrement
       v      %Concatenate these two arrays and the starting array
        Su    %Sort them and remove all duplicate elements.

Şimdi, dizinin devasa bir dizisine sahibiz . (Hesaplamak için gerekenden çok daha fazlası) Bu yüzden döngüyü durduruyoruz ]ve bu diziden i'th sayısını G)(1-indexed) ile alıyoruz


@LuisMendo Tahmininiz için teşekkürler! Bunu for döngüsü yerine bir while döngüsü ile nasıl yeniden yazarsınız? (Belki de MATL sohbet odası için daha iyi bir soru olurdu)
DJMcMayhem

Bu şekilde yapılabilir: 1`tEQy3*qvuStnG<]G). Döngü koşulu tnG<(dizi zaten gerekli boyutta olduğunda çıkış)
Luis Mendo

Ne kadar hile yaptığından emin fordeğilsiniz , ancak -loop sürümünde bir dizgeyi tek bir girdi olarak alıp çıkarabilirsiniz:
Luis Mendo

4

JavaScript (ES6), 63 bayt

 f=(n,a=[1],i=0)=>a[i++]?--n?f(n,a,a[i*2]=a[i*3-2]=1):i:f(n,a,i)

Muhtemelen özyinelemeden dolayı çabucak pes eder.


4

Retina, 57

^.+
$*¶¶1
¶¶(1(1*))
¶1$1$1¶$2$1$1
O`
}`(¶1+)\1\b
$1
G2`
1

Çevrimiçi deneyin!

0 endeksli. Sık kullanılan algoritmayı takip eder: minimum değeri mevcut setten kaldırın, onu çağırın ve girişe eşit sayıda set xekleyin 2x+1ve ekleyin 3x-1, sonra ana sayı sonuçtur. Retina'daki "set" sadece tekrar tekrar sıralanan ve sadece benzersiz elementler içerecek şekilde yapılmış bir listedir. Golf için bir algoritma eklenmiş bazı sinsi bitler var, bir kere daha açıkladıktan sonra açıklayacağım.

Martin'e 20 baytlık golf oynadığı için teşekkürler!


4

Clojure, 114 108 bayt

#(loop[a(sorted-set 1)n 1](let[x(first a)](if(= n %)x(recur(conj(disj a x)(+(* 2 x)1)(-(* 3 x)1))(inc n)))))

Eğer bu önemli ölçüde golf oynadıysa ya da azaltılırsa, şaşırmam, ama nth'i setdesteklememesi düşünce trenime gerçekten zarar vermedi.

Çevrimiçi deneyin

Boşluklu sürüm:

#(loop [a (sorted-set 1)
        n 1]
  (let [x (first a)]
    (if (= n %)
      x
      (recur (conj (disj a x) (+ (* 2 x) 1) (- (* 3 x) 1)) (inc n))
      )))

4

05AB1E, 18 17 bayt

CP-1252 kodlamasını kullanır .

$Fз>s3*<)˜Ù}ï{¹è

açıklama

$                  # initialize with 1
 F          }      # input number of times do
  Ð                # triplicate current list/number
   ·>              # double one copy and add 1
     s3*<          # multiply one copy by 3 and subtract 1
         )˜Ù       # combine the 3 lists to 1 list and remove duplicates
             ï{    # convert list to int and sort
               ¹è  # take the element from the list at index input

Küçük sayılar için çevrimiçi deneyin

Çok yavaş.
0 tabanlı endeksleme kullanır.


3

C ++, 102 bayt

[](int i){int t;map<int,int>k;for(k[1];i--;k.erase(t))t=k.begin()->first,k[t*2+1],k[t*3-1];return t;};

Bu lambda işlevi #include <map>ve gerektirir using std::map.

mapBurada anahtarların sadece bir koleksiyon; değerleri göz ardı edilir. Kullandığım mapyerleştirme için veciz kodundan yarar için:

k[1]; // inserts the key 1 into the map

Sıralama düzeni sayesinde map, en küçük eleman tarafından ayıklanır k.begin()->first.


1
Biraz (97) daha kısa kullanılarak setve listeler başlatıcısı: [](int i){int t;set<int>k{1};for(;i--;k.erase(t))t=*k.begin(),k.insert({t*2+1,t*3-1});return t;};.
nwn

3

Aslında, 27 bayt

╗1#╜`;;2*1+)3*1@-#++╔S`n╜@E

Çevrimiçi deneyin!

Bu program 0 tabanlı endeksleme kullanır. Yaklaşım çok kaba bir güçtür, bu nedenle daha büyük girdiler için çevrimiçi tercümanda çalışmasını beklemeyin.

Açıklama:

╗1#╜`;;2*1+)3*1@-#++╔S`n╜@E
╗                            save input (n) in register 0
 1#                          push [1]
   ╜                         push n
    `;;2*1+)3*1@-#++╔S`n     do the following n times:
     ;;                        make two copies of the list
       2*1+                    apply 2x+1 to each element in one copy
           )3*1@-              and 3x-1 to each element in the other copy
                 #             workaround for a weird list bug
                  ++           append those two lists to the original list
                    ╔S         uniquify and sort
                        ╜@E  get the nth element (0-indexed)

2

CJam (25 bayt)

ri1a1${{_2*)1$3*(}%_&}*$=

Çevrimiçi demo . Bunun sıfır temelli indeksleme kullandığını unutmayın.

Bu, çoğu için benzer bir yaklaşım kullanır: dönüşüm nsürelerini uygulayın ve sonra nth öğesini sıralayıp çıkarın . Verimliliğe bir onay olarak veri tekilleştirme, döngü içinde uygulanır ve sıralama döngü dışına uygulanır.


2
22: 1ari{(_2*)\3*(@||$}*0=(Ayrıca çok daha verimli.)
Martin Ender

2

Retina , 48 bayt

.+
$*
+1`^(((!*)!(!|\3)(?=\3!1))*!)1|\b
!$1
-2`.

Çevrimiçi deneyin!

Nimi'nin cevabından esinlenerek, Retina için farklı bir yaklaşım deneyeceğimi düşündüm, regex motorunun geri izlemesinden faydalanarak verilen (sıradan) bir sayının sırayla olup olmadığını anlamak için geri döndüm. Bunun, 27 baytlık regex ile belirlenebileceği, ancak maliyetlerden birkaç kat daha fazla yararlanabileceği ancak gene de üretken yaklaşımdan daha kısa sürdüğü ortaya çıktı.

İşte alternatif bir 48 baytlık çözüm:

.+
$*
{`1\b
1!
}T`1``1((!*)!(!|\2)(?=!\2$))*!$
!

Ve unary G / Ç kullanarak 42 bayt yapabiliriz, ama bundan kaçmaya çalışıyorum ve diğer Retina cevabı da ondalık kullanıyor:

1\b
1!
}T`1``1((!*)!(!|\2)(?=!\2$))*!$
!
1

2

Ruby, 70 bayt

->n{a=*1
n.times{a<<a.map{|i|([2*i+1,3*i-1]-a).min||1.0/0}.min}
a[-2]}

açıklama

->n{
    # Magical, golfy way of initializing an array. Equivalent to a = [1].
    a=*1
    n.times{
        # Generate the next element in the sequence, by...
        a<<
            # ... finding the minimal term that will appear at some point.
            a.map{|i|
                ([2*i+1,3*i-1]-a).min||1.0/0
            }.min
    }
    # We generated n+1 elements, so we'll take the *second* to last one.
    a[-2]
}

1
Bu *1hile temiz
TuxCrafting

1

J, 31 bayt

{1(]]/:~@~.@,3&*,&:<:2*>:)^:[~]

Sıfır tabanlı endeksleme kullanır. Çok hafıza yetersiz.

açıklama

{1(]]/:~@~.@,3&*,&:<:2*>:)^:[~]  Input: n
                              ]  Identity function, gets n
 1                               The constant 1
  (                      )^:[~   Repeat n times with an initial array a = [1]
                       >:          Increment each in a
                     2*            Multiply by 2 to get 2a+2
             3&*                   Multiply each in a by 3 to get 3a
                 &:<:              Decrement both x and y to get 2a+1 and 3a-1
                ,                  Join them
    ]                              Identity function, gets a
            ,                      Join a with 2a+1 and 3a-1
         ~.@                       Take the distinct values
     /:~@                          Sort up
   ]                               Return the sorted list
{                                Select the value from the list at index n and return it


1

Perl, -n = 133 için 173 132 bayt +1

sub c{my$a=pop;return($a==1||($a%2&&c(($a-1)/2))?1:$a%3!=2?0:$a%3==2?c(($a+1)/3):1)}while($#b<$_){$i++;@b=(@b,$i)if c$i}say$b[$_-1];

Ungolfed:

my @array = ();
my $n = <>;
sub chk {
    my $a = shift;
    return 1 if ($a == 1);
    if ($a % 2 == 0) {
        if ($a % 3 != 2) {
            return 0;
        } else {
            return chk(($a + 1) / 3);
        }
    } else {
        if (chk(($a - 1) / 2) == 0) {
            if ($a % 3 != 2) {
                return 0;
            } else {
                return chk(($a + 1) / 3);
            }
        } else {
            return 1
        }
    }
}
my $i = 1;
while ($#array < $n-1) {
    push(@array,$i) if (chk($i) == 1);
    $i++;
}
print $array[$n];

Eğer daha fazlasını düşünürsem, muhtemelen daha iyisini yapabilirim, ama birkaç dakika sonra geldiğim şey buydu. İlk defa golf oynuyorum, bu yüzden çok eğlenceliydi!

-Dada için @Dada ve @ TùxCräftîñg (ve birkaç küçük bayt optimizasyonu) sayesinde


1
Ben mys sonra boşluk bırakabilirsiniz düşünüyorum , returnve print(Test edemez, perl yok)
TuxCrafting

1
@ TùxCräftîñg hakkında haklı return. A printile değiştirilebilir say. Çoğu mydaha önce sadece bir ihtiyaç (gerekli değildir $abence işlevinde. Değil ilklendir ne de beyan yapın @b. Muhtemelen başlangıç durumuna bırakın $ibunu yaparsanız $i++sonunda ise yerine başlangıcında. popEdilmektedir daha kısa shiftsadece ... beyaz boşlukları ve yeni satır kaldırarak daha perl golf çok daha orada daha unutmayın.
Dada

0

JavaScript (ES6), 58

n=>(a=>{for(;n;)a[++i]?a[i-~i]=a[3*i-1]=--n:0})([i=0,1])|i

Daha az golf oynadı

n=>{
  a=[];
  a[1] = 1;
  for(i = 0; n;)
  {
    ++i
    if (a[i])
    {
      a[2*i+1] = 1;
      a[3*i-1] = 1;
      --n;
    }
  }
  return i
}

Ölçek

Zaman ve bellek hakkında: FireFox 64 bit alfa tarafından kullanılan 500000 ~ 20 saniyede eleman ve 300 MB

F=
n=>(a=>{for(;n;)a[++i]?a[i-~i]=a[3*i-1]=--n:0})([i=0,1])|i

function test() {
  var n=+I.value, t0=+new Date
  O.textContent = F(n)
  console.log((+new Date-t0)/1000,'sec')
}  

test()
#I { width:5em}
<input id=I type=number value=10 oninput="test()"> 
<span id=O></span>

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.