アナグラムを解く


9

参照:Granma loves Ana

小文字のASCII文字列が与えられます。この辞書ファイル(更新済み)を使用し、アナグラムを解くことです。アナグラムを解くには、改行で区切られた入力文字列の各文字を使用して形成できるすべての単語または単語のグループを出力する必要があります。同じ単語の異なる順序でのグループは一意ではないため、個別に出力しないでください。ただし、単語の順序は関係ありません。出力ソリューションの順序も重要ではありません。入力が単語を形成できない場合、何も出力しません。

いくつかの有用なテストケース:

Input:  viinlg
Output: living

Input:  fceodglo
Output: code golf

Input:  flogflog
Output: golf golf

Input:  ahwhygi
Output: highway
        high way

Input:  bbbbbb
Output: 

ルール/警告:

  • 辞書リストには、好きな方法でアクセスできます。コマンドライン引数、標準入力、ファイルからの読み取り、またはインターネットからの読み取りはすべて受け入れられます。

  • 入力は小文字のASCII文字のみで構成されます。特定の場合に結果を出力する必要はありません。

  • 既に有効な単語を形成する文字列は与えられません(ただし、などの複数の単語を形成する文字列が与えられる場合がありますbluehouse)。

  • 末尾の改行は許可されますが、必須ではありません。

  • 標準の抜け穴が適用されます。

これはです。バイト単位の最短コードが優先されます。幸運を!



単語のセットを区切るために1つのスペースを使用する必要がありますか、それとも文字以外のセパレータで十分ですか?
Erik the Outgolfer 2017年

@EriktheOutgolfer 単語のセットを区切るに、セパレータを使用できます。ただし、スペースを使用して単一のソリューション内の単語を分離する必要があります。
散布

@Christianルールでは、単語のセットを改行で区切る必要があるとしています。
Erik the Outgolfer 2017年

@EriktheOutgolferでは、なぜ「単語のセットを区切るために1つのスペースを使用するべきか」と尋ねたのですか?あなたの質問は私を混乱させました、そしてセットを分離するために改行よりも何かを好む理由はありません。スペックにこだわると思います。
散布

回答:


2

パイソン2341の 327 337 320バイト

このソリューションでは、辞書がw文字列のセットとして変数に格納されていると想定しています。最初のセットでcombinationsはを使用する必要はありませんがcombinations_with_replacement、後者を使用するとバイトを節約できます。

from itertools import*
d,o,j,c={},sorted,''.join,combinations_with_replacement
s,w=o(raw_input()),input()
l=len(s)
r=range(l)
for x in w:d.setdefault(j(o(x)),[]).append(x)
b=set(chain(*[d[j(x)]for y in r for x in c(s,y+1)if j(x) in d]))
print'\n'.join(' '.join(x)for y in r for x in c(b,y+1)if(len(j(x)),o(j(x)))==(l,s))

オンラインでお試しください!

入力-アナグラムされた単語とそれに続く単語の辞書のセット:

anagram_word
{'entry1', 'entry2', ...., 'entryN'}

編集:更新された入力。


1

Pythonの3248の 202バイト

from itertools import*
A=set()
def f(s,*G,i=1,A=A):
 if' '>s:A|={' '.join(sorted(G))}
 for _ in s:s[:i]in S and f(s[i:],s[:i],*G);i+=1
I,*S=iter(input,'')
for p in permutations(I):f(''.join(p))
print(A)

オンラインでお試しください!

入力は次のとおりです。

word_input
dic_entry_1
dic_entry_2
....
dic_entry_N
                 # <<< empty line + \n

スピードアップ:

テストの目的で、からI,*S=iter(input,'')に変更するI=input();S=set(iter(input,''))と、ランタイムが大幅に短縮され、出力は同じになります。

説明:

入力のすべての順列で、辞書にある単語を使用して、文字をスキップせずに、左から右に可能なすべての場所で順列を再帰的に分割しようとします。分割の組み合わせがすべての入力順列と一致する場合、分割された単語が並べ替えられset、評価のおよびに出力されるに追加されます。


1

Javascript、139 137 129バイト

-FelipeNardiBatistaのおかげで-2バイト

ドキュメントを読んだおかげで-8バイト;)

k=>w=>{t=w;return k.reduce((a,v)=>{r=([...v].every(c=>w.includes(c)&&((w=w.replace(c,""))||!0)))?a.concat(v):a;w=t;return r},[])}

文字列の配列の形式で入力として辞書を受け取ります。

var arr = ["living", "code", "golf", "highway", "high", "way"];

var _=
k=>w=>{t=w;return k.reduce((a,v)=>{r=([...v].every(c=>w.includes(c)&&((w=w.replace(c,""))||!0)))?a.concat(v):a;w=t;return r},[])};

console.log(_(arr)("viinlg"));
console.log(_(arr)("fceodglo"));

説明:

辞書のすべての単語について、選択した単語にすべての文字が含まれているかどうかを確認すると同時に、単語から削除します。すべての辞書エントリの最後で、単語を変更されていない状態に復元して、さらに一致するかどうかを確認します。


@FelipeNardiBatistaそうですね、その名前をゴルフするのを忘れました。ありがとう:)
Hankrecords 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.