Desafio
Sua tarefa é codificar um número inteiro como uma sequência de caracteres ASCII e decodificá-la com êxito depois que a sequência for aleatoriamente embaralhada.
Você escreverá dois programas / funções , que serão chamados de codificador e decodificador .
Codificador
- Entrada: um número inteiro no intervalo .
- Saída: uma sequência de caracteres ASCII (não necessariamente imprimíveis).
Decodificador
- Entrada: uma permutação aleatória da string .
- Saída: o número inteiro .
Pontuação
Seja o comprimento máximo de em todos os valores possíveis de . Se o codificador agir de forma não determinística (o que é permitido, veja abaixo), então será o comprimento máximo de que pode ocorrer (possivelmente ).
Seja o comprimento do codificador em bytes e o comprimento do decodificador em bytes.
Então sua pontuação é .
A vitória é atribuída à finalização com a menor pontuação .
Prazo
Há um limite de tempo um tanto arbitrário de 1 minuto no tempo de execução do codificador e do decodificador para uma única caixa de teste (ou seja, um valor único de ).
O objetivo é evitar soluções que considerem a codificação forçada, enumerando todas as seqüências com determinadas propriedades. Se sua solução fizer algo mais inteligente que isso, provavelmente se ajustará à restrição de tempo e será considerada válida. Da mesma forma, se funcionar no TIO para alguns valores selecionados aleatoriamente de , será considerado válido. Caso contrário, testarei na minha máquina, mas observe que, se sua solução for pura força bruta, ela quase certamente falhará.
Regras
- O codificador e o decodificador devem ser escritos no mesmo idioma .
- O decodificador deve emitir o número inteiro correto para todas as permutações possíveis da string retornada pelo codificador .
- O codificador e o decodificador não têm permissão para compartilhar informações de nenhuma maneira (por exemplo, por meio de variáveis ou arquivos globais).
- A saída do codificador não precisa ser determinística (ou seja, a mesma entrada pode produzir cadeias de saída diferentes se o codificador for executado várias vezes), mas o decodificador sempre deve adivinhar o número inteiro correto .
- O codificador e o decodificador podem pegar e retornar o número inteiro de qualquer maneira conveniente (por exemplo, se é bom que a entrada seja
14
,"14"
ou[1,4]
). - O codificador pode saída a cadeia quer por imprimindo -o no
stdout
ou por devolver uma cadeia, uma lista / matriz de caracteres ou uma lista / matriz de inteiros no intervalo ; note que o decodificador receberá como entrada uma permutação de retornada pelo codificador , portanto, deve aceitar a string no mesmo formato que . - As brechas padrão são proibidas.
- Se possível, explique como seu código funciona e por que a pontuação reivindicada está correta.
Exemplo
Suponha que .
- O codificador recebe
14
como entrada. Pode sair"qwerty"
.- O decodificador recebe uma permutação de
"qwerty"
como entrada, por exemplo"tweyqr"
. Ele deve gerar14
(em qualquer formato conveniente).
O codificador também poderia ter retornado [113,119,101,114,116,121]
; nesse caso, o decodificador teria recebido (por exemplo) [116,119,101,121,113,114]
.
Observe que a string retornada pelo codificador também pode incluir caracteres ASCII não imprimíveis (mas sempre no intervalo [0x00, ..., 0x7F]
).
Respostas:
Gelatina , (17 bytes + 18 bytes) × comprimento 6 = 210 pontos
Experimente online! (ou com informações adicionais sobre depuração)
Depois de tentar resolver esse desafio, visando a condição de vitória declarada, pensei que seria interessante optar por uma hipótese alternativa de vitória: code-golf, com um comprimento máximo possível mínimo para a saída.
Explicação
Codificação
O primeiro passo na codificação é representar a entrada como base 36 (
b36
). 36 6 = 2176782336> 2147483647, portanto, haverá no máximo 6 dígitos no resultado, cada um no intervalo de 0 a 35.Em seguida, transformamos isso em uma representação que contém 6 dígitos diferentes . Existem vários algoritmos possíveis para isso, mas o usado aqui é adicionar 1 ao dígito menor, 2 ao segundo menor, 3 ao terceiro menor e assim por diante. Isso significa que, se dois dígitos forem iguais, um deles será arbitrariamente considerado menor e, portanto, eles se tornarão diferentes; e, obviamente, esse algoritmo não pode fazer com que dois dígitos diferentes se tornem iguais. Para representar isso no Jelly, usamos
Ụ
("classificar índices por valores") para obter uma lista dos índices em ordem classificada;Ụ
novamente para inverter isso, mapeando efetivamente cada elemento do original para sua posição em ordem classificada; eµ…+
acréscimo do original à nova lista. O resultado é uma representação do número de entrada como seis dígitos diferentes no intervalo de 1 a 41 (mínimo 0 + 1, máximo 35 + 6).Então, dividir esta em ainda uma outra forma: uma ordenada lista de dígitos no intervalo 1-41, juntamente com um número de 1 a 720 que representa qual das 720 permutas possíveis os dígitos foram em (O.
Œ¿
EṢ
extrair o número de permutações e classificados lista respectivamente.)Por fim, convertemos o número de 1 a 720 na base 3 (
b3
), invertemos (U
) e codificamos os seis dígitos da base 3 e seis dígitos de 1 a 41, compactando-os em um único caractere ASCII usando o divmod reverso (o valor de o caractere mod 3 é o dígito base 3, o valor dividido por 3 é o dígito 1–41). O intervalo possível de resultados é (1 × 3) + 0 = 3 no mínimo e (41 × 3) + 2 = 125 no máximo, dentro da nossa faixa ASCII. O empacotamento é feito via×3
e+
, junto com um adicional,µ
para garantir que cada comando opere no bit certo de dados. (Há um truque aqui no golfe, no qual fazemos a multiplicação por 3 antes de extrair a permutação; isso evita a necessidade de gastar um byte em um caractere de agrupamento.)Aliás, o motivo para reverter o número base 3 é porque ele pode ter menos dígitos que o número 1–41. (Ele não pode ter mais; o menor número para o qual n !> 3 n está um pouco acima de 6.) O Jelly efetivamente insere zeros à direita ao adicionar dois números de comprimentos diferentes, a fim de combiná-los; zeros à direita afetariam a interpretação do número, mas zeros à esquerda não, portanto, o inverso é usado para garantir que os zeros extras terminem em algum lugar que não atrapalhem nossa resposta.
Decodificação
O primeiro passo na decodificação é extrair os dois números (o número base 3 e o número 1–41). Podemos obter os dígitos com facilidade com divisão (
:3
) e módulo ( .) Portanto, ambas as extrações começam com , seguidas por ou conforme apropriado.%3
), respectivamente, mas como saber em que ordem eles estavam? Bem, o número 1-41 teve seus dígitos na ordem de classificação, e os dígitos nas posições correspondentes dos dois números foram armazenados nos mesmos caracteres; portanto, podemos descobrir em que ordem os dígitos do número 1-41 foram embaralhados (observando seus valores relativos) e sabemos que os dígitos do número base-3 devem ter sido embaralhados da mesma maneira. De fato, como os caracteres de nossa codificação ASCII são classificados da mesma maneira que os dígitos do número 1–41 (todos eram distintos e são mais significativos que os números base 3),Ṣ
Ṣ
%3
:3
Enquanto os dígitos do número de 1 a 41 ainda estão na ordem de classificação, temos uma maneira muito conveniente / concisa de voltar aos dígitos de 0 a 35 da base 36; basta subtrair 1 do primeiro, 2 do segundo, 3 do terceiro e assim por diante. No Jelly, podemos fazer isso com
_J
("subtrair índice").Enquanto isso, no outro ramo da decodificação, invertemos os dígitos do número da base 3 novamente na ordem (
U
) e convertemos da base 3 novamente em um índice de permutação comḅ3
.Podemos então combinar os dois ramos com
œ?Ç
;œ?
significa "permute dado esse índice de permutação" eÇ
significa "o resultado da aplicação da linha acima", ou seja, é o que diz ao Jelly para executar as duas linhas separadamente na mesma entrada.O que temos agora são os dígitos do número original, na base 36 (devido ao
_J
) e na ordem original (devido aoœ?
), para que possamos simplesmente fazer umḅ36
para converter de volta da base 36 em um único número inteiro.Comentário
O TIO! O link acima usa 312699167 como o número a ser codificado. Esse número na base 36 é
[5, 6, 6, 8, 7, 35]
e, portanto, mostra todos os aspectos da codificação: o 35 testa o limite do intervalo de 0 a 127 que temos; os 6s duplicados testam a resolução de dígitos idênticos na base original 36; e o fato de os dígitos serem quase (mas não completamente) classificados significa que o número de permutação é muito pequeno, fornecendo muito menos dígitos que o número base 36 e, portanto, mostrando a necessidade de revertê-lo antes de adicioná-lo ao original.É realmente conveniente como todas as constantes aqui se encaixam. 36 6 é apenas o suficiente para caber 2 31 , 3 6 é apenas o suficiente para caber 6! E (36 + 6) × 3 é apenas o suficiente para caber dentro das 128 possibilidades que temos. (A última restrição aqui é a menos rígida, porque poderíamos usar a indexação 0 em vez da indexação 1 para usar caracteres no intervalo 0-2. Ainda assim, isso daria espaço suficiente para usar 37 como base, em vez de 36.)
fonte
Gelatina , (
43 bytes +65 bytes) × comprimento 8 =8064 pontosExperimente online!
Gelatina , (
21 byte +43 bytes) × comprimento 10 =6040 pontosExperimente online!
Explicação
Solução 1
Isso está usando um algoritmo diferente da maioria das outras respostas. Começamos codificando o valor em hexadecimal (
b⁴
), como nas outras respostas, e obtemos uma soma cumulativa (Ä
). Cada entrada fornecerá claramente uma saída diferente (pois ambas as operações são reversíveis) e, como a codificação hexadecimal conterá no máximo 8 dígitos cujos máximos são 7 (para o oitavo último dígito) e 15 (para o último ao sétimo) últimos dígitos), o número máximo na lista de saída será 7+ (7 × 15) = 112, menor que o 127 exigido pela pergunta. Além disso, a saída será necessariamente na ordem de classificação, permitindo reverter o shuffle.Para o decodificador, primeiro invertemos o shuffle com um sort (
Ṣ
); depois inverta a soma acumulada, acrescentando um zero (Ż
) e calculando a diferença de pares consecutivos (I
); depois converta novamente de hexadecimal (ḅ⁴
).Solução 2
A questão realmente permite que tomemos a entrada como uma lista de dígitos (presumivelmente decimais), para que possamos "trapacear" simplesmente removendo a conversão básica; o número máximo usado na saída será 2 + (9 × 9) = 83 (na verdade, 82 porque 2999999999 está fora da faixa, portanto a pior entrada possível é 1999999999). A codificação resultante é bastante terrível para as codificações desse problema, mas tem a vantagem de ser muito concisa para gerar, o que supera a verbosidade da codificação.
Essa resposta parece uma trapaça que não é minha solução principal para esse problema, mas parece que vale a pena acrescentar, porque ela está tecnicamente em conformidade com as regras e produz uma pontuação melhor.
Comentário
Eu tenho alguns algoritmos em mente para ficar abaixo do comprimento 8, mas parece improvável que você possa implementar um algoritmo de comprimento 7 em ≤9 bytes (sem trapaça) ou ≤5 bytes (trapaça), portanto, pela pontuação na pergunta, isso é provavelmente a melhor maneira de fazê-lo. (Eu poderia tentar uma solução para o desafio alternativo "minimizar a duração da codificação" de qualquer maneira, apenas por diversão.)
Ao contrário de algumas das soluções, o uso de 16 como base aqui não é crítico; existem muitos outros números que funcionariam para uma solução de comprimento 8 (por exemplo, 18). Escolhi 16 para a primeira solução simplesmente porque o Jelly possui uma maneira de 1 byte para representar isso, e outras bases viáveis precisariam usar vários bytes do programa. Obviamente, a segunda solução precisa usar 10 como base para explorar a brecha.
Agradecemos ao @Dennis por apontar alguns comandos Jelly mais recentes que tornaram esse algoritmo ainda mais difícil de escrever.
fonte
Ä
é curto+\
,Ż
é curto0;
.Linguagem de programação de Shakespeare , 10 * (264 + 494) =
8650 79107580Codificador: 264 bytes
Experimente online!
Decodificador: 494
Experimente online!
Isso foi uma coisa.
O codificador codifica cada dígito como dígito mais o índice do dígito vezes doze. O decodificador armazena toda a entrada na memória do Ford e circula sobre um contador, produzindo e excluindo cada dígito abaixo do contador * 12 + 10.
Explicação:
Codificador
Decodificador
fonte
Python 2.7, 31 * (52 + 37) = 2759
Codificador (
6952 bytes):Decodificador (
4137 bytes):Armazena todos os bits diferentes de zero no número de entrada como valores ascii. O valor do caractere ascii armazena a posição do bit definido. Por exemplo, o valor 'a' significaria que o 97º bit está definido.
Algumas melhorias, graças a @ Delfad0r
Experimente online!
fonte
e =
ed =
o início - as funções anônimas estão perfeitamente bem. Além disso, observe que a declaração do problema diz claramente que o codificador pode retornar uma lista de números inteiros em vez de caracteres, para evitar a conversão número inteiro-> caractere-> número inteiro. Além disso, você pode usar emn&(1<<i)
vez den&(1<<i)>0
e salvar 2 bytes. Finalmente, o limite superior parai
(127) é muito alto , 32 é suficiente e economiza 1 byte.(52+37)*31=2759
porque a mais longa é quando todos os 31 bits estão definidos.lambda n:[chr(i)*(n&1<<i>0)for i in range(32)]
salvar 6 bytes.Stax , pontuação 8 × (10 + 9) = 152
Codificador, 10 bytes
Execute e depure
O codificador envia a string em uma ordem crescente.
Decodificador, 9 bytes
Execute e depure
fonte
05AB1E , 8 comprimento máximo * (8 + 7) bytes = 120
Codificador (8)
Experimente online!
Decodificador (7)
Experimente online!
Usa a mesma técnica que wastl e Jonathan .
fonte
Python 3 , 8 * (45 + 38) = 664
Codificador (45 bytes):
Decodificador (38 bytes):
Experimente online!
fonte
lambda l:sum(x%16<<x//16*4for x in l)
funciona muito bem :)lambda n:[n>>4*i&15|i<<4for i in range(8)]
e um no descodificador:lambda l:sum(x%16<<x//16*4for x in l)
para uma pontuação total de 632JavaScript (ES6), 8 * (40 + 32) = 576
Codificador (40 bytes)
Decodificador (32 bytes)
Demo
Experimente online!
Quão?
A entrada é dividida em 8 blocos de 4 bits e cada bloco é codificado com 1 entre 16 caracteres possíveis. O bit mais significativo do último bloco nunca é definido.
fonte
Gelatina , (8 + 9) bytes * 8 comprimento máximo = 136
Codificador (rodapé formata a lista como Python faria para maior clareza)
Decodificador
Teoricamente, é possível ter um comprimento máximo de seis, isso pode ser feito em 22 bytes ou menos?
É impossível com um comprimento máximo de cinco, pois∑i = 5i = 0( 127+i127) =321402081<231- 1
Quão?
Desde a231- 1 é codificável como 8 dígitos hexadecimais (
7fffffff
ou[7,15,15,15,15,15,15,15]
), podemos adicionar o índice baseado em zero de cada dígito hexadecimal multiplicado por 16 para garantir que essa conversão esteja sempre na ordem classificada, mantendo o valor mais à direita dentro dos limites (ou seja[7,15,15,15,15,15,15,15] + [0,16,32,48,64,80,96,112] = [7,31,47,63,79,95,111,127]
). A decodificação está revertendo esse mesmo processo.Codificador :
Decodificador :
fonte
Shakespeare Linguagem de programação , 31 * (472 +
383379344) =265052638125296Pontuação anterior: 16909322 * (246 + 217) = 7829016086
Ainda é muito alto, mas é o mais baixo em que posso pensar agora.
Codificador:
Experimente online!
Decodificador:
Experimente online!
Basicamente, se a sequência contiver um caractere com o código ASCII (n + 1), o enésimo dígito binário será definido.
fonte
Python 3, (208 bytes + 200 bytes) * 6 comprimento = 2448
Experimente online!(contém os dois, o byte extra é a nova linha entre eles).
-4 bytes (pontuação de -24) utilizando a lista vazia (que permitiu que mais coisas começassem em 0)
Codificador (208 bytes)
Decodificador (200 bytes)
Observações:
A reprodução aleatória pode ser revertida sem perdas para listas estritamente sem aumento (ou seja, classificadas).
Listas numéricas estritamente não crescentes do mesmo tamanho podem ser totalmente ordenadas (como estão no Python).
Podemos definir que as listas são ordenadas por comprimento primeiro para formar uma ordem total de todas as listas classificadas.
Podemos formar uma seqüência indexável dessas listas se definirmos que os valores válidos em uma lista são inteiros de
0
que127
inclusive (ou seja, não existe um número finito de listas válidas com comprimentoL
).Estratégia:
Codificador: dado um número
N
, encontre a listaN
válida estritamente não crescente.Decodificador: dada uma lista válida (aleatória), classifique-a e retorne seu índice na sequência de listas válidas.
Explicação de código comum:
T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
Calcule o
n
número th-d
simplexPara
d=0
sempre1
Para
d=1
,n
(o número de pontos em uma linha de pontos com comprimenton
)Para∑ni = 1Eu , (o número de pontos em um triângulo de pontos com comprimento lateral
d=2
,n
)Para∑nj = 1∑ji = 1Eu , (o número de pontos em um tetraedro de pontos com comprimento lateral
d=3
,n
)Explicação do codificador:
def E(n,h=128):
d=l=0
,s=[]
n
é o número de entrada,h
é o "valor alto" (ou seja, o número mais alto permitido + 1),d
é o comprimento que a saída será,s
é a saída,l
é o "valor baixo" (começando em 0, explicado mais adiante)while n>=T(h,d):
,n-=T(h,d)
,d+=1
Existem listas de
T(h,d)
comprimento válidasd
, e nosso cálculo é mais fácil sen
for um índice relativo à lista[0]*d
(no índice0
) em vez de um índice real; portanto, diminua den
acordo. Isso também ajustad
(o comprimento) para estar correto para o dadon
.for i in range(d):
Efetivamente: "para o
i+1
número th na lista"É aqui que eu vou explicar
l
, o "valor baixo"Depois que um número é colocado na lista, nenhum número menor que ele pode ser colocado na lista (para mantê-lo classificado), assim
l
como o último número que foi adicionado à lista.while n>=T(h-l,d+~i):
,n-=T(h-l,d+~i)
,i+=1
Se
n
for muito grande para ser codificado com uml
"dígito", ajuste-o den
acordo e aumentel
s+=[l]
Codifique
n
com uml
neste "dígito".Inicialmente, temos
h
opções para o "dígito" a ser inserido a seguir, mas uma vez que inserimos o "dígito" (ao qual é atribuídol
), estamos limitados àsh-l
opções para o próximo "dígito".No início, havia
T(h,d)
listas válidas, mas adicionamos um "dígito"l
, diminuindo o número de "dígitos" restantes parad-1
e o número de próximos "dígitos" válidos parah-l
, portanto, o número de listas válidas depois disso éT(h-l,d-1)
Explicação do decodificador:
def D(s):
,s.sort()
,l=0
,d=len(s)
s
é a lista de entrada (embaralhada), pors.sort()
isso;l
é o "valor baixo" (h
o "valor alto" é apenas literal128
s no código para salvar bytes),n
é o número de saída,d
é o comprimento.n=sum(T(128,D)for D in range(d))
Ajustar
n
para o ponto na sequência de[0]*length
for i in s:
Para cada dígito:
for j in range(l,i):
,n+=T(128-j,d-1)
Ajustar
n
para o ponto na sequência de[...prevdigits, thisdigit, 0...]
l=i
: Defina o "valor baixo" para o dígito mais recented-=1
: Diminua o comprimento desde que usamos um dígitoreturn n
: Depois den
ter sido ajustado para todos os dígitos, é o número certo; devolver.Desculpe se isso não está claro, mas aqui está a minha versão original de depuração sem lobo Experimente-a online! , que não usa a lista vazia, o mesmo ocorre com 1 de todos os números usados nesta versão
fonte
Ruby , (36 + 29 bytes) * 8, pontuação 520
Codificar:
Experimente online!
Decodificar:
Experimente online!
Como funciona:
O número é codificado usando blocos de 4 bits e um índice de 3 bits.
O decodificador pega a matriz de entrada e coloca cada petisco em seu lugar novamente.
fonte
Carvão , pontuação 10 * (10 + 15) = 250.
Usa decimal; a solução anterior baseada em 16 teve
328296264.Pode gerar caracteres não imprimíveis. Em particular, o personagem 10 é difícil de inserir no carvão.
Codificador, 10 bytes:
Experimente online!Link é a versão detalhada do código.
Decodificador, 15 bytes:
Experimente online! Link é a versão detalhada do código.
Versão usando uma lista de números inteiros
360296 (base 16; decimal teria 310):Codificador, 19 bytes:
Experimente online! Link é a versão detalhada do código.
Decodificador, 18 bytes:
Experimente online! Link é a versão detalhada do código.
A versão usando caracteres imprimíveis pontua 360 (era
416384368 na base 16):Codificador, 19 bytes:
Experimente online! Link é a versão detalhada do código.
Decodificador, 17 bytes:
Experimente online! Link é a versão detalhada do código.
fonte
Brachylog , 17 + 18 bytes * 8 comprimento = 280
Codificador:
Decodificador:
Um p pode ser adicionado ao final do codificador sem efeito. O decodificador é executado colocando o resultado (embaralhado) como saída e obtendo o número original na entrada.
Se houvesse um predicado cumulativo (implementado adequadamente), a pontuação poderia cair para 20
Experimente online!
fonte
05AB1E , pontuação: (2 + 2 bytes ) * 11 comprimento máximo = 44
Codificador (2 bytes ):
Experimente online.
Decodificador (2 bytes ):
Experimente online.
A entrada do codificador e a saída do decodificador são uma lista de dígitos.
Porto da resposta da 2ª geléia de @ ais523 .
Explicação:
Como231- 1 tem um comprimento de 10 dígitos, o comprimento máximo da saída é 11.
.¥
anexa um zero à saída, o comprimento da saída é o comprimento da entrada + 1. Comofonte
Gol> <> , 8 * (14 + 13) = 216
Codificador Experimente online! , 14 bytes:
Decodificador Experimente online! , 13 bytes:
Como isso pode gerar caracteres ascii imprimíveis, interferindo no decodificador, agora existe uma versão usando números na saída / entrada:
Codificador Experimente online! , 14 bytes:
Decodificador Experimente online! , 13 bytes:
Codificação:
A codificação funciona dividindo o número especificado em pedaços de 8 x 4 bits. Esses pedaços são deslocados para a direita em 3 bits e a localização original do pedaço é anexada no final como um número entre 0 e 7. Portanto, a codificação se parece com isso:
fonte
Perl 6 , 10 * (10 + 12) =
340220Codificador:
Decodificador:
Experimente online!
A função do codificador fecha cada dígito com o índice 0 do número. Em seguida, o codificador classifica a lista de números e obtém o módulo em 10, ou seja, o segundo dígito do número.
O total é 10, pois esse é o comprimento máximo de 2 31 -1.
fonte
Haskell , 10 * (23 + 51) = 740
Aqui está um programa que codifica, embaralha, decodifica e valida valores: Experimente online!
Codificador, 23 bytes
Experimente online!
Decodificador, 51 bytes
Experimente online!
Explicação
Como podemos usar a entrada como dígitos decimais, usaremos isso. O codificador mapeia cada dígito que ocorre
10*index + digit
, observe que todos osdigit
s estarão inseridos[0..9]
para que possamos reverter o acima usandodivMod
. Depois de restaurar os índices e os dígitos, é apenas uma questão de classificar pelos índices e se livrar deles.Espera-se que a solução funcione para valores de até231- 1 = 2147483647 que tem 10 dígitos, então o ponto de código máximo que obtemos será 9 ⋅ 9 = 81 < 128 . Além disso, cada dígito será convertido em um "caractere"; portanto, teremos um comprimento máximo de 10.
fonte
Casca , 10 * (7 + 8) = 150
Porta direta da minha solução Haskell apenas com a observação de que10 ⋅ 9 = 90 < 128 (O Husk's
N
é baseado em 1):Codificador, 7 bytes
Experimente online!
Decodificador, 8 bytes
Experimente online!
fonte
APL (Dyalog Unicode) ,euE+ LD= 36 ; A = 8 → 288 .
Experimente online!(contém 5 bytes extras para as atribuições e a nova linha).
Usos
⎕IO←0
Quão:
fonte
PHP, 8 * (44 + 53) = 776
codificador, 44 bytes:
imprime uma lista de números inteiros separados por espaço. Corra como cano com
-nR
.máximo de 8 bytes com 4 bits de dados (mordidela inferior) e 3 bits de peso (mordidela superior).
Simplificando:
Coloque cada dígito hexadecimal em um caractere próprio e use a metade superior do byte para armazenar a posição do dígito.
exemplo:
1457893891
(0x56e5b203
) Vai se transformar em0x03
,0x10
,0x22
,0x3b
,0x45
,0x5e
,0x66
,0x75
→
3 16 34 59 69 94 102 117
decodificador, 53 bytes:
ou
ou
pegue números inteiros dos argumentos da linha de comando. Corra com
-nr
.Experimente online .
fonte
Python 2 , 10 * (68 + 54) = 1220
Experimente online!
EDIT: Obrigado a Jo King pelas dicas - não sei por que eu estava compensando 32, em retrospecto.
Codifica a posição e o valor de cada local como um único caractere, começando com
[espaço] (posição 0, valor 0)o byte NUL 0x0.Decodifica por:
fonte
32
deslocamento? Além disso,[-1]
poderia estar em%10
vez disso, no lugar certoC (gcc) , 10 * 112 = 1120
Experimente online!
Eu tenho variáveis globais, mas na verdade elas não estão passando nenhuma informação entre duas funções. A declaração variável para
c
é usada nas duas funções, economizando 2 bytes de comprimento de código.Uma versão que usa ASCII imprimível apenas para uma penalidade de
35 bytes está aqui:Obrigado @ceilingcat por melhorias de 70 pontos.
fonte