キーボードフレンドリーな番号を生成する


29

最も一般的なコンピューターのキーボードレイアウトには、10進数字キーがあります

1234567890

上部の文字キーの上を走っています。

10進数字の近傍を、それ自体の数字キーと、数字キーが存在する場合はすぐに左右にある数字のセットとします。

たとえば、0の近傍は{0, 9}であり、5の近傍はです{4, 5, 6}

ここで、キーボードフレンドリー番号を正の整数(先頭にゼロのない10進数形式)として定義します。これは、最初の数字の後の数字の連続するすべての数字が前の数字の近くになるように上記のレイアウトで入力できます。

  • すべての1桁の数字(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(標準入力/コマンドライン/関数引数経由)を取り、(stdoutに)出力するか、キーボードフレンドリーな数字シーケンスのN番目の用語を返すプログラムまたは関数を作成します。

たとえば、入力がの場合、出力は191である必要があります4544

出力には、オプションで単一の末尾の改行を含めることができます。

バイト単位の最短提出が勝ちです。


7
ランダムファクト:OEISが持っているnumpadsための関連シーケンス
SP3000

ありがとう、@ Sp3000。私はそのこと自体を疑問に思いながらここまでスクロールしました。
luser droog

回答:


8

Pyth、27 24バイト

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

デモンストレーション。

オリジナルの改善:

  • metd代わりに.r ... _UJ:を使用して、2バイト少なくします。1つは直接、1つはJを使用する必要がない

  • sandの`T代わりにand を使用JT10:1バイト少ない。


数字の文字列表現から始めます`T

次に、文字列を数字のリストに変換し、で数字を1ずつ逆回転します(9876543210)metsd。次に、で2要素のサブシーケンスを取得し.: ... 2ます。これらのサブシーケンスはでフィルタリングされ/h-FY3ます。この式に相当((a-b)+1)/3差場合にのみゼロであり、a及びbその数は、キーボードフレンドリーである場合だけしたがって1以下であるが、フィルタリングされたリストが空になります。を使用!すると、数字がキーボードフレンドリーである場合にのみ結果がtrueになります。

f ... hGG+1結果がtrueになるまでから上方にフィルターをかけ、キーボードフレンドリーな最初の番号G+1以上を与えます。u ... Q0この関数を、入力QQある0から始まる独自の出力時間に適用します。これにより、Q必要に応じてキーボードフレンドリー番号が与えられます。


4

Pythonの3、112の 102バイト

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バイトが節約されました。


defリターンの代わりにランバ式を使用します。Lambasはデフォルトを許可します。
isaacg

@isaacgおかげで、ラムダで再帰する方法を知りませんでした。
ランダラ

そうだね。単項演算が最初になります。私の間違い。
mbomb007

あなたは、ドロップすることができます[:-1]zip
SP3000

4

CJam、29 28バイト

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

CJamインタープリターでオンラインで試してください。


N番目のフレンドリー番号の上限がN ** 2であるという簡単な証拠はありますか?
オプティマイザー

まだ見つけていません。以下のKFN N ** 4が少なくともあるため、の証明は非常に簡単です。に置き換えてもバイト数は変わりませんが、コードがひどく非効率的になります。2 ** k10 ** k < 16 ** k_*4#
デニス

次に、いくつかの大きな入力番号に対してあなたのコードが間違っていませんか?
オプティマイザー

1
うまくいけない。しかし、私が知るまでそれを変更します。不平を言う
デニス

3

CJam、34 31バイト

デニスが保存した3バイト。

どうやらPythとのギャップを埋めることができると確信していますが、これ以上ゴルフをする時間は今のところありません...

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

ここでテストしてください。


あなたは置き換えることができ)_++:_2つの文字を保存し、し-z1>m2/別のものを保存すること。
デニス

@デニスああ、それらは素晴らしいです、ありがとう!
マーティンエンダー

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}

非ゴルフ

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
}

テスト:Firefoxでスニペットを実行します


私は多くのJSを知りませんが、あなたは何abs(p-d)>1よりも何かをすることができませんでしたp-d>1|p-d<-1か?
アレックスA.

@AlexA。expandedとgolfedの表現は同等です。Math.abs(p-d)>1より長いp-d>1|p-d<-1
-edc65

あ、そう。それらが同等であることは知っていましたが、Math.プレフィックスが必要であることを知りませんでした。
アレックスA.

2

Haskell、90 80バイト

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

これは名前のない関数です。使用するには、パラメータを指定して呼び出し([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!) 199ます5432。例:whichはを返します。

使い方:

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

編集:@Maurisは保存するバイトを見つけました。ありがとう!


x<-[1..]...の代わりに!!n-1、次のことができx<-[0..]ます!!n
リン

そして、もちろんf n=[...]!!nできますf=([...]!!)
リン

私はなくし、単一の関数にそれを降りaf=([x|x<-[0..],all((<2).abs)$zipWith(-)=<<tail$[mod(1+fromEnum c)10|c<-show x]]!!)
リン・

@モーリス:すごい、ありがとう!なしでもaを排除fできます。
-nimi

2

ダーツ、92バイト

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

改行あり:

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

DartPadで見る/実行する


1

バッチ-520バイト

震え。

@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バイト

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

いくつかのテストケース:

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

0

JavaScript ES6、126バイト

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}

以下のゴルフのないコードとテスト。これは確かにさらに改善される可能性があります。

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

コブラ-135

これをしばらくしていないが、ここに行く:

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

ゴルフをしていない:

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.