Isso foi então, mas hoje em dia todo mundo mudou para o IPv6 . (Direito?)
Sua tarefa é escrever um programa que imprima todos os endereços IPv6 .
Você deve escrever um programa completo que não aceite entrada e imprima endereços IPv6, um por linha e nenhuma outra saída. Seu programa deve imprimir todos os 2 128 endereços possíveis, incluindo os inválidos. Cada endereço deve ser impresso exatamente uma vez. Você pode imprimir os endereços em qualquer ordem.
Cada endereço pode ser impresso na íntegra, com 8 grupos de 4 dígitos hexadecimais separados por dois pontos, por exemplo
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Você pode, a seu critério, usar qualquer uma das abreviações padrão da RFC 5952 :
- Os zeros à esquerda em um grupo podem ser omitidos, exceto que
0
não podem ser abreviados ainda mais. ::
pode ser usado no máximo uma vez por endereço para abreviar uma sequência de um ou mais grupos totalmente zero.- Os dígitos hexadecimais podem usar letras minúsculas ou maiúsculas.
Se você obtiver a recomendação de representação da RFC 5952 (apenas letras minúsculas, menor representação possível, e ::
usada o mais cedo possível, se houver vários locais onde ela possa ser usada), você receberá um bônus de -20% .
Devido ao tamanho da saída, não se espera que seu programa termine enquanto estivermos lá. Seu programa pode ser interrompido por meios externos em algum momento ( Ctrl+ C, desligando a energia,…). Seu programa deve produzir saída como um fluxo, para que, após uma espera "razoável", tenha produzido algumas linhas. Basicamente, não é permitido construir uma cadeia gigante na memória apenas para imprimi-la no final. Qualquer programa que fique sem memória em um PC "padrão" é desqualificado. (No entanto, se o seu programa foi deixado em execução por tempo suficiente, ele deve imprimir todos os endereços IPv6 e depois sair.)
(Se essa condição for um problema para intérpretes da web que executam o programa até a conclusão e permitem ver a saída e você não tem um intérprete hospedado, teste seu programa em uma versão menor do problema e ajuste-o com cuidado para o total de 2 128. )
Sua pontuação é o comprimento do seu programa em bytes, multiplicado por 0,8 se você receber o bônus. É código de golfe, então a pontuação mais baixa vence.
fonte
Respostas:
Pitão, 21 bytes
Usa um loop while com
J
a variável iteradora. Inicializa o máximo usando8^chr(' ')
. Almofadas adicionando esse valor inicial, convertendo em hexadecimal e removendo o primeiro caractere.fonte
Python 3, 65 bytes · 0,8 = 52,0
fonte
ipaddress
é apenas python3.Pitão,
272524 bytesNota: o código apresentava um erro anteriormente, corrigindo 1 byte salvo
Imprime os endereços como
Versão anterior (mais complicada) usando o operador pad (também 24 bytes):
Explicação
Pitão, 21 bytes (inválido)
Isso não pode ser executado, pois 1) consumiria pelo menos 2 132 bytes (2 52 yobibytes) de memória e 2) o intérprete não gostou (2 128 não se encaixa
ssize_t
, portanto, nenhumlist
desse tamanho) . Seria imprimir os endereços em ordem lexicográfica. Você pode experimentar o algoritmo alterando os números no final para algo utilizável.fonte
C (com extensões GCC), 76 bytes * 0,8 = 60,8
Este usa a extensão inteiros GCC 128 bits para contar simplesmente a partir
::
deffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
.inet_ntop()
formata corretamente cada endereço para que o bônus de -20% possa ser reivindicado.Resultado
Usando
sed
para produzir cada milionésimo linha até 10 milhões:Observe que estou usando uma máquina x86_64 little-endian e que os endereços de rede geralmente estão sempre em ordem de rede (big-endian); portanto, a endianidade é efetivamente trocada usando
inet_ntop()
. Isso não importa - todos os endereços ainda (eventualmente) serão exibidos.fonte
CJam,
3627 bytes-9 bytes graças a @Dennis (esqueci que o CJam tem formatação de string). Imprime os endereços em minúscula e decrescente.
Por razões óbvias, use o interpretador Java, não o online. Você pode substituir
G32#
por algo menor para testes on-line, por exemplo, aqui estão os últimos 100 .Explicação
fonte
0000:0000:0000:0000:0000:0000:ffff:ffff
. Parece que a formatação da string pode funcionar de maneira diferente online. Confirmei que funciona bem com a versão offline.n
é o mesmo queoNo
no TIO .Python 2.7, 67 bytes
Como efeito colateral do método usado para inserir os dois pontos, os endereços são impressos com a coluna mais à direita aparecendo à esquerda:
fonte
[printing] the addresses in any order
. ;)Verilog, 335
Minha primeira inscrição no Verilog, provavelmente poderia usar mais golfe, mas não tenho energia para fazê-lo agora.
c
é relógio,o
é saída ASCII. Não se qualifica para o bônus de formatação devido ao preenchimento de zero em vez de abreviação.Essa é uma iteração simples, seguida de alguns ajustes de bits para tornar a saída ASCII. Eu corto o cólon após o último grupo com um pequeno corte. Sintetiza e parece funcionar para xc3s500e-4ft256-4 no ISE 13.7 lin64.
fonte
C, 91-126 bytes
Minha versão original, 119 bytes.
Melhor versão portátil de golfe, 103 bytes (obrigado @Dennis por alguns desses conceitos)
Explicação: O próprio algoritmo é razoavelmente direto. Usei int longo, e não sem sinal, porque é mais curto. Declará-los no nível do arquivo significa que tudo é pré-inicializado com zeros. A
f
função é um incremento simples com carry que opera nos baixos 16 bits de cada palavra. O loop termina quando é carregado no 129º bit.Iterar para trás para o printf significa que imprimimos os endereços na ordem "adequada" e também a verificação para imprimir uma nova linha é alguns caracteres mais curta.
Isso usa algumas construções não portáteis. É melhor considerado como um dialeto K&R de C, pois usa tipos de retorno int implícitos e não inclui stdio.h. E meu uso de long foi informado por isso - na maioria dos sistemas modernos, int é suficiente porque é de 32 bits. Provavelmente isso pode ser executado sem modificação no PDP-11 Unix.
No entanto, pode ser mais curto. Se assumirmos que podemos usar int (seja como um tipo maior que 16 bits ou exatamente com 16 bits com várias propriedades que são verdadeiras em muitos sistemas, como complemento de dois e rolagem aritmética), podemos nos livrar de as coisas relacionadas ao uso longo.
Versão para int maior que 16 bits, 97 bytes.
Versão para sistemas de 16 bits, 91 bytes.
Curiosamente, no entanto, o compilador K&R original na verdade não suporta a declaração sem int (ele compila bem, mas trata as variáveis como externas e, portanto, indefinidas no tempo do link), portanto, são necessários três bytes adicionais para alterar a declaração
int*p,a[9];
para um total de 94.Além disso, se a suposição de que ela foi interrompida antes de concluir a saída fosse uma restrição rígida, poderíamos remover a verificação final, economizando cinco bytes.
Bônus: versão totalmente portátil ANSI, 126 bytes:
As novas linhas em todas as versões são inseridas para facilitar a leitura e em locais onde o espaço em branco não é necessário e são excluídas da contagem de bytes, exceto a nova linha após a
#include
linha na versão ANSI.Todas as versões, exceto a versão ANSI, caem no final do main e, portanto, podem retornar um código de saída falso ao sistema operacional.
fonte
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--
verificação da condição.a[0]
e envoltório ema[1]
AutoIt3,
142231 bytesExplicação
For $a=0 To 2^32-1
: Itere 4 vezes em 0-2 ^ 32 ((2 ^ 32) ^ 4 = 2 ^ 128) combinações possíveis.$s=StringFormat("%08x%08x%08x%08x",$a,$b,$c,$d)
: Converta os números em uma sequência hexadecimal com um comprimento de 32 (4 * 32).For $j=0 To 8
: Itere sobre todas as 8 seções da sequência.ConsoleWrite(StringMid($s,$j*4+1,4)&($j<7?":":""))
: Extraia os próximos 4 caracteres da string e adicione dois pontos (:
) no final, se ainda não atingimos a última seção, emita tudo no consoleNext
: Finalize o loop for internoConsoleWrite(@LF)
: Adicione um avanço de linha no final da linhaNext
: Finalize os for-loops externosTamanho de saída esperado: (Uma linha (39 bytes) + avanço de linha) (= 40 bytes) * 2 ^ 128 = 1,361 * 10 ^ 16 YB (yottabytes)
fonte
4^64 - 1
?Goma de canela, 16 bytes
Experimente online. (TIO limita a saída)
Explicação
O
g
modo coloca o Cinnamon Gum no modo de geração . O restante da cadeia de caracteres descompacta para este regex:Em seguida, ele cria um gerador de todas as seqüências possíveis que correspondem ao regex e iteram através dele, imprimindo cada uma.
Um pouco divertido, o regex golfier
([0-9a-f]{4,4}:){7,7}[0-9a-f]{4,4}
realmente comprime para uma seqüência mais longa do que o regex acima.fonte
Commodore BASIC 2.0, 339 bytes
Para obter dígitos hexadecimais em minúsculas, este programa é gravado no "modo deslocado" (pressione
<SHIFT>+<C=>
)Simplesmente fazer esse trabalho no Commodore 64 foi um desafio, devido à memória, tamanho da tela, tamanho dos dados e outras limitações. Eu considerei implementar a representação abreviada, mas outras limitações (como a incapacidade não documentada de usar elementos da matriz como índices de loop) significavam que aumentaria o comprimento do programa em cerca de 1000 bytes.
A linha 7 é uma implementação da
HEX$()
qual o Commodore BASIC 2.0 está ausente. Não posso usar umDEF FN
para isso, porque esses podem apenas retornar números, não seqüências de caracteres. A linha 6 é uma sub-rotina que a aplica a um grupo de quatro dígitos, que seria consideravelmente menor se as funções pudessem retornar cadeias.As linhas 2 e 5 são oito loops aninhados, implementados como sete loops "for" e um goto condicional porque oito loops "for", quando combinados com os dois "gosubs" para imprimir o endereço, irão sobrecarregar a pequena pilha do C64.
Um C64 pode imprimir cerca de 1,2 endereços por segundo, para um tempo de execução estimado de 1,3 * 10 ^ 31 anos.
fonte
PowerShell (v4),
193 166 162 145103 bytesVersão sem bônus do TimmyD em 103 bytes:
Versão anterior com bônus em 145 * 0.8 = 116 bytes
Com a ajuda de TimmyD e tomkandy , quem ressalta isso
0 -eq $false
mas([bigint]0) -eq $true
. Portanto, todas as minhas versões anteriores não serão encerradas.Anteriormente, aos 162, antes de algumas regex serem alteradas:
"Um desafio em que o PowerShell deve ser razoavelmente competitivo!" - eu, antes de tentar.
Explicação
fonte
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*:',''}
Sim, o primeiro endereço está errado, mas não é repetido no final. Observe também quewhile($i)
no seu não vai parar em zero -[boolean][bigint]0
avalia como verdadeira0:
: /)$i=[bigint]::Pow(4,64);while($i-gt0){('{0:X32}'-f($i-=1)-replace'0(?=.{32})'-replace'.{4}(?!$)','$0:')}
a 103 ...AutoIt3, 137 bytes
fonte
4^64 - 1
?Python 2, 95 bytes
Simplesmente passa por todos os números de 0 a 2 ^ 128. Primeiro, converte o número atual em sequência hexadecimal e retira o
'0x'
que essa função fornece. Em seguida, ajusta a string para ter 32 zeros na frente e depois a divide em grupos de quatro. Finalmente, junta os grupos de quatro com dois pontos, imprime isso e adiciona 1 ao número atual. Tem o bônus adicional de que você pode iniciá-lo com qualquer valor, se você der um, mas nenhuma entrada é necessária.fonte
Haskell 111
Com a minha própria função de sequência,
s
ela não perde mais a memória, mas não parece mais jogar golfe.fonte
CBM BASIC v7.0 (166 caracteres)
A resposta de Mark é para o BASIC 2.0 do Commodore 64, que não possui um comando interno para imprimir números em hexadecimal. No entanto, graças à
HEX$()
função no BASIC 7.0, a versão do Commodore 128 é muito mais curta. Ele não cabe em uma única linha lógica (que no C128 é limitada a 160 caracteres), mas ainda pode ser inserida como duas linhas separadas no modo direto.fonte
Ruby 75
Essa é uma solução recursiva que usa um prefixo para cada e encontra todos os sufixos possíveis. Recursivamente.
fonte
x=->s,n{...};x['',8]
Tcl
341318301fonte