Esto fue entonces, pero hoy en día todo el mundo ha cambiado a IPv6 . (¿Derecho?)
Su tarea es escribir un programa que imprima todas las direcciones IPv6 .
Debe escribir un programa completo que no reciba entradas e imprima direcciones IPv6, una por línea y ninguna otra salida. Su programa debe imprimir las 2 128 direcciones posibles, incluidas las no válidas. Cada dirección debe imprimirse exactamente una vez. Puede imprimir las direcciones en cualquier orden.
Cada dirección puede imprimirse en su totalidad, con 8 grupos de 4 dígitos hexadecimales separados por dos puntos, p. Ej.
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Puede, a su discreción, usar cualquiera de las abreviaturas estándar de RFC 5952 :
- Los ceros a la izquierda en un grupo pueden omitirse, excepto que
0
no pueden abreviarse más. ::
se puede usar como máximo una vez por dirección para abreviar una secuencia de uno o más grupos todos cero.- Los dígitos hexadecimales pueden usar minúsculas o mayúsculas.
Si cumple con la recomendación de representación de RFC 5952 (solo letras minúsculas, la representación más corta posible, se ::
usa lo antes posible si hay varios lugares donde se puede usar), obtiene un bono de -20% .
Debido al tamaño de la salida, no se espera que su programa termine mientras estamos sentados allí. Su programa puede ser interrumpido por medios externos en algún momento ( Ctrl+ C, desconectando la alimentación, ...). Su programa debe producir resultados como una secuencia, de modo que después de una espera "razonable", haya producido algunas líneas. Básicamente, no está permitido construir una cadena gigante en la memoria solo para imprimirla al final. Cualquier programa que se quede sin memoria en una PC "estándar" queda descalificado. (No obstante, si su programa se dejó ejecutar durante el tiempo suficiente, debe imprimir todas las direcciones IPv6 y luego salir).
(Si esta condición es un problema para los intérpretes web que ejecutan el programa hasta su finalización y luego le permiten ver el resultado, y no tiene un intérprete alojado, pruebe su programa en una versión más pequeña del problema y luego ajústelo cuidadosamente al completo 2 128. )
Su puntaje es la longitud de su programa en bytes, multiplicado por 0.8 si obtiene el bono. Es el código de golf, por lo que gana el puntaje más bajo.
fuente
Respuestas:
Pyth, 21 bytes
Utiliza un bucle while con
J
la variable iterador. Inicializa el máximo usando8^chr(' ')
. Al agregar ese valor inicial, se convierte en hexadecimal y luego se elimina el primer carácter.fuente
Python 3, 65 bytes · 0.8 = 52.0
fuente
ipaddress
es solo python3.Pyth,
272524 bytesNota: el código tenía un error anteriormente, corrigiéndolo se guardó 1 byte
Imprime las direcciones como
Versión anterior (más complicada) que usa el operador de plataforma (también 24 bytes):
Explicación
Pyth, 21 bytes (no válido)
Esto no se puede ejecutar ya que 1) consumiría al menos 2 132 bytes (2 52 yobibytes) de memoria y 2) al intérprete no le gusta (2 128 no encaja
ssize_t
, por lo que no haylist
s de ese tamaño) . Imprimiría las direcciones en orden lexicográfico. Puede probar el algoritmo cambiando los números al final a algo utilizable.fuente
C (con extensiones GCC), 76 bytes * 0.8 = 60.8
Esto utiliza la extensión GCC de enteros de 128 bits para simplemente contar desde
::
hastaffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
.inet_ntop()
formatea correctamente cada dirección para que se pueda reclamar el bono de -20%.Salida
Utilizando la
sed
salida de cada línea millonésima hasta 10 millones:Tenga en cuenta que estoy usando una máquina little-endian x86_64, y que las direcciones de red generalmente siempre están en orden de red (big-endian), por lo que la endianidad se intercambia de manera efectiva mediante el uso
inet_ntop()
. Esto no importa: todas las direcciones se mostrarán (eventualmente).fuente
CJam,
3627 bytes-9 bytes gracias a @Dennis (olvidé que CJam tiene formato de cadena). Imprime las direcciones en minúsculas y descendentes.
Por razones obvias, use el intérprete de Java, no el en línea. Sin
G32#
embargo, puede reemplazarlo por algo más pequeño para probar en línea, por ejemplo, aquí están los últimos 100 .Explicación
fuente
0000:0000:0000:0000:0000:0000:ffff:ffff
. Parece que el formato de cadena podría funcionar de manera diferente en línea. Confirmé que funciona bien con la versión sin conexión.n
es lo mismo queoNo
en TIO .Python 2.7, 67 bytes
Como efecto secundario del método utilizado para insertar los dos puntos, las direcciones se imprimen con la columna más a la derecha que aparece a la izquierda:
fuente
[printing] the addresses in any order
. ;)Verilog, 335
Mi primera presentación de Verilog, probablemente podría usar más golf, pero no tengo la energía para hacerlo en este momento.
c
es reloj,o
es salida ASCII. No califica para el bono de formato debido a cero relleno en lugar de abreviar.Esta es una iteración simple seguida de un poco de giro de bits para hacer la salida ASCII. Corté el colon después del último grupo con un pequeño truco. Sintetiza y parece funcionar para xc3s500e-4ft256-4 en ISE 13.7 lin64.
fuente
C, 91-126 bytes
Mi versión original, 119 bytes.
La mejor versión de golf portátil-ish, 103 bytes (gracias @Dennis por algunos de estos conceptos)
Explicación: El algoritmo en sí es razonablemente sencillo. Utilicé int en lugar de unsigned porque es más corto. Declararlos a nivel de archivo significa que todo está preinicializado con ceros. La
f
función es un incremento simple con carry que opera en los 16 bits bajos de cada palabra. El bucle termina cuando se lleva al bit 129.Iterar hacia atrás para printf significa que imprimimos las direcciones en el orden "correcto" y también el cheque para imprimir una nueva línea tiene unos pocos caracteres más cortos.
Esto usa algunas construcciones no portátiles. Se considera mejor como un dialecto K&R de C, ya que utiliza tipos de retorno int implícitos y no incluye stdio.h. Y mi uso de long fue informado por esto: en la mayoría de los sistemas modernos int es suficiente porque son 32 bits. Esto probablemente podría ejecutarse sin modificaciones en PDP-11 Unix.
Sin embargo, puede ser más corto. Si suponemos que podemos usar int (ya sea como un tipo más ancho que 16 bits, o un tipo de exactamente 16 bits con varias propiedades que resultan ser ciertas en muchos sistemas, como dos complemento y rollover aritmético), podemos deshacernos de las cosas relacionadas con el uso de largo.
Versión para int más ancho que 16 bits, 97 bytes.
Versión para sistemas de 16 bits, 91 bytes.
Curiosamente, sin embargo, el original K. & R compilador no que realmente apoyan la declaración sin int (que compila bien, pero trata a las variables como externa y por lo tanto sin definir en tiempo de enlace), por lo que se necesitan otros tres bytes adicionales para cambiar la declaración
int*p,a[9];
de un total de 94.Además, si la suposición de que se interrumpe antes de completar la salida fuera una restricción difícil, podríamos eliminar la verificación final, ahorrando cinco bytes.
Bonificación: versión portátil totalmente ANSI, 126 bytes:
Las líneas nuevas en todas las versiones se insertan para facilitar la lectura y en ubicaciones donde no se requiere espacio en blanco, y se excluyen del recuento de bytes, a excepción de la línea nueva después de la
#include
línea en la versión ANSI.Todas las versiones, excepto la versión ANSI, caen al final de main y, por lo tanto, pueden devolver un código de salida falso al sistema operativo.
fuente
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--
comprobación del estado.a[0]
y envolvera[1]
AutoIt3,
142231 BytesExplicación
For $a=0 To 2^32-1
: Iterar 4 veces sobre 0-2 ^ 32 ((2 ^ 32) ^ 4 = 2 ^ 128) combinaciones posibles.$s=StringFormat("%08x%08x%08x%08x",$a,$b,$c,$d)
: Convierte los números en una cadena hexadecimal con una longitud de 32 (4 * 32).For $j=0 To 8
: Itera sobre las 8 secciones de la cadena.ConsoleWrite(StringMid($s,$j*4+1,4)&($j<7?":":""))
: Extraiga los siguientes 4 caracteres de la cadena y agregue dos puntos (:
) al final, si no hemos llegado a la última sección, luego envíe todo a la consolaNext
: Finaliza el bucle for internoConsoleWrite(@LF)
: Agregar un avance de línea al final de la líneaNext
: Fin de los bucles for externosTamaño de salida esperado: (Una línea (39 bytes) + avance de línea) (= 40 bytes) * 2 ^ 128 = 1.361 * 10 ^ 16 YB (yottabytes)
fuente
4^64 - 1
?Chicle de canela, 16 bytes
Pruébalo en línea. (TIO limita la salida)
Explicación
El
g
modo pone Cinnamon Gum en modo generar . El resto de la cadena se descomprime en esta expresión regular:Luego crea un generador de todas las cadenas posibles que coinciden con la expresión regular e itera a través de ella, imprimiendo cada una.
De forma algo divertida, la expresión regular de golf en
([0-9a-f]{4,4}:){7,7}[0-9a-f]{4,4}
realidad se comprime en una cadena más larga que la expresión regular anterior.fuente
Commodore BASIC 2.0, 339 bytes
Para obtener dígitos hexadecimales en minúsculas, este programa está escrito en "modo desplazado" (presione
<SHIFT>+<C=>
)Simplemente haciendo que esto funcione en el Commodore 64 fue un desafío, debido a la memoria, el tamaño de la pantalla, el tamaño de los datos y otras limitaciones. Pensé en implementar la representación abreviada, pero otras limitaciones (como la incapacidad no documentada para usar elementos de matriz como índices de bucle) significaban que aumentaría la longitud del programa en aproximadamente 1000 bytes.
Line 7 es una implementación de la
HEX$()
que falta Commodore BASIC 2.0. No puedo usar unDEF FN
para esto porque solo pueden devolver números, no cadenas. La línea 6 es una subrutina que la aplica a un grupo de cuatro dígitos, que habría sido considerablemente más corta si las funciones pudieran devolver cadenas.Las líneas 2 y 5 son ocho bucles anidados, implementados como siete bucles "for" y un goto condicional porque ocho bucles "for", cuando se combinan con los dos "gosubs" para imprimir la dirección, desbordarán la pequeña pila del C64.
Un C64 puede imprimir aproximadamente 1.2 direcciones por segundo, para un tiempo de ejecución estimado de 1.3 * 10 ^ 31 años.
fuente
PowerShell (v4),
193166162145103bytesLa versión sin bonificación de TimmyD a 103 bytes:
Versión anterior con bonificación en 145 * 0.8 = 116 bytes
Con la ayuda de TimmyD y Tomkandy , que señala eso
0 -eq $false
pero([bigint]0) -eq $true
. Entonces, todas mis versiones anteriores no terminarán.Anteriormente en 162, antes de algunos cambios de expresiones regulares:
"¡Un desafío donde PowerShell debería ser razonablemente competitivo!" - Yo, antes de intentarlo.
Explicación
fuente
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*:',''}
Sí, la primera dirección es incorrecta pero no se repite al final. También tengawhile($i)
en cuenta que en el suyo no se detendrá en cero -[boolean][bigint]0
evalúa como verdadero0:
: /)$i=[bigint]::Pow(4,64);while($i-gt0){('{0:X32}'-f($i-=1)-replace'0(?=.{32})'-replace'.{4}(?!$)','$0:')}
en 103 ...AutoIt3, 137 Bytes
fuente
4^64 - 1
?Python 2, 95 bytes
Simplemente pasa por cada número del 0 al 2 ^ 128. Primero convierte el número actual a una cadena hexadecimal, luego elimina el
'0x'
que le da esa función. A continuación, ajusta la cadena para que tenga 32 ceros en el frente y luego la divide en grupos de cuatro. Finalmente, une los grupos de cuatro con dos puntos, lo imprime y agrega 1 al número actual. Tiene la ventaja adicional de que puede iniciarlo en cualquier valor si le da uno, pero no se necesita ninguna entrada.fuente
Haskell 111
Con mi propia función de secuencia
s
ya no pierde memoria, pero ya no se siente golf.fuente
CBM BASIC v7.0 (166 caracteres)
La respuesta de Mark es para el BASIC 2.0 del Commodore 64, que carece de un comando incorporado para imprimir números en hexadecimal. Sin embargo, gracias a la
HEX$()
función en BASIC 7.0, la versión Commodore 128 es mucho más corta. No cabe en una sola línea lógica (que en el C128 está limitada a 160 caracteres) pero aún se puede ingresar como dos líneas separadas en modo directo.fuente
Rubí 75
Esta es una solución recursiva que toma cada prefijo y encuentra todos los sufijos posibles. Recursivamente.
fuente
x=->s,n{...};x['',8]
Tcl
341318301fuente