A RFC 2550 é uma proposta satírica (publicada em 1 de abril de 1999) para uma representação ASCII com economia de espaço de data e hora que pode suportar qualquer data (mesmo aquelas anteriores ao início do universo e aquelas que ultrapassam o fim previsto do universo). O algoritmo para calcular um registro de data e hora compatível com RFC 2550 é o seguinte (nota: todos os intervalos incluem o início, mas excluem o final - 0 a 10.000 significa tudo em n
que 0 <= n < 10000
):
- Formato do ano
- Anos 0 a 10.000: um número decimal de 4 dígitos, preenchido à esquerda com zeros.
- Anos 10.000 a 100.000: um número decimal de 5 dígitos, prefixado com o caractere A.
- Anos 100.000 a 10 30 : o número decimal do ano, prefixado com a letra ASCII maiúscula cujo índice no alfabeto inglês é igual ao número de dígitos no ano decimal, menos 5 (B para anos de 6 dígitos, C para 7 -dígitos, etc.).
- Anos 10 30 a 10 56 : o mesmo formato que 10.000 a 10 30 , iniciando as letras com A e prefixando adicionalmente um sinal de intercalação (
^
) na sequência de caracteres (para que o ano 10 30 seja representado por^A1000000000000000000000000000000
e o ano 10 31 seja representado por^B10000000000000000000000000000000
). - Anos 10 56 a 10 732 : o ano é precedido por dois circunflexos e duas letras maiúsculas ASCII. As letras maiúsculas formam um número de base 26 representando o número de dígitos no ano, menos 57.
- Anos 10 732 em diante: o mesmo formato para 10 56 a 10 732 é usado, estendendo-o adicionando um sinal de intercalação adicional e uma letra maiúscula quando necessário.
- Anos aC (antes do ano 0): calcule a sequência do ano do valor absoluto do ano. Em seguida, substitua todas as letras pelo complemento da base 26 (A <-> Z, B <-> Y etc.), substitua todos os dígitos pelo complemento da base 10 (0 <-> 9, 1 <-> 8, etc.) e substitua os pontos de intercalação por pontos de exclamação (
!
). Se a sequência do ano tiver 4 dígitos ou menos (-1 a -10.000), adicione uma barra (/
). Se a sequência do ano não for prefixada por uma barra ou um ponto de exclamação, coloque um asterisco (*
).
- Meses, dias, horas, minutos e segundos : como esses valores têm apenas 2 dígitos no máximo, eles são simplesmente anexados à direita da string do ano, em ordem decrescente de significância, preenchidos à esquerda com zeros, se necessário, para formar Sequências de 2 dígitos.
- Precisão adicional : se for necessária precisão adicional (na forma de milissegundos, microssegundos, nanossegundos etc.), esses valores serão preenchidos à esquerda com zeros a 3 dígitos (porque cada valor é
1/1000
do valor anterior e, portanto, é no máximo999
) e anexado ao final do registro de data e hora, em ordem decrescente de significância.
Esse formato tem o benefício de a classificação lexical ser equivalente à classificação numérica do registro de data e hora correspondente - se o tempo A vier antes do tempo B, o registro de data e hora de A virá antes do registro de data e hora de B quando a classificação lexical for aplicada.
O desafio
Dada uma lista arbitrariamente longa de valores numéricos (correspondendo a valores de tempo em ordem decrescente de significância, por exemplo [year, month, day, hour, minute, second, millisecond]
), imprima o registro de data e hora do RFC 2550 correspondente.
Regras
- As soluções devem funcionar para qualquer entrada. As únicas limitações devem ser tempo e memória disponível.
- A entrada pode ser obtida em qualquer formato razoável e conveniente (como uma lista de números, uma lista de cadeias, uma cadeia delimitada por um único caractere que não seja um dígito, etc.).
- A entrada sempre conterá pelo menos um valor (o ano). Valores adicionais estão sempre em ordem decrescente de significância (por exemplo, a entrada nunca conterá um valor de dia sem um valor de mês ou um segundo valor seguido por um valor de mês).
- A entrada sempre será válida (por exemplo, não haverá registro de data e hora para 30 de fevereiro).
- São proibidos os componentes internos que calculam carimbos de data e hora do RFC 2550.
Exemplos
Esses exemplos usam a entrada como uma única sequência, com os valores individuais separados por pontos ( .
).
1000.12.31.13.45.16.8 -> 10001231134516008
12.1.5.1 -> 0012010501
45941 -> A45941
8675309.11.16 -> C86753091116
47883552573911529811831375872990.1.1.2.3.5.8.13 -> ^B478835525739115298118313758729900101020305008013
4052107100422150625478207675901330514555829957419806023121389455865117429470888094459661251.2.3.5.7.11 -> ^^BI40521071004221506254782076759013305145558299574198060231213894558651174294708880944596612510203050711
-696443266.1.3.6.10.15.21.28 -> *V3035567330103061015021028
-5342 -> /4657
-4458159579886412234725624633605648497202 -> !Q5541840420113587765274375366394351502797
Implementação de referência
#!/usr/bin/env python
import string
# thanks to Leaky Nun for help with this
def base26(n):
if n == 0:
return ''
digits = []
while n:
n -= 1
n, digit = divmod(n, 26)
digit += 1
if digit < 0:
n += 1
digit -= 26
digits.append(digit)
return ''.join(string.ascii_uppercase[x-1] for x in digits[::-1])
year, *vals = input().split('.')
res = ""
negative = False
if year[0] == '-':
negative = True
year = year[1:]
if len(year) < 5:
y = "{0:0>4}".format(year)
elif len(year) <= 30:
y = "{0}{1}".format(string.ascii_uppercase[len(year)-5], year)
else:
b26len = base26(len(year)-30)
y = "{0}{1}{2}".format('^'*len(b26len), b26len, year)
if negative:
y = y.translate(str.maketrans(string.ascii_uppercase+string.digits+'^', string.ascii_uppercase[::-1]+string.digits[::-1]+'!'))
if len(year) == 4:
y = '/' + y
if y[0] not in ['/', '!']:
y = '*' + y
res += y
for val in vals[:5]: #month, day, hour, minute, second
res += '{0:0>2}'.format(val)
for val in vals[5:]: #fractional seconds
res += '{0:0>3}'.format(val)
print(res)
-696443266.1.3.6.10.15.21.28
deveria ser*V3035567339896938984978971
?Respostas:
JavaScript (ES6), 325 bytes
Chocantemente longo.
fonte
Befunge,
418384 bytesÉ difícil dizer com antecedência o tamanho de um programa Befunge e, quando comecei a trabalhar nisso, pensei que poderia ter alguma chance de competir. Acontece que eu estava errado.
Experimente online!
fonte
Perl 5 ,
328322231301+ 1 (-a
) = 302 bytesExperimente online!
Ungolfed
fonte
Java 8,
653640637623 bytesInsira como
String
matriz e retorne comoString
.Acabou sendo bastante longo (como esperado), mas definitivamente pode ser jogado um pouco mais. Estou feliz que funcione depois de mexer nele por um bom tempo ..
Experimente aqui.
Explicação:
for(String p:s){
: Loop sobre as peçasif(p.charAt(0)<46){p=p.substring(1);f=1;}
: Determine se é negativo e, se for, remova o sinal de menos e defina um sinalizador para reduzir bytest=p.length();
: Obtenha a quantidade de dígitosif(i++<1){
: Se for o primeiro número (o ano):t<5?"000".substring(t-1)
: Se for de 0 a 100.000 (exclusivo): adicione zeros à esquerda, se necessáriot<32?(char)(t+60)
: Se for 100.000-10 30 (exclusivo): adicione uma letra inicialt<58?"^"+(char)(t+34)
: Se for 10 30 -10 732 (exclusivo): adicione uma letra literal"^"
+ à esquerdaif(t>57)for(r+="^^",u=675;u<t-57;u*=26)r+="^";
: Adicione a quantidade apropriada de letras iniciais literais"^"
+x="";for(String c:Long.toString(t-57,26).toUpperCase().split(""))x+=z.charAt((y+q).indexOf(c));r+=x;
: (conversão de base 26 em alfabeto)r+=p;
: Adicione o próprio ano ao resultado-Stringif(f>0){
: Se o ano foi negativo:x=t<5?"/":t<32?"*":r.replace("^","!").replaceAll("[^!]","");
: Crie uma String temporáriox
com o correto/
,*
ou um ou múltiplos!
for(char c c:r.toCharArray())x+=c>93?"":"ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210".charAt((z+y).indexOf(c));
: Faça a conversão (A↔Z, B↔Y, 0↔9, 1↔8 etc.)r=x;
: E defina o resultado para esta temperatura Stringx
else
: Se for o mês, dias, horas, minutos, segundos, milissegundos, microssegundos, nanossegundos ou menor:i>6?t<2?"00"+p:t<3?0+p:p
: Se for milissegundos ou menor: adicione zeros à esquerda, se necessário:t<2?0+p:p;
: Outro (mês, dias, horas, minutos, segundos): adicione zero inicial simples, se necessárioreturn r
: Retornar o resultadofonte
Input may be taken in any reasonable, convenient format (such as a list of numerics, a list of strings, a string delimited by a single non-digit character, etc.).
- você pode considerar a entrada como uma lista de números e pular a divisão e a conversão dispendiosas.long
com 64 bits sendo o maior) são muito pequenos em Java para algumas das entradas, portanto,String
são mais curtos quejava.math.BigInteger
. Eu mudei para umString
array, no entanto, não preciso dividir por pontos, o que salvou alguns bytes, então obrigado.Excel VBA,
500486485470 bytesFunção de janela imediata VBE anônima
A função de janela imediata VBE anônima, que recebe entrada como ano
[A1]
, mês[B1]
, dias[C1]
, horas[D1]
, minutos[E1]
, segundos[F1]
e uma matriz de precisão extra opcional[G1:Z1]
, calcula o carimbo de data / hora do RFC2550 e envia para a janela imediata do VBE. Faz uso da função auxiliar declarada abaixo.Função auxiliar
Função auxiliar declarada que pega um número de entrada e retorna esse número na base-26, de modo que
1->A
e26->Z
Deve ser colocado em um módulo público.
Uso
Deve ser utilizado em um módulo clara, ou o módulo deve ser limpo antes da execução como os vars
j
,o
ep
estão a ser assumida em seu padrão, o estado não inicializado no início da execução do código. Paraj
, que é umaVariant\Integer
variável, esse valor padrão é0
e parao
ep
, que sãoVariant\String
variáveis, esse valor padrão é a sequência vazia (""
).A entrada, uma matriz de cadeias, é retirada do
1:1
ActiveSheet e a saída é para a janela imediata do VBE.E / S de amostra
Sub
Versão de rotinaSub-rotina declarada que recebe entrada como ano
[A1]
, mês[B1]
, dias[C1]
, horas[D1]
, minutos[E1]
, segundos[F1]
e uma matriz de precisão extra opcional[G1:Z1]
, calcula o carimbo de data / hora do RFC2550 e é enviado para a janela imediata do VBE.Uso
A entrada no intervalo
[A1:ZZ1]
pode ser feita manualmente, digitando nas células, da esquerda para a direita, conforme necessário ou atribuindo a partir da janela imediata do VBE.Observe que, devido à conversão automática de números do Excel em notação científica, qualquer número que tenha um comprimento de base 10 igual ou superior a 12 dígitos deve ser inserido explicitamente na célula como texto, definindo a célula como uma célula de texto ou anexando o literal
'
ao início do valor da célulaE / S de amostra
Ungolfed And Explained
fonte
Geléia ,
165126 bytesExperimente online!
A linha 4 faz a formatação do ano com a ajuda das linhas 2 e 3. A primeira e a última linha lidam com zero preenchendo os elementos da entrada nos comprimentos adequados e concatenando-os com o ano formatado.
_µ‘l26Ċṗ@€ØAẎị@
encontra o prefixo 26 base. É necessário o poder cartesiano do alfabeto (ØA
) para cada número entre 1 e teto (log 26 (piso (log 10 (ano)) - n + 1)) (onde n é 30 ou 4) e, em seguida, obtém índices nessa lista com piso (log 10 (ano)) - n (ị@
).ç30;€”^UZF
formata anos> = 10 30 (®L>30¤?
)ç4⁶;
formata anos <10 30 . ( Editar : salvou um byte usando em⁶;
vez de;@⁶
)1RḊ
ḟ
fornece um prefixo vazio para anos <10 5 (®L>4¤?
). Ele pega a lista de dígitos e filtra todos os elementos em si. Basta usar isso para produzir,[]
porque⁸
não funciona aqui.Isso apenas avalia como[]
.⁸
e[]
não trabalhe aqui e não consegui encontrar outros 2 bytes que retornam uma lista vazia.;®AṾ€¤
acrescenta o ano ao prefixo e depois o nivela.L=4”/x
prefixa a/
se a duração do ano for 4 na declaração do®S<0¤¡
.2£FiЀ¹ị€2£UF¤
leva os complementos deA .. Z
,0 .. 9
e^ /*!
se o ano é negativo (®S<0¤¡
).2£
refere-se ao segundo link,ØD,“^ *!”,ØA
que é a lista[['0' .. '9'], ['^',' ','/','*','!'], ['A' .. 'Z']]
. Com um ano formatado como^C125...
esse link, o índice de cada caractere na versão achatada2£
usa esses índices para construir uma nova sequência a partir da versão achatada de2£
onde cada sublist é revertida, ou seja['9' .. '0','!','*','/',' ','^','Z' .. 'A']
, produzindo!X874...
./
mapeia para si mesmo porque é prefixado antes que tudo seja executado.Acabei incluindo isso na declaração do (anteriorL=4a®S<0x@”/;
adiciona um/
ao início de anos negativos em[-9999 .. -0001]
. Meu palpite é que isso pode ser reduzido.¡
) e salvei 7 bytes, porque não precisava testar os anos negativos duas vezes.Existem muitos usosEu comecei¡
na linha 4 e acho que eles podem ser compactados usando,?
mas não sei como fazê-los funcionar.?
a trabalhar e salvei alguns bytes.James Holderness apontou que minha primeira submissão não lidou com anos com 30 dígitos corretos. Aconteceu que o bug era para qualquer ano que precisasse de um
Z
prefixo 26 na base. Acontece que eu não poderia usar,ṃ
porque quando você converte 26 em base 26, ele fornece em[1,0]
vez de26
(duh). Em vez disso, usei pares encomendados com reposição. Eu não acho que exista um átomo para isso, mas se houver, posso salvar alguns bytes. Corrigir isso acabou me custando ~ 40 bytes. Definitivamente, meu programa de geléia mais longo ainda. Edit : Encontrou uma maneira mais curta de fazer o produto cartesiano. Percebi que não tinha certeza de que o último funcionava para prefixos com mais de duas letras, mas a nova maneira funciona.Desculpe pelas muitas vezes que editei este post, continuo descobrindo maneiras de reduzi-lo.
fonte