Diferenças de 7 segmentos

26

Eu acho que a maioria das pessoas por aqui sabe o que é um display de 7 segmentos para dígitos:

 _         _   _         _    _    _    _    _ 
| |    |   _|  _|  |_|  |_   |_     |  |_|  |_|
|_|    |  |_   _|    |   _|  |_|    |  |_|   _|

Podemos definir a diferença de 7 segmentos (7SD) entre dois dígitos para ser o número de segmentos que precisam ser alternados para alternar de um para o outro. Por exemplo, o 7SD entre 1e 2é 5 (os três segmentos horizontais e os dois segmentos verticais inferiores precisam ser alternados) e o 7SD entre 6 e 8 é 1 .

Além disso, podemos definir o 7SD entre dois números como a soma dos 7SDs entre os dígitos correspondentes. Se um número for maior que o outro, assumimos que eles estão alinhados à direita e adicionamos o número de segmentos necessários para exibir os dígitos mais significativos do número maior. Como exemplo, considere o 7SD entre 12345e 549:

  x:  1 2 3 4 5
  y:      5 4 9
7SD:  2+5+2+0+1 = 10

Sua tarefa é calcular 7SD entre n e n + 1 , dado n .

Por conveniência, aqui está a tabela completa de 7SDs entre dígitos individuais. A linha _representa uma posição vazia.

   _ 0 1 2 3 4 5 6 7 8 9

_  0 6 2 5 5 4 5 6 3 7 6
0  6 0 4 3 3 4 3 2 3 1 2
1  2 4 0 5 3 2 5 6 1 5 4
2  5 3 5 0 2 5 4 3 4 2 3
3  5 3 3 2 0 3 2 3 2 2 1
4  4 4 2 5 3 0 3 4 3 3 2
5  5 3 5 4 2 3 0 1 4 2 1
6  6 2 6 3 3 4 1 0 5 1 2
7  3 3 1 4 2 3 4 5 0 4 3
8  7 1 5 2 2 3 2 1 4 0 1
9  6 2 4 3 1 2 1 2 3 1 0

Entrada

  • A entrada é um único número inteiro positivo n.
  • Você pode escrever um programa ou função, recebendo informações via STDIN (ou alternativa mais próxima), argumento de linha de comando ou argumento de função.
  • Você pode supor que a entrada seja no máximo um menor que o maior número que pode ser representado pelo tipo inteiro padrão do seu idioma, desde que esse tipo suporte pelo menos valores até 127 inclusive.

Saída

  • Você deve imprimir um único número inteiro, o 7SD entre ne n+1.
  • Você pode enviar via STDOUT (ou alternativa mais próxima), valor de retorno da função ou argumento da função (out).

Pontuação

Aplicam-se as regras de padrão, o mais curto (em bytes) vence.

Casos de teste

Por alguma razão obscura, essa sequência ainda não está no OEIS, embora exista a sequência A123587 intimamente relacionada . Aqui estão os 100 primeiros números (começando com n = 1, 2, 3, ...):

5, 2, 3, 3, 1, 5, 4, 1, 4, 4, 5, 2, 3, 3, 1, 5, 4, 1, 7, 4, 5, 2, 3, 3, 1, 
5, 4, 1, 4, 4, 5, 2, 3, 3, 1, 5, 4, 1, 5, 4, 5, 2, 3, 3, 1, 5, 4, 1, 5, 4, 
5, 2, 3, 3, 1, 5, 4, 1, 3, 4, 5, 2, 3, 3, 1, 5, 4, 1, 7, 4, 5, 2, 3, 3, 1, 
5, 4, 1, 6, 4, 5, 2, 3, 3, 1, 5, 4, 1, 3, 4, 5, 2, 3, 3, 1, 5, 4, 1, 6, 4

A primeira entrada para a qual o 7SD é maior que 9 é a 1999que deve render 11. Aqui estão alguns outros exemplos maiores:

n          7SD
1999        11
12345        1
999999      14
5699999     15
8765210248   1
Martin Ender
fonte

Respostas:

8

Geléia , 25 22 21 20 bytes

‘DṁDḟ"DFị9979482ḃ5¤S

Experimente online! ou verifique todos os casos de teste .

fundo

Primeiro incrementamos a entrada n e descartamos todos os dígitos de n + 1 que não foram alterados.

Por exemplo, se n for 5699999 , obtemos o seguinte.

n     : 5700000
n + 1 : 5699999
Result:  700000

Todos os dígitos neste resultado têm um número fixo de segmentos que precisam ser alternados. Podemos converter a lista de alternâncias para a base bijetiva 5 para economizar alguns bytes.

digit:   1 2 3 4 5 6 7 8 9 0
toggles: 4 5 2 3 3 1 5 4 1 2

A saída é simplesmente a soma das alternâncias individuais.

Isso funciona para a maioria dos valores de n , mas deve-se tomar cuidado especial se n + 1 tiver mais dígitos que n . Nesse caso, todos os dígitos devem ter 9 e resolvemos esse problema cortando um 0 à direita de n + 1 .

Por exemplo, se n for 999999 , obtemos o seguinte.

n     :  999999
n + 1 : 1000000
Result: 100000

Isso funciona porque o primeiro 1 é avaliado para 4 alternâncias (distância entre 0 e 1 ), enquanto a quantidade real de alternâncias é 2 (distância entre 0 e 1 ), e suprimir um 0 à direita remove suas 2 alternâncias da soma.

Como funciona

‘DṁDḟ"DFị9979482ḃ5¤S  Main link. Argument: n

‘                     Compute n+1.
 D                    Convert n+1 from integer to base 10.
   D                  Convert n from integer to base 10.
  ṁ                   Mold the left result as the right result.
                      This chops of a 0 if n+1 has more digits than n.
    ḟ"D               Vectorized filter-false with the base 10 digits of n.
                      This removes the digits from n+1 that are identical to
                      the corresponding digits of n.
       F              Flatten the resulting list of lists.
         9979482ḃ5¤   Convert 9979482 to bijective base 5.
                      This yields [4, 5, 2, 3, 3, 1, 5, 4, 1, 2].
        ị             Retrieve the digits at the right that correspond to the
                      indices at the left.
                   S  Compute the sum of the results.
Dennis
fonte
10

JavaScript (ES6), 46 40 bytes

f=n=>n?+"452331541"[n%10]||f(n/10|0)+2:2

Formulação alternativa, também 46 40 bytes:

f=n=>n?26523308>>n%10*3&7||f(n/10|0)+2:2

Editar: salvou 6 bytes graças a @xsot.

Neil
fonte
Se o operador lógico ou no ES6 se comportar como o do python, você poderá reduzir ainda mais o seu segundo código. Consulte minha submissão para um exemplo.
xsot
@xsot Na verdade eu posso reduzir os dois! Eu não acho que isso me ajude a alterar o caso especial zero, porque são apenas 4 bytes.
Neil
Uau, estou surpreso que o primeiro funcione. Eu esperava um erro.
xsot
O javascript @xsot não se limita a erros. Ele faz o que parecia ser a abordagem mais correta nesses dez dias em que o Javascript nasceu. . Versões posteriores permitem que você opte por um comportamento um pouco mais rigoroso, mas por que alguém faria isso aqui? O comportamento de curto-circuito dos operadores lógicos é bastante comum, porém, apenas o PHP faz a coisa errada sempre retornando um valor booleano.
John Dvorak
@JanDvorak Na verdade, fiquei surpreso pelo fato de você poder acessar um índice de uma string maior que o comprimento da string.
xsot
10

Python, 50 48 bytes

f=lambda n:26523308-0**n*2>>n%10*3&7or f(n/10)+2

Explicação

Esta função opera no dígito menos significativo do número n, somando o 7SD dos dígitos quando incrementado por um até o primeiro não 9dígito.

26523308é uma máscara de bits que codifica o mapeamento para os dígitos 0-8. Quando n=0, o que ocorre apenas quando ncompreende apenas 9s, a resposta será desativada em dois. Isso é compensado pela expressão 0**n*2. Quanto ao dígito 9, a máscara de bit é avaliada em zero, o que acionará a chamada recursiva enquanto se adiciona 2ao 7SD.

xsot
fonte
Podemos ter alguma explicação de como isso faz a transformação? Quero dizer, +1 por inteligência, mas me perdi na inteligência.
CAD97
8

05AB1E , 31 30 28 27 26 bytes

Código:

9Ü©T%•2X›ùì•sè¹g®g-·¹Ú9Q·O

Explicação ( desatualizada ):

9Ü                              # Trim off trailing 9's
  ©                             # Copy this into the register
   T%                           # Get the last non-9 digit
     žh                         # Short for 0123456789
       •2X›ù앧                 # Compressed version of 4523315412
               ‡                # Transliterate

Estamos alterando o seguinte para o último dígito não 9:

0 -> 4
1 -> 5
2 -> 2
3 -> 3
4 -> 3
5 -> 1
6 -> 5
7 -> 4
8 -> 1
9 -> 2

Para os casos especiais:

                ¹g              # Get the length of the input
                  ®g            # Get the length of the input with all trailing 9 gone
                    -           # Substract, giving the number of 9's at the end of 
                                  the input
                     2*         # Multiply by two
                       O        # Sum everything up
                        ¹Ú      # Uniquify the input
                          9Qi   # If this is equal to 9 (only 9's in the input)
                             Ì  #   Increment by 2 (_ -> 1)

Usa a codificação CP-1252 . Experimente online! .

Alternativa 28 bytes: D[¤©•2X›ùì•sès®9Ê#¨]\rÚ9Q4*O.

Adnan
fonte
3

MATL , 61 39 36 bytes

tQvV15\'3dAsMh818RG5'6Y27WZaw)Z}Z~Bz

Experimente online!

Explicação

tQv            % Implicit input. Duplicate, add 1, concatenate vertically
V              % Convert to 2D char array: each number in a row, possibly left-padded 
               % with a space
15\            % Modulo 15. With modular indexing this corresponds to the order
               % '9', ' ', '0', '1', ..., '8'
'3dAsMh818RG5' % This string encodes active segments for each of the 11 chars
6Y2            % Source alphabet printable ASCII chars (predefined literal)
7W             % Target alphabet: [0 1 ... 127]
Za             % Base conversion: decode string into vector of 11 numbers, where each
               % number from 0 to 127 encodes the 7-segment representation of a digit,
               % in the order '9', ' ', '0', '1', ..., '8'
w              % Swap top two elements in stack
)              % Use as index. Gives 2-row array, where each column is a digit 
Z}             % Split into the two rows
Z~             % Bitwise XOR, elementwise
B              % Convert to binary. Each number gives a row
z              % Number of nonzero elements. Implicitly display
Luis Mendo
fonte
3

Julia, 44 bytes

!x=x<1?2:(t=x%10÷1)<9?3045058÷6^t%6:2+!.1x

Experimente aqui.

Dennis salvou um byte!

Lynn
fonte
1
Por curiosidade, por que não usar apenas os números?
Conor O'Brien
Não acredito que há um Julia TIO. Welp, tempo para aprender Julia então ...
Mama Fun Rolo
3

Python, 71 66 bytes

48 bytes por xsot . Matemática ainda mais mágica!

f=lambda n:(2+f(n/10)if n%10==9else 26523308>>n%10*3&7)if n else 2

Veja no ideone

Porque a resposta anterior do Python não funciona e está longe de ser ótima. Uma porta simples de uma versão anterior do ES6 . Agora, use o ajuste de bits (da formulação alternativa ES6) para cortar um elenco!

Pode ser feito para trabalhar com Python 3 usando explicitamente floordiv para +1 byte.

CAD97
fonte
você pode tirar o espaço depois 9
Maltysen
@ Maltysen, aparentemente, você está correto. Eu pensei que seria um erro, porque eé uma letra válida após um num, por exemplo 9e9,.
CAD97
Isso é mais longo que minha resposta Java ! Como podemos remediar isso? Observe que a reversão da comparação de n%10==9para n%10<9não salva, pois o if não precisa de espaço nesta ordem.
CAD97
E volto a ver que o xsot criou uma versão muito mais curta do Python. Bem feito!
CAD97
2

Jolf, 32 bytes

Ώ?H?<γ%Ht9P."452331541"γ+2Ώc/Ht2

Experimente aqui!

Explicação

Esta é uma transpilação da resposta de Neil.

Ώ?H?<γ%Ht9P."452331541"γ+2Ώc/Ht2
Ώ                                 define a function Ώ of H
 ?H                            2  (when H is zero, return is 2)
      %Ht                         H mod 10
     γ                            γ = ^
   ?<    9                        is it less than 9?
                                  if so:
           ."452331541"γ           get the γth element of that string
          P                        as a number
                                  else
                        +2         add two to
                          Ώ        Ώ over
                           c/Ht    int(H / 10)
Conor O'Brien
fonte
2

Pitão - 78 30 27 bytes

Aquele primeiro foi embaraçoso.

s@LjC"
(J"ThC{I#.tjRThBQT

Conjunto de Teste .

Maltysen
fonte
26 bytes
Freira vazada
26 bytes
Freira vazada
0

J, 53 bytes

2:`((2+10$:@<.@%~[)`(6|3045058<.@%6^])@.(9>])10&|)@.*

Originalmente baseado na solução da @ Neil . Em seguida, aprimorou-se ao salvar um byte usando a mesma fórmula no @ Lynn solução .

A versão de 54 bytes baseada na string é

2:`((2+10$:@<.@%~[)`('452331541'".@{~])@.(9>])10&|)@.*

Uso

   f =: 2:`((2+10$:@<.@%~[)`(6|3045058<.@%6^])@.(9>])10&|)@.*
   f 1999
11
   f 1999 12345 999999 5699999 8765210248
11 1 14 15 1
milhas
fonte
0

Retina , 34 bytes

M!`.9*$
^9
0
T`d`4523315412
.
$*
.

Experimente online!(A primeira linha apenas permite o processamento de vários casos de teste de uma só vez.)

Explicação

Como a maioria das respostas já descobriu até agora, não precisamos usar a tabela completa, pois apenas os menos significativos9 alterações ao incrementar. É também assim que essa resposta funciona.

M!`.9*$

Isso corresponde ( M) ao regex, .9*$ou seja, o primeiro dígito separado apenas por9 s do final. O !diz à Retina para substituir a entrada por essa correspondência, descartando tudo o que não afeta o 7SD.

^9
0

Se a entrada agora começa com um 9que significa, a entrada em si consistia apenas de 9s, portanto, a exibição de 7 segmentos precisa preceder a 1que custos 2. A maneira mais simples de lidar com isso é substituir a liderança 9neste caso por a 0, uma vez que o custo de incrementar a 9(to 0) é 2e o custo de incrementar 0(to 1) é4 , portanto, isso aumenta o custo geral 2conforme necessário.

T`d`4523315412

Agora temos um estágio de transliteração que substitui cada dígito pelo seu custo para incrementá-lo (já que o dexpande para 0123456789). Observe que este é o primeiro subdiagonal da tabela 7SD.

.
$*

Isso substitui cada dígito nporn cópias de 1, ou seja, converte cada dígito em unário e, como não há separadores, os adiciona imediatamente.

.

Finalmente, contamos o número de caracteres (ou seja, número de correspondências de .) no resultado, que converte a soma unária de volta em decimal.

Martin Ender
fonte