一文字交換


18

postcount ++と呼ばれるウェブ上の最大のフォーラムは、新しいフォーラムゲームを作成することを決定しました。このゲームでは、目標は単語を投稿することですが、単語には1文字追加、削除、または変更する必要があります。あなたの上司は、あなたがよりインテリジェントなフォーラムゲームを備えたよりインテリジェントなフォーラムを持ち、競争を破壊したい会社で働いているときに、単語とUNIX辞書を取得するプログラムを書くことを望んでいました(ちょっと、それはあなたの上司です彼と話し合うと、とにかくあなたの仕事からたくさんの現金を得ることができます)。

プログラムは、単語と辞書という2つの引数を取得します。プログラムを管理するユーザー(はい、ユーザー、会社にはボットを実行するリソースがない)は完全ではないため、両方のケースを正規化する必要があります。辞書内の単語には、ASCII文字(大文字と小文字の両方、ただし比較中は無視する必要があります)、ダッシュ、アポストロフィ、および途中に連続しないスペースが含まれる場合があります。78文字を超えることはありません。単語を手動で考える人々の楽しみを壊すために、ゲームで受け入れられる単語のリストを出力する必要があります。

これは、予想されるプログラムの例で、に類似する単語をチェックしますgolf

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

/usr/share/dict/wordsそれぞれの後に改行して、単語のリストです。たとえば、fgets()で簡単に読むことができます。

あなたが働いている会社はあまりパンチカードを持っていません(そう、それは2014年であり、彼らはまだパンチカードを使用しています)ので、それらを無駄にしないでください。できるだけ短いプログラムを作成してください。ああ、そしてあなたは、レーベンシュタイン距離または同様のアルゴリズムの組み込みまたは外部実装を使用しないように頼まれました。Not Invented Hereや、明らかにベンダーが言語に挿入したバックドアについての何か(それらの証拠はありませんが、上司と話し合ってはいけません)。したがって、距離が必要な場合は、距離を自分で実装する必要があります。

任意の言語を自由に使用できます。パンチカードを使用していても、同社はCobol RubyやHaskell などの最新のプログラミング言語にアクセスできます。文字列操作に適していると思われる場合は、GolfScriptを使用することもできます(おそらく...わかりません)。

勝者は私から15の評判ポイントを獲得し、おそらくコミュニティから他の多くのポイントを獲得します。他の良い答えは10ポイントを獲得し、同様にコミュニティからもポイントを獲得します。ポイントは価値がないと聞きましたが、2050年にドーラーに取って代わる可能性が最も高いと聞きました。


6
「レーベンシュタイン距離または同様のアルゴリズムの組み込みまたは外部実装を使用しないでください」30文字のMathematicaソリューションがあります。
マイケルスターン



「RubyやHaskellなど」-はい、わかりました。参加してほしいです。
ジョンドヴォルザーク

すべてのタイプの変更が表示されるか、人々が間違ったアルゴリズムを送信し続けるように、より良い例を提供してください。
swish 14

回答:


4

GolfScript、59文字

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

もちろん、GolfScriptは文字列操作に最適です!

GolfScriptがあまり得意ではないのは、ファイルI / Oまたはコマンドライン引数の処理です。したがって、このプログラムは、stdinを介してすべての入力を受け取ることを想定しています。最初の非空白行がターゲットワードと見なされ、残りの行には辞書が含まれます。Unixishシステムでは、このコードを次のように実行できます。

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

私のUbuntu Linuxボックスでは、上記のコマンドの出力は次のとおりです。

goff
wolf
gold
golfs
goof
gulf

すべての単語が小文字に変換され、重複が削除されることに注意してください。このように、あなたの出力例とは異なり、鉱山が表示されていないWolfwolf別途。あなたのチャレンジの説明に基づいて、これは受け入れられると思います。

また、コードはかなりブルートフォースのアプローチを使用し、候補語の長さが対象語の長さ±1に一致することを確認するなどの明らかな最適化さえも使用しないため、コードは非常に遅くなります。フィルタリングされていない完全な/usr/share/dict/wordsリストで...えーと...終了したらお知らせします、OK?

編集: OK、約25分かかりましたが、終了しました。


GolfScriptは、文字列操作のためにどのように良いの正確な表現のための+1(およびGolfScriptで文字列操作を行う)
PlasmaPower

6

Bash + coreutils、99バイト

私は質問を完全に誤解しました(@lambruscoAcidoの答えは非常に異なる結果を与えます)、またはこれはかなり簡単な正規表現アプリケーションです:

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

出力:

$ ./similar.sh golf / usr / share / dict / words
ゴフ
ゴールド
ゴルフ
ゴルフ
へま
湾
狼
狼
$ 

何を説明していただけます${a:b:c} か?
AL

1
@ N.1その位置で文字を取得bするc変数でa

2
@professorfish Close-variableのc位置b(ゼロから始まる)から始まる長さの部分文字列a。拡大をサブストリングはの一つであるbashのパラメータ展開
デジタルトラウマ

2
@DigitalTraumaああ私は、私は私のバッシュgolfsでそれを使い続けていても忘れてしまった

3

Python 3、291文字

非常に簡単で、したがってあまり賢くない。しかし、非常においしいジェネレーターのもつれと最適化された遅延があります。割り当てられた計算時間を未使用のままにしたくないのですか?

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
を使用l=lenr=rangeて、これらの機能をさらに削減できます。
TyrantWave 14

1

スカラ- 403 130

[更新]:以前のソリューションでも置換文字を使用できるため、完全に更新されました。正規表現または組み込みツールを使用しません。

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

ゴルフをしていない:

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
}

使用法:

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

@DigitalTraumaその問題の例を教えてください。
lambruscoAcido

私はそれを得ました:私はまた、文字のすべての順列を考慮しました。ため息-だから現実は簡単です。ありがとう...
lambruscoAcido

atechny1文字は変更されません。このソリューションは、質問とは無関係の何かを行います。
コンラッドボロスキー14

+1。仕様により良く適合したように見えます;-)
デジタル外傷14

機能だけでなく、完全なプログラムがいいでしょう。
スウィッシュ

1

Python、174文字:

迅速かつ要点。

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

例:

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

出力:

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

OS Xのwordsファイルにはもっと多くのエントリがあるだけだと思います。


リストには単語自体を含めないでくださいgolf'。また、アポストロフィを無視しません。UNIX辞書では。
swish 14

アポストロフィを無視するとはどういう意味ですか?プロンプトを再度読んだ後、あなたが何を得ているのかまだわかりません。
xleviator 14

辞書を使用golf'してコードを実行すると、印刷されます。
スウィッシュ

ああ、私はプロンプトを読み違えていましたが、今は修正されています。
xleviator 14

0

ハスケル-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

レボル-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(いくつかのコメント付き):

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

使用例(OS X LionのRebol 3でテスト済み):

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

以下は、parse同様の単語をゴルフに一致させるために作成されたルールです。

[
    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]

かなり効率的だと思います。また、私はこれがPythonでどれだけうまくいくかが好きです。


キャラクターの削除や追加を考慮していません。
swish 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.