Trova parole con una sola mano


12

"esagerato" è un esempio di una parola che può essere digitata sulla mano sinistra, su una normale mappa della tastiera qwerty. "monopolio" è un esempio per la mano destra.

Ricerca nel wordsfile unix di parole che possono essere digitate da un lato. L'output dovrebbe essere di due righe: elenco separato da spazi di tali parole per la mano sinistra, seguito dall'elenco per la mano destra. per esempio

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

Le lettere a sinistra sono:

qwertasdfgzxcvb

Le lettere a destra sono:

yuiophjklnm'

Le lettere maiuscole contano come una mano; le lettere con segni diacritici contano come due mani e quindi le parole che le contengono possono essere ignorate.


2
Le lettere maiuscole richiedono due mani o una? Suppongo che caratteri come "é" non possano essere digitati con nessuna delle due mani, giusto? Infine, suppongo che l'apostrofo sia un tasto destro valido, giusto?
Steven Rumbalski,

4
Questa domanda non è autonoma senza una definizione di lettere per la mano sinistra e per la mano destra.
Peter Taylor,

4
Una cosa che potrebbe aiutare le persone a usare espressioni regolari: usare [a-gq-tv-xz]per le lettere della mano sinistra e ['h-puy]per le lettere della mano destra è leggermente più breve di scriverle tutte.
Paul Prestidge,

Risposte:


7

sed, 78 byte

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

richiede GNU sed, funziona con sed -n -f words.sed < /usr/share/dict/words


7

Bash ( 100 89 caratteri)

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

Nota che 21 caratteri passano al percorso completo del file di parole: se ci è permesso supporre che pwd sia / usr / share / dict, 16 di questi possono essere salvati.

Ringraziamo chron per le regex più brevi.


1
"^ ([$ x]) * $" dovrebbe essere la 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, il mio egrep, raggruppamento di caratteri di Chrons.

Per definizione, se digiti con due mani cieche, se ti piace produrre una lettera maiuscola, usi sempre la mano sinistra per produrre un carattere maiuscolo della mano destra e viceversa.

Ovviamente puoi produrre un maiuscolo Wsolo con la mano sinistra, ma puoi anche produrre junkcon la mano sinistra, se lo desideri.


Sconfiggimi al raggruppamento delle lettere, ottimo lavoro!
Rob

È stata una condizione di gara tra Peter Taylor e me. La sua soluzione di char 100 (101?) Era pubblica, quando ho iniziato il mio post e l'ottimizzazione, ma ha finito il suo miglioramento davanti a me, che ho osservato dopo aver terminato il mio. Non avrei pubblicato il post nella stessa lingua, solo con egrep e senza -i, ma avrei fatto un commento, se fosse stato qualche minuto più veloce.
utente sconosciuto

Ci ho pensato subito dopo aver fatto il commento correggendo la regex e ho lasciato il lavoro prima che avessi la possibilità di farlo. Se ne sono completamente dimenticato quando sono tornato a casa.
Rob

Il tuo ultimo paragrafo è il motivo per cui io e Steven Rumbalski abbiamo spinto per un chiarimento, e il chiarimento che il maiuscolo conta come una mano è stato ricevuto più di 24 ore prima della pubblicazione, quindi non è proprio una specifica.
Peter Taylor,

3

Bourne shell, 55 caratteri

(O qualsiasi shell tipo Bourne ma bash, zsho yash)

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

Chiamato come sh -f words.sh /usr/share/dict/words. (ovviamente, nei sistemi in cui shè in realtà bashcome su alcune distribuzioni Linux, usare un altro Bourne-come le coperture, come ash, ksh, mksh, pdksh, posh...)


2

Javascript (nodo), 201 byte

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)

Probabilmente questo può essere riscritto in una versione molto più corta in un'altra lingua, ma volevo solo provare nodo.

Corri con node words.js < /usr/share/dict/words


1

Q ( 121 140 byte)

L'output non è esattamente lo stesso (backtick anziché spazi) ma questo è sintomatico di come Q mostra i tipi di stringa.

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: ha dovuto gestire caso misto, +20 caratteri


Puoi giocare a golf considerevolmente per 111.`$'i(&:')(min'')(+)(i:read0`:/usr/share/dict/words)in/:\:(x,upper x:"qwertasdfgzxcvb";y,upper y:"yuiophjklnm'")
tmartin

1

Ruby, 112 92 caratteri

EDIT: questo è più breve, anche se non altrettanto divertente:

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

Originale:

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

Soluzione basata su regex piuttosto semplice. Come con gli altri, potresti salvare alcuni caratteri se ti è permesso passare il nome file in ARGV o se si presume che si trovi nella tua directory corrente.


1

Python, 130 byte

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

Corri con python one_handed_words.py < /usr/share/dict/words


Posso prendere una delle soluzioni pubblicate qui, accorciarla e inserirla nel mio post?
osserva il

Se si tratta solo di piccoli miglioramenti, è più facile pubblicare commenti. Se stai apportando una modifica significativa, è meglio pubblicare una nuova risposta, ma è bello dare credito alle risposte su cui stai basando.
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 caratteri)

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 byte

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

Corri con perl words.pl /usr/share/dict/words


Ottengo l'errore di sintassi: Bareword trovato dove l'operatore si aspettava alla riga 1 di words.pl, vicino a "tr / \ n / / rfor"
wim

1
Questo funziona per me su perl 5.14.2 e richiede perl 5.14 e versioni successive (che è rstato aggiunto il flag di sostituzione non distruttiva )
Hasturkun

0

Python - 152 137 caratteri (non testato)

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)

modifica: gestire maiuscolo e apostrofo.


0

Python, 243 caratteri

modifica: ecco un programma più conforme secondo la domanda:

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)

invocare: python onehanded.py > /usr/share/dict/words o qualsiasi altro file di parole con parole separate da nuova riga

vecchio: 141 caratteri, solo una funzione di una sola parola

ritorna righto leftse wè a una bothmano e se si usano entrambe le mani.

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]

Lo trasformeresti in un programma di lavoro o elimineresti il ​​conteggio dei personaggi? Altrimenti, il titolo è fuorviante.
Steven Rumbalski,

0

Q, 95 (111 con dict path codificato)

{`$'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`..

Altri 14 caratteri se lo codifichi

`$'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$_

Sono sicuro che questo può essere fatto meglio, non so come manipolare le stringhe :-(


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)

Lanciato con:

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

L'idea è principalmente la stessa di Dillon Cower, ma io uso set(w)<=Sper indicare un sottoinsieme mentre set(w)^S>=Sper un insieme disgiunto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.