Converta em números Agrippa ASCII

8

Desafio

Dado um número natural, produza-o na forma ASCII do sistema de números da Agrippa.

Descrição

Eu gosto de alfabetos ímpares e sistemas de números. Meu sistema numérico favorito é o de Heinrich Cornelius Agrippa . Ele fornece uma maneira sucinta de escrever números no intervalo [0,9999], onde dígitos únicos são escritos da seguinte maneira:

Numerais de 1 a 10

Números maiores que 10^4a combinação de dígitos únicos, mas girados / espelhados horizontalmente em uma única barra central, da seguinte maneira:

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

Aqui estão alguns exemplos:

Exemplos variados

Os equivalentes ASCII são:

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||    _|-
 _|~    _|~    _|\    -|\    \|\

Números maiores que 9999são divididos em seções de 4 dígitos (com zeros à esquerda adicionados para obter um múltiplo de quatro) e cada um é convertido. Por exemplo:

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

Regras

  • Sua resposta pode ser uma função ou programa completo
  • A entrada é um número inteiro positivo
  • As entradas devem suportar entradas sobre 10^8
  • Cada seção de quatro dígitos ocupa exatamente seis caracteres
  • Seções de quatro são separadas por um único espaço
  • A nova linha à direita é opcional
  • São permitidos até dois espaços finais por linha
  • Não vou aceitar minha própria resposta
  • A pontuação está em bytes, a pontuação mais baixa ganha!
Michael Klein
fonte
Desculpe, mas eu não entendo nenhum dos seus exemplos; eles nem são consistentes um com o outro, muito menos com os gráficos.
Neil
@ Neil Eu achei que os 6 não eram consistentes, mas eu os corrigi. Mais alguma coisa? Além disso, o que você quer dizer com "os gráficos"? A arte ASCII é minha interpretação dos gráficos, não uma tradução direta de qualquer tipo.
Michael Klein
1
Quero dizer, i.stack.imgur.com/2BUbM.gif mostra claramente que as unidades estão no canto superior direito e as centenas no canto inferior direito, mas seus exemplos têm as centenas no canto superior esquerdo e as unidades no canto inferior direito.
Neil
@ Neil Obrigado por capturar isso. Perdi mais alguma coisa?
Michael Klein
Seu 1486 me parece 2486, mas agora concordo com o resto.
Neil

Respostas:

3

Haskell, 310 bytes

  • Definir reverse(como eu fiz r:) é um byte menor que importar Data.Liste usá-lo apenas uma vez
  • Definindo z=0:ze (!)=(!!).(++z)é o caminho mais curto ainda que encontrei para retornar 0fora dos limites
  • Eu verifiquei e verifiquei rapidamente a take4sfunção, mas ainda parece mágica para mim

Aqui está o 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 golfe:

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

Testes (caracteres de escape removidos):

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
fonte
1
Eu me perguntava como alguém poderia responder a um desafio tanto tempo depois de um minuto da postagem. Então eu vi que você era 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

Onde \nrepresenta um caractere literal de nova linha.

Editar: atualizado para a alternância de ,'para |. Economizou 14 bytes usando um único replacepara fazer todo o trabalho. Salva 3 bytes usando em &-4vez de <<2>>2. Economizou 2 bytes abusando da atribuição de desestruturação. Economizou 2 bytes abusando das seqüências de caracteres do modelo.

Neil
fonte