Hasilkan Nomor Ramah-Numpad

22

Terinspirasi oleh Generate Keyboard Friendly Numbers .

Latar Belakang

Banyak bantalan nomor memiliki tata letak berikut:

789

456

123

    0    

Kami mendefinisikan lingkungan angka sebagai himpunan sel yang berdekatan secara orthogonal pada numpad yang ditunjukkan, termasuk dirinya sendiri. Misalnya, lingkungan 2 adalah {1,5,3,0,2}dan lingkungan 0 adalah {1,2,0}. Ada daftar lingkungan masing-masing angka di bawah ini, di atas kasus uji.

Kami mendefinisikan nomor ramah numpad sebagai bilangan bulat positif di mana, ketika ditulis dalam desimal tanpa memimpin nol, setiap digit kecuali yang pertama berada di lingkungan digit sebelumnya.

Sebagai contoh,

  • 7856 adalah nomor ramah numpad karena 8 ada di lingkungan 7, 5 ada di tetangga 8, dan 6 ada di lingkungan 5.
  • 1201 adalah nomor ramah numpad karena 2 ada di lingkungan 1, 0 di lingkungan 2, dan 1 di lingkungan 0.
  • 82 bukan nomor ramah numpad karena 2 tidak di lingkungan 8.
  • 802 bukan nomor ramah numpad karena 0 tidak di lingkungan 8 (lingkungan tidak membungkus).

Urutan OEIS terkait . Perhatikan bahwa urutan terkait ini berbeda karena urutannya 0berbatasan dengan 7bukan 1dan 2.

Tantangan

Diberikan bilangan bulat positif n, kembalikan nomor n-th atau nnomor ramah numpad pertama , di mana yang pertama adalah 1. Anda dapat menggunakan pengindeksan berbasis 0, di mana nomor ramah ke-0 numpad adalah 1.

Lingkungan sekitar

Lingkungan masing-masing digit tercantum di sini:

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}

Uji Kasus / Urutan

Ini adalah 100 istilah pertama

[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]
fireflame241
sumber
5
Saya suka bagaimana tantangan ini hanya mempertimbangkan bilangan bulat positif (yang menjaga esensi dan memungkinkan lebih banyak bahasa untuk berpartisipasi) dan memungkinkan menampilkan hasil ke- n atau ke- n pertama untuk fleksibilitas
Luis Mendo
Saya sepenuhnya salah membaca tantangan, inilah skrip "apakah istilah ini valid dalam urutan": Coba online!
Magic Octopus Guci

Jawaban:

9

JavaScript (ES6), 104 93 89 88 byte

Mengembalikan istilah N-th dari urutan, 1-diindeks.

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)

Demo

Arnauld
sumber
Yang terbaik yang bisa saya dapatkan adalah 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-1mungkin sesuatu yang bisa membantu, tes saya mungkin terlalu lama
Conor O'Brien
Jawaban ini membawa konsep angka ajaib ke tingkat yang sama sekali baru ... Saya bahkan tidak mengerti bagaimana Anda menemukannya
scottinet
2
@ skottinet Untuk sebagian besar, penjelasan saya untuk jawaban ini juga berlaku untuk yang satu ini. Perbedaan absolut tidak bekerja dengan baik pada yang itu, jadi saya mencoba dengan XOR sebagai gantinya. Sebagai catatan, saya menemukan formula lain yang bekerja di 96% kasus tanpa memerlukan bitmask pencarian. Tetapi memproses 4% sisanya secara terpisah terlalu mahal di JS. Saya tidak mencoba di Jelly , dan sekarang saya tidak ingat rumusnya ... ¯ \ _ (ツ) _ / ¯
Arnauld
Terima kasih atas penjelasannya. Ini masih mengesankan :-)
scottinet
4

Perl 5 , 123 +1 (-p) = 124 byte

while($_){$r=@d=++$\=~/./g;map$r&&=(120,1240,12350,236,1457,24568,3569,478,5789,689)[$d[$_-1]]=~/$d[$_]/,1..$#d;$r&&$_--}}{

Cobalah online!

Xcali
sumber
3

Jelly , 27 24 byte

Mengembalikan N syarat pertama urutan.

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

Cobalah online!

Ini adalah port jawaban JS saya .

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
Arnauld
sumber
3

05AB1E , 24 23 byte

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

Cobalah online!

Mengembalikan nomor ke-n dalam urutan.

Penjelasan:

µ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

Gagasan utamanya adalah bahwa, terlepas dari 0 kunci, setiap digit yang dikurangi dan dikonversi ke basis 3 memiliki properti berikut:

  • tetangga kiri dan kanan memiliki perbedaan absolut 1
  • tetangga atas dan bawah memiliki perbedaan absolut 10 yang, terbalik, sama dengan 1
  • sepasang kunci numpad lainnya menghasilkan nilai yang berbeda, bahkan ketika dibalik

Tentu saja kita membutuhkan ifpernyataan untuk menangani 0kunci numpad.

scottinet
sumber
Jawaban solid, datang untuk menawarkan lebih banyak perbaikan, tidak dapat menemukannya. Oooo ... dan itu berpasangan membuat Anda memimpin juga :).
Magic Octopus Mm
Saya tidak berpikir saya akan bisa datang dengan 3 aturan itu, tbh cukup mengesankan; apa yang memberimu ide?
Magic Octopus Mm
2

MATL , 29 27 byte

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

Menghasilkan nangka ramah numpad pertama .

Cobalah online!

Penjelasan

Setiap digit dari 1ke 9dikodekan sebagai bilangan kompleks yang mewakili posisinya di numpad, menggunakan dalam langkah-2 kisi, di mana bagian nyata mewakili posisi vertikal dan bagian imajiner mewakili posisi horizontal. Jadi 1adalah 0+0j, 2adalah 0+2j, 3adalah 0+4j, 4adalah 2+0j, ..., 9adalah4+4j .

Digit 0dikodekan sebagai 0+1j, yaitu seolah-olah ditempatkan tepat di antara 1dan2 .

Untuk setiap nomor yang ramah numpad kandidat, sebuah "desimal" konversi dasar yang diterapkan menggunakan di atas bilangan kompleks bukan angka 0, 1, ..., 9. Ini memberikan array, di mana perbedaan absolut berturut-turut dihitung. Nomor kandidat ramah numpad jika dan hanya jika semua perbedaan absolut paling banyak2 (yaitu langkah kisi). Jika itu masalahnya, angkanya tertinggal di tumpukan.

Kode menggunakan loop do... while, yang keluar ketika jumlah angka dalam tumpukan sama dengan inputn .

Grid unit akan menjadi pilihan yang lebih alami. Digit 1, 2dan 0kemudian akan sesuai 0+0j, 1+0jdan 0.5+0jmasing-masing. Tapi golfier menggunakan grid langkah-2, karena mengalikan dengan 2(fungsi E) dan mendorong 0+1j(fungsi J) adalah satu byte lebih pendek daripada mendorong 0+0.5j( J2/atau .5j)

Luis Mendo
sumber
2

Jelly , 26 byte

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

Cobalah online!

-2 byte berkat caird coinheringaahing
-2 bytes berkat Erik the Outgolfer

Penjelasan

’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
HyperNeutrino
sumber
Anda dapat menghapus []untuk 2 byte
caird coinheringaahing
@cairdcoinheringaahing terima kasih!
HyperNeutrino
1
Golf beberapa off.
Erik the Outgolfer
2

Python 2 , 134 byte

g=lambda n,k=1:n and g(n-(lambda l:all(abs(a-b)<1.2for a,b in zip(l,l[1:])))([~-d%3+~-d/3*1j-d/~d*1.5for d in map(int,`k`)]),k+1)or~-k

Cobalah online!

Lynn
sumber
Saat Anda mendefinisikan fdan kemudian menggunakannya sekali , Anda bisa memasukkannya dan menyimpan dua byte .
Jonathan Frech
1

Mathematica, 249 234 202 byte

(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)&


Cobalah online!

terima kasih user202729 untuk mengompresi data (-32 bytes)

Hasil saya:

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

J42161217
sumber
Saya pikir Anda dapat mengompres data dengan menggunakan IntegerDigits:, IntegerDigits/@{210,4210,53210,632,7541,86542,9653,874,9875,986}dan menggunakan FreeQ,, Trgunakan Doalih-alih For, gunakan notasi infiks untuk AppendTodan gunakan Doalih-alih Whileuntuk mengulangi Tr[1^s]kali, juga menghilangkan variabel p. Anda juga belum membuktikan bahwa algoritme itu benar, yaitu, jumlah yang dihasilkan selalu kurang dari kuadrat indeksnya, yang diperlukan untuk membuat jawaban valid.
user202729
1
@ user202729 Saya mengubah banyak hal. Jawaban saya pasti valid. Saya akan memampatkan data sekarang.
J42161217
mengapa downvote?
J42161217
1

PHP, 124 +1 byte

while($argn-=$r)for($p=$r=~0,$x=++$n;$x>=1;$p=[7,23,47,76,178,372,616,400,928,832][$c],$x/=10)$r&=!!($p&1<<$c=$x%10);echo$n;

Jalankan sebagai pipa dengan -nRatau coba online .

Titus
sumber
0

Java 8, 192 190 byte

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

Mengembalikan nomor ke (1-diindeks) ndalam urutan.

Ini ternyata lebih sulit daripada yang saya kira .. Mungkin hanya memiliki beberapa kentut otak sore ini ..

Penjelasan:

Coba di sini.

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
Kevin Cruijssen
sumber