Générer des numéros adaptés au clavier

29

Les dispositions de clavier d' ordinateur les plus courantes ont les touches numériques décimales

1234567890

courir en haut, au-dessus des touches des lettres.

Supposons que le voisinage d' un chiffre décimal soit l'ensemble des chiffres de sa propre clé numérique et des clés numériques immédiatement à gauche et à droite, si elles existent.

Par exemple, le voisinage de 0 est {0, 9}, et le voisinage de 5 est {4, 5, 6}.

Maintenant, définissez un nombre convivial pour le clavier comme un entier positif (sous forme décimale sans zéros de tête) qui peut être tapé dans la disposition ci-dessus de telle sorte que chaque chiffre consécutif du numéro après le premier chiffre se trouve au voisinage du chiffre précédent.

  • Tous les numéros à un chiffre (1-9) sont faciles à utiliser sur le clavier.

  • Un nombre tel que 22321 est compatible avec le clavier car chaque chiffre (sans compter le premier) se trouve dans le voisinage du chiffre juste avant.

  • Un nombre tel que 1245 n'est pas compatible avec le clavier car 4 n'est pas dans le voisinage de 2 (ni vice versa).

  • Un nombre tel que 109 n'est pas compatible avec le clavier car 0 n'est pas dans le voisinage de 1. Les extrémités ne bouclent pas.

En mettant les numéros conviviaux du clavier du plus petit au plus grand, nous pouvons créer une séquence entière .

Voici les 200 premiers termes de la séquence de nombres conviviaux pour le clavier:

N KFN(N)
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 11
11 12
12 21
13 22
14 23
15 32
16 33
17 34
18 43
19 44
20 45
21 54
22 55
23 56
24 65
25 66
26 67
27 76
28 77
29 78
30 87
31 88
32 89
33 90
34 98
35 99
36 111
37 112
38 121
39 122
40 123
41 211
42 212
43 221
44 222
45 223
46 232
47 233
48 234
49 321
50 322
51 323
52 332
53 333
54 334
55 343
56 344
57 345
58 432
59 433
60 434
61 443
62 444
63 445
64 454
65 455
66 456
67 543
68 544
69 545
70 554
71 555
72 556
73 565
74 566
75 567
76 654
77 655
78 656
79 665
80 666
81 667
82 676
83 677
84 678
85 765
86 766
87 767
88 776
89 777
90 778
91 787
92 788
93 789
94 876
95 877
96 878
97 887
98 888
99 889
100 890
101 898
102 899
103 900
104 909
105 987
106 988
107 989
108 990
109 998
110 999
111 1111
112 1112
113 1121
114 1122
115 1123
116 1211
117 1212
118 1221
119 1222
120 1223
121 1232
122 1233
123 1234
124 2111
125 2112
126 2121
127 2122
128 2123
129 2211
130 2212
131 2221
132 2222
133 2223
134 2232
135 2233
136 2234
137 2321
138 2322
139 2323
140 2332
141 2333
142 2334
143 2343
144 2344
145 2345
146 3211
147 3212
148 3221
149 3222
150 3223
151 3232
152 3233
153 3234
154 3321
155 3322
156 3323
157 3332
158 3333
159 3334
160 3343
161 3344
162 3345
163 3432
164 3433
165 3434
166 3443
167 3444
168 3445
169 3454
170 3455
171 3456
172 4321
173 4322
174 4323
175 4332
176 4333
177 4334
178 4343
179 4344
180 4345
181 4432
182 4433
183 4434
184 4443
185 4444
186 4445
187 4454
188 4455
189 4456
190 4543
191 4544
192 4545
193 4554
194 4555
195 4556
196 4565
197 4566
198 4567
199 5432
200 5433

Défi

Écrivez un programme ou une fonction qui prend un entier positif N (via stdin / ligne de commande / fonction arg) et imprime (vers stdout) ou renvoie le Nième terme dans la séquence de nombres conviviaux pour le clavier.

Par exemple, si l'entrée est 191, la sortie doit l'être 4544.

La sortie peut éventuellement avoir une seule nouvelle ligne de fin.

La soumission la plus courte en octets l'emporte.

Loisirs de Calvin
la source
7
Fait aléatoire: OEIS a une séquence connexe pour les pavés numériques
Sp3000
Merci, @ Sp3000. Je suis descendu ici pour me demander cette chose.
luser droog

Réponses:

8

Pyth, 27 24 octets

uf!f/h-FY3.:metsd`T2hGQ0

Manifestation.

Améliorations par rapport à l'original:

  • Utilisation metd, au lieu de .r ... _UJ: 2 octets de moins. 1 direct, 1 pour ne pas avoir à utiliser J.

  • Utiliser set `Tau lieu de JT10: 1 octet de moins.


Nous commençons par la représentation de chaîne d'un nombre: `T.

Ensuite, nous convertissons la chaîne en une liste de chiffres et tournons les chiffres d'un chiffre vers l'arrière, (9876543210) avec metsd. Ensuite, nous prenons les 2 sous-séquences d'éléments avec .: ... 2. Ces sous-séquences sont filtrées /h-FY3. Cette expression correspond à ((a-b)+1)/3, qui est nulle si et seulement si la différence entre aet best au plus 1. Ainsi, la liste filtrée sera vide si et seulement si le numéro est compatible avec le clavier. Avec !, le résultat n'est vrai que si le numéro est compatible avec le clavier.

f ... hGfiltre vers le haut depuis G+1jusqu'à ce que le résultat soit vrai, donnant le premier numéro convivial au clavier égal G+1ou supérieur. u ... Q0applique cette fonction à ses propres Qtemps de sortie , à partir de 0, où Qest l'entrée. Cela donne le Qnuméro du clavier, comme vous le souhaitez.

isaacg
la source
4

Python 3, 112 102 octets

f=lambda n,k=0:n+1and f(n-all(-2<~-int(a)%10-~-int(b)%10<2for a,b in zip(str(k),str(k)[1:])),k+1)or~-k

Nous gardons une trace du nombre de numéros amis encore nécessaires pour trouver net du dernier numéro enregistré k.

5 et 5 octets enregistrés grâce à @isaacg et @ Sp3000.

randomra
la source
Utilisez une expression lamba au lieu d'un retour def. Les lambas autorisent les valeurs par défaut.
isaacg
@isaacg Merci, je ne savais pas comment soigner avec lambda.
randomra
Ah oui. Les opérations unaires viennent en premier. Mon erreur.
mbomb007
Vous pouvez laisser tomber le [:-1]dans lezip
SP3000
4

CJam, 29 28 octets

ri_4#{AbAfe|_1>.-W<3,:(-!},=

Essayez-le en ligne dans l' interpréteur CJam .

Dennis
la source
Existe-t-il une preuve simple que la limite supérieure du N-ème nombre convivial est N ** 2
Optimizer
Je n'en ai pas encore trouvé. La preuve N ** 4est assez simple, car il y a au moins 2 ** kKFN ci-dessous 10 ** k < 16 ** k. Le remplacement _*par 4#ne modifierait pas le nombre d'octets, mais cela rendrait le code horriblement inefficace.
Dennis
Alors, votre code n'est-il pas incorrect pour un grand nombre d'entrée?
Optimizer
1
Heureusement non. Mais je vais le changer jusqu'à ce que je sache. grogne
Dennis
3

CJam, 34 31 octets

3 octets enregistrés par Dennis.

Je suis sûr que l'écart avec Pyth peut être fermé d'une manière ou d'une autre, mais je n'ai pas le temps pour le moment de jouer au golf plus loin ...

0q~{{)_s:_2ew{A,s(+f#~m2/},}g}*

Testez-le ici.

Martin Ender
la source
Vous pouvez remplacer )_++par :_pour enregistrer 2 caractères et -z1>par m2/pour en enregistrer un autre.
Dennis
@Dennis Oh, c'est sympa, merci!
Martin Ender
3

JavaScript (ES6), 95

F=k=>{for(i=0;k;k-=(f=1,p=NaN,[for(d of''+i)(d=(8-~d)%10,d-p>1|p-d>1?f=0:p=d)],f))++i;return i}

Non golfé

F=k=>{
  for(i=0; k>0; )
  {
    ++i;
    f = 1; // presume i it's friendly
    p = NaN; // initial value so that first comparison gives false
    for(d of ''+i) // loop for each digit of i
    {
      // rotate digits 1->0, 2->1 ... 9->8, 0->9
      // note d is string, ~~ convert to number (golfed: 8-~d)
      d = (~~d+9) % 10 
      if (p-d>1 || p-d<-1) 
        f = 0 // not friendly
      else 
        // this can go in the 'else', if not friendly I don't care anymore
        p = d // move current digit to prev digit
    }
    k -= f // count if it's friendly, else skip
  }
  return i
}

Test : exécutez l'extrait dans Firefox

edc65
la source
Je ne connais pas beaucoup JS, mais ne pourriez-vous pas faire quelque chose comme abs(p-d)>1plutôt que p-d>1|p-d<-1?
Alex A.
@AlexA. Les expressions développées et golfées sont équivalentes. Math.abs(p-d)>1est plus long quep-d>1|p-d<-1
edc65
Ah ok. Je savais qu'ils étaient équivalents, je ne savais tout simplement pas que vous aviez besoin du Math.préfixe.
Alex A.
2

Haskell, 90 80 octets

([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 

Il s'agit d'une fonction sans nom. Pour l'utiliser, appelez-le avec un paramètre, par exemple: ([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199qui renvoie 5432.

Comment ça marche:

[x|x<-[0..]           ]  make a list of all integers x starting with 0
           ,             where
             c<-show x   each character in the string representation of x
  mod(1+fromEnum c)10    turned into the number '(ascii+1) mod 10'
 zipWith(-)=<<tail       then turned into a list of differences between neighbor elements
all((<2).abs)            only contains elements with an absolute value less than 2


                   !!    ... take the element given by the parameter (!! is 0 
                         based, that's why I'm starting the initial list with 0)

Edit: @Mauris a trouvé quelques octets à enregistrer. Merci!

nimi
la source
Au lieu de x<-[1..]... !!n-1, vous pouvez le faire x<-[0..]... !!n.
Lynn
Et puis bien sûr f n=[...]!!npeut être f=([...]!!).
Lynn
Je l'ai réduit à une seule fonction, éliminant a:f=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
Lynn
@Mauris: wow, merci! Sans cela, anous pouvons aussi éliminer f.
nimi
2

Fléchette, 92 octets

f(n,[x=0]){t(x)=>x>9?((x+9)%10-((x~/=10)+9)%10).abs()>1||t(x):--n>0;while(t(++x));return x;}

Avec les sauts de ligne:

f(n,[x=0]){
  t(x)=>x>9?((x+9)%10-((x~/=10)+9)%10).abs()>1||t(x):--n>0;
  while(t(++x));  
  return x;
}

Voir / exécuter sur DartPad

lrn
la source
1

Lot - 520 octets

Frémir.

@echo off&setLocal enableDelayedExpansion&set a=0&set b=0
:a
set/ab+=1&set l=0&set c=%b%
:b
if defined c set/Al+=1&set "c=%c:~1%"&goto b
set/am=l-2&set f=0&for /l %%a in (0,1,%m%)do (
set x=!b:~%%a,1!&set/an=%%a+1&for %%b in (!n!)do set y=!b:~%%b,1!
set z=0&set/ad=x-1&set/ae=x+1&if !e!==10 set e=0
if !d!==-1 set d=9
if !y!==!d! set z=1
if !y!==!e! set z=1
if !y!==!x! set z=1
if !y!==0 if !x!==1 set z=0
if !y!==1 if !x!==0 set z=0
if !z!==0 set f=1)
if !f!==0 set/aa+=1
if %a% NEQ %1 goto :a
echo %b%
dégrader
la source
1

Bash + coreutils, 120 octets

seq $1$1|tr 1-90 0-9|sed 's#.#-&)%B)/3)||(((C+&#g;s/^/(0*((/;s/$/))*0)/'|bc|nl -nln|sed '/1$/d;s/   0//'|sed -n "$1{p;q}"

Quelques tests:

$ for i in 1 10 11 99 100 200; do ./kfn.sh $i; done
1     
11    
12    
889   
890   
5433  
$ 
Traumatisme numérique
la source
0

JavaScript ES6, 126 octets

f=n=>{b=s=>[...++s+''].every((e,i,a,p=(+a[i-1]+9)%10)=>i?p==(e=+e?e-1:9)|p-e==1|e-p==1:1)?s:b(s)
for(p=0;n--;)p=b(p)
return p}

Code non testé et tests ci-dessous. Cela pourrait certainement être amélioré davantage.

f=function(n){
  b=function(s){
    return (s+'').split('').every(function(e,i,a){
      e=+e?e-1:9
      p=i?(+a[i-1]+9)%10:e
      return p==e|p-e==1|e-p==1
    })?s:b(s+1)
  }
  for(p=i=0;i<n;i++){
    p=b(p+1)
  }
  return p
}

var input = document.getElementById('n'), results = [];
input.onchange = function(){
  document.getElementById('s').innerHTML = f(input.value)
}
for(var i=0;i<200;i++){
  results.push(i + ':&nbsp;' + f(i))
}
document.getElementById('r').innerHTML=results.join('<br />')
N = <input type="number" id="n" min="1" value="191" /><br />
KBD(N) = <samp id="s">4544</samp>
<div id="r"></div>

NinjaBearMonkey
la source
0

Cobra - 135

Je ne l'ai pas fait depuis longtemps, mais voici:

def f(n,i=0)
    while n,if all for x in (s='[i+=1]').length-1get s[x+1]in' 1234567890'[(int.parse(s[x:x+1])+9)%10:][:3],n-=1
    print i

Non golfé:

def fn(n as int)
    i = 0
    while n <> 0
        i += 1
        s = i.toString
        l = s.length - 1
        v = true
        for x in l
            k = (int.parse(s[x].toString) + 9) % 10
            if s[x + 1] not in ' 1234567890'[k : k + 3], v = false
        if v, n -= 1
    print i
Οurous
la source
0

Pyth, 19 octets

e.f.AgL1.aM.+|RTjZT

Essayez-le ici.

Remarque: utilise un commit plus récent que ce défi, ne doit donc pas être considéré comme un sur-golf de la réponse d'isaacg. C'est toujours en compétition, cependant.

Erik le Outgolfer
la source