Hasilkan Nomor Ramah Keyboard

29

Tata letak keyboard komputer yang paling umum memiliki tombol angka desimal

1234567890

berlari di atas mereka, di atas tombol untuk surat.

Biarkan desimal digit ini lingkungan menjadi seperangkat digit dari tombol angka sendiri dan dari tombol angka segera ke kiri dan kanan, jika mereka ada.

Misalnya, lingkungan 0 adalah {0, 9}, dan lingkungan 5 adalah {4, 5, 6}.

Sekarang, tentukan nomor ramah keyboard sebagai bilangan bulat positif (dalam bentuk desimal tanpa nol di depan) yang dapat diketik pada tata letak di atas sehingga setiap digit berurutan dalam angka setelah digit pertama berada di lingkungan digit sebelumnya.

  • Semua angka digit tunggal (1-9) sepele dari keyboard ramah.

  • Angka seperti 22321 ramah keyboard karena setiap digit (tidak termasuk yang pertama) ada di sekitar digit sebelumnya.

  • Sejumlah seperti 1245 tidak ramah keyboard karena 4 tidak di lingkungan 2 (atau sebaliknya).

  • Angka seperti 109 tidak ramah keyboard karena 0 tidak berada di lingkungan 1. Ujung tidak berputar.

Dengan menempatkan angka-angka ramah keyboard dari terkecil ke terbesar, kita dapat membuat urutan bilangan bulat .

Berikut adalah 200 istilah pertama dari urutan nomor ramah keyboard:

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

Tantangan

Tulis program atau fungsi yang mengambil bilangan bulat positif N (melalui stdin / baris perintah / fungsi arg) dan mencetak (ke stdout) atau mengembalikan istilah ke-N dalam urutan nomor ramah keyboard.

Misalnya, jika inputnya adalah 191, outputnya seharusnya 4544.

Output secara opsional dapat memiliki satu baris baru.

Pengajuan terpendek dalam byte menang.

Hobi Calvin
sumber
7
Fakta acak: OEIS memiliki urutan terkait untuk numpads
Sp3000
Terima kasih, @ Sp3000. Saya gulir ke bawah ke sini bertanya-tanya hal itu.
luser droog

Jawaban:

8

Pyth, 27 24 byte

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

Demonstrasi.

Perbaikan ke aslinya:

  • Menggunakan metd, alih-alih .r ... _UJ: 2 byte lebih sedikit. 1 langsung, 1 karena tidak harus menggunakan J.

  • Menggunakan sdan `Tbukannya JT10: 1 byte kurang.


Kita mulai dengan representasi string nomor: `T.

Kemudian, kita mengonversi string menjadi daftar angka, dan memutar digit itu mundur satu per satu, (9876543210) dengan metsd. Kemudian, kita ambil 2 elemen dengan .: ... 2. Selanjutnya ini difilter pada /h-FY3. Ekspresi ini sesuai dengan ((a-b)+1)/3, yaitu nol jika dan hanya jika perbedaan antara adan bpaling banyak 1. Dengan demikian, daftar yang difilter akan kosong jika dan hanya jika jumlahnya ramah keyboard. Dengan !, hasilnya benar hanya jika angka tersebut ramah keyboard.

f ... hGfilter ke atas dari G+1sampai hasilnya benar, memberikan nomor ramah keyboard pertama di G+1atau di atas. u ... Q0menerapkan fungsi ini ke Qwaktu outputnya sendiri , mulai dari 0, di mana Qinput. Ini memberikan QNomor Keyboard Friendly, seperti yang diinginkan.

isaacg
sumber
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

Kami melacak jumlah nomor ramah yang masih perlu ditemukan ndan nomor yang terakhir diperiksa k.

5 dan 5 byte disimpan berkat @isaacg dan @ Sp3000.

randomra
sumber
Gunakan ekspresi lamba alih-alih pengembalian def. Lambas memungkinkan default.
isaacg
@isaacg Terima kasih, saya tidak tahu bagaimana cara berulang dengan lambda.
randomra
Ah benar. Operasi unary menjadi prioritas utama. Kesalahanku.
mbomb007
Anda dapat menjatuhkan [:-1]dizip
Sp3000
4

CJam, 29 28 byte

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

Cobalah online di juru bahasa CJam .

Dennis
sumber
Apakah ada bukti mudah bahwa batas atas nomor ramah ke-N adalah N ** 2
Pengoptimal
Belum menemukan satu. Buktinya N ** 4cukup mudah, karena setidaknya ada 2 ** kKFN di bawah ini 10 ** k < 16 ** k. Mengganti _*dengan 4#tidak akan mengubah jumlah byte, tetapi itu akan membuat kode ini sangat tidak efisien.
Dennis
Maka bukankah kode Anda salah untuk sejumlah input besar?
Pengoptimal
1
Semoga tidak. Tapi saya akan mengubahnya sampai saya tahu. menggerutu
Dennis
3

CJam, 34 31 byte

3 byte disimpan oleh Dennis.

Saya yakin celah untuk Pyth bisa ditutup entah bagaimana, tapi saya tidak punya waktu sekarang untuk bermain golf ini lebih jauh ...

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

Uji di sini.

Martin Ender
sumber
Anda dapat mengganti )_++dengan :_untuk menyimpan 2 karakter dan -z1>dengan m2/untuk menyimpan yang lain.
Dennis
@ Dennis Oh, itu bagus, terima kasih!
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}

Tidak disatukan

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
}

Uji : jalankan snippet di Firefox

edc65
sumber
Saya tidak tahu banyak JS, tetapi tidak bisakah Anda melakukan sesuatu seperti abs(p-d)>1bukan p-d>1|p-d<-1?
Alex A.
@AlexA. Ekspresi dalam diperluas dan golf adalah setara. Math.abs(p-d)>1lebih panjang darip-d>1|p-d<-1
edc65
Ah, baiklah. Saya tahu mereka setara, saya hanya tidak tahu bahwa Anda memerlukan Math.awalan.
Alex A.
2

Haskell, 90 80 byte

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

Ini adalah fungsi tanpa nama. Untuk menggunakannya, panggil dengan parameter, misalnya: ([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199yang mengembalikan 5432.

Bagaimana itu bekerja:

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

Sunting: @Mauris menemukan beberapa byte untuk disimpan. Terima kasih!

nimi
sumber
Alih-alih x<-[1..]... !!n-1, yang dapat Anda lakukan x<-[0..]... !!n.
Lynn
Dan tentu saja f n=[...]!!nbisa f=([...]!!).
Lynn
Saya turun ke satu fungsi, menghilangkan a:f=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
Lynn
@Mauris: wow, terima kasih! Tanpa akita bisa menghilangkannya fjuga.
nimi
2

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

Dengan linebreak:

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

Lihat / jalankan di DartPad

Tuan
sumber
1

Batch - 520 Bytes

Merasa ngeri.

@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%
hapus clemeat
sumber
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}"

Beberapa testcases:

$ for i in 1 10 11 99 100 200; do ./kfn.sh $i; done
1     
11    
12    
889   
890   
5433  
$ 
Trauma Digital
sumber
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}

Kode dan tes tidak dikumpulkan di bawah ini. Ini tentu bisa lebih ditingkatkan.

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
sumber
0

Cobra - 135

Belum melakukan ini dalam beberapa saat, tetapi begini:

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

Tidak Terkumpul:

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
Suram
sumber
0

Jelly , 11 byte

Do⁵IỊẠ
1Ç#Ṫ

Cobalah online!

Erik the Outgolfer
sumber
0

Pyth, 19 byte

e.f.AgL1.aM.+|RTjZT

Coba di sini.

Catatan: Penggunaan komit lebih baru dari tantangan ini, jadi tidak boleh dianggap sebagai outgolf dari jawaban isaacg. Ini masih bersaing.

Erik the Outgolfer
sumber