Isso é inspirado na resposta 05AB1E da Magic Octupus Urn .
Dados dois argumentos, um número inteiro positivo e uma sequência / lista de caracteres:
- Traduza o número para base-n, onde n é o comprimento da string.
- Para cada caractere, substitua todas as aparências do índice desse caractere no número base-n por esse caractere.
- Imprima ou retorne a nova sequência.
Exemplos:
Input:
2740, ["|","_"]
2740 -> 101010110100 in base 2
-> Replace 0s with "|" and 1s with "_"
Output: _|_|_|__|_||
Input:
698911, ["c","h","a","o"]
698911 -> 2222220133 in base 4
-> Replace 0s with "c", 1s with "h", 2s with "a", and 3s with "o"
Output -> "aaaaaachoo"
Input:
1928149325670647244912100789213626616560861130859431492905908574660758972167966, [" ","\n","|","_","-"]
Output:
__ __
| |_| |
___| |___
- - - -
- - - - - - -
- - - - - - - -
_______________
Input: 3446503265645381015412, [':', '\n', '.', '_', '=', ' ', ')', '(', ',']
Output:
_===_
(.,.)
( : )
( : )
Regras:
- IO é flexível .
- Você pode pegar o número em qualquer base, desde que seja consistente entre as entradas
- A lista de caracteres precisa ser indexada em 0, onde 0 é o primeiro caractere e n-1 é o último
- Os caracteres possíveis podem ser qualquer ASCII imprimível, além de espaços em branco, como guias e novas linhas
- A lista de caracteres fornecida terá um comprimento no intervalo,
2-10
inclusive. Ou seja, a menor base é binária e a maior é decimal ( sem letras traquinas aqui ) - As brechas padrão são proibidas
- Sinta-se à vontade para responder, mesmo que seu idioma não possa lidar com casos de teste maiores.
Como esse é o código-golfe , o código mais curto para cada idioma vence. ( Eu sei que todos os idiomas de golfe têm um byte embutido ;)
code-golf
ascii-art
base-conversion
Brincadeira
fonte
fonte
Respostas:
05AB1E ,
76 bytesComo foi inspirada por uma resposta 05AB1E, uma resposta dada em 05AB1E parece adequada. :)
-1 byte, graças ao @Enigma , removendo o foreach e fazendo isso implicitamente.
Experimente online ou verifique todos os casos de teste .
Explicação:
fonte
gв¹sèJ
para salvar um byte.¹sè
mim agora .. (eu sabia que mudando o?
a umJ
daria o mesmo resultado neste caso.)Java 8,
7250 bytes-22 bytes graças a @ OlivierGrégoire retornando um em
IntStream
vez de imprimir diretamente.Experimente online .
Explicação:
fonte
a->n->n.toString(a.length).chars().map(c->a[c-48])
(50 bytes), já que "o IO é flexível"String f(char[]a,int n){return n>0?f(a,n/a.length)+a[n%a.length]:"";}
(69 bytes) um recursivo, por diversão.Python 3 , 49 bytes
Ainda não posso comentar, então eu posto a resposta do Python 2 adaptada ao Python 3.5.
fonte
Japonês, 2 bytes
Pode receber a segunda entrada como uma matriz ou uma string. Falha nos dois últimos casos de teste, pois os números excedem o número máximo máximo de JavaScript. Substitua
s
porì
para gerar uma matriz de caracteres.Tente
fonte
Haskell ,
4039 bytesExperimente online!
Como o
Int
tipo de Haskell é limitado9223372036854775807
, isso falha em números maiores.-1 byte graças a Laikoni .
Ungolfed
Experimente online!
fonte
cycle
vez demod
!div n(length l)
salva um byte.MATL , 2 bytes
Experimente online!
As entradas são um número e uma sequência.
Falha no número excedente
2^53
, devido à precisão do ponto flutuante.Explicação
O que você
YA
sabe, um builtin (conversão básica com símbolos de destino especificados).fonte
JavaScript (ES6), 48 bytes
Toma entrada em currying sintaxe
(c)(n)
, onde c é uma lista de caracteres e n é um número inteiro.Seguro apenas para n <2 53 .
Experimente online!
JavaScript (ES6), 99 bytes
Com suporte para números inteiros grandes
Recebe entrada na sintaxe de curry
(c)(a)
, em que c é uma lista de caracteres e a é uma lista de dígitos decimais (como números inteiros).Experimente online!
fonte
código de máquina x86 de 32 bits (números inteiros de 32 bits): 17 bytes.
(veja também outras versões abaixo, incluindo 16 bytes para 32 bits ou 64 bits, com uma convenção de chamada DF = 1.)
Chamador passa args em registos, incluindo um ponteiro para o final de um buffer de saída (como minha resposta C ; vê-lo para a justificação e explicação do algoritmo.) Da glibc interna
_itoa
faz isso , então não é apenas inventado para o código-golfe. Os registros de passagem de arg estão próximos do x86-64 System V, exceto que temos um arg no EAX, em vez do EDX.No retorno, o EDI aponta para o primeiro byte de uma cadeia C terminada em 0 no buffer de saída. O registro de valor-retorno usual é EAX / RAX, mas na linguagem assembly você pode usar qualquer convenção de chamada que seja conveniente para uma função. (
xchg eax,edi
no final adicionaria 1 byte).O chamador pode calcular um comprimento explícito, se desejar, de
buffer_end - edi
. Mas acho que não podemos justificar a omissão do terminador, a menos que a função realmente retorne ponteiros de início + fim ou comprimento de ponteiro. Isso economizaria 3 bytes nesta versão, mas não acho que seja justificável.idiv
. Os outros argumentos não são operandos implícitos.)dec edi
, portanto deve estar com pouco 4GiB)nasm -felf32 ascii-compress-base.asm -l /dev/stdout | cut -b -30,$((30+10))-
(Editado manualmente para reduzir os comentários, a numeração das linhas é estranha.)É surpreendente que a versão mais simples, basicamente sem trocas de velocidade / tamanho, seja a menor, mas
std
/cld
custa 2 bytes para usarstosb
em ordem decrescente e ainda seguir a convenção de chamada DF = 0 comum. (E o STOS diminui após o armazenamento, deixando o ponteiro apontando um byte muito baixo na saída do loop, nos custando bytes extras para contornar.)Versões:
Eu criei 4 truques de implementação significativamente diferentes (usando
mov
carga / armazenamento simples (acima), usandolea
/movsb
(puro, mas não ideal), usandoxchg
/xlatb
/stosb
/xchg
, e um que entra no loop com um hack de instrução sobreposta. Veja o código abaixo) . O último precisa de uma trilha0
na tabela de pesquisa para copiar como o terminador da cadeia de saída, então estou contando isso como +1 byte. Dependendo de 32/64 bits (1 byteinc
ou não), e se podemos assumir que o chamador define DF = 1 (stosb
descendente) ou o que for, versões diferentes são (ligadas a) mais curtas.DF = 1 para armazenar em ordem decrescente torna uma vitória para xchg / stosb / xchg, mas o chamador geralmente não deseja isso; Parece transferir o trabalho para o chamador de uma maneira difícil de justificar. (Diferentemente dos registros arg-pass e de valor-retorno personalizados, que normalmente não custam a um chamador asm nenhum trabalho extra.) Mas no código de 64 bits,
cld
/scasb
funciona comoinc rdi
, evitando truncar o ponteiro de saída para 32 bits, então às vezes inconveniente preservar DF = 1 em funções de limpeza de 64 bits. . (Ponteiros para dados / código estático são 32 bits em executáveis não PIE x86-64 no Linux e sempre na ABI do Linux x32, portanto, em alguns casos, uma versão x86-64 usando ponteiros de 32 bits é utilizável.) De qualquer forma, essa interação torna interessante observar diferentes combinações de requisitos.nostring
) .stosb_edx_arg
ouskew
) ; ou com DF de entrada = não cuidar, deixando-o definido: 16 + 1Bstosb_decode_overlap
ou 17Bstosb_edx_arg
stosb_decode_overlap
) , 18B (stosb_edx_arg
ouskew
)x86-64 com ponteiros de 64 bits, outro tratamento de DF: 16B (DF = 1
skew
) , 17B (nostring
com DF = 1, usando emscasb
vez dedec
). 18B (stosb_edx_arg
preservando DF = 1 com 3 bytesinc rdi
).Ou se permitirmos retornar um ponteiro para 1 byte antes da string, 15B (
stosb_edx_arg
sem oinc
no final). Tudo pronto para chamar novamente e expandir outra string no buffer com base / tabela diferente ... Mas isso faria mais sentido se não armazenássemos uma terminação0
também, e você pode colocar o corpo da função dentro de um loop, então isso é realmente um problema separado.x86-64 com ponteiro de saída de 32 bits, DF = 0 convenção de chamada: nenhuma melhoria em relação ao ponteiro de saída de 64 bits, mas 18B (
nostring
) está vinculado agora.skew
). Ou para definir DF = 1 e deixá-lo, 17B paraskew
comstd
mas nãocld
. Ou 17 + 1B parastosb_decode_overlap
cominc edi
no final em vez decld
/scasb
.Com uma convenção de chamada DF = 1: 16 bytes (IA32 ou x86-64)
Requer DF = 1 na entrada, deixa-o definido. Quase plausível , pelo menos por função. Faz o mesmo que a versão acima, mas com o xchg para obter o restante da entrada / saída do AL antes / depois do XLATB (pesquisa de tabela com R / EBX como base) e STOSB (
*output-- = al
).Com um DF = 0 normal na convenção de entrada / saída, a versão
std
/cld
/scasb
é de 18 bytes para códigos de 32 e 64 bits e é limpa de 64 bits (funciona com um ponteiro de saída de 64 bits).Observe que os argumentos de entrada estão em registradores diferentes, incluindo o RBX para a tabela (para
xlatb
). Observe também que esse loop começa armazenando AL e termina com o último caractere ainda não armazenado (portanto,mov
no final). Portanto, o loop é "inclinado" em relação aos outros, daí o nome.Uma versão semelhante não distorcida ultrapassa o EDI / RDI e depois o corrige.
Eu tentei uma versão alternativa disso com
lea esi, [rbx+rdx]
/movsb
como o corpo do loop interno. (O RSI é redefinido a cada iteração, mas o RDI diminui). Mas ele não pode usar xor-zero / stos para o terminador, por isso é 1 byte maior. (E não está limpo de 64 bits para a tabela de pesquisa sem um prefixo REX no LEA.)LUT com comprimento explícito e um terminador 0: 16 + 1 bytes (32 bits)
Esta versão define DF = 1 e deixa assim. Estou contando o byte extra de LUT necessário como parte da contagem total de bytes.
O truque legal aqui é ter os mesmos bytes decodificar de duas maneiras diferentes . Caímos no meio do loop com o restante = base e quociente = número de entrada e copiamos o terminador 0 no lugar.
Na primeira vez através da função, os 3 primeiros bytes do loop são consumidos como os bytes altos de um disp32 para um LEA. Esse LEA copia a base (módulo) para o EDX,
idiv
produz o restante para iterações posteriores.O segundo byte de
idiv ebp
éFD
, que é o código de operação para astd
instrução que esta função precisa para funcionar. (Esta foi uma descoberta de sorte. Eu já estava examinando issodiv
anteriormente, o que se distingue doidiv
uso dos/r
bits no ModRM. O segundo byte dediv epb
decodifica comocmc
, o que é inofensivo, mas não é útil. Mas comidiv ebp
podemos remover ostd
de cima da função.)Observe que os registros de entrada são diferentes novamente: EBP para a base.
Esse truque de decodificação sobreposto também pode ser usado com
cmp eax, imm32
: são necessários apenas 1 byte para avançar efetivamente 4 bytes, apenas sinalizadores de oscilação. (Isso é terrível para o desempenho em CPUs que marcam os limites de instruções no cache L1i, BTW.)Mas aqui, estamos usando 3 bytes para copiar um registro e pular para o loop. Isso normalmente levaria 2 + 2 (mov + jmp) e nos permitiria entrar no loop imediatamente antes do STOS em vez de antes do XLATB. Mas então precisaríamos de uma DST separada, e não seria muito interessante.
Experimente online! (com um
_start
chamador que usasys_write
no resultado)É melhor para a depuração executá-lo
strace
ou fazer o hexdump da saída, para que você possa verificar se há um\0
terminador no lugar certo e assim por diante. Mas você pode ver isso realmente funcionar e produzirAAAAAACHOO
para uma entrada de(Na verdade
xxAAAAAACHOO\0x\0\0...
, porque estamos despejando de 2 bytes anteriores no buffer para um comprimento fixo. Assim, podemos ver que a função gravou os bytes que deveria e não pisou em nenhum bytes que não deveria ter. O ponteiro de início passado para a função era o segundo e últimox
caractere, seguido por zeros.)fonte
Gelatina , 4 bytes
Experimente online!
ṃ
é literalmente um built-in para isso. Os outros três bytes são responsáveis pela indexação baseada em um de Jelly.fonte
ṃ
" Descompressão de base incorporada; converte x em comprimento base (y) e depois indexa em y "? É nos casos muito excepcionais em que a base para a qual você deseja converter e o comprimento de uma string / número inteiro / lista são iguais? Quando procuro, só consigo encontrar três respostas: 1 ; 2 ; 3 . Meio que um estranho embutido em todos os dias desafios de código-golfe. : S“sspspdspdspfdspfdsp”
, mas“çƥ÷£ḟ’ṃ“spdf”¤
você salva seis bytes. É especialmente útil com os números de base 250 da geléiaPython 2 ,
4948 bytes-1 byte graças a Jo King
Experimente online!
Versão alternativa (não será finalizada para números grandes),
4543 bytes-2 bytes graças a Jo King
Experimente online!
fonte
Carvão ,
31 bytesExperimente online! Link é a versão detalhada do código. Editar: salvou 2 bytes graças a @ ASCII-only. Versão anterior antes da adição do builtin, 8 bytes:
Experimente online! Link é a versão detalhada do código. Explicação:
fonte
θη
? Parece um pouco confuso tbh. Por que não apenas removê-lo completamente e sair⍘
?D , 112 bytes
Experimente online!
Esta é uma porta da resposta C ++ de HatsuPointerKun
O estilo de chamada é
u(ulong(n), to!(char[])(b))
, onden
eb
são os argumentos esquerdo e direitoD coisas específicas
Infelizmente, precisamos importar
std.conv
para fazer conversões de tipo acima da conversão de tipo muito básica.Usando o sistema de templates golfy, e dando a função dos tipos necessários (que é porque chamá-lo não é apenas
u(n,b)
), podemos reduzir as ocorrências dechar[]
eulong
para1
byte cada, quando dentro de f a função.D inicializa nossos tipos para nós, então
C t;
é a abreviação deC t=cast(char[])([])
to!C
converte o número inteiron%l
em uma matriz de caracteres (usando pontos de código) e~
é concatenaçãoforeach(ref c;t)
é como ofor(... : ...)
loop do C ++ , mas um pouco mais.ref
é como&
, tratac
como copiado por referência (ou seja, podemos modificart
). Felizmente, D deduz o tipoc
sem qualquer tipo de palavra-chave.fonte
C ++,
150144 bytes,uint64
entrada-6 bytes graças a Zacharý
Usar uma variável para armazenar o tamanho aumentaria o número de bytes em 1
Para chamar a função:
Primeiro o número, o segundo é a string (array de caracteres)
Casos de teste :
fonte
#include
, pode mudar;;
para apenas;
e'0'
pode apenas ser #48
for
loop:for(;n;n/=b.size())t=std::to_string(n%b.size())+t;
b.size()
não muda nesse loop.Galho, 66 bytes
Criou um
macro
que deve serimport
editado em um modelo.Valores esperados:
Para os primeiros argumentos (
n
):Para o segundo argumento (
c
):Como usar:
.twig
arquivo{% import 'file.twig' as uncompress %}
uncompress.d()
Sem Golfe (não funcional):
Você pode testar este código em: https://twigfiddle.com/54a0i9
fonte
Pitão,
987 bytesSalvou um byte graças a hakr14 e outro graças ao Sr. Xcoder.
Experimente aqui
Explicação
fonte
m@Qd
por@LQ
vz
porE
.C89, intervalo limitado assinado
int n
,6453 byteschar **out
e modifique-o, em vez de pegar e retornar umchar *
Pega o número como uma
int
, a tabela de pesquisa como uma matriz + comprimento.A saída é gravada em a
char *outbuf
. O chamador passa (por referência) um ponteiro para o final do buffer. A função modifica esse ponteiro para apontar para o primeiro byte da string no retorno.Este é C89 válido e funciona corretamente mesmo com a otimização ativada. isto é, não depende do
-O0
comportamento do gcc ao cair no final de uma função não nula ou ter qualquer outro UB.Passar um ponteiro para o final de um buffer é normal para uma função int-> string otimizada, como a interna da glibc
_itoa
. Veja esta resposta para obter uma explicação detalhada de dividir um número inteiro em dígitos com um loop div / mod como estamos fazendo aqui, em C, bem como em x86-64 asm. Se a base é uma potência de 2, você pode alternar / mascarar para extrair os dígitos MSD primeiro, mas, caso contrário, a única boa opção é o primeiro com o menor número de dígitos (com módulo).Experimente online! . Versão não destruída:
Nesta versão de tamanho explícito, a entrada é uma
char table[]
que não precisa de um byte final de 0, porque nunca a tratamos como uma string. Poderia ser umint table[]
para todos os que nos importamos. C não possui contêineres que possuem seu próprio comprimento; portanto, ponteiro + comprimento é a maneira normal de passar uma matriz com um tamanho. Então escolhemos isso em vez de precisarstrlen
.O tamanho máximo do buffer é aproximadamente
sizeof(int)*CHAR_BIT + 1
, portanto é pequeno e constante em tempo de compilação. (Usamos esse espaço com base = 2 e todos os bits configurados como 1.) por exemplo, 33 bytes para números inteiros de 32 bits, incluindo o0
terminador.C89, assinado
int
, tabela como uma cadeia C de comprimento implícito, 65 bytesÉ a mesma coisa, mas a entrada é uma cadeia de comprimento implícito, portanto, precisamos encontrar o comprimento por nós mesmos.
fonte
Bash + utilitários principais , 49 bytes
Experimente online!
Comentários / explicação
Isso leva os argumentos da linha de comando como entrada (o número na base 10 e, em seguida, uma única sequência com a lista de caracteres) e gera para stdout. Caracteres especiais como espaço, nova linha, etc., podem ser inseridos em notação octal (por exemplo,
\040
para um espaço), ou\n
por uma mudança de linha,\t
para a guia, ou qualquer outra sequência de escape queecho -e
etr
interpretar de forma idêntica.Muitos dos bytes aqui são para lidar com caracteres especiais e casos de teste maiores. Se eu tiver que lidar apenas com caracteres não terríveis e os números forem pequenos (por exemplo, o primeiro caso de teste), os seguintes 24 bytes o farão:
Isso usa a expansão de parâmetro
${#2}
para obter o número de caracteres na sequência, cria um programa dc para fazer a conversão base e envia o número convertidotr
.Porém, isso não manipula novas linhas, espaços ou tabulações; portanto, para lidar com seqüências de escape sem afetar a base, eu faço uma contagem de caracteres
wc -c
depois de interpretar os escapesecho -en
. Isso expande o programa para 38 bytes:Infelizmente, o dc tem um "recurso" irritante onde, se estiver produzindo um número grande, o alinhará com uma sequência de barra + nova linha, para que os casos de teste maiores tenham essa saída extra. Para removê-lo, canalizo a saída de dc
tr -dc 0-9
para remover caracteres não numéricos. E aí estamos nós.fonte
dc -e${#2}o$1p|tr 0-9 "$2"
pegar a entrada literalmente em vez da forma \ escaped para que ele possa manipular espaços, mastr
não tem uma opção para não tratar-
como um caractere de intervalo, por exemplo. Se a entrada-
não tiver uma extremidade da sequência, ela será quebrada. Talvez você possa usarsed "y/0123456789/$2/"
. Não, acho que não, o GNUsed
exige que os dois argumentosy
tenham o mesmo tamanho, e parece engasgar com a nova linha.APL (Dyalog Unicode) ,
14 1312 bytesExperimente online!
Infix função tácita; não pode lidar com o maior caso de teste devido à representação de ponto flutuante.
Guardado
12 bytes graças a @ Adám!13 bytes adicionados para os cabeçalhos:(Esqueci que isso não se aplica. )⎕IO←0
: Eu NDEX O Rigin = 0 e⎕FR←1287
: F loat R ePresentation = 128 bits.Quão?
fonte
Anexo , 17 bytes
Experimente online!
Explicação
fonte
Tela , 7 bytes
Experimente aqui!
Implementação direta:
O conjunto de caracteres de entrada pode ser uma sequência de caracteres desde que não contenha uma nova linha, porque o Canvas não possui um caractere de nova linha e o converte automaticamente em um objeto 2D.
fonte
Stax ,
65 bytesExecute e depure
Explicação:
fonte
SOGL V0.12 , 10 bytes
Experimente aqui!
Por muito tempo, considerando que a idéia é praticamente implementada no idioma: aqui , entrando
distribui uma string compactada usando esse método.
fonte
Ruby , 31 bytes
Experimente online!
fonte
Stax , 2 bytes
Execute e depure
:B
é uma instrução em stax que faz isso. Normalmente, ele operaria em uma "string" * em vez de uma matriz de "strings". No final, isso significa que a saída é uma matriz de matrizes de caracteres únicos. Mas a saída achatada implicitamente de qualquer maneira.* Stax não tem realmente um tipo de string. O texto é representado por matrizes inteiras de pontos de código.
fonte
J , 12 bytes
Quão?
Experimente online!
fonte
Wolfram Language (Mathematica) , 49 bytes
Experimente online!
fonte
C (gcc) , 110 bytes
Experimente online!
Descrição:
fonte
sprintf
. Minha versão C é de 53 bytes , com o buffer de saída fornecido pelo chamador. Você pode fazer umstrcpy
no final se quiser copiar os bytes para o início de um buffer.CJam , 11 bytes
Experimente online!Recebe entrada como o número, depois uma nova linha e, em seguida, os caracteres na arte ASCII.
Explicação
fonte
liq
no início e isso economiza 3 bytes!JavaScript, 39 bytes
Solução Python do Port of Rod .
Experimente online
fonte
n
até 64 bits, certo? (O Python possui inteiros de precisão arbitrária incorporados, mas os números JS sãodouble
flutuadores de precisão natural que podem ser convertidos em números inteiros). Parece não funcionar para os casos de teste maiores da pergunta, como 1928149325670647244912100789213626616560861130859431492905908574660758972167966. Ah, mas a pergunta permite respostas assim. Ainda assim, deve-se notar.SimpleTemplate , 86 bytes
Uau, este foi um grande desafio!
Isso foi dificultado devido à falta de acesso direto a índices específicos quando o índice é uma variável.
Um bug também o tornava mais longo, exigindo armazenar os valores dentro de uma variável.
Valores esperados:
O primeiro argumento (
argv.0
) pode ser:O segundo argumento (
argv.1
) pode ser:Como isso funciona?
Funciona assim:
C
como uma matriz que contém:C
"{@echoA."
"}"
join
função PHP )Isso resulta, por exemplo, em
C
conter"{@echoA.0}{@echoA.1}..."
C
Ungolfed:
Você pode tentar este código em: https://ideone.com/NEKl2q
Resultado ideal
Se não houvesse bugs, esse seria o melhor resultado, considerando as limitações (77 bytes):
fonte