Rolagem de sete segmentos


15

Postagem da caixa de areia

Introdução

Os painéis de informações estão por toda parte. Quando a tecnologia ficou mais barata, os pôsteres de papel foram transformados em sinais luminosos que mostram palavras que aparecem de um lado e saem do outro, como na figura:

insira a descrição da imagem aqui

Quando um desses sinais é iniciado, geralmente começa vazio e o texto sai do lado direito para a esquerda, movendo-se até desaparecer.

Sua funcionalidade é ligar e desligar as pequenas lâmpadas (LEDs) para dar a sensação de movimento.

Se, em vez de texto, precisarmos apenas mostrar números, o pôster poderá ser muito menos sofisticado, usando os chamados marcadores de sete segmentos, como os seguintes:

insira a descrição da imagem aqui

Nesse caso, cada número é representado pela combinação ativada / desativada de apenas 7 segmentos de luz que permitem representar todos os números:

insira a descrição da imagem aqui

A pergunta que fazemos a nós mesmos é: quantas trocas de luzes (quantas estão ligadas e desligadas) devem ser feitas para passar por um desses pôsteres um determinado número?

Por exemplo, para mostrar o 123 em um sinal de 3 dígitos que começa com todos os LEDs apagados, teremos:

insira a descrição da imagem aqui

Isso totaliza 42 trocas de luzes.


Desafio

Dado um número não negativo e um comprimento de sinal positivo, calcule o número de mudanças de luzes.

Regras

  • Suponha que a entrada consiste em um número não negativo (N> = 0) e um comprimento de sinal positivo (M> 0)
  • Suponha Comprimento do sinal> = Comprimento do número (M> = dígitos (N))

Casos de teste

123, 3        => 42
45, 5         => 60
111, 3        => 12
98765, 10     => 220
0, 3          => 36

1
Qual é o objetivo da pergunta? Na realidade, uma parte como MAX7219 controlará os 8 dígitos; para exibi-los, você apenas enviaria os 8 dígitos ao MAX7219 por meio de comandos SPI. O ponto decimal oitavo bit de 1 ou 2 dígitos seria usado para a luz - / +. Por exemplo, 4 poderia ser daisychained para fazer uma tela de 8 x 32 dot ao texto de rolagem através, como este eu fiz: youtube.com/watch?v=hwYqgyMc5S4
CrossRoads

3
@CrossRoads Na verdade, isso não se destina a uma resposta real de hardware ou algo assim. É um desafio para criar um algoritmo que saída pode o número de luzes muda de um determinado número em múltiplos de 7 segmentos exibe
Luis Felipe de Jesus Munoz

1
Caso de teste sugerido:0,3 => 36
Chas Brown

1
Podemos pegar o primeiro número inteiro como uma string ou lista de dígitos?
Οurous

1
@ Sem Οurous, você deve tomar as duas entradas como inteiro
Luis Felipe de Jesus Munoz

Respostas:


7

Python 2 , 129 126 119 104 bytes

def f(n,k,p=0):z=p<1or n>0;q=-~ord('}/lx2Z^o~z'[n%10])*z;return(z and f(n/10,k,q))+k*bin(p^q).count('1')

Experimente online!

Thx para grandes 15 bytes de ovs .

Conforme especificado, pega um número não negativo e um comprimento de sinal positivo e retorna o total de alterações.


4
Que porra é essa feitiçaria? Você é um lorde Python. Fico muito feliz em obter meu código com menos de 200 bytes e você aparece com #'7367355777e0d93bf0fb'
Don Thousand

@Rushabh Mehta: Heh heh. Bem, eu só estou de pé nos ombros de gigantes. Confira essas dicas publicadas pelos verdadeiros cavaleiros Jedi. A estratégia de cordas que aprendi aqui .
quer

2
104 bytes ou 102 bytes com um não imprimível ( \x7f) entre pe {.
ovs 23/08/18

@ovs: bom ajuste!
Chas Brown

3

Gelatina , 23 bytes

Dị“¤]þ+>~Œ¶?w‘Ø0j^ƝBFS×

Um link diádico que aceita o número inteiro a ser exibido à esquerda e o comprimento do sinal à direita, o que gera o número de alterações (também funciona se o número de dígitos no número a ser exibido for maior que o comprimento do sinal).

Experimente online!

Quão?

Durante o show inteiro, cada exibição de 7 segmentos (em algum momento) faz a transição do vazio para o primeiro dígito, depois para o segundo e assim por diante e, finalmente, do último para o vazio novamente. As transições custam o XOR bit a bit dos segmentos on do dígito e do dígito (onde vazio é um "dígito" com 0 segmentos on). Eu roubei os segmentos on como inteiros de uma revisão anterior da resposta da ETHproductions , mas qualquer permutação dos 7 segmentos faria o mesmo.

Dị“¤]þ+>~Œ¶?w‘Ø0j^ƝBFS× - Link: integer to display, V; integer sign length, L  e.g. 123, 3
D                       - cast V to decimal digits                                  [1,2,3]
  “¤]þ+>~Œ¶?w‘          - code-page indices list = [3,93,31,43,62,126,19,127,63,119]
 ị                      - index into (1-based & modular) (vectorises)             [3,93,31]
              Ø0        - literal = [0,0]                                             [0,0]
                j       - join                                                [0,3,93,31,0]
                  Ɲ     - pairwise application of:
                 ^      -   bitwise XOR                                        [3,94,66,31]
                   B    - convert to binary digits (vectorises)               [[1,1],[1,0,1,1,1,1,0],[1,0,0,0,0,1,0],[1,1,1,1,1]]
                    F   - flatten                                             [1,1,1,0,1,1,1,1,0,1,0,0,0,0,1,0,1,1,1,1,1]
                     S  - sum                                                            14
                      × - multiply by L                                                  42

Você poderia salvar um byte usando o número como uma matriz de dígitos? tio.run/##ATsAxP9qZWxsef//...
Shaggy

Sim, mas "Dado um número não negativo" e "a entrada consiste em um número não negativo" me pareceu estrito.
Jonathan Allan

3

JavaScript (Node.js) , 104 94 93 93 bytes

Guardado 1 byte graças a @Shaggy

B=n=>n&&n%2+B(n>>1)
F=(d,w,q)=>w*B(q^(q=d&&"w`>|i]_p}".charCodeAt(d%10)))+(d&&F(d/10|0,w,q))

Experimente online!


Eu acho que isso funciona para -1 byte.
Shaggy

Truque @Shaggy Nice, obrigado!
ETHproductions

OP esclareceu que ambas as entradas devem ser especificamente inteiros (e não listas de números ou strings)
Οurous

Obrigado, fixado em +0 bytes.
ETHproductions

1
Além disso, acho que 0,3deveria dar 36; você dá 0. (Eu tive o mesmo problema - corrigir isso me custou cerca de 10 bytes grrrr ... :)).
Chas Brown

2

Japonês, 31 30 bytes

Adaptado da solução de Jonathan's Jelly. Leva a entrada na ordem inversa com o número a ser exibido como uma matriz de dígitos.

*Vm!c"w]+>~?" pT ä^T x_¤¬x

Tente


OP esclareceu que ambas as entradas devem ser especificamente inteiros (e não listas de números ou strings)
Οurous

2

Limpo , 280 bytes

import StdEnv,Data.List
~ =toInt
?s=sum[(~s>>p)rem 2\\p<-[0..6]]
$n l#j=repeatn l 0
#n=j++[~c-47\\c<-:toString n]++j
#k=[getItems(map((!!)[0,119,3,62,31,75,93,125,19,127,95])n)[i-l..i-1]\\i<-[0..length n]]
=sum(zipWith@(tl k)k)
@[u][]= ?u
@[u:x][v:y]= ?((bitxor)u v)+ @x y
@[][]=0

Experimente online!

Tem que haver uma maneira mais curta ..


1

Carvão , 40 bytes

≔⁺×⁷0⭆S§⪪”)∧??%←⁶%*An”⁷IιθI×NΣEθ¬⁼ι§θ⁺⁷κ

Experimente online! Link é a versão detalhada do código. Funciona convertendo a entrada nos valores do segmento binário e contando o número de alterações entre cada caractere. Explicação:

      S                     Convert first input to string
     ⭆                      Map over digits and join
         ”)∧??%←⁶%*An”      Compressed segment value string
        ⪪             ⁷     Split into groups of seven characters
                        ι   Current digit
                       I    Convert to integer
       §                    Index into groups
    0                       Literal `0`
  ×⁷                        Repeat seven times
 ⁺                          Concatentate
≔                        θ  Assign to variable `q`

     θ          Variable `q`
    E           Map over characters
             κ  Current index
           ⁺⁷   Add seven
          θ     Variable `q`
         §      Cyclically index
        ι       Current character
       ⁼        Compare
      ¬         Logical not
   Σ            Sum results
  N             Second input
 ×              Multiply
I               Cast to string
                Implicitly print

1

JavaScript (Node.js) , 88 bytes

Toma entrada como (integer)(width).

n=>w=>[...n+'',g=n=>n&&1+g(n&n-1)].map(c=>s+=g(x^(x=Buffer('w$]m.k{%o')[c])),x=s=0)|s*w

Experimente online!

Quão?

Dada uma lista {d1,d2,...,dn} do n dígitos e uma largura de exibição W, o número total N de mudanças de luz é dada por:

N=(Td1+Eu=2nTdEu-1,dEu+Tn)×W

Onde Tx,y é o número de mudanças de luz para uma transição do dígito x digitar y e Tx é o número de alterações de luz para uma transição do dígito em branco para o dígito x (ou o contrário).

Comentado

n => w =>                       // n = integer; w = width of display
  [ ...n + '',                  // coerce n to a string and split it
    g = n =>                    // g = helper function counting the number of 1's
      n && 1 + g(n & n - 1)     // by defining it here, we also force an extra iteration
  ]                             // with an undefined digit (interpreted as the blank digit)
  .map(c =>                     // for each entry c in this array:
    s += g(                     //   add to s the result of a call to g():
      x ^ (x =                  //     XOR the previous value of x
        Buffer('w$]m.k{%?o')[c] //     with the new one, picked from a 10-entry lookup
      )                         //     gives undefined (coerced to 0) for the last entry
    ),                          //   end of call to g()
    x = s = 0                   //   start with x = 0 and s = 0
  ) | s * w                     // end of map(); return s * w
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.