Une sous-séquence est une séquence que vous pouvez obtenir d'une autre en supprimant n'importe quelle quantité de caractères. Les non-vides séquences distinctes 100
sont 0
, 1
, 00
, 10
, 100
. Les non-vides séquences distinctes 1010
sont 0
, 1
, 00
, 01
, 10
, 11
, 010
, 100
, 101
, 110
, 1010
.
Écrivez un programme ou une fonction qui, étant donné un entier positif n, renvoie le nombre de sous-séquences distinctes non vides de l'expansion binaire de n .
Exemple: puisque 4
est 100
en binaire, et nous avons vu qu'il avait cinq sous-séquences distinctes non vides ci-dessus, donc f(4) = 5
. À partir de n = 1 , la séquence commence:
1, 3, 2, 5, 6, 5, 3, 7, 10, 11, 9, 8, 9, 7, 4, 9, 14, 17, 15, 16, 19, 17, 12
Cependant, votre programme doit fonctionner pour tout n <2 50 en moins d'une seconde sur n'importe quelle machine moderne. Quelques grands exemples:
f(1099511627775) = 40
f(1099511627776) = 81
f(911188917558917) = 728765543
f(109260951837875) = 447464738
f(43765644099) = 5941674
Réponses:
Python 3 ,
95 octets83 octets[-12 octets grâce à Mr.XCoder :)]
Essayez-le en ligne!
Une note sur l'algorithme. L'algorithme calcule l'incrément en sous-séquences uniques données par le bit à une position donnée t. L'incrément pour le premier bit est toujours 1. L'algorithme parcourt ensuite la séquence de bits s (t) et ajoute l'incrément v [s (t)]. À chaque étape, l'incrément pour le complément de s (t), v [1 - s (t)] est mis à jour à v [1] + v [0]. Le nombre final est la somme de tous les incréments.
Il doit s'exécuter dans O (log2 (n)), où n est le numéro d'entrée.
la source
JavaScript (ES6),
5351 octetsCas de test
Afficher l'extrait de code
Formaté et commenté
Version non récursive, 63 octets
Enregistré 3 octets grâce à @ThePirateBay
Cas de test
Afficher l'extrait de code
la source
map
) à la variable indicateurl
au lieu d'un tableau vide.Python 2 , 56 octets
Essayez-le en ligne!
Reprenant la méthode de NofP .
59 octets de manière itérative:
Essayez-le en ligne!
la source
Gelée , 10 octets
Cela utilise l'amélioration de @ xnor sur l'algorithme de @ NofP .
Essayez-le en ligne!
Contexte
Soit (a 1 , ..., a n ) une suite binaire finie. Pour chaque entier non négatif k ≤ n , définissez o k comme le nombre de sous-séquences uniques de (a 1 , ..., a k ) qui sont soit vides soit terminées en 1 , z k comme le nombre de sous-séquences uniques qui sont vide ou se termine par 0 .
Clairement, o 0 = z 0 = 1 , car la seule sous-séquence de la séquence vide est la séquence vide.
Pour chaque indice k , le nombre total de sous-séquences de (a 1 , ..., a k ) est o k + z k - 1 (la soustraction de 1 tient compte du fait que o k et z k comptent la séquence vide). Le nombre total de sous- séquences non vides est donc o k + z k - 2 . Le défi demande de calculer o n + z n - 2 .
N'importe quand k> 0 , nous pouvons calculer o k et z k récursivement. Il y a deux cas:
a k = 1
z k = z k-1 , puisque (a 1 , ..., a k-1 ) et (a 1 , ..., a k-1 , 1) ont les mêmes sous-séquences se terminant par 0 .
Pour chacune des o k - 1 sous-séquences non vides de (a 1 , ..., a k ) qui se terminent par 1 , nous pouvons supprimer le 1 de fin pour obtenir l'une des o k-1 + z k-1 - 1 sous- séquences (a 1 , ..., a k-1 ) . Inversement, l'ajout d'un 1 à chacune de ces dernières séquences o k-1 + z k-1 - 1 donne l'une des premières séquences o k - 1 . Ainsi, o k - 1 = o k-1 + zk-1 - 1 et o k = o k-1 + z k-1 .
un k = 0
De façon similaire au cas précédent, on obtient les formules récursives o k = o k-1 et z k = z k-1 + o k-1 .
Comment ça fonctionne
la source
05AB1E , 12 octets
Essayez-le en ligne! Explication: Comme indiqué par les autres réponses, le nombre de sous-séquences pour une chaîne binaire
a..y0
qui se terminent par 1 est le même que le nombre pour la chaîne binairea..y
, tandis que le nombre qui se termine par a0
est le nombre total de sous-séquences pour le binaire chaînea..y
(qui chacun gagne un0
suffixe) plus une pour0
elle-même. Contrairement aux autres réponses, je n'inclus pas la sous-séquence vide car cela enregistre un octet construisant l'état initial.la source
Java 8, 97 octets
Port de la réponse Python 2 de @xnor , qui à son tour est une amélioration de la réponse Python 3 de @NofP .
Essayez-le ici.
C'est peut-être une bonne chose que la balise à temps limité était présente, car j'avais initialement les éléments suivants pour forcer toutes les sous-séquences:
Essayez-le ici.
Ce qui a également fonctionné, mais a pris beaucoup trop de temps pour les trois derniers cas de test. Sans parler de sa longueur (
208204 octets ).la source
6502 code machine (C64), 321 octets
Démo en ligne
Démo en ligne avec vérification des erreurs (346 octets)
Utilisation:,
sys49152,[n]
par exemplesys49152,911188917558917
.La restriction de temps et les cas de test nécessitent des solutions pour calculer en nombres 64 bits, donc le temps de prouver que le C64 est qualifié de " machine moderne ";)
Bien sûr, cela nécessite un peu de code, le système d'exploitation ne fournit rien pour les entiers supérieurs à 16 bits. La partie boiteuse ici: c'est encore une autre implémentation (légèrement modifiée) de l'algorithme de NofP resp. Variante améliorée de xnor . Merci pour l'idée;)
Explication
Voici une liste commentée de démontage de la partie pertinente faisant l'algorithme:
Le reste est une entrée / sortie et une conversion entre une chaîne et un entier non signé 64 bits (little-endian) en utilisant un algorithme à double touche. Si vous êtes intéressé, voici la source complète de l'assemblage pour la version avec vérification des erreurs - la version "golfée" est dans la branche "golf".
la source