키보드 친화적 인 숫자 생성


29

가장 일반적인 컴퓨터 키보드 레이아웃 에는 10 진수 키가 있습니다.

1234567890

글자 키 위를 따라 달려갑니다.

10 진수의 이웃 은 자릿수 키와 숫자 키 (왼쪽 및 오른쪽) (있는 경우)의 자릿수로 설정합니다.

예를 들어, 이웃은 0이고 {0, 9}이웃은 5입니다 {4, 5, 6}.

이제 키보드 친화적 인 숫자 를 양의 정수 (앞의 0이없는 10 진수 형식)로 정의하십시오. 위의 레이아웃에서 첫 번째 숫자 다음의 숫자의 모든 연속 숫자가 앞의 숫자 근처에 입력되도록 지정할 수 있습니다.

  • 모든 한자리 숫자 (1-9)는 키보드에 친숙합니다.

  • 22321과 같은 숫자는 모든 숫자 (첫 번째를 세지 않음)가 숫자 바로 앞에 있기 때문에 키보드에 친숙합니다.

  • 1245과 같은 숫자는 하지 (4) 2 (도 반대의 경우도 마찬가지)의 근처에 있지 않기 때문에 키보드 친화적 인.

  • 숫자와 같은 109입니다 하지 0 1의 근처에 없기 때문에 끝이 주변에 루프를하지 않는 키보드 친화적 인.

키보드에 친숙한 숫자를 작은 숫자부터 큰 숫자까지 순서대로 넣으면 정수 시퀀스를 만들 수 있습니다 .

다음은 키보드 친숙한 숫자 시퀀스의 처음 200 개 용어입니다.

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

도전

양의 정수 N (stdin / command line / function arg를 통해)을 취하고 키보드 표준 번호 순서로 N 번째 항을 출력하거나 (stdout으로) 프로그램 또는 함수를 작성하십시오.

예를 들어, 입력이 191이면 출력은이어야합니다 4544.

출력에는 선택적으로 단일 후행 줄 바꿈이있을 수 있습니다.

바이트 단위의 최단 제출이 이깁니다.



감사합니다, @ Sp3000. 나는 바로 그게 궁금 해져서 여기까지 스크롤했다.
luser droog 님

답변:


8

Pyth, 27 24 바이트

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

데모.

원본 개선 :

  • 사용 metd대신에, .r ... _UJ2 적은 바이트. J를 사용할 필요가없는 경우 1 개, 직접 1 개

  • 사용 s하고 `T대신 JT10: 1 적은 바이트.


우리는 숫자의 문자열 표현으로 시작합니다 : `T.

그런 다음 문자열을 자릿수 목록으로 변환하고을 사용하여 자릿수를 1 씩 뒤로 (9876543210) 회전시킵니다 metsd. 그런 다음로 2 개의 요소 하위 시퀀스를 가져옵니다 .: ... 2. 이 하위 시퀀스는에서 필터링됩니다 /h-FY3. 이 표현은((a-b)+1)/3 제로 인 경우에만, 차이 ab 그 수는 키보드 친화적 인 경우에만 경우에 따라서 1. 대부분에있다가, 필터링 된 목록이 비어 있습니다. 를 사용 !하면 숫자가 키보드 친화적 인 경우에만 결과가 적용됩니다.

f ... hGG+1결과가 true가 될 때까지 위쪽에서 필터링 하여 첫 번째 키보드 친화적 인 숫자를 제공합니다 G+1. u ... Q0이 함수 Q는 0부터 시작 Q하여 입력이있는 자체 출력 시간에 적용됩니다 . Q원하는대로 키보드 친화적 인 번호를 제공합니다 .


4

파이썬 3, 112102 바이트

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

우리는 여전히 찾기 위해 필요한 친숙한 숫자의 수 n와 마지막으로 확인한 숫자를 추적합니다 .k .

@isaacg 및 @ Sp3000 덕분에 5 및 5 바이트가 절약되었습니다.


데프 리턴 대신 람바 식을 사용하십시오. Lambas는 기본값을 허용합니다.
isaacg

@isaacg 감사합니다. 람다로 재귀하는 방법을 몰랐습니다.
randomra

아 맞다. 단항 작전이 먼저입니다. 내 실수.
mbomb007

You can drop the [:-1] in the zip
Sp3000

4

CJam, 29 28 bytes

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

Try it online in the CJam interpreter.


Is there an easy proof that the upper limit of N-th friendly number is N**2
Optimizer

Haven't found one yet. The proof for N ** 4 is pretty easy, since there are at least 2 ** k KFN below 10 ** k < 16 ** k. Replacing _* with 4# wouldn't alter the byte count, but it would make the code horribly inefficient.
Dennis

Then isn't your code incorrect for some large input number ?
Optimizer

1
Hopefully not. But I'll change it until I know. grumbles
Dennis

3

CJam, 34 31 bytes

3 bytes saved by Dennis.

I'm sure the gap to Pyth can be closed somehow, but I don't have time right now to golf this further...

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

Test it here.


You can replace )_++ with :_ to save 2 chars and -z1> with m2/ to save another.
Dennis

@Dennis Oh, those are nice, thank you!
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 : execute snippet in Firefox


I don't know much JS, but couldn't you do something like abs(p-d)>1 rather than p-d>1|p-d<-1?
Alex A.

@AlexA. The expressions in expanded and golfed are equivalent. Math.abs(p-d)>1 is longer than p-d>1|p-d<-1
edc65

Ah, okay. I knew they were equivalent, I just didn't know that you needed the Math. prefix.
Alex A.

2

Haskell, 90 80 bytes

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

This is a function without a name. To use it, call it with a parameter, e.g.:([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199 which returns 5432.

How it works:

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

Edit: @Mauris found some bytes to save. Thanks!


Instead of x<-[1..] ... !!n-1, you can do x<-[0..] ... !!n.
Lynn

And then of course f n=[...]!!n can be f=([...]!!).
Lynn

I got it down to a single function, eliminating a: f=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
Lynn

@Mauris: wow, thank you! Without a we can eliminate f, too.
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;}

With linebreaks:

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

See/run it on DartPad


1

Batch - 520 Bytes

Shudder.

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

Some testcases:

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

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}

Ungolfed code and tests below. This could certainly be improved more.

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

Haven't done this in a while, but here goes:

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 bytes

e.f.AgL1.aM.+|RTjZT

Try it here.

Note: Uses commit newer than this challenge, so shouldn't be considered as an outgolf of isaacg's answer. This is still competing, though.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.