Fonction semi-exponentielle


21

Une fonction semi-exponentielle est une fonction qui, lorsqu'elle est composée d'elle-même, donne une fonction exponentielle. Par exemple, si f(f(x)) = 2^x, alors fserait une fonction semi-exponentielle. Dans ce défi, vous calculerez une fonction semi-exponentielle spécifique.

Plus précisément, vous calculerez la fonction des entiers non négatifs aux entiers non négatifs avec les propriétés suivantes:

  • Croissance monotone: si x < y, alorsf(x) < f(y)

  • Au moins demi-exponentielle: pour tous x,f(f(x)) >= 2^x

  • Le plus petit lexicographiquement: parmi toutes les fonctions possédant les propriétés ci-dessus, sortez celle qui minimise f(0), ce qui étant donné que ce choix minimise f(1), puis f(2), et ainsi de suite.

Les valeurs initiales de cette fonction, pour les entrées 0, 1, 2, ...sont:

[1, 2, 3, 4, 8, 9, 10, 11, 16, 32, 64, 128, 129, 130, 131, 132, 256, 257, ...]

Vous pouvez générer cette fonction via l'une des méthodes suivantes, soit en tant que fonction, soit en tant que programme complet:

  • Prenez xcomme entrée, sortie f(x).

  • Prendre xen entrée, sortir les premières xvaleurs de f.

  • Sortie infinie de tout f.

Si vous voulez prendre xet sortir f(x), xdoit être indexé zéro.

Implémentation de référence

C'est le code golf - le code le plus court en octets gagne. Les failles standard sont interdites, comme toujours.


semble que la définition ne soit pas vérifiée pour 0: f (f (0)) = f (1) = 2 mais 2 ^ 0 = 1
Nahuel Fouilleul

et pour 1: f (f (1)) = f (2) = 3 mais 2 ^ 1 = 2
Nahuel Fouilleul

1
@NahuelFouilleul l'exigence est f (f (x)) > = 2 ^ x.
Martin Ender

1
Faut-il se soumettre à l' OEIS ?
Jeppe Stig Nielsen

Réponses:


8

JavaScript (ES7), 51 48 octets

Sauvegardé 3 octets grâce à @Arnauld

f=i=>i?f[f[q=f(i-1),r=f[i]||q+1]=(i>1)<<i,i]=r:1

Prend en n et délivre en sortie la n -ième élément de la séquence.


JavaScript (ES7), 70 68 64 octets

f=(n,a=[],q=1)=>n?f(n-1,a,(n=2**a.indexOf(a.push(q)))<++q?q:n):a

Une fonction récursive qui prend xet renvoie les premiers xéléments de la séquence sous forme de tableau.

Comment ça marche

Le tableau a est généré de manière procédurale, un élément à la fois, jusqu'à ce qu'il atteigne la longueur souhaitée. (Un portage de la technique infinie utilisée dans l'excellente réponse Python de xnor serait probablement plus court.)

On peut faire l'observation suivante pour chaque indice i (indexé 0):

  • Si i existe en tant qu'élément dans un at index j ( a [j] = i ), alors a [i] doit être d'au moins 2 j .

Cela est vrai car f (f (j)) doit être d'au moins 2 j , et f (f (j)) est équivalent à a [a [j]] , qui est à son tour équivalent à a [i] .

Normalement, l'option correcte est exactement 2 j . Cependant, pour le cas singulier i = 2 , 2 existe dans le tableau à l'indice j = 1 , ce qui signifie que 2 j serait 2 - mais cela signifie que nous aurions 2 à la fois à [1] et à [2] . Pour contourner cela, nous prenons le maximum de 2 j et un [i-1] + 1 (un de plus que l'item précédent), ce qui donne 3 pour i = 2 .

Cette technique arrive également à prendre soin de décider si j existe ou non - si ce n'est pas le cas, la .indexOf()méthode de JS renvoie -1 , ce qui conduit à prendre le maximum de [i-1] + 1 et 2 -1 = 0,5 . Étant donné que tous les éléments de la séquence sont au moins 1 , cela retournera toujours l'élément précédent plus un.

(J'écris cette explication tard dans la nuit, alors faites-moi savoir si quelque chose prête à confusion ou si j'ai raté quelque chose)


Notez que les entrées 272et les versions supérieures donnent des réponses incorrectes en raison de problèmes de dépassement d'entier. C'est très bien, car cela fonctionne jusqu'à la limite du type de données.
isaacg

Utilisez 2**plutôt que 1<<nous espérons résoudre le problème.
user202729

Maintenant, le .99tue la solution. Mais pourquoi utiliser +.99et pas seulement +.9? Quelle est la différence?
user202729

@ user202729 Je me sens comme un idiot - qui a été laissé là d'une version précédente où j'utilisais Math.log2(...)et a dû calculer le plafond. Maintenant, ce n'est plus du tout nécessaire. Merci! J'examinerai la 2**chose - j'utilisais à l' 2**...+.99|0origine, mais 1<<c'était plus court parce que je n'en avais pas besoin |0. Maintenant, je pense qu'il n'y a pas de différence ...
ETHproductions




1

Gelée , 14 octets

iL’2*»Ṁ‘$ṭ
⁸Ç¡

Essayez-le en ligne!

Comment ça marche

⁸Ç¡         Main link. No arguments.

⁸           Set the left argument and the return value to [].
 Ç¡         Read an integer n from STDIN and call the helper link n times, first on
            [], then on the previous result. Return the last result.


iL’2*»Ṁ‘$ṭ  Helper link. Argument: A (array)

 L          Take the length of A. This is the 0-based index of the next element.
i           Find its 1-based index in A (0 if not present).
  ’         Decrement to a 0-based index (-1 if not present).
   2*       Elevate 2 to the 0-based index.
      Ṁ‘$   Take the maximum of A and increment it by 1.
            Note that Ṁ returns 0 for an empty list.
     »      Take the maximum of the results to both sides.
         ṭ  Tack (append) the result to A.

0

Python 2 , 111 octets

def f(x):
 a=range(1,2**x)
 for i in range(1,x):a[i]=max(a[i],a[i-1]+1);a[a[i]]=max(a[a[i]],2**i)
 return a[:x]

Essayez-le en ligne!

Il s'agit d'une modification importante de la réponse de user202729 . J'aurais posté cette amélioration en tant que commentaire, mais la réponse est supprimée et les commentaires sont donc désactivés.


Cela échoue avec une exception "index de liste hors plage" sur l'entrée 258. Je pense que le problème est qu'il x**2est trop petit.
isaacg

Eh bien ... Python 2 est différent (souvent moins d'octets) de Python 3.
user202729

1
Comme prévu, la demi-exponentielle est bien plus grande que quadratique. La solution obtient "index de liste hors plage" sur x=1000. Vous voudrez peut-être essayer 2**x- terriblement grand, mais codegolf est codegolf.
user202729

@ user202729 Ah, c'est vrai. Malheureusement, il rencontre maintenant un problème entièrement différent avec des entrées plus grandes, ce qui 2**xcrée une plage beaucoup trop grande pour que Python continue.
notjagan

0

Swift , 137 octets

func f(n:Int){var l=Array(1...n).map{$0>3 ?0:$0},p=8;if n>3{for i in 3..<n{if l[i]<1{l[i]=l[i-1]+1};if l[i]<n{l[l[i]]=p};p*=2}};print(l)}

Prend l'entrée comme Int(entier) et imprime comme [Int](tableau entier).

Version non golfée

func f(n:Int){
    var l = Array(1...n).map{$0 > 3 ? 0 : $0} // Create the range from 1 to n and set all
    var p = 8                                 // values greater than 3 to 0
    if n > 3 {
        for i in 3 ..< n {
            if l[i] < 1 {
                l[i] = l[i - 1] + 1
            }
            if l[i] < n {
                l[l[i]] = p
            }
            p *= 2
        }
    }
    print(l)
}

Je suis curieux, que se passera-t-il si vous supprimez l'espace avant le ??
ETHproductions

@ETHproductions Cela conduit à une erreur de compilation, car les entiers ne peuvent pas être chaînés en option .
Herman L
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.