Trouver des mots à une main


12

'exagéré' est un exemple de mot qui peut être tapé à gauche, sur une carte clavier qwerty normale. le «monopole» est un exemple pour la main droite.

Recherche dans le wordsfichier Unix de mots pouvant être saisis d'une seule main. La sortie doit être de deux lignes: liste séparée par des espaces de ces mots pour la main gauche, suivie de la liste pour la main droite. par exemple

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

Les lettres de gauche sont:

qwertasdfgzxcvb

Les lettres de droite sont:

yuiophjklnm'

Les lettres majuscules comptent comme une seule main; les lettres avec des signes diacritiques comptent comme deux mains et donc les mots qui les contiennent peuvent être ignorés.


2
Les lettres majuscules nécessitent-elles deux mains ou une? Je suppose que les caractères tels que "é" ne peuvent pas être tapés avec l'une ou l'autre main, non? Enfin, je suppose que l'apostrophe est une touche droite valide, n'est-ce pas?
Steven Rumbalski

4
Cette question n'est pas autonome sans une définition des lettres de gauche et de droite.
Peter Taylor

4
Une chose qui pourrait aider les gens à utiliser des expressions régulières: utiliser [a-gq-tv-xz]pour les lettres de gauche et ['h-puy]pour les lettres de droite est légèrement plus court que de les écrire tous.
Paul Prestidge

Réponses:


7

sed, 78 octets

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

nécessite GNU sed, exécuté avec sed -n -f words.sed < /usr/share/dict/words


7

Bash ( 100 89 caractères)

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

Notez que 21 caractères accèdent au chemin complet du fichier de mots: si nous sommes autorisés à supposer que pwd est / usr / share / dict, 16 d'entre eux peuvent être enregistrés.

Crédit à chron pour les expressions rationnelles plus courtes.


1
"^ ([$ x]) * $" devrait être l'expression régulière
Rob

4

Bash, 86

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

Taylors for, mon égrep, regroupe des groupes de caractères.

Par définition, si vous tapez à deux mains à l'aveugle, si vous souhaitez produire une lettre majuscule, vous utilisez toujours la main gauche pour produire un caractère majuscule de la main droite et vice versa.

Bien sûr, vous pouvez produire une majuscule Wuniquement avec la main gauche, mais vous pouvez également produire junkavec la main gauche, si vous le souhaitez.


Battez-moi au regroupement sur les lettres, bon travail!
Rob

Ça a été une condition de course entre Peter Taylor et moi. Sa solution de 100 (101?) Caractères était publique, lorsque j'ai commencé mon post et son optimisation, mais il a terminé son amélioration avant moi, ce que j'ai observé après avoir terminé le mien. Je n'aurais pas fait le post dans la même langue, juste avec egrep et sans -i, mais j'aurais fait un commentaire à la place, s'il avait été plus rapide de quelques minutes.
utilisateur inconnu

J'y ai pensé juste après avoir fait le commentaire corrigeant l'expression régulière, et j'ai quitté le travail avant d'avoir eu la chance de le faire. Je l'ai complètement oublié au moment où je suis rentré.
Rob

Votre dernier paragraphe est la raison pour laquelle Steven Rumbalski et moi avons demandé des éclaircissements, et la clarification selon laquelle les majuscules comptent comme une seule main a été reçue plus de 24 heures avant que vous ne publiiez cela, donc ce n'est pas vraiment une spécification.
Peter Taylor

3

Coquille Bourne, 55 caractères

(Ou n'importe quel shell de type Bourne mais bash, zshou yash)

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

Appelé comme sh -f words.sh /usr/share/dict/words. (bien sûr, sur les systèmes où shest en fait bashcomme sur certaines distributions Linux, utilisez un autre shell de type Bourne comme ash, ksh, mksh, pdksh, posh...)


2

Javascript (nœud), 201 octets

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)

Cela peut probablement être réécrit dans une version beaucoup plus courte dans une autre langue, mais je voulais juste essayer le nœud.

Courir avec node words.js < /usr/share/dict/words


1

Q ( 121140 octets)

La sortie n'est pas exactement la même (backticks au lieu d'espaces) mais cela est symptomatique de la façon dont Q affiche les types de chaîne.

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: a dû gérer le cas mixte, +20 caractères


Vous pouvez `$'i(&:')(min'')(+)(i:read0`:/usr/share/dict/words)in/:\:(x,upper x:"qwertasdfgzxcvb";y,upper y:"yuiophjklnm'")
jouer au

1

Rubis, 112 92 caractères

EDIT: C'est plus court, mais pas aussi amusant:

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*' '}

Solution assez simple basée sur des regex. Comme pour les autres, vous pouvez enregistrer certains caractères si vous êtes autorisé à passer le nom de fichier dans ARGV ou s'il est supposé être dans votre répertoire actuel.


1

Python, 130 octets

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

Courir avec python one_handed_words.py < /usr/share/dict/words


Suis-je autorisé à prendre l'une des solutions affichées ici, à la raccourcir et à la mettre dans mon message?
snupuns

S'il ne s'agit que de petites améliorations, il est plus convivial de poster des commentaires. Si vous apportez un changement important, il est préférable de publier une nouvelle réponse, mais agréable de donner du crédit à la ou aux réponses sur lesquelles vous vous basez.
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 caractères)

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 octets

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

courir avec perl words.pl /usr/share/dict/words


J'obtiens une erreur de syntaxe: Bareword trouvé là où l'opérateur s'attendait à la ligne 1 de words.pl, près de "tr / \ n / / rfor"
wim

1
Cela fonctionne pour moi sur perl 5.14.2, et nécessite perl 5.14 et plus (c'est là que le drapeau de substitution non destructif a rété ajouté)
Hasturkun

0

Python - 152 137 caractères (non testé)

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)

modifier: gérer les majuscules et l'apostrophe.


0

Python, 243 caractères

edit: voici un programme plus conforme à la question:

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 tout autre fichier de mots avec des mots séparés par des sauts de ligne

ancien: 141 caractères, juste une fonction d'un seul mot

retourne rightou leftsi west à une main, et bothsi les deux mains sont utilisées.

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]

Pourriez-vous en faire un programme de travail ou supprimer le nombre de caractères? Sinon, le titre est trompeur.
Steven Rumbalski

0

Q, 95 (111 avec chemin de dict codé en dur)

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

usage

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`..

14 caractères supplémentaires si vous le codez en dur

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

Je suis sûr que cela peut être mieux fait, je ne sais pas comment manipuler les chaînes :-(


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)

Lancé avec:

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

L'idée est essentiellement la même que celle de Dillon Cower, mais j'utilise set(w)<=Spour indiquer un sous-ensemble tandis que set(w)^S>=Spour un ensemble disjoint.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.