Keyboard satu baris

20

Tantangan

Tujuan dari tantangan ini adalah untuk menentukan apakah suatu String yang diberikan dapat diketik hanya menggunakan satu baris keyboard QWERTY UK standar.

Ini code golf, solusi terpendek dalam byte menang!


IO

Input akan berupa String tunggal nol atau lebih karakter dalam rentang ASCII desimal 32-126 inklusif. Anda dapat mengasumsikan untuk tantangan ini bahwa String kosong tidak memerlukan pengetikan dan dengan demikian dapat diketik menggunakan satu baris.

Anda dapat mengambil input sebagai String, daftar karakter, atau bentuk setara untuk bahasa Anda.

Output harus berupa nilai true untuk String apa pun yang dapat diketik menggunakan satu baris, atau falsey untuk yang tidak bisa.


Tata letak keyboard

Untuk memperjelas setiap ambiguitas tentang apa tata letak keyboard standar di bawah ini adalah daftar tombol yang tersedia di setiap baris, termasuk tombol atas alternatif (diakses menggunakan shift).

  • Baris 1
    • Standar: `1234567890-=
  • Baris 2
    • Standar: qwertyuiop[]
  • Baris 3
    • Standar: asdfghjkl;'#
    • Huruf besar: ASDFGHJKL
    • Spesial: Caps Lock
  • Baris 4
    • Standar: \zxcvbnm,./
    • Bergantian: |<>?
    • Huruf besar: ZXCVBNM
    • Spesial: Bergeser
  • Baris 5
    • Spesial: Space Bar

Tombol atas alternatif hanya dapat ditekan jika Shift juga berada di jalur yang sama, dan tombol huruf besar hanya dapat diakses melalui Caps Lock atau Shift. Anda benar-benar hanya dapat menggunakan satu baris keyboard!


Uji kasus

            -> true     (empty string)
45-2=43     -> true     (line 1)
qwerty      -> true     (line 2)
tryitout    -> true     (line 2)
Qwerty      -> false    (no shift or caps on line 2)
#sad        -> true     (line 3)
AsDf        -> true     (caps lock used)
@sDF        -> false    (no shift for alternate upper)
zxcvbn?     -> true     (line 4)
zxc vbn     -> false    (spacebar on separate line)
123abc      -> false    (multiple lines)
            -> true     (just space bar)
!!!         -> false    (exclamation marks cannot be printed by a single line)
Luke Stevens
sumber
Jadi ini hanya tata letak keyboard AS? (Saya punya tata letak UK).
ouflak
2
@ouflak Sebaliknya, ini hanya tata letak keyboard QWERTY UK
Luke Stevens
@Arnauld Ya saya lakukan, terima kasih telah memperhatikan!
Luke Stevens
Ya saya mulai melihat keduanya dan memperhatikan tata letak Anda tampaknya mengikuti tata letak keyboard UK saya, bukan tata letak AS saya. Hmmm ... Bertanya-tanya seperti apa penampilan orang Austria saya dibandingkan.
ouflak
Apakah kita boleh mengambil input sebagai daftar karakter, atau apakah harus berupa string?
Kevin Cruijssen

Jawaban:

12

Python 2 , 130 123 121 115 byte

lambda s:any(set(s)<=set(l+l.lower())for l in["`1234567890-=","eqwrtyuiop[]","ASDFGHJKL;'#","ZXCVBNM\,./|<>?"," "])

Cobalah online!


Python 3 , 111 byte

lambda s:any({*s}<={*l+l.lower()}for l in["`1234567890-=","eqwrtyuiop[]","ASDFGHJKL;'#","ZXCVBNM\,./|<>?"," "])

Cobalah online!

-4 byte, terima kasih kepada nedla2004

TFeld
sumber
1
Jika Anda bersedia menggunakan Python 3, Anda bisa mendapatkannya hingga 111 byte .
nedla2004
9

Retina 0.8.2 , 72 71 byte

`^([-=\d`]+|[][eio-rtuwy]+|(?i)[adfghjkls;'#]+|[\\bcnmvxz,./|<>?]+| *)$

Cobalah online! Penjelasan: Setiap pergantian cocok dengan baris keyboard yang berbeda. Di (?i)tengah-tengah pola menyebabkan seluruh sisa pola dicocokkan dengan case-insensitive. Sunting: Disimpan 1 byte berkat @ KirillL.

Neil
sumber
opqrdapat diubah menjadi o-runtuk -1. Juga, apakah Anda lupa karakter backtick untuk Jalur 1, saya tidak melihatnya?
Kirill L.
@ KirillL. Aduh, pasti tidak sengaja memilihnya ketika menyalin / menempel, terima kasih telah melihatnya.
Neil
bagus [][...:)
mazzy
8

05AB1E , 66 47 byte

žh…`-=«žS„[]«žTDu…;'#««žUDu"\,./|<>?"««ð)εISåP}O

Mengambil input sebagai daftar karakter.

-19 byte terima kasih kepada @Emigna . Benar-benar lupa kami memiliki built-in konstan qwerty-keyboard. : D

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

žh                # Push "0123456789"
  …`-=            # Push "`-="
      «           # Merge them together
žS                # Push "qwertyuiop"
  „[]             # Push "[]"
     «            # Merge them togeter
žT                # Push "asdfghjkl"
  Du              # Duplicate, and toUppercase the copy
    …;'#          # Push ";'#"
        ««        # Merge all three together
žU                # Push "zxcvbnm"
  Du              # Duplicate, and toUppercase the copy
    "\,./|<>?"    # Push "\,./|<>?"
              ««  # Merge all three together
ð                 # Push a space
 )                # Wrap all string in an array
  ε   }           # Map each to:
   I              #  Take the input (list of characters)
    å             #  Check for each if it's in the current string of the map-iteration
     P            #  Take the product (1 if all are truthy, 0 otherwise)
       O          # Take the sum (either 1 or 0, so truthy/falsey), and output implicitly
Kevin Cruijssen
sumber
8

Perl 5 -pl , 76 byte

$_=/^( *|[\d`=-]+|[][wetyuio-r]+|(?i)[asdfghjkl;'#]+|[\\\/zxcvbnm,.|<>?]+)$/

Cobalah online!

Pendekatan regex yang jelas.

nwellnhof
sumber
6

Ruby -n , 86 81 byte

p /^( *|[\d`=-]+|[\]\[wetyuio-r]+|(?i)[asdfghjkl;'#]+|[\\\/zxcvbnm,.|<>?]+)$/?1:0

Cobalah online!

Kirill L.
sumber
5

JavaScript (Node.js) , 99 98 95 byte

x=>/^([-`=\d]+|[wetyuio-r[\]]+)$/.test(x)|/^([asdfghjkl;'#]+|[zxcvbnm,./<>?\\|]+| *)$/i.test(x)

Cobalah online!

-1 dari komentar oleh @ Kirill L. dalam jawaban Retina.
-3 terima kasih @Ismael Miguel dan @Arnauld untuk upaya gabungan mereka.

Shieru Asakoto
sumber
Mengapa Anda punya asdfghjkldan ASDFGHJKLdi sana? Mengapa Anda tidak menggunakan ibenderanya x=>/.../i.test(x)?
Ismael Miguel
@IsmaelMiguel karena QWERTYUIOPtidak harus dicocokkan oleh regex. Pemeriksaan tambahan akan lebih mahal daripada mengkode huruf-huruf besar itu langsung ke regex.
Shieru Asakoto
Tidak masalah, itu buggy. x=>/^([-`=\d]+|[wetyuio-r\[\]]+)$/.test(x)||/^([asdfghjkl;'#]+|[zxcvbnm,.\/<>?\\|]+| *)$/i.test(x)sama panjangnya
Ismael Miguel
@ IsmaelMiguel Menggunakan bitwise |menghemat 1 byte.
Arnauld
1
@IsmaelMiguel Ini adalah bagian dari spesifikasi ECMAScript. Hanya 3 karakter yang perlu diloloskan dalam kelas karakter \ , ]dan -(lihat ClassAtomNoDash dalam spesifikasi). Tanda hubung juga dapat muncul tidak terhapus jika itu karakter pertama atau terakhir (jika tidak, itu ditafsirkan sebagai pemisah rentang karakter).
Arnauld
5

Perl 6 , 102 101 100 byte

-1 byte terima kasih kepada nwellnhof!

->\a{max map {a.combcomb $_~.lc:},|<eqwrtyuiop[] ASDFGHJKL;'# ZXCVBNM\,./|<>?>,' ',"`-="~[~] ^10}

Cobalah online!

Implementasi standar yang cantik. Mungkin ada solusi berbasis regex yang lebih pendek untuk ini, tapi saya tidak tahu regex Perl 6 cukup baik untuk melakukan upaya.

Jo King
sumber
Anda dapat menggunakan maxsebagai gantinya ?any(dan minbukannya ?all).
nwellnhof
1
Untuk apa nilainya, solusi berbasis regex akan menjadi 84 byte atau 80 byte menggunakan Perl 5 regex dengan m:P5//. Tapi saya pikir keduanya tidak layak untuk dikirim sebagai jawaban.
nwellnhof
4

Java 10, 209 208 byte

s->{int l=0,t;for(var p:s){t=p.matches("[[0-9]`\\-=]")?1:"qwertyuiop[]".contains(p)?2:p.matches("(?i)[asdfghjkl;'#]")?3:"\\zxcvbnm,./|<>?ZXCVBNM".contains(p)?4:p.equals(" ")?5:9;l=l<1?t:l!=t?9:l;}return l<6;}

-1 byte terima kasih kepada @TFeld .

Cobalah online.

Penjelasan:

s->{                    // Method with String-array parameter and boolean return-type
  int l=0,              //  Line-integer, starting at 0
      t;                //  Temp integer
  for(var p:s){         //  Loop over the characters
    t=p.matches("[[0-9]`\\-=]")?
                        //   If it's a character from the first line: 
       1                //    Set `t` to 1
      :"qwertyuiop[]".contains(p)?
                        //   Else-if it's a character from the second line:
       2                //    Set `t` to 2
      :p.matches("(?i)[asdfghjkl;'#]")?
                        //   Else-if it's a character from the third line
       3                //    Set `t` to 3
      :"\\zxcvbnm,./|<>?ZXCVBNM".contains(p)?
                        //   Else-if it's a character from the fourth line:
       4                //    Set `t` to 4
      :p.equals(" ")?   //   Else-if it's a space from the fifth line:
       5                //    Set `t` to 5
      :                 //   Else (invalid character):
       9;               //    Set `t` to 9
    l=l<1?              //   If `l` is still 0:
       t                //    Set it to `t`
      :l!=t?            //   Else-if `t` is a different line than `l`:
       9                //    Set `l` to 9 (non-existing line)
      :                 //   Else (`t` is the same line as `l`):
       l;}              //    Leave `l` the same
  return l<6;}          //  Return whether `l` is not 9
Kevin Cruijssen
sumber
Solusi yang bagus, tetapi hasilnya benar !!!meskipun tanda seru tidak dapat dicetak oleh satu baris pun. Saya baru saja menambahkan itu sebagai test case
Luke Stevens
@LukeStevens Ah, saya salah berasumsi bahwa input selalu valid untuk satu dari lima baris. Saya akan memodifikasi solusi saya. Ini adalah perbaikan sederhana (tetapi akan menambahkan beberapa byte ..)
Kevin Cruijssen
Mengapa tidak digunakan (?i)untuk huruf besar lainnya?
Neil
@Neil Karena pelarian yang diperlukan untuk slash, itu juga 209 byte .
Kevin Cruijssen
Sarankan p==" "alih-alihp.equals(" ")
ceilingcat
4

Powershell, 87 byte

Port of Neil's Retina regex .

"$args"-cmatch"^([-=\d``]+|[][eio-rtuwy]+|(?i)[adfghjkls;'#]+|[\\bcnmvxz,./|<>?]+| *)$"
mazzy
sumber
4

Jelly , 55 byte

ØDW;Øq;Œu$€3,4¦;"“rɠ3“Ż²“¿µ|“aƲƘ0ÞḅzḂ»⁶ṭ
¢f€ẈṠSỊafƑ¢F¤$

Cobalah online!

Baris pertama menghasilkan daftar garis keyboard dan yang kedua memeriksa apakah input program terkandung pada satu baris (atau nol) dan bahwa tidak ada karakter yang tidak dapat diketik (seperti QWE!@#).

dylnan
sumber
3

C , 150 byte

x;f(char*s){for(x=0;*s;x|="@               "[*s++-32]);return!(x&x-1);}

Cobalah online!

Ini tidak akan memenangkan hadiah apa pun, tetapi ini adalah pendekatan yang menyenangkan: kami memetakan karakter pada lima baris keyboard 4 8 16 32 64, dan setiap karakter yang tidak valid 3. Kami bitwise ATAU nilai untuk setiap karakter dalam string bersama-sama, dan memeriksa apakah hasilnya memuaskan x&(x-1) == 0, yang benar ketika xadalah kekuatan 2 atau nol, yaitu setiap kali xmemiliki paling banyak satu bit yang ditetapkan.

Lynn
sumber
2

LUA , 282 262 259 270 bytes

s=io.read()l=0
t=0
for c in s:gmatch"."do
f=c.find
t=f(c,"[0-9%`-=]")or 0|(f(c,"[qwertyuiop%[%]]")or 0)*2|(f(c,"[aAsSdDfFgGhHjJkKlL:'@#~]")or 0)*4|(f(c,"[\\zxcvbnm,./|<>?ZXCVBNM]")or 0)*8|(f(c," ")or 0)*16
t=t==0 and 17or t
l=l<1 and t or l~=t and 17or l
end
print(l<17)

Cobalah online!

ouflak
sumber
2

PHP, 98 byte

Saya sedikit sedih bahwa tidak ada yang lebih pendek dari regex. Itu mungkin bukan solusi tercepat.

<?=preg_match("%^([`\d=-]*|[wetyuio-r[\]]*|(?i)[asdfghjkl;'#]*|[\\\zxcvbnm,./|<>?]*| *)$%",$argn);

Jalankan sebagai pipa dengan -Fatau coba online .


Solusi non-regex terpendek yang saya temukan (124 byte; linebreak dan tab untuk kenyamanan membaca):

foreach(["`1234567890-=","qwertyuiop[]","asdfghjkl;'#ASDFGHJKL","zxcvbnm,./\|<>?ZXCVBNM"," "]as$d)
    trim($argn,$d)>""||die(1);

keluar dengan kode 1untuk kebenaran, 0untuk kepalsuan. Jalankan sebagai pipa dengan -R.
Membutuhkan PHP 5.4 atau yang lebih baru; untuk PHP yang lebih lama, gunakan array(...)alih-alih [...](+5 byte)
atau gunakan 123 byte ini dengan -nRPHP <7:

foreach(split(_,"`1234567890-=_qwertyuiop[]_asdfghjkl;'#ASDFGHJKL_zxcvbnm,./\|<>?ZXCVBNM_ ")as$d)
    trim($argn,$d)>""||die(1);
Titus
sumber
2

AWK , 163 119 113 byte

Ini adalah jawaban AWK, mengembalikan string 1 numerik untuk true, 0 string untuk false. (Ditulis sebagai AWK dipanggil sebagai awk -f file untuk penggunaan interaktif.)

{print/^[-`1234567890=]*$/||/^[]qwertyuiop\[]*$/||/^[asdfghjkl;'#ASDFGHJKL]*$/||/^[zxcvbnm,.\/\|<>?ZXCVBNM]*$/||/^ *$/}

Cobalah online!

Namun, tidak menangani karakter TAB seperti yang tertulis (ekstensi sepele) sebagai bukan bagian dari spesifikasi.

Phil F
sumber
4
"Semua solusi untuk tantangan harus: (...) Menjadi pesaing serius untuk kriteria kemenangan yang digunakan. Misalnya, entri ke kontes golf kode harus golf, dan entri ke kontes kecepatan harus membuat beberapa upaya untuk menjadi cepat . " - help center Tidak perlu mendeklarasikan 2 variabel tersebut dan jelas tidak perlu membuatnya menjadi string. Dan satu saja printsudah cukup: Cobalah secara online!
manatwork
Komentar Anda bahwa solusi harus serius adalah valid tetapi saya berpendapat bahwa solusi apa pun setelah revisi 05AB1E adalah tidak relevan karena mereka tidak dapat mencocokkan atau memperbaiki hasilnya. Saya tidak melihat bagaimana Anda tidak dapat menggunakan cetakan dua kali untuk mendapatkan benar dan salah (tentu untuk sesuatu yang membaca string sampai akhir input). Dan saya bilang dioptimalkan tidak optimal pada saat itu. Berkat pemikiran Anda, ini dapat dikurangi hingga 143 karakter.
Phil F
Dan pada kenyataannya berjalan jauh akan membuatnya menjadi 121 karakter ...
Phil F
2
kode-golf bukan kompetisi untuk kode terpendek secara keseluruhan, tetapi terpendek untuk bahasa Anda. Jika Anda dapat meningkatkan solusi Anda, maka saya sarankan melakukannya
Jo King
@ Jo King, terima kasih atas klarifikasi Anda. kode yang sudah direvisi akan / bisa: {print/^[-```1234567890=]*$/||/^[]qwertyuiop\[]*$/||/^[asdfghjkl;'#ASDFGHJKL]*$/||/^[zxcvbnm,.\/\|<>?ZXCVBNM]*$/||/^ *$/}
Phil F
1

Bash , 119 byte

Termasuk gema untuk memberikan output "dapat dibaca". Jika Anda meletakkan pembungkus shell yang sesuai (pilihan Anda) di sekitarnya untuk menyertakan print / output, maka Anda dapat menghemat 8 byte. Bacaan saya tentang tantangan menyarankan solusi harus menampilkan indikasi output yang cocok jadi saya tetap dengan 119 byte.

[[ "$@" =~ ^[asdfghjklASDFGHJKL\;\'#]*$|^[-\`0-9=]+$|^[]qwertyuiop\[]*$|^[zxcvbnm,./\|\<\>\?ZXCVBNM]*$|^\ *$ ]];echo $?

Cobalah online!

Phil F
sumber
Maklum solusi Bash juga berarti solusi AWK my / @ manatwork saya dapat dikurangi menjadi 113 byte.
Phil F