Esto está inspirado en una respuesta 05AB1E de Magic Octupus Urn .
Dados dos argumentos, un entero positivo y una cadena / lista de caracteres:
- Traduzca el número a base-n, donde n es la longitud de la cadena.
- Para cada carácter, reemplace cada aparición del índice de ese carácter en el número base-n con ese carácter.
- Imprime o devuelve la nueva cadena.
Ejemplos:
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:
_===_
(.,.)
( : )
( : )
Reglas:
- IO es flexible .
- Puede tomar el número en cualquier base, siempre que sea coherente entre las entradas
- Sin embargo, la lista de caracteres debe estar indexada en 0, donde 0 es el primer carácter y n-1 es el último
- Los caracteres posibles pueden ser cualquier ASCII imprimible, junto con espacios en blanco como pestañas y líneas nuevas
- La lista de caracteres dada tendrá una longitud en el rango
2-10inclusive. Es decir, la base más pequeña es binaria y la más grande es decimal ( no hay letras molestas aquí ) - Las lagunas estándar están prohibidas
- No dude en responder incluso si su idioma no puede manejar los casos de prueba más grandes.
Como se trata de código de golf , gana el código más corto para cada idioma. ( Sé que todos los idiomas de golf tienen incorporados un byte listo para usar ;)
code-golf
ascii-art
base-conversion
Jo King
fuente
fuente

Respuestas:
05AB1E ,
76 bytesComo se inspiró en una respuesta 05AB1E, una respuesta dada en 05AB1E parece adecuada. :)
-1 byte gracias a @Enigma al eliminar el foreach y hacer esto implícitamente.
Pruébelo en línea o verifique todos los casos de prueba .
Explicación:
fuente
gв¹sèJpara guardar un byte¹sèmí ahora ... (sabía que cambiarlo?a aJdaría la misma salida en este caso)Java 8,
7250 bytes-22 bytes gracias a @ OlivierGrégoire devolviendo un en
IntStreamlugar de imprimir directamente.Pruébalo en línea .
Explicación:
fuente
a->n->n.toString(a.length).chars().map(c->a[c-48])(50 bytes) desde "IO es flexible"String f(char[]a,int n){return n>0?f(a,n/a.length)+a[n%a.length]:"";}(69 bytes) uno recursivo, por diversión.Python 3 , 49 bytes
No puedo comentar todavía, así que publico la respuesta de Python 2 adaptada a Python 3.5.
fuente
Japt, 2 bytes
Puede tomar la segunda entrada como una matriz o una cadena. Falla los últimos 2 casos de prueba ya que los números exceden el entero máximo de JavaScript Reemplace
sconìpara generar una matriz de caracteres en su lugar.Intentalo
fuente
Haskell ,
4039 bytesPruébalo en línea!
Como el
Inttipo de Haskell se limita a9223372036854775807, esto falla para números más grandes.-1 byte gracias a Laikoni .
Sin golf
Pruébalo en línea!
fuente
cyclelugar demod!div n(length l)guarda un byte.MATL , 2 bytes
Pruébalo en línea!
Las entradas son un número y una cadena.
Falla para los números que exceden
2^53, debido a la precisión de punto flotante.Explicación
Lo que sí
YAsé, un incorporado (conversión de base con símbolos de destino especificados).fuente
JavaScript (ES6), 48 bytes
Toma entrada en la sintaxis de curry
(c)(n), donde c es una lista de caracteres yn es un número entero.Seguro solo para n <2 53 .
Pruébalo en línea!
JavaScript (ES6), 99 bytes
Con soporte para enteros grandes
Toma entrada en la sintaxis de curry
(c)(a), donde c es una lista de caracteres y a es una lista de dígitos decimales (como enteros).Pruébalo en línea!
fuente
Código de máquina x86 de 32 bits (enteros de 32 bits): 17 bytes.
(vea también otras versiones a continuación, incluidos 16 bytes para 32 bits o 64 bits, con una convención de llamada DF = 1).
La persona que llama pasa argumentos en los registros, incluido un puntero al final de un búfer de salida (como mi respuesta C ; míralo para justificar y explicar el algoritmo). El interno de glibc
_itoahace esto , por lo que no solo está diseñado para el golf de código. Los registros de paso de argumentos están cerca de x86-64 System V, excepto que tenemos un argumento en EAX en lugar de EDX.Al regresar, EDI apunta al primer byte de una cadena C terminada en 0 en el búfer de salida. El registro de valor de retorno habitual es EAX / RAX, pero en lenguaje ensamblador puede usar cualquier convención de llamada que sea conveniente para una función. (
xchg eax,edial final agregaría 1 byte).La persona que llama puede calcular una longitud explícita si lo desea, desde
buffer_end - edi. Pero no creo que podamos justificar la omisión del terminador a menos que la función realmente devuelva punteros de inicio + fin o puntero + longitud. Eso ahorraría 3 bytes en esta versión, pero no creo que sea justificable.idiv. Los otros argumentos no son operandos implícitos).dec edi, por lo que debe estar en los 4GiB bajos)nasm -felf32 ascii-compress-base.asm -l /dev/stdout | cut -b -30,$((30+10))-(Editado a mano para reducir los comentarios, la numeración de líneas es extraña).Es sorprendente que la versión más simple, básicamente sin compensaciones de velocidad / tamaño, sea la más pequeña, pero
std/cldcostó 2 bytes para usarstosben orden descendente y seguir la convención de llamadas DF = 0 común. (Y STOS disminuye después del almacenamiento, dejando el puntero apuntando un byte demasiado bajo en la salida del bucle, lo que nos cuesta bytes adicionales para evitar).Versiones
Se me ocurrieron 4 trucos de implementación significativamente diferentes (usando simple
movload / store (arriba), usandolea/movsb(ordenado pero no óptimo), usandoxchg/xlatb/stosb/xchg, y uno que ingresa al ciclo con un hack de instrucciones superpuestas. Ver código a continuación) . El último necesita un seguimiento0en la tabla de búsqueda para copiar como terminador de cadena de salida, por lo que lo cuento como +1 byte. Dependiendo de 32/64 bits (1 byteinco no), y si podemos asumir que la persona que llama establece DF = 1 (stosbdescendente) o lo que sea, las diferentes versiones son (empatadas) más cortas.DF = 1 para almacenar en orden descendente lo convierte en una victoria para xchg / stosb / xchg, pero la persona que llama a menudo no querrá eso; Se siente como descargar el trabajo a la persona que llama de una manera difícil de justificar. (A diferencia de los registros personalizados de paso de argumento y valor de retorno, que generalmente no cuestan a un llamador de asm ningún trabajo adicional). Pero en el código de 64 bits,
cld/scasbfunciona comoinc rdi, evitando truncar el puntero de salida a 32 bits, por lo que a veces es inconveniente para preservar DF = 1 en funciones de limpieza de 64 bits. . (Los punteros a código / datos estáticos son de 32 bits en x86-64 ejecutables no PIE en Linux, y siempre en Linux x32 ABI, por lo que en algunos casos se puede usar una versión x86-64 que usa punteros de 32 bits). Esta interacción hace que sea interesante observar diferentes combinaciones de requisitos.nostring) .stosb_edx_argoskew) ; o con DF entrante = no importa, dejándolo configurado: 16 + 1Bstosb_decode_overlapo 17Bstosb_edx_argstosb_decode_overlap) , 18B (stosb_edx_argoskew)x86-64 con punteros de 64 bits, otro manejo de DF: 16B (DF = 1
skew) , 17B (nostringcon DF = 1, usando enscasblugar dedec). 18B (stosb_edx_argpreservando DF = 1 con 3 bytesinc rdi).O si permitimos devolver un puntero a 1 byte antes de la cadena, 15B (
stosb_edx_argsinincel final). Todo listo para llamar de nuevo y expandir otra cadena en el búfer con una base / tabla diferente ... Pero eso tendría más sentido si tampoco almacenamos una terminación0, y podría poner el cuerpo de la función dentro de un bucle, así que eso es realmente un problema separadox86-64 con puntero de salida de 32 bits, convención de llamada DF = 0: no hay mejora con respecto al puntero de salida de 64 bits, pero
nostringahora se vincula 18B ( ).skew). O para establecer DF = 1 y dejarlo, 17B paraskewconstdpero nocld. O 17 + 1B parastosb_decode_overlapconinc edial final en lugar decld/scasb.Con una convención de llamada DF = 1: 16 bytes (IA32 o x86-64)
Requiere DF = 1 en la entrada, lo deja configurado. Apenas plausible , al menos en función de cada función. Hace lo mismo que la versión anterior, pero con xchg para obtener el resto de entrada / salida de AL antes / después de XLATB (búsqueda de tabla con R / EBX como base) y STOSB (
*output-- = al).Con un DF = 0 normal en la convención de entrada / salida, la versión
std/cld/scasbtiene 18 bytes para el código de 32 y 64 bits, y está limpia en 64 bits (funciona con un puntero de salida de 64 bits).Tenga en cuenta que los argumentos de entrada están en diferentes registros, incluido RBX para la tabla (para
xlatb). También tenga en cuenta que este ciclo comienza almacenando AL y termina con el último carácter que aún no está almacenado (de ahímovel final). Entonces el bucle está "sesgado" en relación con los demás, de ahí el nombre.Una versión similar no sesgada supera el EDI / RDI y luego lo arregla.
Intenté una versión alternativa de esto con
lea esi, [rbx+rdx]/movsbcomo el cuerpo del bucle interno. (RSI se restablece cada iteración, pero RDI disminuye). Pero no puede usar xor-zero / stos para el terminador, por lo que es 1 byte más grande. (Y no está limpio para 64 bits para la tabla de búsqueda sin un prefijo REX en la LEA).LUT con longitud explícita y un terminador 0: 16 + 1 bytes (32 bits)
Esta versión establece DF = 1 y lo deja así. Estoy contando el byte LUT adicional requerido como parte del recuento total de bytes.
El truco genial aquí es tener los mismos bytes decodificar de dos maneras diferentes . Caemos en el medio del bucle con resto = base y cociente = número de entrada, y copiamos el terminador 0 en su lugar.
En la primera vez a través de la función, los primeros 3 bytes del bucle se consumen como los bytes altos de un disp32 para un LEA. Esa LEA copia la base (módulo) a EDX,
idivproduce el resto para iteraciones posteriores.El segundo byte de
idiv ebpesFD, que es el código de operación para lastdinstrucción que esta función necesita para funcionar. (Este fue un descubrimiento afortunado. Había estado mirando estodivantes, que se distingue delidivuso de los/rbits en ModRM. El segundo byte dediv epbdecodifica comocmc, que es inofensivo pero no útil. Pero conidiv ebpeso podemos eliminarlostdde la parte superior de la función.)Tenga en cuenta que los registros de entrada son una vez más diferencia: EBP para la base.
Este truco de decodificación superpuesta también se puede usar con
cmp eax, imm32: solo se necesita 1 byte para avanzar de manera efectiva 4 bytes, solo banderas de clobbering. (Esto es terrible para el rendimiento en las CPU que marcan los límites de las instrucciones en la caché L1i, por cierto).Pero aquí, estamos usando 3 bytes para copiar un registro y saltar al bucle. Eso normalmente tomaría 2 + 2 (mov + jmp), y nos permitiría saltar al bucle justo antes del STOS en lugar de antes del XLATB. Pero entonces necesitaríamos una ETS por separado, y no sería muy interesante.
Pruébalo en línea! (con una
_startpersona que llama que usasys_writeen el resultado)Es mejor para la depuración ejecutarlo
straceo reducir la salida de forma hexadecimal, para que pueda verificar que haya un\0terminador en el lugar correcto y así sucesivamente. Pero puede ver que esto realmente funciona y producirAAAAAACHOOpara una entrada de(En realidad
xxAAAAAACHOO\0x\0\0..., porque estamos volcando desde 2 bytes antes en el búfer a una longitud fija. Entonces podemos ver que la función escribió los bytes que se suponía que debía y no pisó ningún byte que no debería tener. El puntero de inicio que se pasó a la función fue el segundo y últimoxcarácter, seguido de ceros).fuente
Jalea , 4 bytes
Pruébalo en línea!
ṃestá literalmente incorporado para esto. Los otros tres bytes representan la indexación basada en uno de Jelly.fuente
ṃ" Descompresión de base incorporada ; convierte x a la longitud de base (y) y luego indexa a y "? ¿Es para los casos muy excepcionales en los que la base que desea convertir y la longitud de una cadena / entero / lista son iguales? Cuando lo busco, solo puedo encontrar tres respuestas al usarlo: 1 ; 2 ; 3 . Un poco raro en todos los días, el golf de código desafía a la OMI. : S“sspspdspdspfdspfdsp”, pero“çƥ÷£ḟ’ṃ“spdf”¤ahorra seis bytes. Es especialmente útil con los números de base 250 de JellyPython 2 ,
4948 bytes-1 byte gracias a Jo King
Pruébalo en línea!
Versión alternativa (no terminará para números grandes),
4543 bytes-2 bytes gracias a Jo King
Pruébalo en línea!
fuente
Carbón ,
31 bytesPruébalo en línea! El enlace es a la versión detallada del código. Editar: Guardado 2 bytes gracias a @ ASCII-only. Versión anterior antes de que se agregara el incorporado, 8 bytes:
Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:
fuente
θη? Parece un poco confuso tbh. ¿Por qué no simplemente eliminarlo por completo y dejarlo⍘?D , 112 bytes
Pruébalo en línea!
Este es un puerto de la respuesta C ++ de HatsuPointerKun
El estilo de llamada es
u(ulong(n), to!(char[])(b)), dondenybson los argumentos izquierdo y derechoD cosas específicas
Lamentablemente, necesitamos importar
std.convpara realizar conversiones de cualquier tipo por encima de una conversión de tipo muy básica.Utilizando el sistema de plantillas golfy, y dando la función de los tipos requeridos (por eso llamándolo no es sólo
u(n,b)), podemos acortar las apariciones dechar[]yulonga1byte cada uno, cuando dentro de la función f.D inicializa nuestros tipos para nosotros, por lo que
C t;es la abreviatura deC t=cast(char[])([])to!Cconvierte el enteron%len una matriz de caracteres (usando puntos de código) y~es una concatenaciónforeach(ref c;t)es como elfor(... : ...)bucle de C ++ , pero un poco más largo.refes como si&se trataraccomo copiado por referencia (es decir, podemos modificarlot). Por suerte, infiere D del tipo decsin ningún tipo de palabras clave que denota.fuente
C ++,
150144 bytes,uint64de entrada-6 bytes gracias a Zacharý
El uso de una variable para almacenar el tamaño aumentaría el bytecount en 1
Para llamar a la función:
Primero el número, segundo es la cadena (matriz de caracteres)
Casos de prueba :
fuente
#include, puede cambiar;;a solo;y'0'puede ser simplemente48forciclo:for(;n;n/=b.size())t=std::to_string(n%b.size())+t;b.size()no cambia en ese ciclo.Ramita, 66 bytes
Creado un
macroque debe serimported en una plantilla.Valores esperados:
Para los primeros argumentos (
n):Para el segundo argumento (
c):Cómo utilizar:
.twigarchivo{% import 'file.twig' as uncompress %}uncompress.d()Sin golf (no funcional):
Puede probar este código en: https://twigfiddle.com/54a0i9
fuente
Pyth,
987 bytesAhorré un byte gracias a hakr14 y otro gracias al Sr. Xcoder.
Pruébalo aquí
Explicación
fuente
m@Qdcon@LQvzconE.C89, rango limitado firmado
int n,6453 byteschar **outy modifíquelo, en lugar de tomar y devolver unchar *Toma el número como una
int, la tabla de búsqueda como una matriz + longitud.La salida se escribe en a
char *outbuf. La persona que llama pasa (por referencia) un puntero al final del búfer. La función modifica ese puntero para que apunte al primer byte de la cadena al regresar.Este es un C89 válido y funciona correctamente incluso con la optimización habilitada. es decir, no depende del
-O0comportamiento de gcc cuando se cae al final de una función no nula o tiene cualquier otra UB.Pasar un puntero al final de un búfer es normal para una función int-> string optimizada, como la interna de glibc
_itoa. Consulte esta respuesta para obtener una explicación detallada de cómo dividir un número entero en dígitos con un bucle div / mod como lo estamos haciendo aquí, en C y en x86-64 asm. Si la base es una potencia de 2, puede cambiar / enmascarar para extraer dígitos MSD primero, pero de lo contrario, la única buena opción es el primer dígito menos significativo (con módulo).Pruébalo en línea! . Versión sin golf:
En esta versión de longitud explícita, la entrada es una
char table[]que no necesita un byte de terminación 0, porque nunca la tratamos como una cadena. Podría ser unint table[]para todo lo que nos importa. C no tiene contenedores que conozcan su propia longitud, por lo que puntero + longitud es la forma normal de pasar una matriz con un tamaño. Así que elegimos eso en lugar de necesitarlostrlen.El tamaño máximo del búfer es aproximadamente
sizeof(int)*CHAR_BIT + 1, por lo que es pequeño y constante en tiempo de compilación. (Utilizamos este espacio con base = 2 y todos los bits establecidos en 1.) por ejemplo, 33 bytes para enteros de 32 bits, incluido el0terminador.C89, firmada
int, tabla como una cadena C de longitud implícita, 65 bytesEsto es lo mismo, pero la entrada es una cadena de longitud implícita, por lo que tenemos que encontrar la longitud nosotros mismos.
fuente
Bash + utilidades principales , 49 bytes
Pruébalo en línea!
Comentarios / explicación
Esto toma los argumentos de la línea de comandos como entrada (el número en la base 10, luego una sola cadena con la lista de caracteres) y sale a stdout. Los caracteres especiales como el espacio, salto de línea, etc se pueden introducir en notación octal (por ejemplo,
\040por un espacio), o\nde una nueva línea,\tpara la lengüeta, o cualquier otra secuencia de escape queecho -eetrinterpretar de forma idéntica.Muchos de los bytes aquí son para manejar caracteres especiales y casos de prueba más grandes. Si solo tengo que manejar caracteres no terribles y los números son pequeños (por ejemplo, el primer caso de prueba), los siguientes 24 bytes lo harán:
Esto usa la expansión de parámetros
${#2}para obtener el número de caracteres en la cadena, crea un programa de CC para realizar la conversión base y luego envía el número convertidotr.Sin embargo, esto no manejará nuevas líneas o espacios o pestañas, por lo que para tratar las secuencias de escape sin afectar la base, hago un recuento de caracteres
wc -cdespués de interpretar los escapesecho -en. Esto expande el programa a 38 bytes:Desafortunadamente, DC tiene una "característica" molesta en la que si está generando un gran número, lo envolverá en línea con una secuencia de barra + nueva línea, por lo que los casos de prueba más grandes tienen esta salida adicional. Para eliminarlo, canalizo la salida de CC
tr -dc 0-9para eliminar caracteres no numéricos. Y ahí estamos.fuente
dc -e${#2}o$1p|tr 0-9 "$2"tomar la entrada literalmente en lugar de en forma \ escape para que pueda manejar espacios, perotrno tiene una opción para no tratar-como un carácter de rango, por ejemplo. Si la entrada-no tiene un extremo de la cadena, se rompe. Quizás puedas usarsed "y/0123456789/$2/". No, supongo que no, GNUsedrequiere que ambos argumentosytengan la misma longitud, y parece que se ahoga en la nueva línea.APL (Dyalog Unicode) ,
14 1312 bytesPruébalo en línea!
Función infija tácita; no puede manejar el caso de prueba más grande debido a la representación de punto flotante.
Guardado
12 bytes gracias a @ Adám!13 bytes añadidos para los encabezados:(Había olvidado que esto no se aplica ) .⎕IO←0: I ndex O rigin = 0 y⎕FR←1287: F loat R ePresentation = 128 bits.¿Cómo?
fuente
Adjunto , 17 bytes
Pruébalo en línea!
Explicación
fuente
Lienzo , 7 bytes.
Pruébalo aquí!
Implementación directa:
El conjunto de caracteres de entrada también puede ser una cadena siempre que no contenga una nueva línea, ya que Canvas no tiene un carácter de nueva línea y lo convierte automáticamente en un objeto 2D.
fuente
Stax ,
65 bytesEjecutar y depurarlo
Explicación:
fuente
SOGL V0.12 , 10 bytes
Pruébalo aquí!
Bastante largo, considerando que la idea está más o menos implementada en el lenguaje: aquí , ingresando
emite una cadena comprimida usando este método.
fuente
Ruby , 31 bytes
Pruébalo en línea!
fuente
Stax , 2 bytes
Ejecutar y depurarlo
:Bes una instrucción en stax que hace esto. Normalmente funcionaría en una "cadena" * en lugar de una matriz de "cadenas". Al final, esto significa que la salida es una matriz de matrices de un solo carácter. Pero la salida implícitamente se aplana de todos modos.* Stax en realidad no tiene un tipo de cadena. El texto está representado por conjuntos enteros de puntos de código.
fuente
J , 12 bytes
¿Cómo?
Pruébalo en línea!
fuente
Wolfram Language (Mathematica) , 49 bytes
Pruébalo en línea!
fuente
C (gcc) , 110 bytes
Pruébalo en línea!
Descripción:
fuente
sprintf. Mi versión C es de 53 bytes , con el búfer de salida proporcionado por la persona que llama. Puede hacer unostrcpyal final si desea copiar los bytes al inicio de un búfer.CJam , 11 bytes
Pruébalo en línea! Toma la entrada como el número, luego una nueva línea, luego los caracteres en el arte ASCII.
Explicación
fuente
liqal principio, ¡y eso te ahorra 3 bytes!JavaScript, 39 bytes
Solución Python del puerto de Rod .
Pruébalo en línea
fuente
nhasta 64 bits, ¿verdad? (Python tiene enteros de precisión arbitraria incorporados, pero los números JS sondoubleflotantes de precisión natural que se pueden convertir a enteros). No parece funcionar para los casos de prueba más grandes en la pregunta, como 1928149325670647244912100789213626616560861130859431492905908574660758972167966. Oh, pero la pregunta permite respuestas como esa. Aún así, debe tenerse en cuenta.SimpleTemplate , 86 bytes
¡Guau, este fue un gran desafío!
Esto se hizo difícil debido a la falta de acceso directo a índices específicos cuando el índice es una variable.
Un error también lo hizo más largo, requiriendo almacenar los valores dentro de una variable.
Valores esperados:
El primer argumento (
argv.0) puede ser:El segundo argumento (
argv.1) puede ser:¿Cómo funciona esto?
Funciona de esta manera:
Ccomo una matriz que contiene:C"{@echoA.""}"joinfunción de PHP )Esto resulta, por ejemplo, en
Ccontener"{@echoA.0}{@echoA.1}..."CSin golf:
Puede probar este código en: https://ideone.com/NEKl2q
Resultado óptimo
Si no hubiera errores, este sería el mejor resultado, teniendo en cuenta las limitaciones (77 bytes):
fuente