Generuj przyjazne numery klawiatury

29

Najpopularniejsze układy klawiatury komputera mają cyfry dziesiętne

1234567890

biegną u góry, ponad klawiszami liter.

Niech sąsiedztwo cyfr dziesiętnych będzie zbiorem cyfr z własnego klawisza cyfry i z klawiszy cyfr bezpośrednio po lewej i prawej stronie, jeśli istnieją.

Na przykład sąsiedztwo 0 to {0, 9}, a sąsiedztwo 5 to {4, 5, 6}.

Teraz zdefiniuj liczbę przyjazną dla klawiatury jako dodatnią liczbę całkowitą (w postaci dziesiętnej bez zer wiodących), którą można wpisać w powyższym układzie, tak aby każda kolejna cyfra w liczbie po pierwszej cyfrze znajdowała się w sąsiedztwie poprzedniej cyfry.

  • Wszystkie cyfry jednocyfrowe (1-9) są trywialnie przyjazne dla klawiatury.

  • Liczba taka jak 22321 jest przyjazna dla klawiatury, ponieważ każda cyfra (nie licząc pierwszej) znajduje się w sąsiedztwie cyfry tuż przed nią.

  • Liczba taka jak 1245 nie jest przyjazna dla klawiatury, ponieważ 4 nie znajduje się w sąsiedztwie 2 (i odwrotnie).

  • Liczba taka jak 109 nie jest przyjazna dla klawiatury, ponieważ 0 nie znajduje się w sąsiedztwie 1. Końce się nie zapętlają.

Ustawiając liczby przyjazne dla klawiatury w kolejności od najmniejszej do największej, możemy utworzyć ciąg liczb całkowitych .

Oto pierwsze 200 terminów sekwencji numerów przyjaznych dla klawiatury:

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

Wyzwanie

Napisz program lub funkcję, która przyjmuje dodatnią liczbę całkowitą N (za pomocą stdin / wiersza poleceń / funkcji arg) i wypisuje (na standardowe wyjście) lub zwraca N-ty termin w sekwencji liczb przyjaznych dla klawiatury.

Na przykład, jeśli wejście jest 191, wyjście powinno być 4544.

Dane wyjściowe mogą opcjonalnie mieć jeden końcowy znak nowej linii.

Najkrótsze przesłanie w bajtach wygrywa.

Hobby Calvina
źródło
7
Przypadkowy fakt: OEIS ma podobną sekwencję dla numpadów
Sp3000
Dzięki, @ Sp3000. Przewinąłem w dół, zastanawiając się nad tym.
luser droog

Odpowiedzi:

8

Pyth, 27 24 bajtów

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

Demonstracja.

Ulepszenia oryginału:

  • Używanie metdzamiast .r ... _UJ: 2 mniej bajtów. 1 bezpośredni, 1 za brak konieczności używania J.

  • Używanie si `Tzamiast JT10: 1 mniej bajtu.


Zaczynamy ciąg znaków z numeru: `T.

Następnie konwertujemy ciąg znaków na listę cyfr i obracamy cyfry cyfr o jedną pozycję wstecz (9876543210) za pomocą metsd. Następnie bierzemy podsekwencje 2-elementowe z .: ... 2. Te podsekwencje są filtrowane /h-FY3. Wyrażenie to odpowiada ((a-b)+1)/3zeru wtedy i tylko wtedy, gdy różnica między ai bwynosi co najwyżej 1. W ten sposób filtrowana lista będzie pusta wtedy i tylko wtedy, gdy liczba jest przyjazna dla klawiatury. Z! , wynik jest prawdziwy tylko wtedy, gdy liczba jest przyjazna dla klawiatury.

f ... hGfiltruje w górę od, G+1aż wynik będzie prawdziwy, dając pierwszą przyjazną klawiaturę liczbę równą G+1lub większą. u ... Q0stosuje tę funkcję do własnych Qczasów wyjściowych , zaczynając od 0, gdzie Qjest wejście. Daje to Qliczbę przyjazną dla klawiatury, zgodnie z życzeniem.

isaacg
źródło
4

Python 3, 112 102 bajtów

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

Śledzimy liczbę przyjaznych numerów potrzebnych do znalezienia ni ostatnią sprawdzoną liczbę wk .

5 i 5 bajtów zapisanych dzięki @isaacg i @ Sp3000.

randomra
źródło
Użyj wyrażenia Lamba zamiast powrotu def. Lambas zezwalają na wartości domyślne.
isaacg
@isaacg Dzięki, nie wiedziałem, jak powrócić do lambda.
randomra
Ah, tak. Unary ops są najważniejsze. Mój błąd.
mbomb007
Możesz upuścić [:-1]wzip
Sp3000
4

CJam, 29 28 bajtów

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

Wypróbuj online w interpretatorze CJam .

Dennis
źródło
Czy istnieje łatwy dowód, że górna granica N-tego przyjaznego numeru to N ** 2
Optymalizator
Jeszcze nie znalazłem. Dowód na N ** 4to jest dość łatwy, ponieważ 2 ** kponiżej jest co najmniej KFN 10 ** k < 16 ** k. Zastąpienie _*go 4#nie zmieniłoby liczby bajtów, ale spowodowałoby okropnie nieefektywność kodu.
Dennis
Czy Twój kod nie jest nieprawidłowy w przypadku dużej liczby wejściowej?
Optymalizator
1
Mam nadzieję, że nie. Ale zmienię to, dopóki się nie dowiem. narzeka
Dennis
3

CJam, 34 31 bajtów

3 bajty zapisane przez Dennisa.

Jestem pewien, że dystans do Pytha można jakoś zlikwidować, ale nie mam teraz czasu na grę w golfa ...

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

Sprawdź to tutaj.

Martin Ender
źródło
Można wymienić )_++ze :_aby zapisać 2 znaków i -z1>ze m2/aby zapisać inny.
Dennis
@Dennis Oh, te są miłe, dziękuję!
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}

Nie golfił

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 : uruchom fragment w przeglądarce Firefox

edc65
źródło
Nie wiem, dużo JS, ale nie można zrobić coś takiego abs(p-d)>1zamiast p-d>1|p-d<-1?
Alex A.
@AlexA. Wyrażenia w rozwiniętej i golfowej są równoważne. Math.abs(p-d)>1jest dłuższy niżp-d>1|p-d<-1
edc65
Ah, dobrze. Wiedziałem, że są równoważne, po prostu nie wiedziałem, że potrzebujesz Math.prefiksu.
Alex A.
2

Haskell, 90 80 bajtów

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

Jest to funkcja bez nazwy. Aby go użyć, wywołaj go z parametrem, np .: ([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199który zwraca 5432.

Jak to działa:

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

Edycja: @ Mauris znalazł bajty do zapisania. Dzięki!

nimi
źródło
Zamiast x<-[1..]... !!n-1można zrobić x<-[0..]... !!n.
Lynn
I oczywiście f n=[...]!!nmoże być f=([...]!!).
Lynn
Sprowadziłem to do jednej funkcji, eliminując a:f=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
Lynn
@Mauris: wow, dziękuję! Bez anas też nie możemy wyeliminować f.
nimi
2

Dart, 92 bajty

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

Z łamaniem linii:

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

Zobacz / uruchom go na DartPad

lrn
źródło
1

Partia - 520 bajtów

Dreszcz.

@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%
nieprzyzwoity
źródło
1

Bash + coreutils, 120 bajtów

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

Niektóre przypadki testowe:

$ for i in 1 10 11 99 100 200; do ./kfn.sh $i; done
1     
11    
12    
889   
890   
5433  
$ 
Cyfrowa trauma
źródło
0

JavaScript ES6, 126 bajtów

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}

Kod niepoznany i testy poniżej. Z pewnością można to jeszcze bardziej poprawić.

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
źródło
0

Kobra - 135

Nie robiłem tego od dłuższego czasu, ale oto:

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

Nie golfowany:

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
Obrzydliwe
źródło
0

Pyth, 19 bajtów

e.f.AgL1.aM.+|RTjZT

Wypróbuj tutaj.

Uwaga: Zastosowania zatwierdzają nowsze niż to wyzwanie, dlatego nie należy ich uważać za outgolf odpowiedzi Isaacga. To jednak wciąż konkuruje.

Erik the Outgolfer
źródło