Échange d'une lettre


18

Le plus grand forum du Web, appelé postcount ++, a décidé de créer un nouveau jeu de forum. Dans ce jeu, l'objectif est de publier le mot, mais le mot doit avoir une lettre ajoutée, supprimée ou modifiée. Votre patron voulait que vous écriviez un programme qui a le mot et le dictionnaire UNIX, car vous travaillez pour une entreprise qui a un forum plus intelligent avec des jeux de forum plus intelligents et veut détruire la concurrence (hé, c'est votre patron, ne le faites pas discutez avec lui, vous obtenez quand même beaucoup d'argent de votre travail).

Votre programme recevra deux arguments, le mot et le dictionnaire. Parce que l'utilisateur qui gère le programme (oui, un utilisateur, votre entreprise n'a pas les ressources pour exécuter les bots) n'est pas parfait, vous devez normaliser le cas dans les deux. Les mots du dictionnaire peuvent avoir des lettres ASCII (majuscules et minuscules, mais elles doivent être ignorées lors de la comparaison), des tirets, des apostrophes et des espaces non consécutifs au milieu. Ils ne dépasseront pas 78 caractères. Vous devez générer une liste de mots qui seraient acceptés dans le jeu, pour briser le plaisir des gens qui pensent aux mots manuellement.

Ceci est un exemple de votre programme attendu, recherchant des mots similaires à golf.

> ./similar golf /usr/share/dict/words
Goff
Wolf
gold
golfs
goof
gulf
wolf

Il /usr/share/dict/wordss'agit d'une liste de mots, avec un saut de ligne après chacun. Vous pouvez facilement lire cela avec fgets (), par exemple.

L'entreprise dans laquelle vous travaillez n'a pas beaucoup de cartes perforées (oui, c'est 2014, et elles utilisent toujours des cartes perforées), alors ne les gaspillez pas. Écrivez le programme le plus court possible. Oh, et on vous a demandé de ne pas utiliser les implémentations intégrées ou externes de la distance de Levenshtein ou tout autre algorithme similaire. Quelque chose à propos de Not Invented Here ou de backdoors que le vendeur a apparemment inséré dans la langue (vous n'en avez pas de preuve, mais ne discutez pas avec votre patron). Donc, si vous voulez de la distance, vous devrez l'implémenter vous-même.

Vous êtes libre d'utiliser n'importe quelle langue. Même avec des cartes perforées, l'entreprise a accès aux langages de programmation les plus modernes, tels que Cobol Ruby ou Haskell ou tout ce que vous voulez. Ils ont même GolfScript, si vous pensez que c'est bon pour la manipulation de chaînes (je ne sais pas, peut-être ...).

Le gagnant obtient 15 points de réputation de ma part, et probablement beaucoup d'autres points de la communauté. Les autres bonnes réponses obtiendront 10 points, ainsi que des points de la communauté. Vous avez entendu dire que les points ne valent rien, mais il est fort probable qu'ils remplaceront les dolars en 2050. Cela n'a toutefois pas été confirmé, mais c'est quand même une bonne idée d'obtenir des points.


6
Nous ne devons pas "utiliser des implémentations intégrées ou externes de la distance de Levenshtein ou tout autre algorithme similaire"? Voilà la solution Mathematica à 30 caractères.
Michael Stern

@MichaelStern et un autre python similaire utilisant la correspondance floue de cette bibliothèque d'expressions régulières
Martin Ender

2
Presque la même chose que codegolf.stackexchange.com/questions/6939/… .
Howard

"comme Ruby ou Haskell" - ok, je l'ai, vous voulez que je participe.
John Dvorak

Veuillez fournir un meilleur exemple, afin que tous les types de modifications apparaissent ou que les gens continuent de soumettre de mauvais algorithmes.
swish

Réponses:


4

GolfScript, 59 caractères

{32|}%"*"%.|(:w;{:x,),{:^[x>.1>]{.[^w=]\+}%{^x<\+w=},},},n*

Bien sûr, GolfScript est idéal pour la manipulation de chaînes!

Ce que GolfScript n'est pas si bon, c'est la gestion des E / S de fichiers ou des arguments de ligne de commande. Ainsi, ce programme s'attend à recevoir toutes ses entrées via stdin: la première ligne non vide est considérée comme le mot cible, tandis que les lignes restantes doivent contenir le dictionnaire. Sur un système Unixish, vous pouvez exécuter ce code, par exemple avec:

(echo golf; cat /usr/share/dict/words) | ruby golfscript.rb similar.gs

Sur ma boîte Ubuntu Linux, la sortie de la commande ci-dessus est:

goff
wolf
gold
golfs
goof
gulf

Notez que tous les mots sont convertis en minuscules et tous les doublons sont éliminés; ainsi, contrairement à votre exemple de sortie, le mien ne répertorie pas Wolfet wolfséparément. Sur la base de votre description de défi, je suppose que cela est acceptable.

De plus, le code est vraiment lent, car il utilise une approche de force assez brute, et n'utilise pas même des optimisations évidentes comme vérifier que la longueur du mot candidat correspond à celle du mot cible ± 1. Pourtant, il parvient à aller à travers la /usr/share/dict/wordsliste complète et non filtrée dans ... euh ... Je vous ferai savoir quand elle se terminera, OK?

Edit: OK, cela a pris environ 25 minutes, mais cela s'est terminé.


+1 pour une représentation précise de la qualité de GolfScript pour la manipulation de chaînes (et la manipulation de chaînes dans GolfScript)
PlasmaPower

6

Bash + coreutils, 99 octets

Soit j'ai totalement mal compris la question ( la réponse de @ lambruscoAcido donne des résultats très différents ), soit il s'agit d'une application d'expression rationnelle assez simple:

for((i=0;i<${#1};i++)){
a=${1:0:i}
b=${1:i+1}
egrep -i "^($a$b|$a.$b|$a.${1:i}|$1.)$" $2
}|sort -u

Production:

$ ./similar.sh golf / usr / share / dict / mots
Goff
or
le golf
golfs
gaffe
golfe
Loup
Loup
$ 

Pouvez-vous expliquer quoi ${a:b:c} faire?
AL

1
@ n.1 il prend les caractères à des positions bà cla variablea

2
@professorfish Fermer - c'est la sous-chaîne de longueur ccommençant à la position b(basée sur zéro) de la variable a. L'expansion des sous-chaînes est l'une des extensions de paramètres bash
Digital Trauma

2
@DigitalTrauma oh j'ai oublié même si je continue de l'utiliser dans mes golfs Bash

3

Python 3, 291 caractères

Très simple, et donc pas très intelligent. Mais avec un gros enchevêtrement de générateur délicieux et une lenteur optimisée. Parce que vous ne voulez pas laisser inutilisé votre temps de calcul alloué, n'est-ce pas?

from itertools import*
from sys import*
a=argv[1].lower()
r,l=range,len
n=l(a)
print('\n'.join((b for b in(s.strip()for s in open(argv[2]).readlines())if l(b)>n-2and b.lower()in(''.join(compress(a,(i!=j for j in r(n))))for i in r(n))or n==l(b)and sum(1for i in r(n)if a[i]!=b.lower()[i])<2)))

1
Peut utiliser l=lenet r=rangeréduire davantage ces fonctions.
TyrantWave

1

Scala - 403 130

[Mise à jour]: complètement mise à jour car l'ancienne solution permettait également les lettres permutées. N'utilise ni regex ni aucun outil intégré.

def f(x:String,d:List[String])={for{y<-d;c=(x zip y filter(t=>t._1!=t._2)length);n=y.length-x.length;if c<2&n==0|c==0&n==1}yield y

Non golfé:

def f(x:String, d:List[String]) = {
  for {
    y <- d
    c = (x zip y filter (t=>t._1!=t._2) length)  // #letter changes.
    n = y.length-x.length                        // Difference in word length.
    if c<2 & n==0 | c==0 & n==1
  } yield y
}

Usage:

f("golf", io.Source.fromFile("/usr/share/dict/words").getLines.toList)

@DigitalTrauma Pouvez-vous me donner un exemple pour ce problème?
lambruscoAcido

Je l'ai compris: j'ai également considéré toutes les permutations des lettres. Soupir - donc la réalité est plus facile. Merci ...
lambruscoAcido

atechnyne change pas une lettre. Cette solution fait quelque chose sans rapport avec la question.
Konrad Borowski

+1. on dirait qu'il correspond mieux aux spécifications maintenant ;-)
Digital Trauma

Un programme complet serait bien, pas seulement fonctionnel.
swish

1

Python, 174 caractères:

Rapide et au point.

import re;from sys import*;w=argv[1]
print"\n".join(set(sum([re.findall(r"\b%s%s?[^'\n]?%s\b"%(w[:i],w[i],w[i+1:]),open(argv[2]).read(),re.I)for i in range(len(w))],[]))-{w})

Exemple:

python similar.py golf /usr/share/dict/words

Production:

goof
gola
gulf
gold
gol
gowf
goli
Golo
Gulf
goaf
Wolf
Goll
Rolf
wolf
goff
Gold

Je suppose que le fichier de mots OS X a juste plus d'entrées.


La liste ne doit pas inclure le mot lui-même et il n'ignore pas non plus les apostrophes: avec le dictionnaire UNIX, il l'a également golf'.
swish

Que voulez-vous dire par ignorer les apostrophes? Après avoir relu l'invite, je ne vois toujours pas où vous en êtes.
xleviator

Si je lance votre code sur le dictionnaire avec golf', il sera imprimé.
swish

Ah, j'avais mal lu l'invite, mais c'est corrigé maintenant.
xleviator

0

Haskell - 219

import System.Environment
import Data.Char
u@(x:a)%w@(y:b)|x==y=a%b|1>0=1+minimum[a%w,u%b,a%b]
x%y=max(length x)$length y
main=do[w,d]<-getArgs;readFile d>>=mapM putStrLn.filter((==1).(%map toLower w).map toLower).words

0

Rebol - 213

set[i d]split system/script/args" "r:[skip i | i skip]repeat n length? i[append r compose[|(poke s: split i 1 n 'skip s)|(head remove at copy i n)]]foreach w read/lines to-file d[if all[w != i parse w r][print w]]


Ungolfed (avec quelques commentaires):

set [i d] split system/script/args " "

; build parse rule
r: [skip i | i skip]       ; RULE - one letter added (prefix and postfix)

; sub-rule for each letter in word
repeat n length? i [
    append r compose [
        | (poke s: split i 1 n 'skip s)     ; RULE - letter changed
        | (head remove at copy i n)         ; RULE - letter removed
    ]
]

foreach w read/lines to-file d [
    if all [w != i parse w r] [print w]
]

Exemple d'utilisation (testé dans Rebol 3 sur OS X Lion):

$ rebol similar.reb golf /usr/share/dict/words
goaf
goff
gol
gola
Gold
gold
goli
Goll
Golo
goof
gowf
Gulf
gulf
Rolf
Wolf
wolf

Voici la parserègle créée pour faire correspondre des mots similaires au golf :

[
    skip "golf"
  | "golf" skip
  | skip "o" "l" "f"
  | "olf"
  | "g" skip "l" "f"
  | "glf"
  | "g" "o" skip "f"
  | "gof"
  | "g" "o" "l" skip
  | "gol"
]

-1

Python (103):

f=lambda x:[a for a in open('/usr/share/dict/words')if len(x)==len(a)&sum(b!=c for b,c in zip(a,x))==1]

Assez efficace, je pense. Aussi, j'aime à quel point ce golf en Python.


Vous ne tenez pas compte de la suppression ou de l'ajout d'un personnage.
swish
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.