Nomor Ksatria Numpad

33

Untuk digit non-nol pada numpad standar

789
456
123

pertimbangkan untuk menempatkan ksatria catur pada angka berapa pun dan menggerakkannya dengan sejumlah lompatan berbentuk L normal, menelusuri bilangan bulat desimal positif. Bilangan bulat positif apa yang dapat diekspresikan sedemikian rupa?

Salah satunya adalah 38, karena ksatria bisa mulai di 3dan bergerak ke kiri dan ke atas 8. 381dan 383juga dimungkinkan.

3itu sendiri dimungkinkan jika tidak ada lompatan yang diambil (yang diizinkan). 5juga, tetapi tidak ada angka lain yang dapat dicapai dari 5, jadi itu adalah satu-satunya angka di mana angka itu 5muncul.

Tulis program atau fungsi yang menggunakan bilangan bulat desimal positif (Anda dapat menganggapnya sebagai string jika diinginkan) dan mencetak atau mengembalikan nilai kebenaran jika angka tersebut dapat diekspresikan oleh seorang ksatria pada numpad dengan cara yang dijelaskan, tetapi sebaliknya menghasilkan sebuah falsy nilai.

Kode terpendek dalam byte menang. Tiebreaker adalah jawaban sebelumnya

Contohnya

Benar:

1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 18, 38, 61, 81, 294, 349, 381, 383, 729, 767, 38183, 38383, 18349276, 183492761, 618349276

Falsy:

10, 11, 50, 53, 55, 65, 95, 100, 180, 182, 184, 185, 186, 187, 188, 189, 209, 305, 2009, 5030, 3838384, 4838383, 183492760
Hobi Calvin
sumber
2
Ada apa dengan ksatria catur hari ini ? :-D
Luis Mendo
1
Petunjuk: Jika Anda menuliskan angka-angka sebagai garis pembungkus, maka ksatria selalu melompat empat ruang searah jarum jam atau empat ruang penghitung. Saya tidak tahu apakah ini bermanfaat.
Dana Gugatan Monica
3
@LuisMendo Wrapping. Seperti dalam, jika Anda memperlakukan adalah sebagai daftar tak berujung 78963214, diulang berulang kali. Hitung jaraknya - selalu empat, satu arah atau lainnya. Saya seharusnya lebih jelas dan secara eksplisit mengatakan bahwa Anda harus menulisnya dalam urutan lingkaran.
Dana Gugatan Monica
@ QPaysTaxes Oh, saya pikir Anda maksud lingkaran tetapi 123...9. Maaf
Luis Mendo
@LuisMendo Jangan khawatir. Seperti yang saya katakan, saya seharusnya lebih jelas tentang apa yang saya maksudkan.
Dana Gugatan Monica

Jawaban:

16

Jelly, 19 15 14 byte

Doȷ’d3ạ2\P€=2P

Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

Doȷ’d3ạ2\P€=2P  Main link. Argument: n (integer)

D               Convert n to base 10 (digit array).
  ȷ             Yield 1000.
 o              Logical OR. This replaces each 0 with 1000.
   ’            Decrement each digit.
    d3          Divmod; replace each digit k with [k:3, k%3].
      ạ2\       Pairwise reduce by absolute difference.
                For each pair of adjacent digits [i, j], this computes
                [abs(i:3 - j:3), abs(i%3 - j%3)].
         P€     Compute the product of each result.
                n is a Numpad's Knight Number iff all products yield 2.
           =2   Compare each product with 2.
             P  Multiply the resulting Booleans.
Dennis
sumber
18

Python 2, 52 byte

f=lambda n:n<6or`n%100`in'18349276167294381'*f(n/10)

Periksa apakah ada dua digit berurutan dalam string '18349276167294381'. Untuk mendapatkan digit berturut-turut, alih-alih melakukan zip(`n`,`n`[1:]), fungsi berulang kali memeriksa dua digit terakhir dan menghapus digit terakhir.

Tidak
sumber
13

Retina , 58 40 byte

Terima kasih kepada Sp3000 untuk menyarankan ide ini:

M&!`..
O%`.
A`16|18|27|29|34|38|49|67
^$

Cobalah online! (Sedikit dimodifikasi untuk menjalankan seluruh test suite sekaligus.)

Mencetak 1untuk 0hasil yang benar dan salah.

Penjelasan

M&!`..

Temukan semua kecocokan yang tumpang tindih .., yaitu semua pasangan digit berurutan, dan bergabunglah dengan umpan garis.

O%`.

Urutkan digit di setiap baris, sehingga kita hanya perlu memeriksa separuh jumlah pasangan.

A`16|18|27|29|34|38|49|67

Hapus semua garis yang sesuai dengan langkah yang valid.

^$

Hitung kecocokan dari regex ini. Yaitu, jika semua baris dihapus, ini cocok dengan string kosong yang dihasilkan sekali, jika tidak gagal untuk mencocokkan dan memberikan nol sebagai gantinya.

Martin Ender
sumber
7

Pyth - 35 28 byte

!s.bt/@c`C"_xÖ({ζz"2tsNYztz

Test Suite .

Maltysen
sumber
7

Ruby, 57 byte

Fungsi anonim. Argumen adalah sebuah string.

->n{(0..n.size).count{|i|!"16729438183492761"[n[i,2]]}<1}

Program dengan suite tes:

f=->n{(0..n.size).count{|i|!"16729438183492761"[n[i,2]]}<1}

a=%w{1 2 3 4 5 6 7 8 9 16 18 38 61 81 294 349 381 383 729 767 38183 38383 18349276 183492761 618349276
10 11 50 53 55 65 95 100 180 182 184 185 186 187 188 189 209 305 2009 5030 3838384 4838383 183492760}

a.each {|e|p [e, f[e]]}

Saya baru saja mengkodekan semua kemungkinan knight move ke dalam string dan memeriksa apakah setiap 2 digit di dalam input ada di string itu.

Nilai Tinta
sumber
Oh, string pencarian itu juga akan menyelamatkan saya 17 byte. Apakah Anda keberatan jika saya menggunakannya untuk jawaban Retina saya?
Martin Ender
Lakukan itu! Berikan kredit, kurasa.
Nilai Tinta
Terima kasih, tetapi saya berakhir dengan solusi yang lebih pendek berdasarkan saran dari Sp3000 :)
Martin Ender
6

grep 58 byte

grep "^((?=18|16|29|27|34|38|49|43|61|67|72|76|81|83|94|92).)*.$"

Karena sungguh, jika Anda tidak dapat mengalahkan grep ...

Yakk
sumber
2
Baik 5atau 185memancarkan 1dengan baris perintah Anda, sementara 5di truthy, dan 185dalam daftar falsy.
Guntram Blohm mendukung Monica
1
@GuntramBlohm diperbaiki - tersesat dalam negasi reguler
Yakk
6

Haskell 46 byte

q=zip<*>tail
all(`elem`q"16729438183492761").q

Contoh penggunaan: all(`elem`q"16729438183492761").q $ "183492761"->True

Cara kerjanya: Menggunakan string pencarian yang ditemukan di jawaban @Kevin Lau . qmembuat daftar pasangan karakter yang berdekatan dari string, misalnya q "1672" -> [('1','6'),('6','7'),('7','2')]. Fungsi mengembalikan true jika semua pasangan dari input muncul di pasangan dari string pencarian. qmengubah input satu digit ke daftar kosong, jadi elemselalu berhasil.

nimi
sumber
Mengapa zip<*>tailberfungsi seperti versi terbalik zip=<<tail? Saya pikir saya tidak mengerti apa yang digeneralisasikan oleh pelamar.
xnor
@ xnor: Saya hanya menggunakannya. <*> didefinisikan sebagai (<*>) f g x = f x (g x) .
nimi
6

JavaScript (ES6), 65 62 byte

s=>[...s].every((c,i)=>!i|"16729438183492761".match(s[i-1]+c))

Mengembalikan nilai true atau false. Saya sebelumnya telah mencoba solusi rekursif, yang membutuhkan 63 byte, dan mapdan bahkan reducetetapi mereka membawa saya 73 byte.

Sunting: Disimpan 3 byte berkat @ user81655.

Neil
sumber
Tidak bisa berbuat lebih baik, percobaan terbaik saya adalah pada 88 byte. Bravo!
Naouak
@ user81655 Maksud Anda matchbekerja, bukan~search (tapi bagaimanapun, itu benar-benar curang) dan |dapat menggantikan ||(tetapi tidak dalam versi rekursif, sayangnya.)
Neil
@ user81655 saya mengacu pada cara itu !i|...match bekerja karena hasil pertandingan, jika berhasil, adalah array dari string tunggal dua digit, yang |akhirnya dipaksakan oleh operator menjadi integer yang valid.
Neil
@Neil Ah, benar.
user81655
6

C, 85 81 byte

Golf:

i;f(char*b){i=*b++-49;return*b?(*b=="8749x7214"[i]||*b=="6983x1632"[i])&&f(b):1;}

Versi non-rekursif lama (85 byte):

i;f(char*b){for(;(i=*b++-49),*b&&*b=="8749x7214"[i]||*b=="6983x1632"[i];);return!*b;}

Kode lama dengan ruang putih dan program utama:

i;
f(char*b){
    for (; (i=*b++-49), *b     // i = index of digit + 1 in following arrays
        &&*b=="8749x7214"[i]   // 1st possible jump for 1..9
        ||*b=="6983x1632"[i];  // 2nd possible jump for 1..9
    );
    return !*b;
}

main(){
    char b[16];
    while(scanf("%s", b) == 1) printf("%d",f(b));
    return 0;
}

Ini menerima angka yang dibatasi ruang melalui input standar dan menghasilkan 0 jika tidak-numpad-knight, atau 1 sebaliknya.

Versi rekursif 81-byte baru mencukur 4 byte.

tucuxi
sumber
5

MATL , 38 37 29 byte

Ini menggunakan gagasan @QPaysTaxes .

I:8JK5:7Pvj!Uttnqh?)d|2:EQm}h

Outputnya adalah array 2D, kompleks, tidak kosong. Adalah benar jika semua nilainya memiliki bagian nyata yang bukan nol, dan sebaliknya salah.

Cobalah online!

Luis Mendo
sumber
1
Apakah ini bahkan diizinkan ??
CalculatorFeline
Pertanyaannya meminta nilai yang benar atau salah , bukan seluruh array.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
2
@CatsAreFluffy Ini adalah definisi kami tentang truthy / falsy. Seperti dalam MATLAB / Oktaf, array benar di MATL jika semua elemennya benar. ( contoh )
Dennis
CC @ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
Dennis
4

MATL, 25 24 33 26 byte

Dicukur 1 byte berkat @LuisMendo!
@ Dennis menemukan bug, dan kemudian memperbaikinya! Terima kasih!

'bSVYXbTUZW'j47-)d2^48\1=A

Mengambil bilangan bulat sebagai input. Output 1/0.

Cobalah online!

gelas kimia
sumber
@LuisMendo Tepat di kedua hal, terima kasih!
gelas kimia
@Dennis Diperbarui, dan semoga benar. Terima kasih atas bantuan Anda.
gelas kimia
Saya tidak berpikir Anda perlu Apada akhirnya. Vektor MATL adalah benar jika mereka tidak mengandung 0.
Dennis
4

C, 140 92 byte

c;L(char*i){while(*i&&(!c||*i=="6743x1212"[c-49]||*i=="8989x7634"[c-49]))c=*i++;return !*i;}

Dengan asumsi ASCII

Detail Coba di sini

// valid transition from x to n[x-'1'][0 or 1]

int n[9][2] =
{
    {'6','8'},{'7','9'},{'4','8'},
    {'3','9'},{'x','x'},{'1','7'},
    {'2','6'},{'1','3'},{'2','4'}
};

// i is a pointer to where to start on a string

bool L(char * i)
{
    char c = 0;

    // move if not \0 and (not-first-char or is a valid move)

    while((*i) && (!c || (*i)==n[c-'1'][0] || (*i)==n[c-'1'][1]))
    {
        c = (*i++);
    }

    return !(*i); // success if it's \0
}
Khaled.K
sumber
tabel pencarian itu sangat besar. Anda dapat meningkatkan skor banyak jika Anda menghilangkan semua pembatas {,}[]dan menyandikannya sebagai char*string. Juga, perhatikan bahwa Anda #definetidak hemat biaya ketika Anda hanya menggunakannya dua kali: menghapusnya akan menghemat 4 byte.
tucuxi
@tucuxi terima kasih atas tipsnya, saya berhasil menurunkannya menjadi 92, karena \0di dalam array menyebabkan perilaku yang tidak terdefinisi jadi saya menggantinya denganx
Khaled.K
Bagus - juga, jangan lupa gunakan <s>oldscore</s> newscoresaat mengedit untuk mencerminkan peningkatan skor, dan <!-- language-all: lang-c -->sebelum kode Anda mulai memperbaiki penyorotan sintaksis. Saya juga berhasil mengurangi byte-count saya agak dengan menjatuhkan loop sama sekali
tucuxi
'Perincian' Anda terlihat sangat berbeda dari perluasan kode golf yang sederhana (di mana ada ndalam versi pendek?). Juga, Anda mungkin harus menyebutkan bahwa Anda mengasumsikan pengkodean ASCII - Anda akan mendapatkan nomor yang berbeda pada mesin EBCDIC.
Toby Speight
@TobySpeight versi terperinci seharusnya menunjukkan bagaimana itu dibangun pada dasarnya, ya saya mengasumsikan ASCII yang merupakan kasus umum dalam C.
Khaled.K
3

Julia, 51 49 byte

n->diff(["@1634@8725"...][digits(n)+1]).^2%48⊆1

Verifikasi

julia> f=n->diff(["@1634@8725"...][digits(n)+1]).^2%48⊆1
(anonymous function)

julia> all(map(f,(1,2,3,4,5,6,7,8,9,16,18,38,61,81,294,349,381,383,729,767,38183,38383,18349276,183492761,618349276)))
true

julia> any(map(f,(10,11,50,53,55,65,95,100,180,182,184,185,186,187,188,189,209,305,2009,5030,3838384,4838383,183492760)))
false
Dennis
sumber
3

Sebenarnya, 30 byte

;#pXZdX`Σ"67294381";'1+R+íu`Mπ

Mengambil input sebagai string. Menghasilkan bilangan bulat positif untuk true dan 0 untuk false.

Cobalah online!

Penjelasan:

;#pXZdX`Σ"67294381";'1+R+íu`Mπ
                                 (implicit) push input
;#pXZdx                         push zip(n[:-1], n[1;]) (pairs of digits)
       `Σ"67294381";'1+R+íu`M   map:
        Σ                         join digits
         "67294381";'1+R+         push "16729438183492761" (the magic string used in many other solutions)
                         íu       0-based index (-1 if not found), increment so 0 is not found and >=1 is the 1-based index
                             π  product
Mego
sumber
3

PowerShell v2 +, 105 96 byte

param($a)((1..$a.length|%{'27618349294381672'.IndexOf($a[$_-1]+$a[$_])+1})-join'*'|iex)-or$a-eq5

Iterasi melalui input (yang harus dienkapsulasi dengan "") dengan memverifikasi bahwa indeks dari setiap pasangan karakter berurutan ada dalam string pencarian yang valid. Saya melihat Kevin Lau memiliki sesuatu yang serupa , tetapi saya datang dengan ini secara mandiri. Masing-masing indeks ditambahkan dengan +1, karena .IndexOf()fungsi akan kembali -1jika string tidak ditemukan. Ini akan mengubah "tidak ditemukan" menjadi 0.

Kami kemudian -joinsemua nilai integer yang dihasilkan dengan *dan pipa itu ke iex(mirip dengan eval). Ini berarti jika salah satu dari indeks tidak ditemukan, seluruh ekspresi akan menghasilkan 0. Itu dirangkum dalam parens dan -orakan dengan $a-eq5untuk kasus khusus input "5"untuk mencapai hasil keluaran kami.

Tes Berjalan

PS C:\Tools\Scripts\golfing> 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 18, 38, 61, 81, 294, 349, 381, 383, 729, 767, 38183, 38383, 18349276, 183492761, 618349276 | %{.\numpad-knight-numbers.ps1 "$_"}
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True

PS C:\Tools\Scripts\golfing> 10, 11, 50, 53, 55, 65, 95, 100, 180, 182, 184, 185, 186, 187, 188, 189, 209, 305, 2009, 5030, 3838384, 4838383, 183492760 | %{.\numpad-knight-numbers.ps1 "$_"}
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
False
AdmBorkBork
sumber
2

C, 78 byte

char*a="9614397052";f(x){int b=x/10;return!b||abs(a[x%10]-a[b%10])%6==1&f(b);}

Karena semua orang telah mengambil input sebagai string, saya mencoba melakukannya dalam bilangan bulat. Ia bekerja secara rekursif dari digit paling tidak signifikan ( a%10); jika itu satu-satunya digit, maka kembalikan benar. Jika tidak, kembalikan benar hanya jika puluhan digit ( b%10) tidak dapat dicapai dari digit satuan, dan (secara rekursif), sisa input memenuhi pengujian yang sama.

Tes untuk keterjangkauan bekerja dengan mengkodekan tur knight secara linear, dan mengubah setiap digit ke posisi (nol hingga tujuh) pada tur. Untuk digit 0dan 5, kami menetapkan posisi sembilan, yang terputus dari posisi lain. Kemudian, angka-angka yang dapat saling dijangkau berbeda satu per satu (mod delapan); yaitu a[x%10]-a[b%10]± 1 atau ± 7. Jadi kami menguji perbedaan absolut (mod 6) terhadap 1.

Solusi ini berfungsi untuk pengkodean karakter apa pun yang valid untuk C (yaitu digit memiliki kode yang berdekatan dari 0 hingga 9).

Toby Speight
sumber
1

Java 8, 179 167 Bytes

Tempatkan int nomor pad (minus 5 dan 0) dalam lingkaran. lmemegang indeks lingkaran int ini. Jika perbedaan dua indeks adalah +/- 3 mod 8, maka ada gerakan ksatria antara int yang sesuai dengan indeks tersebut. Perhatikan itu xadalah int[].

x->{if(x.length<2)return 1;int[] l={0,0,1,2,7,0,3,6,5,4};int o=l[x[1]];for(int i:x){int n=l[i];if(i%5==0||(Math.abs(n-o)!=3&&Math.abs(n-o)!=5))return 0;o=n;}return 1;}

Memperbarui

  • -11 [16-12-10] Beralih ke lambda
  • -1 [16-12-10] Gunakan <2sebagai ganti==1
Buah Nonlinier
sumber