Convertir a números ASCII Agrippa

8

Desafío

Dado un número natural, imprímalo en la forma ASCII del sistema de números de Agrippa.

Descripción

Me gustan los alfabetos impares y los sistemas numéricos. Mi sistema numérico favorito es uno dado por Heinrich Cornelius Agrippa . Da una forma sucinta de escribir números en el rango [0,9999], donde los dígitos individuales se escriben de la siguiente manera:

Números del 1 al 10

Los números más grandes son menos que 10^4una combinación de dígitos individuales, pero girado / reflejado horizontalmente en una sola barra central de la siguiente manera:

[0° mirrored, 10's  ] | [0°,            1's  ]
[180°,        1000's] | [180° mirrored, 100's]

Aquí están algunos ejemplos:

Ejemplos variados

Los equivalentes ASCII son:

Ones:
  0  1  2  3  4  5  6  7  8  9
  |  |- |_ |\ |/ |~ || |^ |v |]
  |  |  |  |  |  |  |  |  |  |

Tens:
  0  1  2  3  4  5  6  7  8  9
  | -| _| /| \| ~| || ^| v| [|
  |  |  |  |  |  |  |  |  |  |

Hundreds:
  0  1  2  3  4  5  6  7  8  9
  |  |  |  |  |  |  |  |  |  |
  |  |_ |- |/ |\ |~ || |v |^ |]

Thousands:
  0  1  2  3  4  5  6  7  8  9
  |  |  |  |  |  |  |  |  |  |
  | _| -| \| /| ~| || v| ^| [|

 1510:  1511:  1471:  1486:  3421:
 -|     -|-    ^|-    v||    _|-
 _|~    _|~    _|\    -|\    \|\

Los números más grandes que 9999se dividen en secciones de 4 dígitos (con ceros iniciales agregados para obtener un múltiplo de cuatro) y cada uno se convierte. Por ejemplo:

314159: (0031 4159)
         /|-  ~|]
          |   /|_

Reglas

  • Su respuesta puede ser una función o un programa completo
  • La entrada es un entero positivo.
  • Las entradas deben admitir entradas sobre 10^8
  • Cada sección de cuatro dígitos tiene exactamente seis caracteres
  • Las secciones de cuatro están separadas por un solo espacio.
  • La nueva línea final es opcional
  • Se permiten hasta dos espacios finales por línea
  • No aceptaré mi propia respuesta.
  • La puntuación está en bytes, ¡gana la puntuación más baja!
Michael Klein
fuente
Lo siento, pero no entiendo ninguno de tus ejemplos; ni siquiera son consistentes entre sí, y mucho menos los gráficos.
Neil
@Neil Descubrí que los 6 no eran consistentes, pero los arreglé. ¿Hay algo mas? Además, ¿qué quieres decir con "los gráficos"? El arte ASCII es mi interpretación de los gráficos, no una traducción directa de ningún tipo.
Michael Klein
1
Quiero decir que i.stack.imgur.com/2BUbM.gif muestra claramente que las unidades están en la parte superior derecha y las centenas en la parte inferior derecha, pero sus ejemplos tienen las centenas en la parte superior izquierda y las unidades en la parte inferior derecha.
Neil
@Neil Gracias por entender esto. ¿Me he perdido algo más?
Michael Klein
Tu 1486 me parece 2486, pero ahora estoy de acuerdo con el resto.
Neil

Respuestas:

3

Haskell, 310 bytes

  • Definir reverse(como lo hice r:) es un byte más corto que importar Data.Listy usarlo solo una vez
  • Definir z=0:zy (!)=(!!).(++z)es el camino más corto que he encontrado para volver 0fuera de límites
  • He verificado y verificado rápidamente la take4sfunción, pero todavía me parece mágico

Aquí está el código:

l=lines"    \n--__\n__--\n\\//\\\n/\\\\/\n~~~~\n||||\n^^vv\nvv^^\n][]["
d x|x<1=[]|1<2=mod x 10:d(div x 10)
(&)=(!!)
z=(0::Int):z
(!)=(&).(++z)
t a=[[a!q|q<-[p..p+3]]|p<-[0,4..length a-1]]
g[c,d,b,a]=[[l&b&1,'|',l&a&0,' '],[l&d&3,'|',l&c&2,' ']]
r[]=[]
r(x:y)=r y++[x]
f=unlines.foldl1(zipWith(++)).map g.r.t.d

Menos golfizado:

import Data.List (reverse)

dict = lines "    \n--__\n__--\n\\//\\\n/\\\\/\n~~~~\n||||\n^^vv\nvv^^\n][]["


-- Note that (digits x) returns the digits of x in little-endian order
digits x  | x < 1     = []
          | otherwise = mod x 10 : digits (div x 10)

-- Note: zeros needs the type signature, because otherwise it won't match [Int] (inferred from (!!))
zeros = (0::Int) : zeros

-- list ! position gives the element at the position, or 0 for out of bounds
(!) = (!!) . (++zeros)

-- This partitions the digits into groups of four, padded right
take4s a = [[a!q | q <-[p..p+3]] | p <- [0,4..length a - 1]]

convertOne[c,d,b,a] = [[dict !! b !! 1, '|', dict !! a !! 0, ' '], [dict !! d !! 3, '|', dict !! c !! 2, ' ']]

f = unlines . foldl1(zipWith (++)) . map convertOne . reverse . take4s . digits

Pruebas (caracteres de escape eliminados):

mapM_ print $ lines $ f 1510
-|  
_|~ 

mapM_ print $ lines $ f 1511
-|- 
_|~ 

mapM_ print $ lines $ f 1471
^|- 
_|\ 

mapM_ print $ lines $ f 1486
v|| 
_|\ 

mapM_ print $ lines $ f 3421
_|- 
\|\ 

mapM_ print $ lines $ f 1234567891011121314
_|\ ||^ -|  -|_ -|/ 
 |_ /|~ ^|] _|_ _|/ 

mapM_ print $ lines $ f 1024628340621757567
 |_ _|v  || ^|~ ||^ 
 |_ /|| \|\ -|_ v|~ 
Michael Klein
fuente
1
Me preguntaba cómo alguien podría responder un desafío tanto tiempo después de un minuto de publicación. Entonces vi que eras OP.
lirtosiast
3

Javascript (ES6), 180 159 bytes

s=>`000${s}`.slice(-s.length&-4).replace(/..../g,([t,h,d,u])=>(r+=' _-\\/~|v^['[t]+`|${'_-/\\~|v^]'[h]} `,' -_/\\~|^v['[d]+`|${' -_\\/~|^v]'[u]} `),r='')+`\n`+r

Donde \nrepresenta un carácter de nueva línea literal.

Editar: actualizado para el cambio de ,'a |. Ahorró 14 bytes usando un solo replacepara hacer todo el trabajo. Guardado 3 bytes usando en &-4lugar de <<2>>2. Se guardaron 2 bytes al abusar de la asignación de desestructuración. Ahorró 2 bytes al abusar de las cadenas de plantillas.

Neil
fuente