Tạo số bàn phím thân thiện


29

Bố trí bàn phím máy tính phổ biến nhất có các phím chữ số thập phân

1234567890

chạy dọc theo đỉnh của chúng, phía trên các phím cho các chữ cái.

Đặt vùng lân cận của một chữ số thập phân là tập hợp các chữ số từ khóa chữ số của chính nó và từ các phím chữ số ngay lập tức sang trái và phải, nếu chúng tồn tại.

Ví dụ: vùng lân cận 0 là {0, 9}và vùng lân cận 5 là {4, 5, 6}.

Bây giờ, hãy xác định số thân thiện với bàn phím là số nguyên dương (ở dạng thập phân không có số 0 đứng đầu) có thể được gõ trên bố cục ở trên sao cho mỗi chữ số liên tiếp trong số sau chữ số đầu tiên nằm trong vùng lân cận của chữ số trước.

  • Tất cả các số có một chữ số (1-9) đều thân thiện với bàn phím.

  • Một số như 22321 là thân thiện với bàn phím vì mỗi chữ số (không tính số đầu tiên) nằm trong vùng lân cận của chữ số trước đó.

  • Một số như 1245 không thân thiện với bàn phím vì 4 không nằm trong vùng lân cận của 2 (cũng không phải ngược lại).

  • Một số như 109 không thân thiện với bàn phím vì 0 không nằm trong vùng lân cận của 1. Các đầu không lặp xung quanh.

Bằng cách đặt các số thân thiện với bàn phím theo thứ tự từ nhỏ nhất đến lớn nhất, chúng ta có thể tạo một chuỗi số nguyên .

Dưới đây là 200 điều khoản đầu tiên của chuỗi số thân thiện với bàn phím:

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

Thử thách

Viết chương trình hoặc hàm lấy số nguyên dương N (thông qua stdin / dòng lệnh / hàm arg) và in (ra thiết bị xuất chuẩn) hoặc trả về số hạng N trong chuỗi số thân thiện với bàn phím.

Ví dụ, nếu đầu vào là 191, đầu ra phải là 4544.

Đầu ra có thể tùy chọn có một dòng mới duy nhất.

Đệ trình ngắn nhất tính bằng byte thắng.


7
Sự thật ngẫu nhiên: OEIS có một chuỗi liên quan cho
numpads

Cảm ơn, @ Sp3000. Tôi cuộn xuống đây tự hỏi điều đó rất nhiều.
luser droog

Câu trả lời:


8

Bình thường, 27 24 byte

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

Trình diễn.

Cải tiến so với bản gốc:

  • Sử dụng metd, thay vì .r ... _UJ: 2 byte ít hơn. 1 trực tiếp, 1 vì không phải sử dụng J.

  • Sử dụng s`Tthay vì JT10: 1 byte ít hơn.


Chúng tôi bắt đầu với đại diện chuỗi của một số : `T.

Sau đó, chúng tôi chuyển đổi chuỗi thành một danh sách các chữ số và xoay các chữ số ngược lại với một, (9876543210) với metsd. Sau đó, chúng tôi lấy 2 phần tử con với .: ... 2. Những phần sau được lọc trên /h-FY3. Biểu thức này tương ứng với ((a-b)+1)/3, bằng 0 khi và chỉ khi chênh lệch giữa abnhiều nhất là 1. Do đó, danh sách được lọc sẽ trống nếu và chỉ khi số đó thân thiện với bàn phím. Với !, kết quả chỉ đúng nếu số đó là bàn phím thân thiện.

f ... hGcác bộ lọc trở lên G+1cho đến khi kết quả là đúng, đưa ra số thân thiện với bàn phím đầu tiên ở mức G+1hoặc trên. u ... Q0áp dụng chức năng này cho Qthời gian đầu ra của chính nó , bắt đầu từ 0, Qđầu vào ở đâu. Điều này mang lại cho QSố bàn phím thân thiện, như mong muốn.


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

Chúng tôi theo dõi số lượng số thân thiện vẫn cần tìm nvà số được kiểm tra lần cuối k.

5 và 5 byte được lưu nhờ @isaacg và @ Sp3000.


Sử dụng một biểu thức lamba thay vì trả lại def. Lambas cho phép mặc định.
isaacg

@isaacg Cảm ơn, tôi không biết làm thế nào để tái phát với lambda.
ngẫu nhiên

À đúng rồi. Ops unary đến đầu tiên. Lỗi của tôi.
mbomb007

Bạn có thể thả [:-1]trongzip
Sp3000

4

CJam, 29 28 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .


Có bằng chứng dễ dàng nào cho thấy giới hạn trên của số thân thiện N-th là N ** 2
Trình tối ưu hóa

Chưa tìm thấy cái nào cả. Bằng chứng N ** 4là khá dễ dàng, vì có ít nhất 2 ** kKFN bên dưới 10 ** k < 16 ** k. Thay thế _*bằng 4#sẽ không làm thay đổi số byte, nhưng nó sẽ làm cho mã không hiệu quả khủng khiếp.
Dennis

Sau đó, mã của bạn không chính xác cho một số đầu vào lớn?
Trình tối ưu hóa

1
Hy vọng là không. Nhưng tôi sẽ thay đổi nó cho đến khi tôi biết. càu nhàu
Dennis

3

CJam, 34 31 byte

3 byte được lưu bởi Dennis.

Tôi chắc chắn rằng khoảng cách với Pyth có thể được đóng lại bằng cách nào đó, nhưng tôi không có thời gian để chơi gôn thêm nữa ...

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

Kiểm tra nó ở đây.


Bạn có thể thay thế )_++bằng :_để lưu 2 ký tự và -z1>với m2/để lưu một ký tự khác.
Dennis

@Dennis Oh, thật tuyệt, cảm ơn bạn!
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}

Bị đánh cắp

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
}

Kiểm tra : thực thi đoạn trích trong Firefox


Tôi không biết nhiều về JS, nhưng bạn không thể làm gì đó abs(p-d)>1hơn là p-d>1|p-d<-1sao?
Alex A.

@AlexA. Các biểu thức trong mở rộng và chơi golf là tương đương. Math.abs(p-d)>1dài hơnp-d>1|p-d<-1
edc65

À được rồi. Tôi biết chúng tương đương nhau, tôi chỉ không biết rằng bạn cần Math.tiền tố.
Alex A.

2

Haskell, 90 80 byte

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

Đây là một chức năng không có tên. Để sử dụng nó, hãy gọi nó với một tham số, ví dụ: ([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199trả về 5432.

Làm thế nào nó hoạt động:

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

Chỉnh sửa: @Mauris tìm thấy một số byte để lưu. Cảm ơn!


Thay vì x<-[1..]... !!n-1, bạn có thể làm x<-[0..]... !!n.
Lynn

Và sau đó tất nhiên f n=[...]!!ncó thể f=([...]!!).
Lynn

Tôi đã chuyển nó xuống một chức năng duy nhất, loại bỏ a:f=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
Lynn

@Mauris: wow, cảm ơn bạn! Không có achúng ta có thể loại bỏ f, quá.
nimi

2

Phi tiêu, 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;}

Với ngắt dòng:

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

Xem / chạy nó trên DartPad


1

Mẻ - 520 byte

Nghẹn ngào.

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

Một số mẫu thử:

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

Mã xác nhận và thử nghiệm dưới đây. Điều này chắc chắn có thể được cải thiện nhiều hơn.

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

Rắn hổ mang - 135

Không làm điều này trong một thời gian, nhưng ở đây đi:

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

Ung dung:

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


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.