Étant donné une entrée d'un entier positif, affichez le nombre d'étapes nécessaires pour trouver l'entrée via une recherche binaire commençant à 1.
Nous simulons une recherche binaire de l'entier qui a été donné en entrée, dans laquelle le chercheur simulé peut deviner à plusieurs reprises un entier et être informé s'il est trop élevé, trop bas ou correct. La stratégie pour trouver l'entier est la suivante:
Soit n l'entier donné en entrée que nous essayons de trouver.
Commencez avec une supposition de 1. (Pour chaque supposition, augmentez le nombre d'étapes (indépendamment du fait que ce soit correct ou non), et arrêtez immédiatement et affichez le nombre total d'étapes si la supposition était correcte.)
Doublez la supposition à plusieurs reprises jusqu'à ce que la supposition soit supérieure à n (le nombre cible). (Ou si c'est correct, mais c'est déjà couvert par notre règle de supposition correcte mentionnée ci-dessus.)
Maintenant, définissez une limite supérieure de la première puissance de 2 supérieure à n (c'est-à-dire le nombre qui vient d'être deviné) et définissez une limite inférieure de la puissance de 2 directement en dessous.
Devinez à plusieurs reprises la moyenne (arrondie vers le bas) de la limite supérieure et de la limite inférieure. S'il est trop élevé, définissez-le comme limite supérieure. S'il est trop bas, définissez-le comme limite inférieure. Cette procédure est garantie pour éventuellement aboutir à une estimation correcte.
Voici un exemple, pour l'entrée de n = 21:
1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 24 -> 20 -> 22 -> 21
\__________________________/
repeated doubling \________________________/
repeated averaging
Puisqu'il s'agit de code-golf , le code le plus court en octets gagnera.
Voici toutes les sorties de n = 1 à n = 100:
1
2
4
3
6
5
6
4
8
7
8
6
8
7
8
5
10
9
10
8
10
9
10
7
10
9
10
8
10
9
10
6
12
11
12
10
12
11
12
9
12
11
12
10
12
11
12
8
12
11
12
10
12
11
12
9
12
11
12
10
12
11
12
7
14
13
14
12
14
13
14
11
14
13
14
12
14
13
14
10
14
13
14
12
14
13
14
11
14
13
14
12
14
13
14
9
14
13
14
12
Et voici quelques cas de test plus importants:
1234 -> 21
1337 -> 22
3808 -> 19
12345 -> 28
32768 -> 16
32769 -> 32
50000 -> 28
Gelée,
1815109 octetsEssayez-le en ligne! ou vérifiez les petits cas de test et les grands cas de test .
Contexte
Soit n un entier positif et m la plus petite puissance de 2 supérieure ou égale ou égale à n .
La phase de doublage fait un pas pour chaque chiffre dans la représentation binaire de m .
Prenez la représentation binaire de n , supprimez le premier chiffre le plus significatif (toujours 1 ) et tous les zéros de fin. La phase de calcul de moyenne fait une étape pour chaque chiffre restant.
Pour éviter de calculer m , nous observons que, si n <m , le nombre de chiffres binaires de n est exactement un de moins que le nombre de chiffres binaires de m .
Si nous remplaçons le premier chiffre binaire de n par un 0 , inversons le résultat, ajoutons les chiffres binaires d'origine et supprimons tous les zéros en tête, alors ce qui suit se produit:
Si n est une puissance de 2 , tous les chiffres de la première moitié (modifiée) sont supprimés, ne laissant que les chiffres de la représentation binaire d'origine de n = m .
Si n n'est pas une puissance de 2 , le chiffre de la première moitié qui correspond au chiffre le plus significatif n'est pas supprimé, compensant le fait que n a un chiffre binaire inférieur à m .
Comment ça fonctionne
la source
’B;Bt0L
(7 octets) fonctionne dans la dernière version de Jelly, en utilisant la même approche que dans ma réponse Julia .ES6, 38 octets
Comme mentionné dans d'autres réponses, vous pouvez calculer le nombre de pas à partir des positions des premier et dernier bits.
Le nombre d'étapes dans la phase de doublement est
n=33-Math.clz32(x-1)
. Nous voulons 2ⁿ ≥ x maisn=33-Math.clz32(x)
nous donne 2ⁿ> x donc nous soustrayons 1 de x pour compenser.Le nombre d'étapes dans la phase de moyenne est plus facile, c'est tout simplement
n=Math.clz32(x&-x)-Math.clz32(x)
.x&-x
est une expression pratique qui évalue au bit le plus bas dex
(comme une puissance de 2).la source
x&-x
marche? J'aurais pensé qu'il évaluerait à la valeur absolue de x.Pyth,
1513 octetsJ'ai trouvé que le nombre à calculer est
1 + 2*ceil(log_2(x)) - [number of 2s in x's prime factorization, minus 1 if x is a power of 2 greater than 1].
Essayez-le ici .
la source
Julia,
3735 octetsMerci à @AlexA. pour économiser 2 octets!
Cela fait suite aux observations de ma réponse Jelly , mais traite différemment des cas marginaux.
Si n> 1 , la représentation binaire de n - 1 a un chiffre de moins que celui de la puissance suivante de 2 , ce qui est compensé en ne supprimant pas le premier chiffre de la représentation binaire de n .
En supprimant tous les zéros des deux côtés , nous traitons également le cas de bord 1 .
la source
Haskell, 82 octets
Il s'agit d'une implémentation assez simple dans Haskell:
Moins golfé:
la source