Meu primeiro quebra-cabeça de programação e código de golfe é o Seven-Slash Display . Aqui está o meu primeiro desafio, também baseado em 7 segmentos.
Costumo pensar, além dos números, em que tipo de letras posso exibir usando um simples display de 7 segmentos. Acontece que muitas letras podem ser exibidas. De fato, todas as letras, exceto K, M, V, W, X, podem ser exibidas usando uma única tela de 7 segmentos. Isso ocorre porque você pode exibir letras minúsculas ou maiúsculas. por exemplo
"abcdef" pode ser exibido como
_ _ _ _
!_!!_ ! _!!_ !_
! !!_!!_ !_!!_ !
Observe que cada caractere é uma matriz 3x3 composta por !
e _
.
Obviamente, a tela de 7 segmentos pode ser usada para exibir números e símbolos:
_ _ _ _ _ _ _
! _ !_ !_ ! _! !!_ !_!! !_!!_!
! _!!_ !_! !_! ! _!! !_ ! ! _!
Algumas letras podem ter letras maiúsculas e minúsculas:
_ _
! _ !_!!_ ! ! ! _ ! !
!_ !_ ! !! ! ! !!_!!_!!_!!_!
Aqui está o conjunto completo de caracteres:
_ _ _ _ _ _ _ _ _
! ! ! _! _!!_!!_ !_ !!_!!_! _ !_ _ _ _!
!_! !!_ _! ! _!!_! !!_! _! !_ ! ! !!_!!_! !
_ _ _ _ _ _ _ _ _ _
!_!!_ ! _!!_ !_ ! !_! ! !! _ ! !!_!!_! _ !_ !_ ! !!_! _!
! !!_!!_ !_!!_ ! !_!! ! !!_!!_ ! !!_!! !! _!!_ !_! _!!_
Preste atenção que há um espaço em branco ( ), um traço (
-
) e um ponto de interrogação ( ?
). A carta I
, O
e Z
são os mesmos que os números 1
, 0
e 2
, respectivamente.
Neste desafio, você escreverá um programa ou uma função para exibir uma string usando o formato de exibição de 7 segmentos acima.
Regras
Você pode escrever um programa ou uma função
Isso é código-golfe, o código mais curto em bytes vence
Seu programa ou função deve receber a entrada do STDIN ou como parâmetro. E gera uma string para STDOUT ou como uma string em 3 linhas sem espaço à esquerda, mas finalizada com nova linha. Manuseie as letras maiúsculas / minúsculas
CHIOU
corretamente.Opcionalmente, você pode imprimir espaços em branco à direita
Você deve seguir o formato acima. Usando sublinhado
_
e ponto de exclamação!
para formar sua exibição de 7 segmentos.Você deve oferecer espaço em branco (
), traço (
-
) e ponto de interrogação (?
)Se a sequência contiver caracteres não suportados (k, m, v, w, x), um único caractere de erro (3 linhas horizontais, veja o exemplo) será exibido. Além dos 5 caracteres não suportados, você pode assumir que a entrada é composta apenas por um conjunto de caracteres suportado.
Optei por não ter uma letra para L (
l
) em minúsculas devido a confusões, mas se você estiver inclinado, poderá exibi-la como uma1
à direita ou à esquerda.
Exemplos
$./a.out Start
_ _
!_ !_ !_! _ !_
_!!_ ! !! !_
$./a.out "7-seg dIsplay"
_ _ _ _ _ _ _
! _ !_ !_ ! _! !!_ !_!! !_!!_!
! _!!_ !_! !_! ! _!! !_ ! ! _!
$./a.out "0123456789 chiou-?"
_ _ _ _ _ _ _ _ _
! ! ! _! _!!_!!_ !_ !!_!!_! _ !_ _ _ _!
!_! !!_ _! ! _!!_! !!_! _! !_ ! ! !!_!!_! !
$./a.out "ABCDEFGHIJLNOPQRSTUZ"
_ _ _ _ _ _ _ _ _ _
!_!!_ ! _!!_ !_ ! !_! ! !! _ ! !!_!!_! _ !_ !_ ! ! _!
! !!_!!_ !_!!_ ! !_!! ! !!_!!_ ! !!_!! !! _!!_ !_!!_
$./a.out "abcdefghijlnopqrstuz"
_ _ _ _ _ _ _ _
!_!!_ _ _!!_ !_ ! !_ !! _ _ !_!!_! _ !_ !_ _!
! !!_!!_ !_!!_ ! !_!! ! !!_!!_ ! !!_!! !! _!!_ !_!!_
$./a.out "Bad Form"
_
_
_
$./a.out "Hello"
_
!_!!_ ! ! _
! !!_ !_ !_ !_!
$./a.out "World"
_
_
_
k, m, v, w, x
não sejam exibidas.\r
) com avanço de linha (LF,\n
). * nix usa LF e Windows usa CRLF. Apenas certos sistemas legados usam o CR por si só. Mais informações aqui: en.wikipedia.org/wiki/NewlineRespostas:
CJam,
123114112110 bytesO exemplo acima usa notação de intercalação, pois o código contém caracteres não imprimíveis. Um deles é um byte nulo (
^@
), o que significa que esse código só pode ser executado a partir da linha de comando.Ao custo de apenas mais dois bytes (para um total de 112 ), podemos corrigir isso.
Desta vez, todos os caracteres são imprimíveis. Experimente on-line no intérprete CJam .
Exemplo de execução
Ideia (versão para impressão)
Cada caractere pode ser mostrado no visor de 9 segmentos
substituindo alguns de seus caracteres por espaços.
Podemos transformar um caractere específico em um número inteiro substituindo cada segmento mostrado, em ordem de leitura natural, por 1 , cada segmento não mostrado com 0 e considerando os dígitos binários do resultado.
O primeiro e o terceiro segmento nunca são mostrados, portanto, isso produzirá números inteiros nos intervalos [0,64) e [128,192) .
Podemos codificar cada um desses números inteiros como um único byte, mas metade deles resultará em caracteres não imprimíveis. Assim, adicionamos 64 a cada número inteiro antes de converter o caractere, o que garante que os pontos de código estejam nos intervalos [64,128) e [192,256) .
O único caractere não imprimível nesses dois intervalos é DEL (ponto de código 127), que corresponde à seguinte configuração de exibição não impressa:
Podemos reverter a codificação acima adicionando 448 == 512 - 64 a cada ponto de código, convertendo para a base 2 e removendo o primeiro dígito binário.
Tudo o que resta para encontrar uma maneira eficiente de associar esses segmenets codificados aos seus caracteres ASCII correspondentes.
Se mapearmos os caracteres de
" -chiou"
para os caracteres de";=KMVWX"
e convertermos toda a entrada em maiúscula, podemos simplesmente armazenar a codificação para todos os caracteres entre0
(ponto de código 48) eZ
(ponto de código 90), fornecendo um intervalo de 43.A indexação de matrizes é modular no CJam, portanto, se
A
for uma sequência de comprimento 43A86=
,A43=
eA0=
todas produzem os mesmos resultados. O caractere com o ponto de código 86 éV
, então simplesmente armazenamos os segmentos codificados de V - Z e 0 - U , em ordem.No código real, selecionamos o sinal de arroba como "formato incorreto", substituímos toda a entrada pela string
"@"
se ela contiver uma letra proibida e inverta as etapas acima.Código (versão para impressão)
fonte
Perl,
475469424390280272 bytesmultilinhas com comentários:
Os padrões de bits que codificam os segmentos são armazenados em uma string (escapando de 3 caracteres não imprimíveis usando
\x
e usando\0
espaço) e são mapeados para os caracteres de entrada usando o operador de transliteração Perl.Para 5 dos 7 segmentos, um bit a bit e é usado junto com o operador ternário para gerar um espaço ou o caractere de segmento. Para os dois segmentos inferior esquerdo (codificados por 2 e 4 no conjunto de bits), uma pesquisa de substring em uma cadeia de 8 caracteres é usada para salvar 2 bytes.
Obrigado a Dom Hastings por suas dicas de golfe em Perl.
Versão antiga (usando expressões regulares para codificar os padrões), 390 bytes:
multilinhas com comentários:
A sequência é lida e verificada quanto a caracteres inválidos usando um regex, saindo se houver algum. Os caracteres minúsculos permitidos são substituídos pelos caracteres inválidos e a string inteira é convertida em minúsculas.
As linhas são geradas uma de cada vez, com 1 segmento por letra na primeira linha e 3 nas outras duas. Para cada linha, a sequência é processada um caractere de cada vez e o caractere é comparado a uma expressão regular para cada segmento para verificar se a! ou _ deve ser exibido. O uso de uma regex significa que, para caracteres em que o segmento não está definido, são necessários zero bits por segmento por caractere para codificá-lo, ou seja, para aqueles em que está, são necessários um pouco menos de 8 bits, em média, porque os intervalos de caracteres de expressão regular podem ser usava. Portanto, funciona em torno de 3 ou 4 bits por segmento por caractere no conjunto, ou em torno de 21 a 24 bits por caractere.
Ele não lida com quebra de linha.
fonte
' '
pode ser substituído por$"
e' '
pode ser o$"x3
que apara alguns, seus\n
s podem ser novas linhas literais para se livrar de mais alguns. Sua saída antecipada também pode ser curta, usando die, para que issoif(/[kmvwx]/i){print" -\n"x3;exit}
se tornedie" - "x3if(/[kmvwx]/i)
. Com um pouco mais de falsificação, você também pode reorganizar o loop para evitar os colchetes e não precisa$z
economizar mais!$_=lc<>
não trabalho, porque então o código não pode discriminar entre maiúsculas e minúsculas ChiouLisp comum,
488416Exemplo
Com
"abcdefg'hijklnopqrstuz"
, imprime:Observações
Os caracteres e suas representações são codificados neste número na base 36:
A representação binária desse dígito é dividida em grupos de 17 bits.
Por exemplo, o último grupo de 17 bits
110000111101010
é decomposto aqui em duas partes:110000
, o código de caractere0
111101010
, uma codificação do desenho, melhor representada da seguinte maneira:Os bits na primeira e na última "coluna" são para
!
caracteres, os da coluna do meio para o_
caractere. Quando necessário, as versões maiúsculas e minúsculas de um caractere são armazenadas.A função itera três vezes sobre a sequência de entrada, uma para cada linha de saída, procura um caractere correspondente na tabela (ou o padrão é 146, também conhecido como três barras) e imprime a representação na linha atual.
fonte
'
personagem, o que é legal; no entanto, ele será exibido fora do que uma tela de 7 segmentos é capaz. Se você mover o!
down em 1 linha, seria perfeito.'
caractere e editar a perguntaK
porque, de fato, coloquei oK
lugar errado na string de entrada ("... jlKn ...") ;-) Você pode ver as barras triplas (erro) apenas depois do L. Obrigado por perceber.JavaScript (ES6),
380352324 bytes( Nota: O código usa notação de intercalação, pois contém alguns caracteres não imprimíveis. Para obter o código original, clique aqui e selecione os dados brutos. E não,
h
não é um programa CJam.;)Chamado como
d("7-seg display")
ou similar. Funciona no Firefox 40, mas pode não estar em outros navegadores. Por alguma razão, o snippet HTML / JS não salva os não imprimíveis, mas você pode copiar e colar os dados brutos daqui .Ungolfed:
( Nota:
g
eh
foram preenchidos com espaços para combinar8
,-
,ÿ
espace
com seus valores Unicode correspondentes.)Explicação:
Percebi imediatamente que os 7 segmentos, convertidos em
0
/1
bits, combinariam bem com os primeiros 128 caracteres Unicode. O problema com essa idéia é que 1/4 desses caracteres são caracteres de controle não imprimíveis. Usá-los no meu código faria com que parecesse incrivelmente bagunçado (ou incrivelmente inteligente; ainda não decidi qual). Para resolver isso, mantendo o restante do código simples, surgiu a seguinte idéia:Com a excepção de
-
, espaço , e erro , nenhum dos caracteres faltavam ambos os segmentos verticais inferiores. Portanto, para garantir que todos esses caracteres fiquem entre0020
e007f
, simplesmente mapeei os 64 e 32 bits para esses segmentos, da seguinte forma:Os números dos outros 5 segmentos não são muito importantes; eles podem ser organizados de qualquer outra maneira e ainda ter os mesmos caracteres "dentro dos limites".
Como exemplo, aqui está a versão codificada de A :
Em seguida, coloquei a versão codificada de cada caractere 7-seg
h
. No entanto,8
resultou em007f
(o código de controle de exclusão ; constante, independentemente de como os segmentos estão organizados), o espaço resultou em0000
(o código nulo ; também constante),-
resultou em0002
e resultou em erro0007
. Copiei e colei os bytes brutos na posição correta para8
,-
e erro ; espaço foi facilmente alcançado com\0
.Depois de toda essa codificação, tudo que eu precisava fazer era usá-lo para decodificar a string e produzi-la em um formato legível em 7 seg. Eu usei uma por laço e três variáveis (
x
,y
, ez
, cada um correspondente a uma linha de saída) para passar por cada carácter na cadeia e adicionar o seu equivalente 7-seg para a saída. Eu escolhiÿ
o caractere de erro porque o AFAIK não está em nenhum teclado e é o último caractere nou+0000-u+00ff
intervalo. Talvez eu pudesse ter sido espirituoso e escolhidoΞ
(letra grega xi) ...;)Editar 1: Salvo um grupo de espaço, criando mini-funções para determinar se
!
,_
oué necessário.
Editar 2: economizei muito mais espaço usando os truques que aprendi desde a última vez que visitei este post.
Como sempre, as sugestões são muito apreciadas!
fonte