略語の一般化


14

単語のリストとその略語の入力が与えられた場合、略語を形成できるパターンを出力します。

の入力例を見てみましょう

potato ptao
puzzle pzze

例として(つまり、の略語potatoptaoであり、の略語puzzleはであるpzze)。

取得するためにすべての可能な方法を検討ptaoからをpotato。可能な方法の1つは、最初、3番目、4番目、6番目の文字を取得すること 1346です。しかし、以来to言葉に複数回表示され、そこに生成するために、複数の他の可能な方法がありますptaoからはpotato15461342、と1542

同様に、音符pzzeから生成することができるpuzzleのいずれかと1336134614361446。これら2つの略語に共通する唯一のパターンは1346;です。したがって、それはこの入力の出力でなければなりません。複数の可能なパターンが可能な場合、それらのいずれか、一部、またはすべて(少なくとも1つ)を出力できます。

あなたはそれを仮定するかもしれません:

  • 入力語と略語には小文字のみが含まれます。

  • 入力に少なくとも1つの単語/略語のペアがあります。

  • すべての略語が、対応する単語から形成される可能性があります。

  • すべての略語を形成する少なくとも1つのパターンが常に存在します。

  • 各単語の最大長は9文字です。

入力は、次のいずれかとして取得できます。

  • 2次元配列/リスト/タプルの配列/など。 [[word, abbr], [word, abbr], ...]

  • フラットな1次元配列/リスト [word, abbr, word, abbr, ...]

  • 小文字ではない単一の文字で区切られた単一の文字列 "word abbr word abbr"

  • ハッシュ/連想配列/など {word => abbr, word => abbr, ...}

これらの入力オプションのいずれでも、単語/略号の順序を入れ替えることができます(投稿の入力形式を完全に説明してください)。

出力は、単一の数字、非数字で区切られた文字列、または配列/リスト/タプル/などとして指定できます。数字の。

これはであるため、バイト単位の最短コードが優先されます。

テストケース(複数のパターンが機能する場合、1つ以上の結果を出力するだけでよいことに注意してください):

In                                Out
--------------------------------------------------------
potato ptao puzzle pzze         | 1346
aabbcc abc fddeef def           | 246
prgrmming prgmg puzzles pzzlz   | 14353
aaaaa a bbbb b ccc c dd d e e   | 1
aaaaa a bbbb b ccc c            | 1, 2, 3
abcxyz zbcyax                   | 623514
abcxyz acbbacbcbacbbac          | 132213232132213
potato ptao                     | 1346, 1546, 1342, 1542
a aaaaa                         | 11111

私が理解したことを確認するために、略語プロセスは文字を並べ替えることができますか?
-xnor

@xnor正しい、いくつかのテストケースで見られます。
ドアノブ

2Dアレイは他の方向に向いていますか?各列ではなく、各列に単語/略語のペアが含まれます
ルイスメンドー

@DonMuesliいいえ、できません。
ドアノブ

ゼロインデックスを使用できるので、1346ではなく0235を出力しますか?
デンカー

回答:


3

Pyth、19バイト

mhh@Fd.TmmxkmbhdedQ

ここで試してみてください!

次の形式でリストを取得します。

[["word","abbr"],["word","abbr"],...]

1要素のリストにラップされたゼロベースのインデックスのリストとして結果を出力する17バイトの代替ソリューション:

m@Fd.TmmxkmbhdedQ

説明

例: [["potato", "ptao"],["puzzle", "pzze"]]

最初に、略語のすべての文字を、単語内のすべての出現のインデックスのリストにマッピングします。

[[[0], [2, 4], [3], [1, 5]], [[0], [2, 3], [2, 3], [5]]]

次に、このリストを転置します。

[[[0], [0]], [[2, 4], [2, 3]], [[3], [2, 3]], [[1, 5], [5]]]

したがって、各略語の各文字のインデックスは1つのリストにまとめられています。

次に、これらのすべてのリストで1つの共通インデックスを見つける必要があります。

[[0], [2], [3], [5]]

これは、上記の17バイトの代替ソリューションの出力です。これはに変換され[1,3,4,6]ます。

コードの内訳

mhh@Fd.TmmxkmbhdedQ#Q =入力

m Q#dを使用してマップ入力
        m ed#各略語をkでマップ
            mbhd#単語を文字リストにマップ
         mxk#各略語をインデックスのリストにマッピングします
      .T#転置
    Fd#すべての要素を折りたたむ
   @#および存在のフィルター
 hh#結果の最初の要素undを取り、それをインクリメントします

dm前の権利も削除できません@か?
ドアノブ

@Doorknobできます。見つけてくれてありがとう!
デンカー

3

MATL、29バイト

!"@Y:!=2#fX:wX:h]N$v1XQtv4#X>

入力は、次の形式の2D配列です。

{'potato' 'ptao'; 'puzzle' 'pzze'}

オンラインでお試しください!リンクされたコードには、この回答が投稿されてからの言語の変更による修正が含まれています

!       % take input. Transpose
"       % for each column
  @Y:   %   push column. Unpack the two strings and push them onto the stack
  !     %   transpose second string
  =     %   matrix with all pairwise matchings of characters in word and abbreviation
  2#f   %   find row and col indices of those matchings
  X:    %   transform into column vector
  wX:   %   swap, transform into column vector
  h     %   concat into a two-col matrix
]       % end for
N$v     % concatenate all matrices containing the indices
1       % push 1
XQ      % build matrix adding 1 for each (row,col) index
tv      % concat vertically with itself, so that it has at least two rows.
        % This forces the following function to work on each col.
4#X>    % arg max of each col: position that produces a match in all pairs.
        % If there are several maximizers in each col this gives the first

コードには、いくつかの複雑な(そして長い!)トリックが必要でした

  • findf)によって生成されるベクトルの方向が入力形状に応じて変化しないようにします。これらはステートメントX:wX:です。両方の出力を列ベクトルに強制します。
  • minX>)関数の「最初の1でない次元に沿った作業」のデフォルト動作を打ち消します。これらはステートメントtvです:少なくとも2行を保証するために、それ自身のコピーを連結します);

2

Perl、46 45 42バイト

+1を含む -p

STDINで連続した単語として入力を与えます。例えば

perl -p abbrev.pl
prgrmming
prgmg
puzzles
pzzlz

^Dまたは^Zシステムで必要なSTDINを終了します

abbrev.pl

s#.#${${--$_.$.%2}.=$&}||=-$_#eg;$_ x=eof

説明

この入力を考慮してください(このプログラムの実際の入力方法ではなく、概念的なレイアウト):

potatoes     ptao
puzzle       pzze

プログラムは、列IDでインデックス付けされた完全な文字列の垂直列を表す文字列を作成します

id1    pp     -> 1
id2    ou     -> 2
id3    tz     -> 3
id4    az     -> 4
...

など。略語についても同じことを行いますが、異なるIDを使用します。

ID1    pp     -> 1
ID2    tz     -> 3
ID3    az     -> 4
ID4    oe     -> 6

-pオプションを使用すると、単語は暗黙的に1つずつ処理されます。列の文字列は繰り返し連結を使用して構築され、各単語はを使用しs#.# ...code.. #egてウォークされるため、各列には繰り返し可能なIDが必要です。列番号から2を法とする行番号を引いたものを使用します。列番号はを使用し--$_て構築できa-zます。だから私は得る-1, -2, -3, ...。私は実際に使用するのが好きだろうと思います1, 2, 3, ...が、使用して$_++代わりに、通常の数値カウンタのperlの魔法の文字列の増分をトリガーします。私はない使用したいです$_ 他の変数ではありません。なぜなら、他の変数は、バイトが多すぎるすべてのループでゼロに初期化する必要があるからです。

2を法とする行番号は、完全な単語のIDと略語のIDが衝突しないようにするためです。完全な単語はすべて同じ長さではないため、省略された単語の列が揃わないため、1つの文字列で完全な単語と略語を使用して結合文字列を超える列番号を持つことはできません。また、完全な単語の最初の列のカウントが1である必要があるため、省略された単語を最初に置くことはできません(それらはすべて同じ長さです)。

私はperlのグローバルネームスペースを、厳密ではない参照を通じて悪用して、列文字列を次のように構築します。

${--$_.$.%2}.=$&

次に、perlグローバル名前空間を再び悪用することで、各列文字列を文字列が最初に現れる最初の列番号にマッピングします(マッピングは既に示したとおりです)

${${--$_.$.%2}.=$&} ||= -$_

$_上記で説明したように、列をとしてカウントするため、否定する必要があります-1, -2, -3, ...||=メイクは確かにだけ与えられた列の最初の出現は、それ以外の場合は、前の列番号が保存され、新しい列番号を取得し、値として返さ。これは特に、短縮されたすべての単語に対して発生します。これは、仕様によって、完全な単語に事前に表示される列があることが保証されているためです。そのため、最後の短縮語では、各文字は、すべての短縮語の列に対応する完全な語の列番号に置き換えられます。したがって、最後の置換の結果は、必要な最終結果です。したがって、入力の最後にいる場合にのみ印刷します。

$_ x=eof

列がまだ完全に構成されていないか、一部の単語が短くて列の長さ全体に達していないため、列インデックスの割り当てによって不完全な列のエントリも作成されます。これは問題ではありません。すべての省略語に必要な列には、可能な最大長(現在表示されているペアの数)を持つ完全な語の対応する列があることが保証されているため、これらの余分なエントリが誤った一致を引き起こすことはありません。


1

Haskell、74バイト

import Data.List
foldl1 intersect.map(\(w,a)->mapM(`elemIndices`(' ':w))a)

入力形式は、文字列のペアのリストです。例:

*Main > foldl1 intersect.map(\(w,a)->mapM(`elemIndices`(' ':w))a)  $ [("potato","ptao"),("puzzle","pzze")]
[[1,3,4,6]]

仕組み:(mapMと同じsequence . map)最初に、すべてのペア(w,a)を略語の文字のインデックスのリストのリストに変換します(' ':Haskellのネイティブの0ベースのインデックスを1ベースに修正します)("potato", "ptao") -> [[1],[3,5],[4],[2,6]]。位置の要素iは、ithサブリストから描画され[[1,3,4,2],[1,3,4,6],[1,5,4,2],[1,5,4,6]]ます。foldl1 intersectそのようなリストのすべてのリストの共通部分を見つけます。


0

ES6、92バイト

(w,a)=>[...a[0]].map((_,i)=>[...w[0]].reduce((r,_,j)=>w.some((s,k)=>s[j]!=a[k][i])?r:++j,0))

入力を単語の配列および略語の配列として受け入れます。1から始まるインデックスの配列を返します(2バイトのコストがかかります)。複数のソリューションの場合、最高のインデックスが返されます。


0

Python 3、210バイト

ここでトップスコアを獲得した印象的な答えではありませんが、これは私がこれまでPythonで行った中で最もクレイジーなリスト理解の一部です。このアプローチは非常に単純です。

 def r(p):
    z=[[[1+t[0]for t in i[0]if l==t[1]]for l in i[1]]for i in[[list(enumerate(w[0])),w[1]]for w in p]]
    return[list(set.intersection(set(e),*[set(i[z[0].index(e)])for i in z[1:]]))[0]for e in z[0]]

この関数は、入力を常に次のような文字列の2次元配列として予期し[[word, abbr],...]、整数のリストを返します。

シモンズ:詳細な説明はすぐに来る

Ps2:さらにゴルフの提案を歓迎します!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.