C'était à l'époque, mais aujourd'hui, tout le monde est passé à IPv6 . (Droite?)
Votre tâche consiste à écrire un programme imprimant toutes les adresses IPv6 .
Vous devez écrire un programme complet ne prenant aucune entrée et imprimant les adresses IPv6, une par ligne, et aucune autre sortie. Votre programme doit imprimer les 2 128 adresses possibles, y compris les adresses non valides. Chaque adresse doit être imprimée exactement une fois. Vous pouvez imprimer les adresses dans n'importe quel ordre.
Chaque adresse peut être imprimée en entier, avec 8 groupes de 4 chiffres hexadécimaux séparés par des points, par exemple
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Vous pouvez, à votre discrétion, utiliser l’une des abréviations standard du RFC 5952 :
- Les zéros non significatifs d'un groupe peuvent être omis, à l'exception de ceux qui
0
ne peuvent pas être abrégés davantage. ::
peut être utilisé au plus une fois par adresse pour abréger une séquence d'un ou de plusieurs groupes entièrement nuls.- Les chiffres hexadécimaux peuvent utiliser des minuscules ou des majuscules.
Si vous atteignez la recommandation de représentation de la RFC 5952 (lettres minuscules uniquement, représentation la plus courte possible, ::
utilisée le plus tôt possible s'il existe plusieurs endroits où elle peut être utilisée), vous obtenez un bonus de -20% .
En raison de la taille de la sortie, votre programme ne devrait pas se terminer tant que nous resterons assis. Votre programme peut être interrompu par des moyens externes à un moment donné ( Ctrl+ C, coupure de courant,…). Votre programme doit produire une sortie sous forme de flux, afin qu'après une attente «raisonnable», il ait généré des lignes. Fondamentalement, la construction d'une chaîne de caractères géante en mémoire uniquement pour l'imprimer à la fin n'est pas autorisée. Tout programme qui manquerait de mémoire sur un PC «standard» est disqualifié. (Néanmoins, si votre programme doit être exécuté suffisamment longtemps, il doit imprimer toutes les adresses IPv6 puis quitter.)
(Si cette condition pose un problème pour les interprètes Web qui exécutent le programme jusqu'à la fin, puis vous permettent d'afficher le résultat et que vous ne disposez pas d'un interprète hébergé, testez votre programme sur une version plus petite du problème, puis ajustez-le soigneusement. au maximum 2 128. )
Votre score est la longueur en octets de votre programme, multipliée par 0,8 si vous obtenez le bonus. C'est le code de golf, donc le score le plus bas gagne.
la source
Réponses:
Pyth, 21 octets
Utilise une boucle while avec
J
comme variable itérateur. Initialise le maximum en utilisant8^chr(' ')
. Pads en ajoutant cette valeur initiale, la conversion en hexadécimal, puis en supprimant le premier caractère.la source
Python 3, 65 octets · 0.8 = 52.0
la source
ipaddress
est python3 seulement.Pyth,
272524 octetsNote: le code avait un bogue précédemment, le corrigeant sauvé 1 octet
Imprime les adresses comme
Version précédente (plus compliquée) utilisant l'opérateur Pad (également 24 octets):
Explication
Pyth, 21 octets (invalide)
Cela ne peut pas être exécuté car 1) il consommerait au moins 2 132 octets (2 52 yobibytes) de mémoire et 2) l'interpréteur ne l'aime pas (2 128 n'entre pas
ssize_t
, donc pas delist
s de cette taille) . Il imprimerait les adresses dans l'ordre lexicographique. Vous pouvez essayer l'algorithme en changeant le (s) numéro (s) en un objet utilisable.la source
C (avec extensions GCC), 76 octets * 0.8 = 60.8
Il utilise les entiers de 128 bits extension de GCC pour compter tout simplement de
::
laffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
.inet_ntop()
formate correctement chaque adresse pour que le bonus de -20% puisse être réclamé.Sortie
Utilisant
sed
pour produire chaque millionième ligne jusqu'à 10 millions:Remarque J'utilise une machine little-endian x86_64 et, comme les adresses réseau sont généralement toujours dans l'ordre du réseau (big-endian), l'endianité est donc efficacement permutée par
inet_ntop()
. Cela n'a pas d'importance - toutes les adresses seront toujours (éventuellement) affichées.la source
CJam,
3627 octets-9 octets grâce à @Dennis (j'ai oublié que CJam a un formatage de chaîne). Imprime les adresses minuscules et décroissantes.
Pour des raisons évidentes, utilisez l’interpréteur Java, pas celui en ligne. Vous pouvez toutefois remplacer
G32#
par quelque chose de plus petit pour les tests en ligne, par exemple , les 100 derniers .Explication
la source
0000:0000:0000:0000:0000:0000:ffff:ffff
. On dirait que le formatage de la chaîne pourrait fonctionner différemment en ligne. J'ai confirmé que cela fonctionne bien avec la version hors ligne.n
est le même queoNo
dans TIO .Python 2.7, 67 octets
Comme effet secondaire de la méthode utilisée pour insérer les deux points, les adresses sont imprimées avec la colonne la plus à droite apparaissant à gauche:
la source
[printing] the addresses in any order
. ;)Verilog, 335
Ma première soumission Verilog pourrait probablement utiliser davantage de golf, mais je n’ai pas l’énergie pour le faire pour le moment.
c
is clock,o
est une sortie ASCII. Ne remplit pas les conditions pour bénéficier d'un bonus de mise en forme en raison de la mise à zéro et non de l'abréviation.Il s’agit d’une simple itération suivie d’un peu de bricolage pour rendre la sortie ASCII. Je coupe le côlon après le dernier groupe avec un petit hack. Synthétise et semble fonctionner pour xc3s500e-4ft256-4 sur ISE 13.7 lin64.
la source
C, 91-126 octets
Ma version originale, 119 octets.
Meilleure version portable au golf, 103 octets (merci à Dennis pour certains de ces concepts)
Explication: L’algorithme lui-même est relativement simple. J'ai utilisé long plutôt que unsigned int parce que c'est plus court. Les déclarer au niveau du fichier signifie que tout est pré-initialisé avec des zéros. La
f
fonction est un simple incrémentation avec retenue qui opère sur les 16 bits les plus bas de chaque mot. La boucle se termine quand elle passe dans le 129ème bit.Une itération en arrière pour printf signifie que nous imprimons les adresses dans le "bon" ordre et que le contrôle pour l'impression d'une nouvelle ligne est plus court de quelques caractères.
Cela utilise des constructions non portables. Il est préférable de le considérer comme un dialecte K & R de C, car il utilise des types de retour int implicites et n'inclut pas stdio.h. Et mon utilisation de long a été informée par cela - sur la plupart des systèmes modernes, int est suffisant car 32 bits. Cela pourrait probablement fonctionner sans modification sur PDP-11 Unix.
Cependant, cela peut être plus court. Si nous supposons que nous pouvons utiliser int (soit comme un type plus large que 16 bits, ou un type d’exactement 16 bits avec diverses propriétés qui se vérifient sur de nombreux systèmes tels que le complément à deux et le basculement arithmétique), nous pouvons nous débarrasser de les trucs liés à l'utilisation de long.
Version pour int plus large que 16 bits, 97 octets.
Version pour les systèmes 16 bits, 91 octets.
Curieusement, cependant, le compilateur K & R original ne supportait pas la déclaration sans int (il compile bien, mais traite les variables comme externes et donc indéfinies au moment du lien), donc trois octets supplémentaires sont nécessaires pour changer la déclaration en
int*p,a[9];
pour un total de 94.De plus, si l'hypothèse qu'il est interrompu avant la fin de la sortie était une contrainte difficile, nous pourrions supprimer le contrôle de fin en économisant cinq octets.
Bonus: version portable entièrement ANSI, 126 octets:
Les nouvelles lignes de toutes les versions sont insérées pour des raisons de lisibilité et aux emplacements où aucun espace n'est requis, et sont exclues du nombre d'octets, à l'exception de la nouvelle ligne après la
#include
ligne dans la version ANSI.Toutes les versions, à l'exception de la version ANSI, tombent à la fin de la version principale et peuvent par conséquent renvoyer un code de sortie parasite au système d'exploitation.
la source
a[9];f(int*x){if(++*x>>16)*x=f(x+1);}main(i){for(;!a[8];f(a))for(i=8;i--;)printf(i?"%x:":"%x\n",a[i]);}
i--
vérification de mon état.a[0]
et enveloppera[1]
AutoIt3,
142231 octetsExplication
For $a=0 To 2^32-1
: Itérer 4 fois sur 0-2 ^ 32 ((2 ^ 32) ^ 4 = 2 ^ 128) combinaisons possibles.$s=StringFormat("%08x%08x%08x%08x",$a,$b,$c,$d)
: Convertir les nombres en chaîne hexadécimale d’une longueur de 32 (4 * 32).For $j=0 To 8
: Itérer sur les 8 sections de la chaîne.ConsoleWrite(StringMid($s,$j*4+1,4)&($j<7?":":""))
: Extrait les 4 prochains caractères de la chaîne et ajoute un signe deux-points (:
) à la fin, si nous n’avons pas atteint la dernière section, puis tout afficher sur la consoleNext
: Termine la boucle for interneConsoleWrite(@LF)
: Ajouter un saut de ligne à la fin de la ligneNext
: Terminez les boucles externesTaille de sortie attendue: (une ligne (39 octets) + saut de ligne) (= 40 octets) * 2 ^ 128 = 1,361 * 10 ^ 16 YB (yottabytes)
la source
4^64 - 1
?Cannelle, 16 octets
Essayez-le en ligne. (TIO limite la sortie)
Explication
Le
g
mode met Cinnamon Gum en mode de génération . Le reste de la chaîne se décompresse en cette regex:Il crée ensuite un générateur de toutes les chaînes possibles qui correspondent à l'expression rationnelle et effectue une itération à travers celle-ci, en affichant chacune d'elles.
De manière assez amusante, la regex golfier
([0-9a-f]{4,4}:){7,7}[0-9a-f]{4,4}
compresse en fait une chaîne plus longue que la regex ci-dessus.la source
Commodore BASIC 2.0, 339 octets
Pour obtenir des chiffres hexadécimaux minuscules, ce programme est écrit en "mode décalé" (appuyez sur
<SHIFT>+<C=>
).Faire fonctionner ce système sur le Commodore 64 était un véritable défi en raison de la mémoire, de la taille de l’écran, de la taille des données et d’autres limitations. J'ai envisagé d'implémenter la représentation abrégée, mais d'autres limitations (telles que l'incapacité non documentée d'utiliser des éléments de tableau en tant qu'indices de boucle) impliquaient une augmentation de la longueur du programme d'environ 1000 octets.
La ligne 7 est une implémentation de
HEX$()
laquelle Commodore BASIC 2.0 fait défaut. Je ne peux pas utiliser unDEF FN
pour cela car ceux-ci ne peuvent que renvoyer des nombres, pas des chaînes. La ligne 6 est un sous-programme qui l’applique à un groupe de quatre chiffres, ce qui aurait été considérablement plus court si les fonctions pouvaient renvoyer des chaînes.Les lignes 2 et 5 sont huit boucles imbriquées, implémentées comme sept boucles "pour" et une condition conditionnelle, car huit boucles pour "," combinées aux deux "gosubs" pour imprimer l'adresse débordent de la pile minuscule du C64.
Un C64 peut imprimer environ 1,2 adresse par seconde, pour un temps d'exécution estimé à 1,3 * 10 ^ 31 ans.
la source
PowerShell (v4),
193 166 162 145103 octetsLa version sans bonus de TimmyD à 103 octets:
Version précédente avec bonus à 145 * 0.8 = 116 octets
Avec l' aide de TimmyD et tomkandy , qui souligne que ,
0 -eq $false
mais([bigint]0) -eq $true
. Donc, toutes mes versions précédentes ne se termineront pas.Auparavant à 162, avant quelques changements de regex:
"Un défi où PowerShell doit être raisonnablement compétitif!" - moi, avant de l'essayer.
Explication
la source
for($g=[bigint]::pow(2,128);$g;$g-=1){'{0:X32}'-f$g-replace'(?=(.{4})+$)',':'-replace'^0+:',''}
for($g=[bigint]::pow(2,120);$g;$g-=1){'{0:X32}'-f$g-replace'(?=(.{4})+$)',':'-replace'^0*:',''}
for($g=[bigint]::pow(2,128);$g-gt0;$g-=1){'{0:X32}'-f$g-replace'(?=(.{4})+$)',':'-replace'^\d*:',''}
Oui, la première adresse est fausse mais elle ne se répète pas à la fin. Notez également quewhile($i)
chez vous, ne vous arrêtez pas à zéro - est[boolean][bigint]0
considéré comme vrai0:
: /)$i=[bigint]::Pow(4,64);while($i-gt0){('{0:X32}'-f($i-=1)-replace'0(?=.{32})'-replace'.{4}(?!$)','$0:')}
à 103 ...AutoIt3, 137 octets
la source
4^64 - 1
?Python 2, 95 octets
Parcourt simplement tous les nombres de 0 à 2 ^ 128. Il convertit d'abord le nombre actuel en chaîne hexadécimale, puis supprime le résultat de la
'0x'
fonction. Ensuite, il ajuste la chaîne de manière à avoir 32 zéros à l’avant, puis la divise en groupes de quatre. Enfin, il joint les groupes de quatre avec des deux points, les imprime et ajoute 1 au nombre actuel. A le bonus supplémentaire que vous pouvez le démarrer à n'importe quelle valeur si vous lui donnez un, mais aucune entrée n'est nécessaire.la source
Haskell 111
Avec ma propre fonction de séquence,
s
il ne perd plus de mémoire, mais ne se sent plus joué au golf.la source
CBM BASIC v7.0 (166 caractères)
La réponse de Mark concerne BASIC 2.0 du Commodore 64, pour lequel il manque une commande intégrée permettant d’imprimer des nombres au format hexadécimal. Cependant, grâce à la
HEX$()
fonction de BASIC 7.0, la version du Commodore 128 est beaucoup plus courte. Il ne tient pas sur une seule ligne logique (limitée à 160 caractères sur le C128), mais peut toujours être saisi en tant que deux lignes distinctes en mode direct.la source
Ruby 75
C'est une solution récursive qui prend un préfixe et trouve tous les suffixes possibles. Récursivement.
la source
x=->s,n{...};x['',8]
Tcl
341318301la source