Teclado de uma linha


20

O desafio

O objetivo deste desafio é determinar se uma determinada String pode ser digitada usando apenas uma linha de um teclado QWERTY padrão do Reino Unido.

Isto é code golf, a solução mais curta em bytes vence!


IO

A entrada será uma única sequência de zero ou mais caracteres no intervalo decimal ASCII de 32 a 126, inclusive. Você pode assumir que, para esse desafio, uma String vazia não requer digitação e, portanto, pode ser digitada usando uma única linha.

Você pode considerar a entrada como uma sequência, lista de caracteres ou forma equivalente para o seu idioma.

A saída deve ser um valor verdadeiro para qualquer String que pode ser digitada usando uma única linha, ou falsey para uma que não pode.


Layout do teclado

Para esclarecer qualquer ambiguidade sobre o que está abaixo o layout padrão do teclado, há uma lista de teclas disponíveis em cada linha, incluindo teclas superiores alternativas (acessadas usando shift).

  • Linha 1
    • Padrão: `1234567890-=
  • Linha 2
    • Padrão: qwertyuiop[]
  • Linha 3
    • Padrão: asdfghjkl;'#
    • Maiúsculas: ASDFGHJKL
    • Especial: Caps Lock
  • Linha 4
    • Padrão: \zxcvbnm,./
    • Alternar: |<>?
    • Maiúsculas: ZXCVBNM
    • Especial: Turno
  • Linha 5
    • Especial: Barra de espaço

As teclas superiores alternativas somente podem ser pressionadas se Shift também estiver na mesma linha, e as teclas maiúsculas somente podem ser acessadas através de Caps Lock ou Shift. Você realmente só pode usar uma linha de teclado!


Casos de teste

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

Portanto, esses são estritamente os layouts de teclado dos EUA? (Eu tenho um layout no Reino Unido).
ouflak

2
@ouflak Pelo contrário, é estritamente apenas o layout do teclado QWERTY do Reino Unido
Luke Stevens

@ Arnauld Sim, agradeci por perceber!
Luke Stevens

Sim, eu comecei a olhar para os dois e notei que seu layout parece seguir o layout do meu teclado no Reino Unido, não o meu nos EUA. Hmmm ... Gostaria de saber como é o meu austríaco em comparação.
ouflak

Podemos aceitar a entrada como uma lista de caracteres ou precisa ser uma string?
Kevin Cruijssen 10/10

Respostas:


12

Python 2 , 130 123 121 115 bytes

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

Experimente online!


Python 3 , 111 bytes

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

Experimente online!

-4 bytes, graças a nedla2004


1
Se você estiver disposto a usar o Python 3, poderá reduzi-lo para 111 bytes .
nedla2004

9

Retina 0.8.2 , 72 71 bytes

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

Experimente online! Explicação: Cada alternação corresponde a uma linha diferente do teclado. O (?i)meio do padrão faz com que todo o restante do padrão seja correspondido sem distinção entre maiúsculas e minúsculas. Editar: salvou 1 byte graças a @KirillL.


opqrpode ser alterado para o-rpara -1. Além disso, você esqueceu um caractere de backtick para a Linha 1, não o vejo?
quer

@KirillL. Ops, você deve ter deixado de selecioná-lo acidentalmente ao copiar / colar, obrigado por identificá-lo.
Neil

bom [][...:)
Mazzy

8

05AB1E , 66 47 bytes

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

Toma a entrada como uma lista de caracteres.

-19 bytes graças a @Emigna . Esquecemos completamente que tínhamos built-in constantes de teclado qwerty. : D

Experimente online ou verifique todos os casos de teste .

Explicação:

ž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 bytes

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

Experimente online!

-1 do comentário de @Kirill L. na resposta da Retina.
-3 agradece a @Ismael Miguel e @Arnauld pelo esforço conjunto.


Por que você tem asdfghjkle ASDFGHJKLlá dentro? Por que você não usa a ibandeira, tipo x=>/.../i.test(x)?
Ismael Miguel

@IsmaelMiguel porque QWERTYUIOPnão deve ser correspondido pelo regex. A verificação extra custará mais do que codificar essas letras maiúsculas diretamente no regex.
Shieru Asakoto 10/10

Deixa pra lá, é buggy. x=>/^([-`=\d]+|[wetyuio-r\[\]]+)$/.test(x)||/^([asdfghjkl;'#]+|[zxcvbnm,.\/<>?\\|]+| *)$/i.test(x)é o mesmo comprimento
Ismael Miguel

@IsmaelMiguel Usar um bit a bit |economiza 1 byte.
Arnauld 10/10

1
@IsmaelMiguel Isso faz parte da especificação do ECMAScript. As únicas 3 personagens que precisam ser escapado numa classe de caracteres são \ , ]e -(ver ClassAtomNoDash na especificação). O traço também pode parecer sem escape se for o primeiro ou o último caractere (caso contrário, é interpretado como um separador de intervalo de caracteres).
Arnauld 10/10

5

Perl 6 , 102 101 100 bytes

-1 byte graças a nwellnhof!

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

Experimente online!

Implementação bastante padrão. Provavelmente existe uma solução mais curta baseada em regex para isso, mas não conheço a regex do Perl 6 o suficiente para fazer uma tentativa.


Você pode usar em maxvez de ?any(e em minvez de ?all).
Nwellnhof 10/10

1
Pelo que vale, uma solução baseada em regex seria de 84 bytes ou 80 bytes usando os regexes do Perl 5 m:P5//. Mas acho que nenhum deles vale a pena postar como resposta.
Nwellnhof 10/10

4

Java 10, 209 208 bytes

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 graças a @TFeld .

Experimente online.

Explicação:

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

Solução agradável, mas retorna verdadeira, !!!apesar de os pontos de exclamação não poderem ser impressos por nenhuma linha. Acabei de adicionar isso como um caso de teste
Luke Stevens

@LukeStevens Ah, eu assumi falsamente que a entrada é sempre válida para uma das cinco linhas. Vou modificar minha solução. É uma solução simples (mas irá adicionar alguns bytes ..)
Kevin Cruijssen

Por que não usar (?i)para as outras letras maiúsculas?
Neil

@ Neil Por causa da fuga necessária para a barra, também é de 209 bytes .
Kevin Cruijssen 10/10

Sugerir em p==" "vez dep.equals(" ")
ceilingcat 27/09

4

Powershell, 87 bytes

Regex do porto de Neil's Retina .

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

4

Geléia , 55 bytes

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

Experimente online!

A primeira linha produz uma lista das linhas do teclado e a segunda verifica se a entrada do programa está contida em uma única (ou zero) linhas e se não há caracteres que não possam ser digitados (como QWE!@#).


3

C , 150 bytes

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

Experimente online!

Não ganhará nenhum prêmio, mas é uma abordagem divertida: mapeamos caracteres nas cinco linhas do teclado 4 8 16 32 64e todos os caracteres inválidos 3. Nós bit a bit OU o valor de cada caractere na string juntos, e verificamos se o resultado é satisfatório x&(x-1) == 0, o que é verdadeiro quando xé uma potência de 2 ou zero, ou seja, sempre que xhouver no máximo um bit definido.


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)

Experimente online!


2

PHP, 98 bytes

Estou um pouco triste por não haver nada mais curto que regex. Provavelmente não é a solução mais rápida.

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

Execute como pipe -Fou experimente online .


A solução não-regex mais curta que encontrei (124 bytes; quebra de linha e guia para facilitar a leitura):

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

sai com código 1para verdade, 0para falsidade. Corra como cano com -R.
Requer PHP 5.4 ou posterior; para PHP antigo, use em array(...)vez de [...](+5 bytes)
ou use esses 123 bytes -nRno PHP <7:

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

2

AWK , 163 119 113 bytes

Esta é uma resposta AWK, retorna uma string numérica 1 para true, 0 string para false. (Escrito como AWK, invoque como arquivo awk -f para uso interativo.)

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

Experimente online!

No entanto, não lida com o caractere TAB como gravado (extensão trivial) como parte da especificação.


4
"Todas as soluções para os desafios devem: (...) ser um candidato sério aos critérios de vencimento em uso. Por exemplo, uma entrada em um concurso de código de golfe precisa ser jogada, e uma entrada em um concurso de velocidade deve tentar ser rápido . " - centro de ajuda Não há necessidade de declarar essas duas variáveis ​​e, definitivamente, não há necessidade de torná-las strings. E printbasta um single : Experimente online!
manatwork

Seu comentário de que as soluções devem ser sérias é válido, mas eu argumentaria que qualquer solução, portanto, após a 05AB1E revisada é, portanto, irrelevante, pois não poderia corresponder ou melhorar o resultado. Não vejo como você não pode usar print duas vezes para obter verdadeiro e falso (certamente para algo que lê cadeias de caracteres até o final da entrada). E eu disse que otimizado não é o ideal na época. Graças aos seus pensamentos, ele pode ser reduzido para 143 caracteres.
Phil F

E, de fato indo todo o caminho irá torná-lo 121 caracteres ...
Phil F

2
O code-golf não é uma competição pelo código mais curto em geral, mas pelo seu idioma. Se você pode melhorar a sua solução, então eu sugiro fazê-lo
Jo rei

@Jo King, obrigado por seus esclarecimentos. o código revisado seria / poderia ser: # {print/^[-```1234567890=]*$/||/^[]qwertyuiop\[]*$/||/^[asdfghjkl;'#ASDFGHJKL]*$/||/^[zxcvbnm,.\/\|<>?ZXCVBNM]*$/||/^ *$/}
Phil F #

1

Bash , 119 bytes

Inclui um eco para fornecer saída "legível". Se você colocar um invólucro de casca adequado (sua escolha) ao redor para incluir impressão / saída, poderá salvar 8 bytes. Minha leitura do desafio sugere que a solução deve gerar uma indicação de saída adequada, portanto, permaneço com 119 bytes.

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

Experimente online!


Esteja ciente de que a solução Bash também significa que minha solução AWK / @ manatwork pode ser reduzida para 113 bytes.
Phil F
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.