テンキーに優しい番号を生成する


22

キーボードフレンドリー番号の生成に触発された。

バックグラウンド

多くの数字パッドのレイアウトは次のとおりです。

789

456

123

    0    

数値の近傍を、表示されているテンキー上のそれに隣接するセルのセットとして定義します。たとえば、2の近傍は{1,5,3,0,2}0の近傍です{1,2,0}。テストケースの上に、各番号の近傍のリストがあります。

テンキーのフレンドリ番号を正の整数として定義します。先頭にゼロを付けずに10進数で記述すると、最初の数字を除く各数字は前の数字の近くにあります。

例えば、

  • 7856は8が7の近傍にあり、5は8のネイバーフッドにあり、6は5の近傍にあるため、テンキーに優しい番号です。
  • 2は1の近傍にあり、0は2の近傍にあり、1は0の近傍にあるため、1201はテンキーに優しい数字です。
  • 82でない 2は、8の近傍にないためテンキー優しい数。
  • 802はない 0が8(近隣ラップアラウンドしていない)の近傍ではないので、テンキー優しい番号。

関連OEISシーケンス。この関連シーケンスは、およびの代わりに0隣接するものとしてカウントされるため、異なることに注意してください。712

チャレンジ

正の整数nを指定すると、n-thまたは最初のnテンキーのフレンドリ番号を返します。最初のテンキーは1です。0から始まるテンキーのフレンドリ番号は1です。

近所

各桁の近傍は次のとおりです。

0:{0,1,2}
1:{0,1,2,4}
2:{0,1,2,3,5}
3:{2,3,6}
4:{1,4,5,7}
5:{2,4,5,6,8}
6:{3,5,6,9}
7:{4,7,8}
8:{5,7,8,9}
9:{6,8,9}

テストケース/シーケンス

これらは最初の100用語です

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 20, 21, 22, 23, 25, 32, 33, 36, 41, 44, 45, 47, 52, 54, 55, 56, 58, 63, 65, 66, 69, 74, 77, 78, 85, 87, 88, 89, 96, 98, 99, 100, 101, 102, 110, 111, 112, 114, 120, 121, 122, 123, 125, 141, 144, 145, 147, 200, 201, 202, 210, 211, 212, 214, 220, 221, 222, 223, 225, 232, 233, 236, 252, 254, 255, 256, 258, 320, 321, 322, 323, 325, 332, 333, 336, 363, 365, 366, 369, 410, 411, 412, 414, 441, 444, 445, 447]

5
私、この課題は、どのようにのような正の整数のみ考慮(本質を維持し、より多くの言語が参加することを可能にする)のいずれかを表示できますn個目または最初のn個の柔軟性のための出力を
ルイス・Mendo

私はこのチャレンジを完全に読み違えました。「この用語はシーケンスで有効ですか」というスクリプトをオンラインで試してみてください。
魔法のタコUr

回答:


9

JavaScript(ES6)、104 93 89 88バイト

シーケンスのN番目の項を1インデックスで返します。

f=(i,k,n=k,N=n/5>>1)=>(N?8530025>>(n%10*6191^N%10*6191)%26&1:!i--)?N?f(i,k,N):k:f(i,-~k)

デモ


私が得ることができる最高は151 k=(n,a=1)=>n?k(n-([...(x=a+[]).slice(0,-1)].reduce((a,c)=>a*!!~"012 0124 01235 236 1457 24568 3569 478 5789 689".split` `[c].indexOf(x[i++]),i=1)),a+1):a-1多分そこに役立つかもしれない、私のテストはおそらく長すぎる
コナー・オブライエン

この答えは、マジックナンバーの概念をまったく新しいレベルに引き上げます...あなたがそれらをどのように見つけたのかさえわかりませんo_O
scottinet

2
@scottinet大部分は、この答えに対する私の説明はこれにも当てはまります。絶対的な違いはその上でうまく機能しなかったので、代わりにXORを試しました。補足として、ルックアップビットマスクを必要とせずにケースの96%で機能する別の式を見つけました。しかし、残りの4%を個別に処理することは、JSではコストがかかりすぎました。私がしようとしなかったゼリーで、そして今私はとにかく公式を覚えていない...¯\ _(ツ)_ /¯
アルノー

説明ありがとう。これはまだ印象的です:
スコチネット


3

ゼリー27 24バイト

シーケンスのN個の最初の項を返します。

D⁽ÞȦ×^2\%26“⁷wð’æ»ḂẠ
1Ç#

オンラインでお試しください!

これは私のJS回答の移植です。

D⁽ÞȦ×^2\%26“⁷wð’æ»ḂẠ    - helper link: test numpad-friendliness of a number, e.g. 1257
D                       - get decimal digits             -> [1, 2, 5, 7]
    ×                   - multiply by ...
 ⁽ÞȦ                    - ... the integer 6191           -> [6191, 12382, 30955, 43337]
     ^2\                - bitwise XOR overlapping reduce -> [10353, 18613, 53666]
        %26             - modulo 26                      -> [5, 23, 2]
                æ»      - right-shift by each value ...
           “⁷wð’        - ... the integer 8530025        -> [266563, 1, 2132506]
                  Ḃ     - isolate the LSB                -> [1, 1, 0] which means that 1->2
                                                            and 2->5 are OK and 5->7 is not
                   Ạ    - all (0 if there's any 0)       -> 0, i.e. not numpad-friendly :'(

1Ç#                     - main link: return the [input] first matching numbers,
                          using our helper link as a monad and starting with 1

3

05AB1E24 23バイト

µNSü‚εW_iO<ë<3BÆ}ÄR2‹}P

オンラインでお試しください!

シーケンスのn番目の数値を返します。

説明:

µNSü‚εW_iO<ë<3BÆ}ÄR2‹}P    Full program
µ                          Until counter is equal to input
 N                         Push current iteration number (e.g. 1025)
  S                        Split to a list of chars (-> ['1', '0', '2', '5'])
   ü‚                      Group into pairs (-> ['1', '0'], ['0', '2'], ['2', '5'])
     ε                     For each pair
      W_                      Is smallest digit equal to 0?
        iO<                      True: sum all digits and decrement 
           ë                     False: 
            <                       - decrement all digits
             3B                     - convert to base 3
               Æ                    - reduced substraction
                }             End if
                 Ä            Absolute value
                  R           Reverse 
                   2‹         1 if result is < 2, 0 otherwise
                     }     End for each
                      P    Cumulative product (1 if all pair results are 
                                     1, 0 otherwise)
                           -- implicit counter increment if stack value is 1

主なアイデアは、0キーとは別に、デクリメントされてベース3に変換される数字には次のプロパティがあることです。

  • 左右の隣人の絶対差は1です
  • 上下の隣人の絶対差は10で、逆にすると1になります。
  • テンキーのその他のペアは、逆の場合でも異なる値になります

もちろんif0テンキーを処理するステートメントが必要です。


確かな答えは、より多くの改善を提供するようになりましたが、何も見つかりません。Oooo ...そして、そのペアワイズもあなたをリードします:)。
魔法のタコUr

これらの3つのルールを思い付くことができたとは思いませんが、かなり印象的です。何があなたにアイデアを与えましたか?
魔法のタコ

2

MATL29 27バイト

`@J3:qEt!J*+hYAd|2>~A?@]NG-

最初のnテンキーに優しい数字を出力します。

オンラインでお試しください!

説明

1to からの各数字9は、ステップ2グリッドを使用して、テンキー内の位置を表す複素数としてエンコードされます。実数部は垂直位置を表し、虚数部は水平位置を表します。そう1です0+0j2is 0+2j3is 0+4j4is 2+0j、...、9is 4+4jです。

数字は0としてエンコードされ0+1j、それが正確に間に配置されたかのように、すなわち、12

各候補テンキー向け数のために、「小数」ベースの変換は、上記の複素数の代わりに数字を使用して適用され01、...、 9。これにより、絶対連続差が計算される配列が得られます。候補番号は、すべての絶対差が最大2(グリッドステップ)である場合にのみ、テンキーに対応しています。その場合、数値はスタックに残ります。

コードはdo... whileループを使用します。このループは、スタック内の数値の量がinputと等しくなると終了しますn

ユニットグリッドはより自然な選択でした。数字12そして0、その後に対応するであろう0+0j1+0j0.5+0jrespecrively。掛けるので、しかし、それは、ステップ2のグリッドを使用するgolfierです2(機能E)とプッシュ0+1j(機能するJ)1バイトのプッシュよりも短くなっている0+0.5jJ2/または.5j


2

ゼリー、26バイト

’d-,.⁸?3µ€ạ/S
Dṡ2Ç€<2Ạ
1Ç#

オンラインでお試しください!

-2 caird coinheringaahingおかげバイト
-2 Outgolferエリックのおかげでバイト

説明

’d-,.⁸?3µ€ạ/S  Helper Link; compute the distance between two keys z = [x, y]
      ?        Switch:
     ⁸         If z (is not 0):
’              Decrement
 d             Divmod by:
  -,.          Else: [-1, 0.5] (special position for 0)
       3       3; right argument for divmod otherwise ignored
        µ      Begin a new monadic link / end this link
         €     Compute the position for each [x, y]
           /   Reduce on
          ạ    Absolute Difference
            S  Sum (this gives the Manhattan Distance)
Dṡ2Ç€<2Ạ       Helper Link; determine if a number <z> is numpad friendly
D              Convert number to decimal digits
 ṡ             Slice into overlapping slices of length
  2            2 (pairs)
    €          For each pair,
   Ç           The distance between the keys
     <2        Compare with 2 (the distance between two adjacent keys is 1; corners 2; 0 - 1 and 0 - 2 are 1.5)
       Ạ       All; either all of the distances are less than 2 or there were no distances
1Ç#            Main Link; find the first (input) numpad friendly numbers
  #            nfind; counting up from _ collect the first _______ matches that are
1                                      1
                                                           (input)
 Ç             Numpad Friendly

あなたは削除することができます[]2バイトのために
coinheringaahing caird

@cairdcoinheringaahingありがとう!
ハイパーニュートリノ



1

Mathematicaの、249の 234 202バイト

(a=o=1;While[a<=#,s=IntegerDigits@o;t=1;p=0;While[t+p<Length@s,If[!FreeQ[(IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986})[[s[[t]]+1]],s[[t+1]]],t++,p++]];If[t==Length@s,a++];o++];o-1)&


オンラインでお試しください!

データを圧縮してくれたuser202729に感謝(-32バイト)

私の結果:

100-> 447
1000-> 20023
10000-> 788777


を使用してデータを圧縮できると思いますIntegerDigitsIntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}、use FreeQTruseのDo代わりにFor、infix表記をAppendTo使用Doして、While繰り返しの代わりに使用しTr[1^s]、変数も削除しますp。また、アルゴリズムが正しいことを証明していません。つまり、結果の数は、インデックスの2乗よりも常に小さく、回答を有効にするために必要です。
user202729

1
@ user202729私は多くのことを変更しました。私の答えは間違いなく有効です。ここでデータを圧縮します。
J42161217

どうして下票?
J42161217


0

Java 8、192 190バイト

n->{int r=1,p;a:for(;n>0;){p=-1;for(int c:(r+++"").getBytes())if(p>-1&!"012;0124;01235;236;1457;24568;3568;478;5789;689".split(";")[c-=48].contains(p+""))continue a;else p=c;n--;}return~-r;}

nシーケンスの(1-indexed)番目の数を返します。

これは私が思っていたよりも驚くほど大変でした。たぶん、今日の午後に脳みそをいくつか持っているだけでしょう。

説明:

ここで試してみてください。

n->{                 // Method with integer as both parameter and return-type
  int r=1,           //  Return-integer
      p;             //  Previous digit
  a:for(;n>0;){      //  Loop (1) as long as the input is larger than 0
    p=-1;            //   Start `p` at an integer that is not 0-9 (-1 in this case)
    for(int c:(r+++"").getBytes())
                     //   Loop (2) over the digits of the current number
      if(p>=0        //    If this is not the first digit (`p` != -1),
         &!"012;0124;01235;236;1457;24568;3568;478;5789;689".split(";")[c-=48]
           .contains(p+""))
                     //    and the adjacent digits are NOT part of a NumberPad-Friendly Nr:
        continue a;  //     Go to the next iteration of loop (1)
      else           //    Else:
        p=c;         //     Set `p` to the current digit for the next iteration
                     //   End of loop (2) (implicit / single-line body)
      n--;           //   If we haven't encountered the `continue`, decrease `n` by 1
  }                  //  End of loop (1)
  return~-r;         //  Return the result-integer - 1
}                    // End of method
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.