Diferencias de 7 segmentos

26

Creo que la mayoría de las personas de por aquí saben lo que es una pantalla de 7 segmentos para dígitos:

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

Podemos definir la diferencia de 7 segmentos (7SD) entre dos dígitos para que sea el número de segmentos que deben alternarse para cambiar de uno a otro. Por ejemplo, el 7SD entre 1y 2es 5 (los tres segmentos horizontales y los dos segmentos verticales inferiores deben alternarse), y el 7SD entre 6 y 8 es 1 .

Además, podemos definir el 7SD entre dos números para que sea la suma de 7SD entre sus dígitos correspondientes. Si un número es más largo que el otro, asumimos que están alineados a la derecha y agregamos el número de segmentos necesarios para mostrar los dígitos adicionales más significativos del número mayor. Como ejemplo, considere el 7SD entre 12345y 549:

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

Su tarea es calcular 7SD entre n y n + 1 , dado n .

Para mayor comodidad, aquí está la tabla completa de 7SD entre dígitos individuales. La fila _representa una posición vacía.

   _ 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

  • La entrada es un solo entero positivo n.
  • Puede escribir un programa o función, tomando datos a través de STDIN (o la alternativa más cercana), argumento de línea de comandos o argumento de función.
  • Puede suponer que la entrada es como máximo uno menos que el número más grande que puede ser representado por el tipo entero estándar de su idioma, siempre que ese tipo admita al menos valores hasta 127 inclusive.

Salida

  • Debe imprimir un solo entero, el 7SD entre ny n+1.
  • Puede enviar a través de STDOUT (o la alternativa más cercana), el valor de retorno de la función o el argumento de la función (fuera)

Tanteo

Se aplican las reglas estándar de , gana el código más corto (en bytes).

Casos de prueba

Por alguna oscura razón, esta secuencia aún no está en OEIS, aunque existe la secuencia estrechamente relacionada A123587 . Aquí están los primeros 100 números (comenzando con 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

La primera entrada para la cual el 7SD es mayor que 9 es la 1999que debería producir 11. Aquí hay algunos otros ejemplos más grandes:

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

Respuestas:

8

Jalea , 25 22 21 20 bytes

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

Pruébalo en línea! o verificar todos los casos de prueba .

Fondo

Primero incrementamos la entrada n y descartamos todos los dígitos de n + 1 que no han cambiado.

Por ejemplo, si n es 5699999 , obtenemos lo siguiente.

n     : 5700000
n + 1 : 5699999
Result:  700000

Todos los dígitos en este resultado tienen un número fijo de segmentos que deben alternarse. Podemos convertir la lista de conmutadores a la base biyectiva 5 para guardar algunos bytes.

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

La salida es simplemente la suma de los conmutadores individuales.

Esto funciona para la mayoría de los valores de n , pero se debe tener especial cuidado si n + 1 tiene más dígitos que n . En este caso, todos los dígitos deben ser 9 , y resolvemos este problema cortando un 0 al final de n + 1 .

Por ejemplo, si n es 999999 , obtenemos lo siguiente.

n     :  999999
n + 1 : 1000000
Result: 100000

Esto funciona porque el 1 inicial se evalúa en 4 conmutaciones (distancia entre 0 y 1 ), mientras que la cantidad real de conmutaciones es 2 (distancia entre 0 y 1 ), y al suprimir un 0 final elimina su 2 conmutadores de la suma.

Cómo 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
fuente
10

JavaScript (ES6), 46 40 bytes

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

Formulación alternativa, también 46 40 bytes:

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

Editar: Guardado 6 bytes gracias a @xsot.

Neil
fuente
Si el lógico o el operador en ES6 se comporta como el de Python, puede acortar aún más su segundo código. Consulte mi presentación para ver un ejemplo.
xsot
@xsot ¡En realidad puedo acortar ambos! No creo que me ayude a cambiar el caso especial de cero porque solo son 4 bytes.
Neil
Wow, me sorprende que el primero funcione. Esperaba un error
xsot
@xsot javascript no simplemente elimina el error. Simplemente hace lo que parecía el enfoque más correcto durante esos diez días que nació Javascript. . Las versiones posteriores le permiten optar por un comportamiento un poco más estricto, pero ¿por qué alguien aquí haría eso? Sin embargo, el comportamiento de cortocircuito de los operadores lógicos es bastante común, solo PHP hace lo incorrecto al devolver siempre un valor booleano.
John Dvorak
@ JanDvorak En realidad, me sorprendió el hecho de que puede acceder a un índice de una cadena más grande que la longitud de la cadena.
xsot
10

Python, 50 48 bytes

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

Explicación

Esta función opera en el dígito menos significativo del número n, sumando el 7SD de los dígitos cuando se incrementa en uno hasta después del primer no 9dígito.

26523308es una máscara de bits que codifica la asignación de los dígitos 0-8. Cuando n=0, que solo ocurre cuando ncomprende solo 9s, la respuesta se desactivará en dos. Esto se compensa con la expresión 0**n*2. En cuanto al dígito 9, la máscara de bits se evalúa a cero, lo que activará la llamada recursiva mientras se agrega 2al 7SD.

xsot
fuente
¿Podemos tener alguna explicación de cómo esto hace la transformación? Quiero decir, +1 por inteligencia, pero me perdí en la inteligencia.
CAD97
8

05AB1E , 31 30 28 27 26 bytes

Código:

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

Explicación ( obsoleta ):

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 cambiando lo siguiente al último dígito que no sea 9:

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

Para los casos especiales:

                ¹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)

Utiliza la codificación CP-1252 . Pruébalo en línea! .

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

Adnan
fuente
3

MATL , 61 39 36 bytes

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

Pruébalo en línea!

Explicación

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
fuente
3

Julia, 44 bytes

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

Pruébalo aquí

¡Dennis salvó un byte!

Lynn
fuente
1
Por curiosidad, ¿por qué no solo usar los números?
Conor O'Brien
No puedo creer que haya un Julia TIO. Welp, hora de aprender Julia entonces ...
Mama Fun Roll
3

Python, 71 66 bytes

48 bytes por xsot . ¡Aún más matemáticas mágicas!

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

Véalo en ideone

Porque la respuesta anterior de Python no funciona y está lejos de ser óptima. Un puerto simple de una versión ES6 anterior . ¡Ahora usando un poco de giro (de la formulación alternativa ES6) para cortar un yeso!

Se puede hacer que funcione con Python 3 usando explícitamente floordiv para +1 byte.

CAD97
fuente
puedes sacar el espacio después9
Maltysen
@Maltysen aparentemente tienes razón. Pensé que iba a error porque ees una carta válida después de un num en, por ejemplo, 9e9.
CAD97
¡Esto es más largo que mi respuesta Java ! ¿Cómo podemos remediar esto? Tenga en cuenta que revertir la comparación den%10==9 a n%10<9no se guarda ya que el if no necesita un espacio en este orden.
CAD97
Y vuelvo para ver que xsot ha hecho una versión de Python mucho más corta. ¡Bien hecho!
CAD97
2

Jolf, 32 bytes

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

Pruébalo aquí!

Explicación

Esta es una traducción de la respuesta 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
fuente
0

J, 53 bytes

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

Originalmente basado en la solución de @ Neil . Luego se mejoró guardando un byte usando la misma fórmula en la solución de @ Lynn .

La versión de 54 bytes basada en la cadena es

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
millas
fuente
0

Retina , 34 bytes

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

Pruébalo en línea!(La primera línea solo permite el procesamiento de múltiples casos de prueba a la vez).

Explicación

Como la mayoría de las respuestas han descubierto hasta ahora, no necesitamos usar la tabla completa, ya que solo los 9cambios sin dígitos menos significativos al incrementar. Así es también como funciona esta respuesta.

M!`.9*$

Esto coincide ( M) con la expresión regular, .9*$es decir, el primer dígito que solo está separado por 9s desde el final. El !le dice a Retina que reemplace la entrada con esta coincidencia, descartando todo lo que no afecta el 7SD.

^9
0

Si la entrada ahora comienza con un 9eso, la entrada en sí consistió solo en 9s, por lo que la pantalla de 7 segmentos debe anteponer un 1costo 2. La forma más sencilla de manejar esto es reemplazar el líder 9en este caso con a 0, ya que el costo de incrementar a 9(to 0) es 2y el costo de incrementar 0(to 1) es 4, por lo que aumenta el costo general según 2sea ​​necesario.

T`d`4523315412

Ahora tenemos una etapa de transliteración que reemplaza cada dígito con su costo para incrementarlo (ya que se dexpande a 0123456789). Tenga en cuenta que este es el primer subdiagonal de la tabla 7SD.

.
$*

Esto reemplaza cada dígito ncon ncopias de 1, es decir, convierte cada dígito en unario, y dado que no hay separadores, los agrega de inmediato.

.

Finalmente, contamos el número de caracteres (es decir, número de coincidencias de .) en el resultado, que convierte la suma unaria de nuevo a decimal.

Martin Ender
fuente