Клавиатура в одну линию

20

Соревнование

Цель этой задачи - определить, можно ли набирать данную строку, используя только одну строку стандартной британской QWERTY-клавиатуры.

Это code golfсамое короткое решение в байтах!


IO

Ввод будет одной строкой из нуля или более символов в десятичном диапазоне ASCII от 32 до 126 включительно. Для этой задачи вы можете предположить, что пустая строка не требует ввода и, следовательно, может быть набрана с помощью одной строки.

Вы можете принять ввод в виде строки, списка символов или эквивалентной формы для вашего языка.

Вывод должен быть истинным значением для любой строки, которая может быть набрана с использованием одной строки, или ложью для строки, которая не может.


Раскладка клавиатуры

Чтобы прояснить любую неоднозначность относительно того, какая стандартная раскладка клавиатуры приведена ниже, приведен список клавиш, доступных в каждой строке, включая альтернативные верхние клавиши (доступ к которым осуществляется с помощью клавиши shift).

  • Строка 1
    • Стандарт: `1234567890-=
  • Линия 2
    • Стандарт: qwertyuiop[]
  • Линия 3
    • Стандарт: asdfghjkl;'#
    • Верхний регистр: ASDFGHJKL
    • Специальный: Caps Lock
  • Строка 4
    • Стандарт: \zxcvbnm,./
    • Alternate: |<>?
    • Верхний регистр: ZXCVBNM
    • Специальный: Shift
  • Строка 5
    • Специальный: пробел

Альтернативные верхние клавиши могут быть нажаты только в том случае, если Shift также находится в той же строке, а клавиши в верхнем регистре доступны только через Caps Lock или Shift. Вы действительно можете использовать только одну линию клавиатуры!


Контрольные примеры

            -> 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)
Люк Стивенс
источник
Так это сугубо американские раскладки клавиатуры? (У меня есть макет в Великобритании).
августа
2
@ouflak Напротив, это строго только раскладка клавиатуры QWERTY в Великобритании
Люк Стивенс
@Arnauld Да, спасибо, что заметили!
Люк Стивенс
Да, я начал смотреть на оба и заметил, что ваша раскладка, похоже, соответствует моей раскладке клавиатуры в Великобритании, а не моей. Хммм ... Интересно, как выглядит мой австрийский в сравнении.
августа
Разрешено ли использовать входные данные в виде списка символов или это должна быть строка?
Кевин Круйссен

Ответы:

12

Python 2 , 130 123 121 115 байтов

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

Попробуйте онлайн!


Python 3 , 111 байт

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

Попробуйте онлайн!

-4 байта, благодаря nedla2004

TFeld
источник
1
Если вы хотите использовать Python 3, вы можете уменьшить его до 111 байт .
nedla2004
9

Retina 0.8.2 , 72 71 байт

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

Попробуйте онлайн! Объяснение: Каждое чередование соответствует отдельному ряду клавиатуры. В (?i)середине шаблона происходит сопоставление всего остального шаблона без учета регистра. Редактировать: 1 байт сохранен благодаря @KirillL.

Нил
источник
opqrможно изменить o-rна -1. Кроме того, вы забыли символ обратной черты для строки 1, я не вижу этого?
Кирилл Л.
@KirillL. Ой, должно быть, случайно пропустил выбор при копировании / вставке, спасибо, что заметили это.
Нил
приятно [][...:)
mazzy
8

05AB1E , 66 47 байт

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

Принимает ввод в виде списка символов.

-19 байт благодаря @Emigna . Полностью забыл, что у нас были постоянные встроенные функции qwerty-клавиатуры. : D

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

ž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
Кевин Круйссен
источник
5

JavaScript (Node.js) , 99 98 95 байт

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

Попробуйте онлайн!

-1 из комментария @Kirill L. в ответе Retina.
-3 спасибо @Ismael Miguel и @Arnauld за их совместные усилия.

Сиеру Асакото
источник
Почему у вас asdfghjklи ASDFGHJKLтам? Почему вы не используете iфлаг, как x=>/.../i.test(x)?
Исмаэль Мигель
@IsmaelMiguel, потому QWERTYUIOPчто регулярное выражение не должно совпадать. Дополнительная проверка будет стоить больше, чем кодирование этих заглавных букв непосредственно в регулярное выражение.
Шиеру Асакото
Неважно, это глючит. x=>/^([-`=\d]+|[wetyuio-r\[\]]+)$/.test(x)||/^([asdfghjkl;'#]+|[zxcvbnm,.\/<>?\\|]+| *)$/i.test(x)такой же длины
Исмаэль Мигель
@IsmaelMiguel Использование побитового |сохраняет 1 байт.
Арно
1
@IsmaelMiguel Это часть спецификации ECMAScript. Только 3 символов , которые должны быть экранированы внутри класса символов являются \ , ]и -(см АтомаКлассаБезТира в спецификации). Тире также может отображаться без экранирования, если это первый или последний символ (в противном случае он интерпретируется как разделитель диапазона символов).
Арно
5

Perl 6 , 102 101 100 байт

-1 байт благодаря nwellnhof!

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

Попробуйте онлайн!

Довольно стандартная реализация. Вероятно, есть более короткое решение на основе регулярных выражений, но я недостаточно хорошо знаю регулярное выражение Perl 6, чтобы попытаться сделать это.

Джо Кинг
источник
Вы можете использовать maxвместо ?anyminвместо ?all).
nwellnhof
1
Что бы это ни стоило, решение на основе регулярных выражений будет 84 байта или 80 байтов с использованием регулярных выражений Perl 5 с m:P5//. Но я не думаю, что кто-то из них стоит опубликовать в качестве ответа.
nwellnhof
4

Java 10, 209 208 байт

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 байт благодаря @TFeld .

Попробуйте онлайн.

Объяснение:

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
Кевин Круйссен
источник
Хорошее решение, но оно возвращает истину, !!!несмотря на то, что восклицательные знаки не могут быть напечатаны ни одной строкой. Я только что добавил это в качестве теста
Люк Стивенс
@ LukeStevens Ах, я ошибочно предположил, что ввод всегда действителен для одной из пяти строк. Я изменю свое решение. Это простое исправление (но добавит несколько байтов ..)
Кевин Круйссен
Почему бы не использовать (?i)другие заглавные буквы?
Нил
@Neil Из-за экранирования, необходимого для косой черты, он также составляет 209 байтов .
Кевин Круйссен
Предлагаю p==" "вместоp.equals(" ")
потолок кошка
4

Powershell, 87 байт

Port of Neil's Retina regex .

"$args"-cmatch"^([-=\d``]+|[][eio-rtuwy]+|(?i)[adfghjkls;'#]+|[\\bcnmvxz,./|<>?]+| *)$"
Mazzy
источник
4

Желе , 55 байт

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

Попробуйте онлайн!

Первая строка выдает список строк клавиатуры, а вторая проверяет, содержится ли ввод программы в одной (или нулевой) строке и нет ли символов, которые нельзя набрать (например QWE!@#).

dylnan
источник
3

С , 150 байтов

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

Попробуйте онлайн!

Он не выиграет никаких призов, но это забавный подход: мы сопоставляем символы на пяти строках клавиатуры с 4 8 16 32 64каждым недопустимым символом 3. Мы поразрядно ИЛИ значение для каждого символа в строке вместе, и проверяем, удовлетворяет ли результат x&(x-1) == 0, который является истинным, когда xэто степень 2 или ноль, то есть всякий раз, когда xустановлен не более одного бита.

Линн
источник
2

LUA , 282 262 259 270 байт

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)

Попробуйте онлайн!

ouflak
источник
2

PHP, 98 байт

Мне немного грустно, что нет ничего короче, чем регулярное выражение. Это, наверное, не самое быстрое решение.

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

Запустите как трубу с -Fили попробуйте онлайн .


Самое короткое решение без регулярных выражений, которое я нашел (124 байта; перенос строки и табуляция для удобства чтения):

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

выходит с кодом 1для правды, 0для фальши. Беги как труба с -R.
Требуется PHP 5.4 или более поздняя версия; для более старого PHP используйте array(...)вместо [...](+5 байт)
или используйте эти 123 байта -nRв PHP <7:

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

AWK , 163 119 113 байтов

Это ответ AWK, возвращает числовую 1 строку для истины, 0 строку для ложной. (Записывается как AWK, вызывается как файл awk -f для интерактивного использования.)

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

Попробуйте онлайн!

Однако, не обрабатывает символ TAB как написано (тривиальное расширение), как не часть спецификации.

Фил Ф
источник
4
«Все решения проблем должны: (…) быть серьезным претендентом на критерии выигрыша в использовании. Например, участие в состязании по коду для гольфа должно быть в гольфе, а участие в соревновании по скорости должно быть попыткой быть быстрым «. - Справочный центр Нет необходимости объявлять эти 2 переменные и определенно не нужно делать их строками. И достаточно одного print: попробуйте онлайн!
manatwork
Ваш комментарий о том, что решения должны быть серьезными, действителен, но я бы сказал, что любое решение, поэтому после пересмотренного 05AB1E, не имеет значения, так как они не могут соответствовать или улучшить результат. Я не вижу, как вы не можете использовать print дважды, чтобы получить и истину, и ложь (конечно, для чего-то, что читает строки до конца ввода). И я сказал, оптимизированный не оптимальный в то время. Благодаря вашим мыслям его можно уменьшить до 143 символов.
Фил Ф
И на самом деле проделав весь путь, вы получите 121 символ ...
Фил Ф
2
Код-гольф - это не соревнование за самый короткий код в целом, но самый короткий для вашего языка. Если вы можете улучшить свое решение, то я бы предложил сделать это
Джо Кинг,
@ Джо Кинг, спасибо за разъяснения. пересмотренный код будет / может быть: {print/^[-```1234567890=]*$/||/^[]qwertyuiop\[]*$/||/^[asdfghjkl;'#ASDFGHJKL]*$/||/^[zxcvbnm,.\/\|<>?ZXCVBNM]*$/||/^ *$/}
Phil F
1

Баш , 119 байт

Включает эхо, чтобы обеспечить «читаемый» вывод. Если вы поместите вокруг него подходящую оболочку оболочки (на ваш выбор), чтобы включить печать / вывод, то вы можете сохранить 8 байтов. Мое чтение задачи показывает, что решение должно выводить подходящую индикацию вывода, поэтому я придерживаюсь 119 байтов.

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

Попробуйте онлайн!

Фил Ф
источник
Имейте в виду, что решение Bash также означает, что моё решение / @ manatwork AWK может быть уменьшено до 113 байт.
Фил Ф