Encontre palavras com uma mão


12

'exagerado' é um exemplo de uma palavra que pode ser digitada na mão esquerda, em um mapa de teclado qwerty normal. 'monopólio' é um exemplo para a mão direita.

Pesquisando no wordsarquivo unix por palavras que podem ser digitadas por um lado. A saída deve ter duas linhas: lista separada por espaços dessas palavras para a mão esquerda, seguida pela lista para a mão direita. por exemplo

a abaft abase abased abases abate abated abates abbess abbesses ...
h hi hill hilly him hip hippo hippy ho hokum ...

As letras da esquerda são:

qwertasdfgzxcvb

As letras da direita são:

yuiophjklnm'

Letras maiúsculas contam como uma mão; letras com diacríticos contam como duas mãos e, portanto, as palavras que as contêm podem ser ignoradas.


2
As letras maiúsculas requerem duas mãos ou uma? Suponho que caracteres como "é" não possam ser digitados com as duas mãos, certo? Finalmente, eu assumo que o apóstrofo é uma chave válida do lado direito, correto?
Steven Rumbalski

4
Esta pergunta não é autônoma sem uma definição de letras da esquerda e da direita.
31412 Peter Taylor

4
Uma coisa que pode ajudar as pessoas a usar expressões regulares: usar [a-gq-tv-xz]para as letras da esquerda e ['h-puy]da direita é um pouco mais curta do que escrever todas elas.
Paul Prestidge

Respostas:


7

sed, 78 bytes

1{x;s/^/! /;x};/^['h-puy]*$/IH;/^[a-gq-tv-xz]*$/I{G;x};${x;y/\n/ /;s/! */\n/p}

requer GNU sed, execute com sed -n -f words.sed < /usr/share/dict/words


7

Bash ( 100 89 caracteres)

for x in a-gq-tvwxz h-puy\'
do grep -iE ^[$x]*$ /usr/share/dict/words|tr '
' \ 
echo
done

Observe que 21 caracteres vão para o caminho completo para o arquivo de palavras: se for permitido assumir que pwd é / usr / share / dict, 16 deles podem ser salvos.

Crédito para chron pelas regexes mais curtas.


1
"^ ([$ x]) * $" deve ser o regex
Rob

4

Bash, 86

for x in a-gq-tvwxz h-pyu\'
do egrep ^[$x]*$ /usr/share/dict/words|tr '
' \ 
echo
done

Taylors for, meu egrep, chrons agrupamento de caracteres.

Por definição, se você digitar com as duas mãos às cegas, se desejar produzir uma letra maiúscula, sempre use a mão esquerda para produzir um caractere maiúsculo da mão direita e vice-versa.

É claro que você pode produzir uma letra maiúscula Wapenas com a mão esquerda, mas também pode produzir junkcom a mão esquerda, se quiser.


Bata-me ao agrupamento nas cartas, bom trabalho!
Rob

Tem sido uma condição de corrida entre Peter Taylor e eu. Sua solução de 100 (101?) Caracteres era pública, quando iniciei minha postagem e otimização, mas ele terminou sua melhoria antes de mim, o que observei depois de terminar a minha. Eu não teria postado no mesmo idioma, apenas com egrep e sem -i, mas teria feito um comentário, se ele estivesse alguns minutos mais rápido.
usuário desconhecido

Pensei nisso logo depois de ter feito o comentário corrigindo o regex e saí do trabalho antes que eu tivesse a chance de fazê-lo. Esqueci completamente quando cheguei em casa.
Rob

Seu parágrafo final é a razão pela qual Steven Rumbalski e eu insistimos em esclarecer, e o esclarecimento de que maiúsculas contam como uma mão foi recebido mais de 24 horas antes de você publicá-lo, portanto, não é exatamente necessário.
Peter Taylor

3

Casca de Bourne, 55 caracteres

(Ou qualquer concha tipo Bourne bash, mas , zshou yash)

w=$1;f()echo `grep -ixe[$1]*<$w`;f a-gq-tvwxz;f h-puy\'

Chamado como sh -f words.sh /usr/share/dict/words. (claro, em sistemas onde shé realmente bashcomo em algumas distribuições Linux, use outro Bourne-como shell como ash, ksh, mksh, pdksh, posh...)


2

Javascript (nó), 201 bytes

f=require('fs');c=d='';r=(a=f.readFileSync('/dev/stdin')+c).split('\n');a.
replace(/[aqzxswcdevfrbgt]/ig,'').split('\n').map(function(k,i){k==r[i]&&(
d+=k+' ');!k.length&&(c+=r[i]+' ')});console.log(c,d)

Provavelmente, isso pode ser reescrito para uma versão muito mais curta em outro idioma, mas eu só queria tentar o nó.

Correr com node words.js < /usr/share/dict/words


1

Q ( 121 140 bytes)

A saída não é exatamente a mesma (backticks em vez de espaços), mas isso é sintomático de como Q exibe os tipos de string.

i:read0`:/usr/share/dict/words;
0N!/:i:`$/:i where each (min each) each flip i in/:\:(x,upper x:"qwertasdfgzxcvb";y,upper y:"yuiophjklnm");

EDIT: teve que lidar com caso misto, 20 caracteres


Você pode golfe esta consideravelmente para 111.`$'i(&:')(min'')(+)(i:read0`:/usr/share/dict/words)in/:\:(x,upper x:"qwertasdfgzxcvb";y,upper y:"yuiophjklnm'")
tmartin

1

Ruby, 112 92 caracteres

EDIT: Este é mais curto, embora não tão divertido:

puts %w(a-gq-tv-xz 'h-puy).map{|r|File.read('/usr/share/dict/words').scan(/^[#{r}]+$/i)*' '}

Original:

puts File.read('/usr/share/dict/words').scan(/(^[a-gq-tv-xz]+$)|(^['h-puy]+$)/i).transpose.map{|w|w.compact*' '}

Solução bastante simples baseada em regex. Assim como os outros, você pode salvar alguns caracteres se for permitido passar o nome do arquivo no ARGV ou se ele estiver no seu diretório atual.


1

Python, 130 bytes

a="\n"
b=""
try:
 while 1:v=raw_input();m=[x.lower()in"yuiophjklnm'"for x in v];v+=" ";a+=v*all(m);b+=0**any(m)*v
except:print b+a

Correr com python one_handed_words.py < /usr/share/dict/words


Posso pegar uma das soluções postadas aqui, abreviá-la e colocá-la em minha postagem?
snupuns

Se forem apenas pequenas melhorias, é mais fácil postar comentários. Se você estiver fazendo uma alteração significativa, é melhor postar uma nova resposta, mas é bom dar crédito à (s) resposta (s) em que você a baseia.
gnibbler

1

Haskell (191)

import Char
g x=all(`elem`x)
f m[]=m
f[x,y](w:ws)|g"quertasdfgzxcvb"w=f[w:x,y]ws|g"yuiophjklnm'"w=f[x,w:y]ws|1<2=f[x,y]ws
main=getContents>>=mapM(putStrLn.unwords).f[[],[]].lines.map toLower

1

Python 2.7 (139 caracteres)

import os
a=set("yuiophjklnm'")
c=os.read(0,9**9).lower().split()
print'\n'.join([' '.join(filter(x,c))for x in a.isdisjoint,a.issuperset])

1

Perl, 72 bytes

$a{/^['h-puy]+$/i-/^[a-gq-tv-xz]+$/i}.=y/\n/ /rfor<>;print@a{1,-1,$,=$/}

correr com perl words.pl /usr/share/dict/words


Eu recebo erro de sintaxe: bareword encontrada onde o operador espera na linha words.pl 1, perto "tr / \ n / / rfor"
wim

1
Isso funciona para mim em perl 5.14.2, e requer perl (que é onde a bandeira substituição não destrutivo 5,14 e até rfoi adicionado)
Hasturkun

0

Python - 152 137 caracteres (não testado)

r,a,b=set("YUIOPHJKLNM'"),[],[]
try:
 while 1:
  w=raw_input()
  s=set(w.upper())
  if r|s==r:a+=w
  if s-r==s:b+=w
except:for x in a,b:print' '.join(x)

editar: lidar com maiúsculas e apóstrofo.


0

Python, 243 caracteres

edit: aqui está um programa mais compatível de acordo com a pergunta:

import sys
def o(w):
 r="yuiophjklnm'";f=2;w=w.lower()
 for l in w:
  if(f==1)&(l in r)|(f==0)&(l not in r):return 2
  f=l not in r
 return f
y=[[],[],[]]
for w in sys.stdin.read().split('\n'):y[o(w)].append(w)
for i in y[0:2]:print' '.join(i)

invoke: python onehanded.py > /usr/share/dict/wordsou qualquer outro arquivo de palavras com palavras separadas por nova linha

old: 141 caracteres, apenas uma função de palavra única

retorna rightou leftse wé de uma mão e bothse as duas mãos são usadas.

def o(w):
 r="yuiophjklnm'";f=2
 for l in w:
  if(f==1)&(l in r)|(f==0)&(l not in r):f=2;break
  f=[1,0][l in r]
 return'rlbieogfththt'[f::3]

Você poderia transformar isso em um programa de trabalho ou remover a contagem de caracteres? Caso contrário, o título é enganoso.
Steven Rumbalski

0

Q, 95 (111 com caminho de dict codificado)

{`$'e[(w(&)l(w)in .Q.a except a)],(e:enlist)w(&)(l:all')(w:(_)read0 -1!`$x)in a:"yuiophjklnm'"}

uso

q){`$'e[(w(&)l(w)in .Q.a except a)],(e:enlist)w(&)(l:all')(w:(_)read0 -1!`$x)in a:"yuiophjklnm'"} "/usr/share/dict/words"
`a`a`aa`aa`aaa`aaa`aaaa`aaaaaa`aaas`aaberg`aae`aaee`aaf`aag`aar`aara`aarc`aas..
`h`h`hh`hi`hi`hi`hih`hiko`hikuli`hili`hill`hill`hillo`hilly`hilly`hilo`hilum`..

Mais 14 caracteres se você o codificar

`$'e[(w(&)l(w)in .Q.a except a)],(e:enlist)w(&)(l:all')(w:(_)read0`:/usr/share/dict/words)in a:"yuiophjklnm'"

0

J, 109

1!:2&2;:^:_1('qwertasdfgzxcvb';'yuiophjkl''nm')((#@[>[:>./i.)&>/#]);:1!:1<'/usr/share/dict/words'[9!:37]0,3$_

Tenho certeza que isso pode ser feito melhor, não sei como manipular string :-(


0

Python: 122

import os
S=set("yuiophjklnm'")
c=os.read(0,9**9).lower().split()
print"\n".join(w for w in c if set(w)<=S or set(w)^S>=S)

Lançado com:

python name_of_program.py < /usr/share/dict/words

A idéia é basicamente a mesma de Dillon Cower, mas eu uso set(w)<=Spara indicar um subconjunto enquanto set(w)^S>=Spara um conjunto não definido.

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.