Vous devez écrire un programme ou une fonction qui prend un entier non négatif N
en entrée et génère ou renvoie deux entiers (négatif, zéro ou positif) X
et Y
.
Les entiers sont signifiés au sens mathématique car ils sont infiniment nombreux.
La fonction implémentée doit être bijective . Cela signifie que pour chaque N
il doit sortir une X
Y
paire différente et chaque X
Y
paire doit être sortie pour une entrée, N
c'est-à-dire que toutes les paires suivantes doivent être sorties pour certaines N
:
...
┌─────┬─────┬────┬────┬────┐
│-2 -2│-2 -1│-2 0│-2 1│-2 2│
├─────┼─────┼────┼────┼────┤
│-1 -2│-1 -1│-1 0│-1 1│-1 2│
├─────┼─────┼────┼────┼────┤
... │0 -2 │0 -1 │0 0 │0 1 │0 2 │ ...
├─────┼─────┼────┼────┼────┤
│1 -2 │1 -1 │1 0 │1 1 │1 2 │
├─────┼─────┼────┼────┼────┤
│2 -2 │2 -1 │2 0 │2 1 │2 2 │
└─────┴─────┴────┴────┴────┘
...
Notez que U V
et V U
sont des paires différentes si U!=V
.
Détails
- Si votre langue ne prend pas en charge les entiers arbitrairement grands, c'est bien, mais votre algorithme devrait fonctionner avec un type de données entier arbitrairement grand. Votre code doit toujours prendre en charge les valeurs d'entrée pendant au moins
2^31-1
. - Si vous choisissez d'imprimer ou de renvoyer la sortie sous forme de chaîne, aucun signe de
0
début ni+
signe n'est autorisé. Sinon, la représentation entière standard de votre langue est correcte.
Exemple
Si la tâche consistait à créer une fonction bijective prenant un entier non négatif N
et à générer un entier, X
une solution pourrait être la fonction
if (input mod 2 == 0) return N/2 else return -(N+1)/2
,
mis en œuvre dans une langue. Cette fonction revient X = 0 -1 1 -2 2...
pour N = 0 1 2 3 4...
.
10=>11 12, 9=>10 11
est-ce invalide parce que 11 est répété?Réponses:
Pyth, 15
Essayez-le en ligne.
Une traduction Python:
ou itérativement:
où
binlist
convertit un nombre en une liste de chiffres commebinlist(4) = [1,0,0]
.Donc comment ça fonctionne? Il interprète les chiffres binaires du nombre comme deux nombres entrelacés en base négative deux comme dans ma solution Python .n
Le nombre binaire correspond à la paire ( x , y ) = ( b 0 - 2 b 2 + 4 b 4 - 8 b 6 + ⋯ , b 1 - 2 b 3 + 4 b 5 - 8 b 7 + ⋯ )
Si nous n'avions pas encore traité le dernier chiffre de n , nous aurions tous les indices supérieurs de $ 1 $, n ′ = … b 5 b 4 b 3 b 2 b 1 correspondant à la paire ( x ′ , y ′ ) = ( b 1 - 2 b 3 + 4 b 5 - 8 b 7 + ⋯ , b 2 - 2 b 4b0 n
la source
CJam,
242221 octetsMon cerveau a du mal à comprendre les mathématiques que les autres solutions utilisent. Mais mon cerveau comprend définitivement le binaire, alors voici une soultion basée sur la manipulation de bits!
Essayez-le en ligne.
Explication
Cette approche traite l'entrée comme deux valeurs binaires entrelacées, une pour chaque numéro de sortie. Tous, sauf le bit le moins significatif de chacun, codent une amplitude, et le bit le moins significatif indique s'il faut ou non prendre le complément binaire de cette amplitude. Dans cette implémentation, les bits impairs correspondent au premier numéro de sortie (et les bits pairs correspondent au second) et un LSB de
0
signaux pour prendre le complément.Par exemple, étant donné une entrée de
73
, sans entrelacer sa représentation binaire des1001001b
produits0 1|0
(bits impairs) et1 0 0|1
(bits pairs). La première valeur a une magnitude de01b = 1
et doit être complétée pour une valeur finale de~1 = -2
, et la seconde valeur a une magnitude de100b = 4
et ne doit pas être complétée.Démonstration informelle de l'exactitude
J'ai créé un programme de test qui place chaque entrée de zéro à un nombre spécifié par l'utilisateur moins un à son emplacement de sortie sur une grille 2D. Vous pouvez également l' essayer en ligne . Voici une sortie de ce programme montrant comment l'algorithme est mappé
0-99
:Le motif de remplissage semble un peu bizarre, mais il est en fait bijectif! Avec chaque puissance successive de 4, il remplit un carré avec le double de la longueur du côté précédent. Par exemple, voici comment l'algorithme mappe
0-15
:Cela constitue le carré 4x4 au milieu du carré 8x8 de
0-63
:Ce qui constitue le carré 8x8 au milieu du carré 16x16 de
0-255
:la source
li4b2fmd2/
au lieu de0li2b+W%2/W%
. Cela donne les mêmes nombres entiers, mais dans l'ordre inverse.Python 2, 49
Edit: Amélioré à 49 en utilisant une meilleure récursion en une étape pour la base -2.
Voici une version Pyth utilisant
reduce
.Edit: Amélioré à 52 en passant à la base -2 du ternaire équilibré .
Python 2, 52
Python 2, 54
Cela utilise l'entrelacement des chiffres comme la solution de Runer112 , mais avec un ternaire équilibré plutôt que binaire signé. Python n'a pas de conversion de base intégrée, donc le code l'implémente récursivement.
La fonction d'assistance
h
(avec3
à la place de9
) prend un nombre naturel et le convertit du ternaire en ternaire équilibré avec les substitutions de chiffresAinsi, par exemple, 19, qui est 201 en base, devient (-1) (0) (+ 1) en ternaire équilibré, qui est (-1) * 3 ^ 2 + (0) * 3 ^ 1 + (+ 1) * 3 ^ 0 = -8.
Un ternaire équilibré suffit pour coder chaque entier, et donne ainsi une correspondance entre les nombres naturels et les entiers.
Pour mapper sur des paires d'entiers, nous entrelacement les chiffres dans
n
. Pour ce faire, nous avonsh
examiné tous les autres chiffres en faisantn/9
comme étape récursive plutôt quen/3
. Ensuite, pour une coordonnée, nous décalonsn
en divisant le sol par3
.Voici les 81 premières sorties, qui couvrent la région [-4,4] ^ 2.
Un codage alternatif avec quart-imaginaire s'est avéré plus long, bien qu'il soit très joli.
Python 2, 63
Dans une langue avec une gestion moins maladroite des conversions complexes, ce serait probablement une meilleure approche. Si nous pouvions sortir des nombres complexes, nous pourrions faire:
Python 2, 38
la source
L&b-%b2*2y/b4,yQy/Q2
ne fait que 20 octets.Python 2, 98 octets
Commençons par une approche simple:
Il forme simplement une spirale rectangulaire
N
sur une grille 2D, en partant de l'origine, et renvoie les coordonnées du dernier point.La fonction est bijective puisque:
La spirale ressemble à ceci (sauf à partir de 0 plutôt que 1):
la source
0**0 == 1
en python, c'est donc la même chose queif a == 0: a = b/2
a=a or b/2
plus court0^0=1
en toutes mathématiques, pas seulement en python.0**0
est en fait une forme indéterminée en mathématiquesdc, 49
Cela commence par disposer les entiers non négatifs sur une grille ainsi:
Notez que la façon dont les positions de la grille sont remplies en diagonale avec l'augmentation de N. Remarquez que la ligne Y = 0 contient la séquence de nombres triangulaires, donnée par
N = X(X+1)/2
. Il s'agit d'une équation quadratique qui est résolue en utilisant la formule normale, en utilisant uniquement la racine + ve, afin que nous puissions déterminer X à partir de N lorsque Y = 0. Vient ensuite un simple mélange arithmétique pour donner un {X, Y} unique pour chaque N.Cela fournit la qualité bijective requise, mais X et Y ne sont que non négatifs, mais la question nécessite tous les entiers possibles. Donc X et Y sont mappés en utilisant
((t+1)/2)*((t+1)~2*2-1)
pour donner tous les entiers possibles.dc
a des nombres de précision arbitraires, donc la plage d'entrée à2^31-1
ne pose aucun problème. Notez également que la précision par défaut est 0 chiffres décimaux, etsqrt()
et/
vers le bas autour de ce qui est le comportement nécessaire ici.Sortie:
la source
Matlab, 54 octets
La clé ici est
spiral
cela crée une matrice en spirale d'une taille arbitraire.résultats
spiral
la source
Haskell,
7874 octetsEssai:
Fonctionnement: répertoriez toutes les paires du premier quadrant dans l'ordre suivant
miroir chaque point dans les autres quadrants pour faire une liste de 4 listes d'éléments. Concatène tout en une seule liste et prends le
n
e élément.Edit: la fonction n'a pas besoin de nom, les mathématiques ont été réorganisées. expressions.
la source
do
-notation: Essayez-le en ligne!Haskell , 50 octets
Essayez-le en ligne ou essayez-le avec son inverse!
Non golfé
Explication
(!)
l
xCounter
y
.Notez que la fonction réelle
f
(ntoN2
) incrémente l'entrée avant de commencer la procédure.la source
05AB1E , 35 octets
Essayez-le en ligne! ou comme suite de tests
Explication
Considérer
la source
Mathematica, 46
Trier les vecteurs selon leur norme, puis prendre le
n
th.la source
JavaScript, 166
168octets / caractèresNouvelle approche utilisant une spirale rectangulaire comme les autres utilisent.
J'ai utilisé cette réponse sur Math.SE, je l'ai traduite en JS et je l' ai compressée en utilisant UglifyJS .
Cette approche n'utilise aucune boucle et ne crée aucune spirale.
Mise à jour: enregistré 2 caractères en stockant
Math
dansb
.t-=1
t+=4
la source