Différences sur 7 segments

26

Je pense que la plupart des gens d'ici savent ce qu'est un affichage à 7 segments pour les chiffres:

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

Nous pouvons définir la différence à 7 segments (7SD) entre deux chiffres comme étant le nombre de segments qui doivent être basculés pour passer de l'un à l'autre. Par exemple, le 7SD entre 1et 2est 5 (les trois segments horizontaux et les deux segments verticaux inférieurs doivent être basculés), et le 7SD entre 6 et 8 est 1 .

De plus, nous pouvons définir le 7SD entre deux nombres comme étant la somme des 7SD entre leurs chiffres correspondants. Si un nombre est plus long que l'autre, nous supposons qu'ils sont alignés à droite et ajoutons le nombre de segments nécessaires pour afficher les chiffres supplémentaires les plus significatifs du plus grand nombre. Par exemple, considérons le 7SD entre 12345et 549:

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

Votre tâche consiste à calculer 7SD entre n et n + 1 , étant donné n .

Pour plus de commodité, voici le tableau complet des 7SD entre les chiffres individuels. La ligne _représente une position vide.

   _ 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

Contribution

  • L'entrée est un seul entier positif n.
  • Vous pouvez écrire un programme ou une fonction, en prenant des entrées via STDIN (ou l'alternative la plus proche), un argument de ligne de commande ou un argument de fonction.
  • Vous pouvez supposer que l'entrée est au plus un de moins que le plus grand nombre qui peut être représenté par le type entier standard de votre langue, tant que ce type prend en charge au moins des valeurs allant jusqu'à 127 inclus.

Sortie

  • Vous devez imprimer un seul entier, le 7SD entre net n+1.
  • Vous pouvez sortir via STDOUT (ou l'alternative la plus proche), la valeur de retour de fonction ou l'argument de fonction (out).

Notation

Les règles de standard s'appliquent, le code le plus court (en octets) l'emporte.

Cas de test

Pour une raison obscure, cette séquence n'est pas encore dans OEIS, bien qu'il existe la séquence étroitement liée A123587 . Voici les 100 premiers chiffres (commençant par 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 première entrée pour laquelle le 7SD est supérieur à 9 est celle 1999qui devrait donner 11. Voici quelques autres exemples plus importants:

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

Réponses:

8

Gelée , 25 22 21 20 octets

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

Essayez-le en ligne! ou vérifiez tous les cas de test .

Contexte

Nous incrémentons d'abord l'entrée n et éliminons tous les chiffres de n + 1 qui n'ont pas changé.

Par exemple, si n est 5699999 , nous obtenons ce qui suit.

n     : 5700000
n + 1 : 5699999
Result:  700000

Tous les chiffres de ce résultat ont un nombre fixe de segments qui doivent être basculés. Nous pouvons convertir la liste des bascules en base bijective 5 pour économiser quelques octets.

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

La sortie est simplement la somme des bascules individuelles.

Cela fonctionne pour la plupart des valeurs de n , mais une attention particulière doit être prise si n + 1 a plus de chiffres que n . Dans ce cas, tous les chiffres doivent être 9 , et nous résolvons ce problème en coupant un 0 de fin de n + 1 .

Par exemple, si n est 999999 , nous obtenons ce qui suit.

n     :  999999
n + 1 : 1000000
Result: 100000

Cela fonctionne parce que le premier 1 est évalué à 4 bascules (distance entre 0 et 1 ), tandis que le nombre réel de bascules est de 2 (distance entre 0 et 1 ), et la suppression d'un 0 à la fin supprime ses 2 bascules de la somme.

Comment ça marche

‘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
la source
10

JavaScript (ES6), 46 40 octets

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

Formulation alternative, également 46 40 octets:

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

Edit: 6 octets enregistrés grâce à @xsot.

Neil
la source
Si l'opérateur logique ou dans ES6 se comporte comme celui de python, vous pouvez raccourcir davantage votre deuxième code. Référez-vous à ma soumission pour un exemple.
xsot
@xsot En fait, je peux raccourcir les deux! Je ne pense pas que cela m'aide à changer le cas spécial zéro car il ne s'agit que de 4 octets.
Neil
Wow, je suis surpris que le premier fonctionne. Je m'attendais à une erreur.
xsot
@xsot javascript ne fait pas que des erreurs. Il fait tout ce qui semblait être l'approche la plus correcte pendant ces dix jours de la naissance de Javascript. . Les versions ultérieures vous permettent d'adopter un comportement un peu plus strict, mais pourquoi quelqu'un ici ferait-il cela? Le comportement de court-circuit des opérateurs logiques est assez courant, cependant, seul PHP fait la mauvaise chose en renvoyant toujours un booléen.
John Dvorak
@JanDvorak En fait, j'ai été surpris par le fait que vous pouvez accéder à un index d'une chaîne plus grand que la longueur de la chaîne.
xsot
10

Python, 50 48 octets

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

Explication

Cette fonction fonctionne sur le chiffre le moins significatif du nombre n, en additionnant le 7SD des chiffres lorsqu'il est incrémenté de un jusqu'à la fin du premier non- 9chiffre.

26523308est un masque de bits qui code le mappage des chiffres 0-8. Lorsque n=0, ce qui ne se produit que lorsque nne comprend que 9s, la réponse sera désactivée par deux. Ceci est compensé par l'expression 0**n*2. Quant au chiffre 9, le bitmask est évalué à zéro, ce qui déclenchera l'appel récursif lors de l'ajout 2au 7SD.

xsot
la source
Pouvons-nous avoir une explication de la façon dont cela se transforme? Je veux dire, +1 pour l'intelligence mais je me suis perdu dans l'intelligent.
CAD97
8

05AB1E , 31 30 28 27 26 octets

Code:

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

Explication ( obsolète ):

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

Nous modifions ce qui suit au dernier chiffre non 9:

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

Pour les cas particuliers:

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

Utilise l' encodage CP-1252 . Essayez-le en ligne! .

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

Adnan
la source
3

MATL , 61 39 36 octets

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

Essayez-le en ligne!

Explication

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
la source
3

Julia, 44 octets

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

Essayez-le ici.

Dennis a sauvé un octet!

Lynn
la source
1
Par curiosité, pourquoi ne pas simplement utiliser les chiffres?
Conor O'Brien
Je ne peux pas croire qu'il y ait un Julia TIO. Welp, il est temps d'apprendre Julia alors ...
Mama Fun Roll
3

Python, 71 66 octets

48 octets par xsot . Encore plus de maths magiques!

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

Voir sur ideone

Parce que la réponse Python précédente ne fonctionne pas et est loin d'être optimale. Un simple port d' une précédente version ES6 . Maintenant, utilisez le bit twiddling (de la formulation alternative ES6) pour découper un plâtre!

Peut être fait fonctionner avec Python 3 en utilisant explicitement floordiv pour +1 octet.

CAD97
la source
vous pouvez retirer l'espace après9
Maltysen
@Maltysen, vous avez apparemment raison. Je pensais que ce serait erreur , car eune lettre valide après un num, par exemple, 9e9.
CAD97
C'est plus long que ma réponse Java ! Comment y remédier? Notez que l'inversion de la comparaison de n%10==9à n%10<9n'enregistre pas car if n'a pas besoin d'espace dans cet ordre.
CAD97
Et je reviens pour voir que xsot a fait une version Python beaucoup plus courte. Bien joué!
CAD97
2

Jolf, 32 octets

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

Essayez-le ici!

Explication

Ceci est une transpilation de la réponse 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
la source
2

Pyth - 78 30 27 octets

Ce premier était embarrassant.

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

Suite de tests .

Maltysen
la source
26 octets
Leaky Nun
26 octets
Leaky Nun
0

J, 53 octets

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

Initialement basé sur la solution de @ Neil . Amélioré ensuite en enregistrant un octet en utilisant la même formule dans la solution de @ Lynn .

La version de 54 octets basée sur la chaîne est

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

Usage

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

Rétine , 34 octets

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

Essayez-le en ligne!(La première ligne permet simplement le traitement de plusieurs cas de test à la fois.)

Explication

Comme la plupart des réponses l'ont découvert, nous n'avons pas besoin d'utiliser le tableau complet, car seuls les changements non 9numériques les moins significatifs changent lors de l'incrémentation. C'est aussi ainsi que cette réponse fonctionne.

M!`.9*$

Cela correspond à ( M) l'expression régulière, .9*$c'est-à-dire le premier chiffre qui n'est séparé que par 9s de la fin. Le !dit à Retina de remplacer l'entrée par cette correspondance, en rejetant tout ce qui n'affecte pas le 7SD.

^9
0

Si l'entrée commence maintenant par ce 9qui signifie, l'entrée elle-même n'était composée que de 9s, de sorte que l'affichage à 7 segments doit ajouter un 1qui coûte 2. La manière la plus simple de gérer cela est de remplacer le début 9dans ce cas par un 0, car le coût de l'incrémentation de a 90) est 2et le coût de l'incrémentation 01) est 4, donc cela augmente le coût global selon 2les besoins.

T`d`4523315412

Nous avons maintenant une étape de translittération qui remplace chaque chiffre par son coût pour l'incrémenter (puisque le se ddéveloppe en 0123456789). Notez qu'il s'agit de la première sous-diagonale du tableau 7SD.

.
$*

Cela remplace chaque chiffre npar des ncopies de 1, c'est-à-dire qu'il convertit chaque chiffre en unaire, et puisqu'il n'y a pas de séparateurs, il les ajoute immédiatement ensemble.

.

Enfin, nous comptons le nombre de caractères (c'est-à-dire le nombre de correspondances de .) dans le résultat, qui convertit la somme unaire en décimale.

Martin Ender
la source