Contexte
Il est bien connu en mathématiques que les entiers peuvent être mis en correspondance biunivoque avec des paires d'entiers. Il existe de nombreuses façons de le faire, et dans ce défi, vous allez mettre en œuvre l'un d'entre eux et son fonctionnement inverse.
La tâche
Votre entrée est un entier positif n > 0
. On sait qu'il existe des entiers non négatifs uniques a, b ≥ 0
tels que . Votre sortie est la "version inversée" de , l'entier positifn == 2a * (2*b + 1)
n
2b * (2*a + 1)
.
Vous pouvez supposer que l'entrée et la sortie correspondent au type de données entier non signé standard de votre langue.
Règles et notation
Vous pouvez écrire soit un programme complet soit une fonction. Le nombre d'octets le plus bas l'emporte et les failles standard sont interdites.
Cas de test
Celles-ci sont données au format in <-> out
, car la fonction à implémenter est son propre inverse: si vous lui renvoyez la sortie, vous devriez obtenir l'entrée d'origine.
1 <-> 1
2 <-> 3
4 <-> 5
6 <-> 6
7 <-> 8
9 <-> 16
10 <-> 12
11 <-> 32
13 <-> 64
14 <-> 24
15 <-> 128
17 <-> 256
18 <-> 48
19 <-> 512
20 <-> 20
28 <-> 40
30 <-> 384
56 <-> 56
88 <-> 224
89 <-> 17592186044416
Classement
Voici un extrait de pile pour générer à la fois un classement régulier et un aperçu des gagnants par langue. Pour vous assurer que votre réponse apparaît, veuillez commencer votre réponse avec un titre, en utilisant le modèle Markdown suivant:
## Language Name, N bytes
où N
est la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les rayant. Par exemple:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Si vous souhaitez inclure plusieurs nombres dans votre en-tête (par exemple, parce que votre score est la somme de deux fichiers ou si vous souhaitez répertorier les pénalités de drapeau d'interprète séparément), assurez-vous que le score réel est le dernier numéro de l'en-tête:
## Perl, 43 + 2 (-p flag) = 45 bytes
Vous pouvez également faire du nom de la langue un lien qui apparaîtra ensuite dans l'extrait de classement:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
Réponses:
Gelée ,
171615 octetsEssayez-le en ligne!
Comment ça fonctionne
la source
Pyth,
1615 octets1 octet merci à Dennis
Suite de tests
Explication:
la source
MATL , 22 octets
Essayez-le en ligne!
Explication
la source
Q
pour1+
(cela a été introduit récemment) etq
pour1-
. Cela permet également d'économiser un espace (avec lequel vous pourriez économiser deH
toute façon). Voir iciPython 2, 39 octets
n & -n
donne la plus grande puissance de 2 qui se divisen
. Cela fonctionne parce que dans l' arithmétique en complément à deux,-n == ~n + 1
. Sin
a k zéros de fin, la prise de son complément lui fera avoir k zéros de fin. Ensuite, l'ajout de 1 changera tous les zéros de fin et changera le bit 2 ^ k de 0 à 1. Donc,-n
se termine par un 1 suivi de k 0 (tout commen
), tout en ayant le bit opposé den
tous les endroits supérieurs.la source
n&-n
marche? je vois ce que cette astuce fait mais pas comment :(n&-n
renvoie la puissance la plus élevée de 2 qui divisen
.n & -n
.n=1;exec"c=n&-n;print n,':',2*len(bin(c))-5<<n/2/c;n+=1;"*100
, mais c'est deux caractères derrière la meilleure solution.n
.MATL , 25
26octetsCela utilise la version actuelle (10.2.1) du langage / compilateur.
Essayez-le en ligne!
Explication
Assez simple, basé sur la force brute. Essaie toutes les combinaisons de a et b , sélectionne la bonne et effectue le calcul requis.
la source
Julia, 41 octets
Il s'agit d'une fonction anonyme qui accepte un entier et renvoie un entier. Pour l'appeler, affectez-le à une variable.
Nous définissons
a
comme 1 + l'exposant de 2 dans la décomposition en facteurs premiers den
. Depuis lefactor
rendement d' unDict
, nous pouvons utiliserget
avec une valeur par défaut de 0 dans le cas où le premier factorisation ne contient pas 2. Nous décalage de bits à droiten
para
, et prendre 2 à ce pouvoir. Nous multiplions cela par2a-1
pour obtenir le résultat.la source
Perl 5, 40 octets
38 octets plus 2 pour
-p
-p
lit le STDIN dans la variable$_
.$i++,$_/=2until$_%2
incrémente$i
(qui commence à 0) et divise par deux$_
jusqu'à ce qu'il$_
soit différent de zéro mod 2. Après cela,$_
est le facteur impair du nombre d'origine, et$i
est l'exposant de 2.$_=2*$i+1<<$_/2-.5
- Le côté droit de la=
est juste la formule du nombre recherché: {1 plus de deux fois l'exposant de 2} fois {2 à la puissance de {la moitié du facteur impair moins la moitié}}}. Mais «fois {2 à la puissance de…}» est considéré comme «décalé vers la gauche par…». Et ce côté droit est affecté à$_
.Et
-p
imprime$_
.la source
C, 49 octets
la source
JavaScript ES6,
3633 octetsJe crois comprendre que cela
Math.clz32
va être plus court que de jouer avectoString(2).length
.Edit: sauvé 3 octets grâce à @ user81655.
la source
n&-n
une variable:n=>63-2*Math.clz32(x=n&-n)<<n/x/2
n&=-n
, mais j'en ain
encore besoin ...PARI / GP , 38 octets
Notez que
>>
et\
ont la même priorité et sont calculés de gauche à droite, de sorte que la dernière partie peut êtren>>k\2
plutôt que(n>>k)\2
. La version non golfée seraitk
lexicale avecmy
:la source