Générer des numéros compatibles avec le pavé numérique

22

Inspiré par la génération de numéros adaptés au clavier .

Contexte

De nombreux pavés numériques ont la disposition suivante:

789

456

123

    0    

Nous définissons le voisinage d'un nombre comme l'ensemble de cellules orthogonalement adjacentes à celui-ci sur le pavé numérique illustré, y compris lui-même. Par exemple, le quartier de 2 est {1,5,3,0,2}et le quartier de 0 est {1,2,0}. Il y a une liste des environs de chaque numéro ci-dessous, au-dessus des cas de test.

Nous définissons un nombre convivial du pavé numérique comme un entier positif où, lorsqu'il est écrit en décimal sans zéros non significatifs, chaque chiffre, à l'exception du premier, se trouve au voisinage du chiffre précédent.

Par exemple,

  • 7856 est un numéro convivial car 8 se trouve dans le quartier de 7, 5 dans le voisinage de 8 et 6 dans le quartier de 5.
  • 1201 est un nombre convivial du pavé numérique, car 2 se trouve dans le voisinage de 1, 0 est dans le voisinage de 2 et 1 est dans le voisinage de 0.
  • 82 n'est pas un numéro convivial car 2 n'est pas dans le voisinage de 8.
  • 802 n'est pas un numéro convivial car 0 n'est pas dans le voisinage de 8 (les quartiers ne s'enroulent pas).

Séquence OEIS associée . Notez que cette séquence associée est distincte car elle compte 0comme adjacente à la 7place de 1et 2.

Défi

Étant donné un entier positif n, retournez le n-ème ou les premiers nnombres compatibles avec le pavé numérique, où le premier est 1. Vous pouvez utiliser une indexation basée sur 0, où le 0-ème numéro compatible avec le pavé numérique serait 1.

Quartiers

Le quartier de chaque chiffre est répertorié ici:

0:{0,1,2}
1:{0,1,2,4}
2:{0,1,2,3,5}
3:{2,3,6}
4:{1,4,5,7}
5:{2,4,5,6,8}
6:{3,5,6,9}
7:{4,7,8}
8:{5,7,8,9}
9:{6,8,9}

Cas de test / séquence

Ce sont les 100 premiers termes

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 20, 21, 22, 23, 25, 32, 33, 36, 41, 44, 45, 47, 52, 54, 55, 56, 58, 63, 65, 66, 69, 74, 77, 78, 85, 87, 88, 89, 96, 98, 99, 100, 101, 102, 110, 111, 112, 114, 120, 121, 122, 123, 125, 141, 144, 145, 147, 200, 201, 202, 210, 211, 212, 214, 220, 221, 222, 223, 225, 232, 233, 236, 252, 254, 255, 256, 258, 320, 321, 322, 323, 325, 332, 333, 336, 363, 365, 366, 369, 410, 411, 412, 414, 441, 444, 445, 447]
fireflame241
la source
5
Je aime la façon dont ce défi ne tient compte que des nombres entiers positifs (qui maintient l'essence et permet plus de langues à participer) et permet d' afficher soit le n -ème ou les premiers n sorties de flexibilité
Luis Mendo
J'ai complètement mal lu le défi, voici un script "ce terme est-il valide dans la séquence": Essayez-le en ligne!
Magic Octopus Urn

Réponses:

9

JavaScript (ES6), 104 93 89 88 octets

Renvoie le N-ème terme de la séquence, indexé 1.

f=(i,k,n=k,N=n/5>>1)=>(N?8530025>>(n%10*6191^N%10*6191)%26&1:!i--)?N?f(i,k,N):k:f(i,-~k)

Démo

Arnauld
la source
Le mieux que j'aie pu obtenir est 151 k=(n,a=1)=>n?k(n-([...(x=a+[]).slice(0,-1)].reduce((a,c)=>a*!!~"012 0124 01235 236 1457 24568 3569 478 5789 689".split` `[c].indexOf(x[i++]),i=1)),a+1):a-1peut-être quelque chose aide, mon test est probablement trop long
Conor O'Brien
Cette réponse amène le concept des nombres magiques à un tout nouveau niveau ... Je ne comprends même pas comment vous les avez trouvés o_O
scottinet
2
@ scottinet Dans une large mesure, mon explication de cette réponse s'applique également à celle-ci. La différence absolue ne fonctionnait pas très bien sur celui-ci, j'ai donc essayé avec XOR à la place. En remarque, j'ai trouvé une autre formule qui a fonctionné dans 96% des cas sans avoir besoin d'un masque de bit de recherche. Mais le traitement des 4% restants séparément était trop coûteux dans JS. Je n'ai pas essayé dans Jelly , et maintenant je ne me souviens plus de la formule de toute façon ... ¯ \ _ (ツ) _ / ¯
Arnauld
Merci pour les explications. C'est toujours impressionnant :-)
scottinet
4

Perl 5 , 123 + 1 (-p) = 124 octets

while($_){$r=@d=++$\=~/./g;map$r&&=(120,1240,12350,236,1457,24568,3569,478,5789,689)[$d[$_-1]]=~/$d[$_]/,1..$#d;$r&&$_--}}{

Essayez-le en ligne!

Xcali
la source
3

Gelée , 27 24 octets

Renvoie les N premiers termes de la séquence.

D⁽ÞȦ×^2\%26“⁷wð’æ»ḂẠ
1Ç#

Essayez-le en ligne!

Ceci est un port de ma réponse JS .

D⁽ÞȦ×^2\%26“⁷wð’æ»ḂẠ    - helper link: test numpad-friendliness of a number, e.g. 1257
D                       - get decimal digits             -> [1, 2, 5, 7]
    ×                   - multiply by ...
 ⁽ÞȦ                    - ... the integer 6191           -> [6191, 12382, 30955, 43337]
     ^2\                - bitwise XOR overlapping reduce -> [10353, 18613, 53666]
        %26             - modulo 26                      -> [5, 23, 2]
                æ»      - right-shift by each value ...
           “⁷wð’        - ... the integer 8530025        -> [266563, 1, 2132506]
                  Ḃ     - isolate the LSB                -> [1, 1, 0] which means that 1->2
                                                            and 2->5 are OK and 5->7 is not
                   Ạ    - all (0 if there's any 0)       -> 0, i.e. not numpad-friendly :'(

1Ç#                     - main link: return the [input] first matching numbers,
                          using our helper link as a monad and starting with 1
Arnauld
la source
3

05AB1E , 24 23 octets

µNSü‚εW_iO<ë<3BÆ}ÄR2‹}P

Essayez-le en ligne!

Renvoie le nième nombre de la séquence.

Explications:

µNSü‚εW_iO<ë<3BÆ}ÄR2‹}P    Full program
µ                          Until counter is equal to input
 N                         Push current iteration number (e.g. 1025)
  S                        Split to a list of chars (-> ['1', '0', '2', '5'])
   ü‚                      Group into pairs (-> ['1', '0'], ['0', '2'], ['2', '5'])
     ε                     For each pair
      W_                      Is smallest digit equal to 0?
        iO<                      True: sum all digits and decrement 
           ë                     False: 
            <                       - decrement all digits
             3B                     - convert to base 3
               Æ                    - reduced substraction
                }             End if
                 Ä            Absolute value
                  R           Reverse 
                   2‹         1 if result is < 2, 0 otherwise
                     }     End for each
                      P    Cumulative product (1 if all pair results are 
                                     1, 0 otherwise)
                           -- implicit counter increment if stack value is 1

L'idée principale est que, outre la 0 clé, tout chiffre décrémenté et converti en base 3 a les propriétés suivantes:

  • les voisins gauche et droit ont une différence absolue de 1
  • les voisins de haut en bas ont une différence absolue de 10 qui, inversée, est commodément égale à 1
  • toute autre paire de touches du pavé numérique donne des valeurs différentes, même en cas d'inverse

Bien sûr, nous avons besoin d'une ifinstruction pour gérer la 0touche du pavé numérique.

scottinet
la source
Réponse solide, est venue offrir plus d'améliorations, n'en trouve pas. Oooo ... et cela vous met également en tête :).
Magic Octopus Urn
Je ne pense pas que j'aurais pu arriver à ces 3 règles, assez impressionnantes tbh; qu'est-ce qui vous a donné l'idée?
Magic Octopus Urn
2

MATL , 29 27 octets

`@J3:qEt!J*+hYAd|2>~A?@]NG-

Génère les premiers nnuméros compatibles avec le pavé numérique.

Essayez-le en ligne!

Explication

Chaque chiffre de 1à 9est codé comme un nombre complexe représentant sa position dans le pavé numérique, en utilisant dans une grille de l'étape 2, où la partie réelle représente la position verticale et la partie imaginaire représente la position horizontale. Ainsi 1est 0+0j, 2est 0+2j, 3est 0+4j, 4est 2+0j, ..., 9est4+4j .

Le chiffre 0est codé comme 0+1j, c'est-à-dire comme s'il était placé exactement entre 1et 2.

Pour chaque candidat numéro numpad convivial, une conversion de base « décimale » est appliquée en utilisant ce qui précède des nombres complexes au lieu des chiffres 0, 1..., 9. Cela donne un tableau, dont les différences consécutives absolues sont calculées. Le numéro de candidat est compatible avec le pavé numérique si et seulement si toutes les différences absolues sont au maximum 2(c'est-à-dire le pas de grille). Si c'est le cas, le numéro est laissé sur la pile.

Le code utilise une boucle do... while, qui est quittée lorsque le nombre de nombres dans la pile est égal à l'entrée n.

Une grille unitaire aurait été un choix plus naturel. Chiffres 1, 2et 0correspondraient alors 0+0j, 1+0jet 0.5+0jrespectivement. Mais il est plus judicieux d'utiliser une grille de l'étape 2, car multiplier par 2(fonction E) et pousser 0+1j(fonction J) est un octet plus court que pousser 0+0.5j( J2/ou .5j)

Luis Mendo
la source
2

Gelée , 26 octets

’d-,.⁸?3µ€ạ/S
Dṡ2Ç€<2Ạ
1Ç#

Essayez-le en ligne!

-2 octets grâce à caird coinheringaahing
-2 octets grâce à Erik the Outgolfer

Explication

’d-,.⁸?3µ€ạ/S  Helper Link; compute the distance between two keys z = [x, y]
      ?        Switch:
     ⁸         If z (is not 0):
’              Decrement
 d             Divmod by:
  -,.          Else: [-1, 0.5] (special position for 0)
       3       3; right argument for divmod otherwise ignored
        µ      Begin a new monadic link / end this link
         €     Compute the position for each [x, y]
           /   Reduce on
          ạ    Absolute Difference
            S  Sum (this gives the Manhattan Distance)
Dṡ2Ç€<2Ạ       Helper Link; determine if a number <z> is numpad friendly
D              Convert number to decimal digits
 ṡ             Slice into overlapping slices of length
  2            2 (pairs)
    €          For each pair,
   Ç           The distance between the keys
     <2        Compare with 2 (the distance between two adjacent keys is 1; corners 2; 0 - 1 and 0 - 2 are 1.5)
       Ạ       All; either all of the distances are less than 2 or there were no distances
1Ç#            Main Link; find the first (input) numpad friendly numbers
  #            nfind; counting up from _ collect the first _______ matches that are
1                                      1
                                                           (input)
 Ç             Numpad Friendly
HyperNeutrino
la source
Vous pouvez supprimer le []pour 2 octets
caird coinheringaahing
@cairdcoinheringaahing merci!
HyperNeutrino
1
Jouez au golf à deux.
Erik the Outgolfer
2

Python 2 , 134 octets

g=lambda n,k=1:n and g(n-(lambda l:all(abs(a-b)<1.2for a,b in zip(l,l[1:])))([~-d%3+~-d/3*1j-d/~d*1.5for d in map(int,`k`)]),k+1)or~-k

Essayez-le en ligne!

Lynn
la source
Lorsque vous le définissez f, puis l'utilisez une fois , vous pouvez l'intégrer et enregistrer deux octets .
Jonathan Frech
1

Mathematica, 249 234 202 octets

(a=o=1;While[a<=#,s=IntegerDigits@o;t=1;p=0;While[t+p<Length@s,If[!FreeQ[(IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986})[[s[[t]]+1]],s[[t+1]]],t++,p++]];If[t==Length@s,a++];o++];o-1)&


Essayez-le en ligne!

merci à user202729 pour la compression des données (-32 octets)

Mes résultats:

100 -> 447
1000 -> 20023
10000 -> 788777

J42161217
la source
Je pense que vous pouvez compresser les données en utilisant IntegerDigits: IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}et l' utilisation FreeQ, Tr, utilise au Dolieu de For, la notation utilisation infix pour AppendToet utiliser au Dolieu de Whilela répétition Tr[1^s]fois, éliminer également la variable p. De plus, vous n'avez pas prouvé que l'algorithme est correct, c'est-à-dire que le nombre résultant est toujours inférieur à son index au carré, ce qui est nécessaire pour valider une réponse.
user202729
1
@ user202729 J'ai changé beaucoup de choses. Ma réponse est définitivement valable. Je vais compresser les données maintenant.
J42161217
pourquoi le downvote?
J42161217
1

PHP, 124 + 1 octets

while($argn-=$r)for($p=$r=~0,$x=++$n;$x>=1;$p=[7,23,47,76,178,372,616,400,928,832][$c],$x/=10)$r&=!!($p&1<<$c=$x%10);echo$n;

Exécuter en tant que pipe avec -nRou l' essayer en ligne .

Titus
la source
0

Java 8, 192 190 octets

n->{int r=1,p;a:for(;n>0;){p=-1;for(int c:(r+++"").getBytes())if(p>-1&!"012;0124;01235;236;1457;24568;3568;478;5789;689".split(";")[c-=48].contains(p+""))continue a;else p=c;n--;}return~-r;}

Renvoie le nnuméro (indexé 1) dans la séquence.

C'était étonnamment plus difficile que je ne le pensais.

Explication:

Essayez-le ici.

n->{                 // Method with integer as both parameter and return-type
  int r=1,           //  Return-integer
      p;             //  Previous digit
  a:for(;n>0;){      //  Loop (1) as long as the input is larger than 0
    p=-1;            //   Start `p` at an integer that is not 0-9 (-1 in this case)
    for(int c:(r+++"").getBytes())
                     //   Loop (2) over the digits of the current number
      if(p>=0        //    If this is not the first digit (`p` != -1),
         &!"012;0124;01235;236;1457;24568;3568;478;5789;689".split(";")[c-=48]
           .contains(p+""))
                     //    and the adjacent digits are NOT part of a NumberPad-Friendly Nr:
        continue a;  //     Go to the next iteration of loop (1)
      else           //    Else:
        p=c;         //     Set `p` to the current digit for the next iteration
                     //   End of loop (2) (implicit / single-line body)
      n--;           //   If we haven't encountered the `continue`, decrease `n` by 1
  }                  //  End of loop (1)
  return~-r;         //  Return the result-integer - 1
}                    // End of method
Kevin Cruijssen
la source