Calculer A190810


27

Votre tâche est assez simple, calculez le n-ième élément de A190810 .

Les éléments de A190810 sont calculés selon ces règles:

  1. Le premier élément est 1
  2. La séquence augmente
  3. Si cela xse produit dans la séquence, alors 2x+1et 3x-1aussi

Vous pouvez utiliser une indexation basée sur 1 ou 0, mais si vous utilisez une indexation basée sur 0, veuillez le dire dans la réponse.

Cas de test

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

Puisqu'il s'agit de code-golf, la réponse la plus courte en octets l'emporte!


2
Vous devez ajouter des cas de test plus grands.
mbomb007

7
Pouvez-vous expliquer cela un peu plus clairement? Je suis un anglophone natif et je n'ai aucune idée de ce que "... et si x est dans un, alors 2x + 1 et 3x-1 sont dans un." est censé signifier.
chat

1
@cat x ϵ A → (2*x) + 1 ϵ Aet x ϵ A → (3*x)-1 ϵ A, où ϵsignifie "est membre de" et peut être compris comme "implique".
Steven H.

3
Condition implicite: la séquence ne contient pas de nombres non requis par les autres règles. (Sinon $ a (i) = i $ serait une séquence valide)
Stig Hemmer

1
Et vous obtenez des réponses Mathematica et Haskell gratuites pour commencer :)
Arrêtez de nuire à Monica

Réponses:


9

Gelée , 16 octets

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

Très inefficace. Essayez-le en ligne!

Comment ça marche

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
Cela peut être 16 caractères , mais je ne connais aucun encodage qui représente cela en moins de 30 octets .
remer riche

18
Jelly a sa propre page de codes qui permet à ces caractères de 1 octet chacun.

15

Python 2, 88 83 72 octets

Vous voudrez peut-être lire les programmes de cette réponse dans l'ordre inverse ...

Plus lent et plus court encore, grâce à Dennis:

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

Essayez-le en ligne


Cela ne fonctionne pas aussi vite, mais est plus court ( 83 octets ). En triant et en supprimant les doublons à chaque itération, ainsi qu'en supprimant le premier élément, je supprime la nécessité d'un index dans la liste. Le résultat est simplement le premier élément après les nitérations.

J'ai peut-ętre surpassé Dennis. :RÉ

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]

Essayez-le en ligne


Cette version ci-dessous ( 88 octets ) fonctionne très rapidement, trouvant le 500000ème élément en environ deux secondes.

C'est assez simple. Calculez les éléments de la liste jusqu'à ce qu'il y ait trois fois plus d'éléments n, car chaque élément ajouté peut ajouter au plus 2 éléments uniques supplémentaires. Supprimez ensuite les doublons, triez et imprimez le ne élément (indexé zéro).

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]

Essayez-le en ligne


8

Python 2, 59 octets

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

Basé sur la réponse Python de @ mbomb007 . Testez-le sur Ideone .


"On ne dépasse pas simplement Dennis" ... J'aimerais avoir pensé à utiliser des littéraux fixes. Cela semble tellement évident maintenant. Cette réponse est-elle encore plus rapide que mon programme "rapide" si vous passez de l'exécution d'une chaîne au code réel?
mbomb007

Nan. C'est plus lent. Les opérations d'ensemble sont plus coûteuses.
mbomb007

Ouais, minest O (n) alors que l'indexation de liste est O (1) , donc cette solution est au moins O (n²) ...
Dennis

8

Haskell, 76 73 69 octets

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

Utilise un index basé sur 0. Exemple d'utilisation: (filter t[1..]!!) 54-> 255.

Au lieu de construire la liste en insérant à plusieurs reprises 2x+1et 3x-1comme on le voit dans la plupart des autres réponses, je passe en revue tous les entiers et vérifie s'ils peuvent être réduits 1en appliquant à plusieurs reprises (x-1) / 2ou (x+1) / 3s'ils sont divisibles.


Cela ne définit pas vraiment une fonction ou un extrait de code valide, n'est-ce pas?
Zeta

@Zeta La dernière ligne correspond à une fonction sans nom.
Zgarb

@Zgarb Ce qui est une erreur dans un fichier Haskell, et aucun interprète à ma connaissance ne supporte ce type de fonctionnalité. Alors, s'il vous plaît, éclairez-moi, comment un utilisateur est-il censé utiliser cela sans modifier le code ci-dessus de quelque manière que ce soit? Ou pourriez-vous me pointer vers une méta-publication qui autorise ce type de code?
Zeta

2
@Zgarb Je pense que pour la dernière ligne, affectez-le à une liaison (comme f=filter t[1..]!!), parce que je ne pense pas que ce soit correct.
TuxCrafting

1
@ TùxCräftîñg Sur ce message Meta , il a été déterminé que des fonctions d'aide supplémentaires sont acceptables par défaut dans cette situation. C'est également le format que je vois habituellement pour les réponses Haskell ici. Bien sûr, en tant qu'auteur du défi, vous avez l'autorité finale.
Zgarb

7

Haskell, 77 74 octets

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

Cela fournit une fonction apour la nième entrée. Il est indexé zéro. Alternativement, a=nub$f[1]créera la liste entière (paresseusement).

Il s'agit d'une variante de liste du Setcode de Reinhard Zumkeller .


Pourquoi pas yau lieu de xssauver deux octets? En outre, je pense que vous pourrez peut-être réduire la dernière ligne à quelque chose comme(!!)$nub.f[1]
Michael Klein

@MichaelKlein: Je suis juste trop habitué (x:xs), j'ai complètement oublié ça, merci.
Zeta

6

Python 2, 88 84 octets

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)

Testez-le sur Ideone .


13
Vous êtes un pro pour transformer quelque chose de simple en quelque chose d'illisible.
mbomb007


5

Brachylog , 45 octets

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

Calcule N = 1000en environ 6 secondes sur ma machine.

Ceci est indexé 1, par exemple

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

Explication

  • Prédicat principal:

    :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
    
  • Prédicat 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
           )
    

Vous pouvez noter que nous ne transmettons aucune entrée au prédicat 1 lorsque nous appelons y - Yield. En raison de la propagation des contraintes, il trouvera la bonne entrée une fois atteint la 1.clause qui propagera les valeurs d'entrée correctes.


4

MATL, 19, 18 17 octets

1w:"tEQy3*qvSu]G)

Il s'agit d'un algorithme extrêmement inefficace. L'interpréteur en ligne manque de mémoire pour les entrées supérieures à 13.

Un octet sauvé, grâce à Luis Mendo!

Essayez-le en ligne!

Cette version est plus longue, mais plus efficace (21 octets)

1`tEQy3*qvSutnG3*<]G)

Essayez-le en ligne

Explication:

La façon logique de le faire est d'ajouter des éléments au tableau jusqu'à ce qu'il soit suffisamment long pour saisir le ième élément. Voilà comment fonctionne l'efficacité. La manière golfique (et inefficace) de le faire est simplement d'augmenter la taille du tableau i fois.

Alors d' abord, nous définissons le tableau de départ: 1. Ensuite, nous échangeons les deux éléments supérieurs, de sorte que l'entrée soit au-dessus. w. Maintenant, nous parcourons l'entrée avec :". Donc je le fais:

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.

Maintenant, nous avons un gigantesque tableau de la séquence. (Beaucoup plus que ce qui est nécessaire pour calculer) Nous arrêtons donc la boucle ], et prenons le ième nombre de ce tableau avec G)(1-indexé)


@LuisMendo Merci pour le conseil! Comment réécririez-vous cela avec une boucle while au lieu de la boucle for? (Peut-être que ce serait une meilleure question pour la salle de chat MATL)
DJMcMayhem

Cela pourrait se faire de cette façon: 1`tEQy3*qvuStnG<]G). La condition de boucle est tnG<(quitter lorsque le tableau a déjà la taille requise)
Luis Mendo

Je ne sais pas à quel point c'est de la triche, mais dans la forversion -loop, vous pouvez prendre l'entrée en unaire sous forme de chaîne et supprimer le:
Luis Mendo

4

JavaScript (ES6), 63 octets

 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)

Abandonne probablement rapidement à cause de la récursivité.


4

Rétine, 57

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

Essayez-le en ligne!

0 indexé. Suit l'algorithme fréquemment utilisé: supprimez la valeur minimale de l'ensemble actuel, appelez-la x, et ajoutez 2x+1et 3x-1à l'ensemble un nombre de fois égal à l'entrée, puis le nombre de tête est le résultat. Le "set" dans Retina est juste une liste qui est triée à plusieurs reprises et faite pour ne contenir que des éléments uniques. Il y a quelques morceaux sournois ajoutés à l'algorithme pour le golf, que j'expliquerai une fois que j'aurai plus de temps.

Un grand merci à Martin pour avoir joué à environ 20 octets!


4

Clojure, 114 108 octets

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

Je ne serais pas surpris si cela pouvait être joué au golf / réduit de manière significative, mais setle fait de ne pas soutenir nth a vraiment nui à ma pensée.

Essayez le en ligne

Version avec espaces:

#(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 octets

Utilise l' encodage CP-1252 .

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

Explication

$                  # 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

Essayez-le en ligne pour les petits nombres

Très lent.
Utilise l'indexation basée sur 0.


3

C ++, 102 octets

[](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;};

Cette fonction lambda nécessite #include <map>et using std::map.

Le mapici est juste une collection de clés; leurs valeurs sont ignorées. J'utilise mapafin de bénéficier du code laconique pour l'insertion:

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

Grâce à l'ordre trié de map, le plus petit élément est extrait par k.begin()->first.


1
Légèrement plus courte (97) à l' aide setet initialiseur listes: [](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

En fait, 27 octets

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

Essayez-le en ligne!

Ce programme utilise une indexation basée sur 0. L'approche est très brute, alors ne vous attendez pas à ce qu'elle fonctionne dans l'interpréteur en ligne pour des entrées plus importantes.

Explication:

╗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 octets)

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

Démo en ligne . Notez que cela utilise une indexation basée sur zéro.

Cela utilise une approche similaire à la plupart: appliquer les ntemps de transformation , puis trier et extraire le ne élément. En signe d'efficacité, la déduplication est appliquée à l'intérieur de la boucle et le tri est appliqué à l'extérieur de la boucle.


2
22: 1ari{(_2*)\3*(@||$}*0=(Aussi beaucoup plus efficace.)
Martin Ender

2

Rétine , 48 octets

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

Essayez-le en ligne!

Inspiré par la réponse de Nimi, je pensais que j'essaierais une approche différente pour Retina, en utilisant le retour arrière du moteur regex pour déterminer si un nombre (unaire) donné est dans la séquence ou non. Il s'avère que cela peut être déterminé avec une expression régulière de 27 octets, mais son utilisation coûte un peu plus, mais cela finit toujours par être plus court que l'approche générative.

Voici une solution alternative de 48 octets:

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

Et en utilisant les E / S unaires, nous pouvons faire 42 octets, mais j'essaie d'éviter cela et l'autre réponse Retina utilise également des décimales:

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

2

Ruby, 70 octets

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

Explication

->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
Cette *1astuce est
géniale

1

J, 31 octets

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

Utilise une indexation à base zéro. Très peu efficace en mémoire.

Explication

{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

Octave, 68 octets

function r=a(n)s=1;for(i=1:n)r=s(i);s=union(s,[r*2+1 r*3-1]);end;end

Vous pouvez retirer la finale;end
Luis Mendo

Sur la version que j'utilise, au moins (4.0.0) vous ne pouvez pas ...
dcsohl

1

Perl, 173 132 octets +1 pour -n = 133

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];

Non golfé:

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];

Je peux probablement faire mieux si j'y réfléchis davantage, mais c'est ce que j'ai trouvé après quelques minutes seulement. Ma première fois au golf, donc c'était assez amusant!

Merci à @Dada et @ TùxCräftîñg (et un tas d'optimisations mineures d'octets) pour -40 octets


1
Je pense que vous pouvez supprimer les espaces après le mys, le returnet le print(impossible de tester, ne pas avoir de perl)
TuxCrafting

1
@ TùxCräftîñg a raison sur le return. Le printpeut être remplacé par un say. La plupart myne sont pas nécessaires (vous n'avez besoin que de la précédente $adans la fonction, je pense. N'initialisez ni ne déclarez @b. Vous pouvez probablement supprimer l'initialisation de $isi vous le faites $i++au début du temps plutôt qu'à la fin. popEst plus courte que shiftGardez à l' esprit que il y a beaucoup plus à jouer au golf perl que juste enlever et espaces blancs ... retour à la ligne.
Dada

0

JavaScript (ES6), 58

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

Moins golfé

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
}

Tester

À propos du temps et de la mémoire: élément 500000 en ~ 20 s et 300 Mo utilisés par mon FireFox 64 bits alpha

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>

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.