Genera numeri compatibili con la tastiera


29

I layout di tastiera del computer più comuni hanno i tasti numerici decimali

1234567890

correndo in cima, sopra le chiavi per le lettere.

Consenti al vicinato di una cifra decimale di essere l'insieme di cifre dal proprio tasto numerico e dai tasti numerici immediatamente a sinistra e a destra, se esistono.

Ad esempio, il vicinato di 0 è {0, 9}e il vicinato di 5 è {4, 5, 6}.

Ora, definisci un numero descrittivo come un intero positivo (in formato decimale senza zero iniziale) che può essere digitato sul layout sopra in modo tale che ogni cifra consecutiva nel numero dopo la prima cifra si trovi nelle vicinanze della cifra precedente.

  • Tutti i numeri a una cifra (1-9) sono banalmente facili da usare con la tastiera.

  • Un numero come 22321 è compatibile con la tastiera perché ogni cifra (senza contare la prima) si trova nelle vicinanze della cifra appena prima.

  • Un numero come 1245 non è compatibile con la tastiera perché 4 non è nelle vicinanze di 2 (né viceversa).

  • Un numero come 109 non è compatibile con la tastiera perché 0 non è nelle vicinanze di 1. Le estremità non si ripetono.

Mettendo i numeri di tastiera in ordine dal più piccolo al più grande, possiamo creare una sequenza intera .

Ecco i primi 200 termini della sequenza numerica per tastiera:

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

Sfida

Scrivi un programma o una funzione che accetta un numero intero positivo N (tramite stdin / riga di comando / arg funzione) e stampa (su stdout) o restituisce l'ennesimo termine nella sequenza numerica della tastiera.

Ad esempio, se l'input è 191, l'output dovrebbe essere 4544.

L'output può facoltativamente avere una nuova riga finale.

Vince l'invio più breve in byte.



Grazie, @ Sp3000. Sono sceso fino a qui chiedendomi proprio quella cosa.
luser droog

Risposte:


8

Pyth, 27 24 byte

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

Dimostrazione.

Miglioramenti all'originale:

  • Utilizzo metd, anziché .r ... _UJ: 2 byte in meno. 1 diretto, 1 per non dover usare J.

  • Utilizzo se `Tanziché JT10: 1 byte in meno.


Si comincia con la rappresentazione di stringa di un numero: `T.

Quindi, convertiamo la stringa in un elenco di cifre e ruotiamo le cifre all'indietro di una, (9876543210) con metsd. Quindi prendiamo le sottosequenze di 2 elementi con .: ... 2. Queste sottosequenze vengono filtrate /h-FY3. Questa espressione corrisponde a ((a-b)+1)/3, che è zero se e solo se la differenza tra ae bè al massimo 1. Pertanto, l'elenco filtrato sarà vuoto se e solo se il numero è compatibile con la tastiera. Con !, il risultato è vero solo se il numero è adatto alla tastiera.

f ... hGfiltra verso l'alto da G+1fino a quando il risultato è vero, fornendo il primo numero di tastiera amichevole G+1o superiore. u ... Q0applica questa funzione ai propri Qtempi di uscita , a partire da 0, dove si Qtrova l'ingresso. Questo dà il Qnumero di tastiera amichevole, come desiderato.


4

Python 3, 112 102 byte

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

Teniamo traccia del conteggio dei numeri amici ancora necessari per trovare ne dell'ultimo numero verificato k.

5 e 5 byte salvati grazie a @isaacg e @ Sp3000.


Utilizzare un'espressione lamba anziché un ritorno def. Lambas consente impostazioni predefinite.
isaacg,

@isaacg Grazie, non sapevo come ricorrere con lambda.
randomra,

Ah giusto. Le operazioni unarie vengono prima. Errore mio.
mbomb007,

È possibile eliminare l' [:-1]inzip
SP3000

4

CJam, 29 28 byte

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

Provalo online nell'interprete CJam .


C'è una prova facile che il limite superiore dell'N-esimo numero è N ** 2
Ottimizzatore

Non ne ho ancora trovato uno. La prova per N ** 4è abbastanza facile, poiché ci sono almeno 2 ** kKFN di seguito 10 ** k < 16 ** k. La sostituzione _*con 4#non altera il conteggio dei byte, ma renderebbe il codice orribilmente inefficiente.
Dennis,

Quindi il tuo codice non è errato per un numero di input grande?
Ottimizzatore

1
Spero di no. Ma lo cambierò finché non lo saprò. brontola
Dennis

3

CJam, 34 31 byte

3 byte salvati da Dennis.

Sono sicuro che il divario con Pyth possa essere chiuso in qualche modo, ma non ho tempo in questo momento per giocare a golf ulteriormente ...

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

Provalo qui.


È possibile sostituire )_++con :_per salvare 2 caratteri e -z1>con m2/per salvarne un altro.
Dennis,

@Dennis Oh, quelli sono carini, grazie!
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}

Ungolfed

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 : esegue lo snippet in Firefox


Non conosco molto JS, ma non potresti fare qualcosa del genere abs(p-d)>1piuttosto che p-d>1|p-d<-1?
Alex A.

@AlexA. Le espressioni in espanso e golf sono equivalenti. Math.abs(p-d)>1è più lungo dip-d>1|p-d<-1
edc65

Ah ok. Sapevo che erano equivalenti, non sapevo che avessi bisogno del Math.prefisso.
Alex A.

2

Haskell, 90 80 byte

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

Questa è una funzione senza nome. Per usarlo, chiamalo con un parametro, ad es .: ([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199che ritorna 5432.

Come funziona:

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

Modifica: @Mauris ha trovato alcuni byte da salvare. Grazie!


Invece di x<-[1..]... !!n-1, si può fare x<-[0..]... !!n.
Lynn,

E poi ovviamente f n=[...]!!npuò essere f=([...]!!).
Lynn,

Ho ottenuto una sola funzione, eliminando a:f=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
Lynn,

@Mauris: wow, grazie! Senza apossiamo anche eliminare f.
nimi,

2

Dardo, 92 byte

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 interruzioni di riga:

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

Vedi / eseguilo su DartPad


1

Lotto - 520 byte

Brivido.

@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%

1

Bash + coreutils, 120 byte

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

Alcuni test:

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

0

JavaScript ES6, 126 byte

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}

Codice non golfato e test di seguito. Questo potrebbe sicuramente essere migliorato di più.

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>


0

Cobra - 135

Non lo faccio da un po ', ma ecco qui:

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

Ungolfed:

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


0

Pyth, 19 byte

e.f.AgL1.aM.+|RTjZT

Provalo qui.

Nota: gli utilizzi sono più recenti di questa sfida, quindi non devono essere considerati come un esagerato della risposta di isaacg. Questo è ancora in competizione, però.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.