Generar números amigables con el teclado

29

Los diseños de teclado de computadora más comunes tienen las teclas de dígitos decimales

1234567890

corriendo en su parte superior, por encima de las teclas para letras.

Deje que la vecindad de un dígito decimal sea ​​el conjunto de dígitos de su propia clave de dígitos y de las teclas de dígitos inmediatamente a la izquierda y a la derecha, si existen.

Por ejemplo, el vecindario de 0 es {0, 9}y el vecindario de 5 es {4, 5, 6}.

Ahora, defina un número compatible con el teclado como un entero positivo (en forma decimal sin ceros a la izquierda) que se pueda escribir en el diseño de arriba de modo que cada dígito consecutivo en el número después del primer dígito esté cerca del dígito anterior.

  • Todos los números de un solo dígito (1-9) son trivialmente amigables con el teclado.

  • Un número como 22321 es compatible con el teclado porque cada dígito (sin contar el primero) está cerca del dígito justo antes.

  • Un número como 1245 no es compatible con el teclado porque 4 no está cerca de 2 (ni viceversa).

  • Un número como 109 no es compatible con el teclado porque 0 no está cerca del 1. Los extremos no se repiten.

Al ordenar los números compatibles con el teclado de menor a mayor, podemos crear una secuencia de enteros .

Aquí están los primeros 200 términos de la secuencia de números amigables con el teclado:

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

Reto

Escriba un programa o función que tome un entero positivo N (a través de stdin / línea de comando / función arg) e imprima (a stdout) o devuelva el enésimo término en la secuencia de números amigables del teclado.

Por ejemplo, si la entrada es 191, la salida debería ser 4544.

La salida puede tener opcionalmente una nueva línea final.

La presentación más corta en bytes gana.

Pasatiempos de Calvin
fuente
77
Dato aleatorio: OEIS tiene una secuencia relacionada para los teclados numéricos
Sp3000
Gracias, @ Sp3000. Me desplacé hasta aquí preguntándome eso mismo.
luser droog

Respuestas:

8

Pyth, 27 24 bytes

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

Demostración.

Mejoras al original:

  • Usando metd, en lugar de .r ... _UJ: 2 bytes menos. 1 directo, 1 por no tener que usar J.

  • Usando sy en `Tlugar de JT10: 1 byte menos.


Comenzamos con la representación de cadena de un número: `T.

Luego, convertimos la cadena en una lista de dígitos, y rotamos los dígitos dígitos hacia atrás en uno, (9876543210) con metsd. Luego, tomamos las subsecuencias de 2 elementos con .: ... 2. Estas subsecuencias se filtran /h-FY3. Esta expresión corresponde a ((a-b)+1)/3, que es cero si y solo si la diferencia entre ay bes como máximo 1. Por lo tanto, la lista filtrada estará vacía si y solo si el número es compatible con el teclado. Con !, el resultado es verdadero solo si el número es compatible con el teclado.

f ... hGfiltra hacia arriba desde G+1hasta que el resultado sea verdadero, dando el primer número amigable con el teclado igual G+1o superior. u ... Q0aplica esta función a sus propios Qtiempos de salida , comenzando desde 0, donde Qestá la entrada. Esto le da al Qnúmero de teclado amigable, según lo deseado.

isaacg
fuente
4

Python 3, 112102 bytes

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

Llevamos un registro del recuento de números amistosos que aún necesitamos encontrar ny el último número registrado k.

5 y 5 bytes guardados gracias a @isaacg y @ Sp3000.

randomra
fuente
Use una expresión lamba en lugar de un retorno def. Las lambas permiten valores predeterminados.
isaacg
@isaacg Gracias, no sabía cómo recurrir con lambda.
randomra
Ah bien. Las operaciones unarias son lo primero. Mi error.
mbomb007
Puede colocar el [:-1]en elzip
Sp3000
4

CJam, 29 28 bytes

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

Pruébelo en línea en el intérprete de CJam .

Dennis
fuente
¿Hay alguna prueba fácil de que el límite superior del número amistoso N-ésimo es N ** 2
Optimizador
No he encontrado uno todavía. La prueba N ** 4es bastante fácil, ya que hay al menos 2 ** kKFN a continuación 10 ** k < 16 ** k. Sustitución _*con 4#no alteraría el número de bytes, pero esto haría que el código terriblemente ineficiente.
Dennis
Entonces, ¿no es incorrecto su código para algún número de entrada grande?
Optimizador
1
Ojalá no. Pero lo cambiaré hasta que lo sepa. se queja
Dennis
3

CJam, 34 31 bytes

3 bytes guardados por Dennis.

Estoy seguro de que la brecha con Pyth se puede cerrar de alguna manera, pero no tengo tiempo en este momento para jugar más ...

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

Pruébalo aquí.

Martin Ender
fuente
Puede reemplazar )_++con :_para guardar 2 caracteres y -z1>con m2/para guardar otro.
Dennis
@ Dennis Oh, eso es bueno, ¡gracias!
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}

Sin 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
}

Prueba : ejecutar fragmento en Firefox

edc65
fuente
No sé mucho JS, pero ¿no podrías hacer algo así en abs(p-d)>1lugar de p-d>1|p-d<-1?
Alex A.
@AlexA. Las expresiones en expandido y golfizado son equivalentes. Math.abs(p-d)>1es más largo quep-d>1|p-d<-1
edc65
Ah bien. Sabía que eran equivalentes, pero no sabía que necesitabas el Math.prefijo.
Alex A.
2

Haskell, 90 80 bytes

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

Esta es una función sin nombre. Para usarlo, llámelo con un parámetro, por ejemplo: ([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199que devuelve 5432.

Cómo funciona:

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

Editar: @Mauris encontró algunos bytes para guardar. ¡Gracias!

nimi
fuente
En lugar de x<-[1..]... !!n-1, se puede hacer x<-[0..]... !!n.
Lynn
Y luego, por supuesto, f n=[...]!!npuede ser f=([...]!!).
Lynn
Lo reduje a una sola función, eliminando a:f=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
Lynn
@Mauris: wow, gracias! Sin anosotros también podemos eliminar f.
nimi
2

Dart, 92 bytes

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;}

Con saltos de línea:

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;
}

Ver / ejecutarlo en DartPad

lrn
fuente
1

Lote: 520 bytes

Estremecimiento.

@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%
carne sin carne
fuente
1

Bash + coreutils, 120 bytes

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}"

Algunos casos de prueba:

$ for i in 1 10 11 99 100 200; do ./kfn.sh $i; done
1     
11    
12    
889   
890   
5433  
$ 
Trauma digital
fuente
0

JavaScript ES6, 126 bytes

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}

Código no protegido y pruebas a continuación. Esto ciertamente podría mejorarse más.

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>

NinjaOsoMono
fuente
0

Cobra - 135

No he hecho esto en mucho tiempo, pero aquí va:

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

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

Pyth, 19 bytes

e.f.AgL1.aM.+|RTjZT

Pruébalo aquí.

Nota: Utiliza commit más nuevo que este desafío, por lo que no debe considerarse como un outgolf de la respuesta de Isaac. Sin embargo, esto todavía está compitiendo.

Erik el Outgolfer
fuente