缩写的泛化


14

给定单词列表及其缩写的输入,输出可以形成缩写的模式。

让我们以输入的示例为例

potato ptao
puzzle pzze

作为一个例子(即,缩写potatoIS ptao,和缩写puzzlepzze)。

考虑到所有可能的方法来获得ptaopotato。一种可能的方法是采用第一,第三,第四和第六个字母,我们将其称为 1346。但自从to这个词出现多次,还有其他多种可能的方式来产生ptaopotato15461342,和1542

同样,该说明pzze可从产生puzzle任何的1336134614361446。这两个缩写唯一的共同之处是1346; 因此,该输入必须是此输入的输出。如果有多种可能的模式,则可以输出其中的任何一个,一些或全部(至少一个)。

您可以假设:

  • 输入的单词和缩写仅包含小写字母。

  • 输入中至少有一个单词/缩写对。

  • 每个缩写都有可能由其对应的单词构成。

  • 总是会有至少一个模式构成每个缩写。

  • 每个单词的最大长度为9个字符。

输入可以视为以下任意一项:

  • 二维数组/列表/元组数组等 [[word, abbr], [word, abbr], ...]

  • 平面一维数组/列表 [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阵列可以有其他方向吗?各列,而不是每一行,将包含一对字/缩写
路易斯Mendo

@DonMuesli不,它不能。
门把手

我们可以使用零索引,所以打印0235而不是1346?
Denker

Answers:


3

Pyth,19个字节

mhh@Fd.TmmxkmbhdedQ

在这里尝试!

采取以下格式的列表:

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

替代的17字节解决方案,将结果输出为从零开始的索引列表,并包装在1元素列表中:

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

因此,每个缩写的每个字符的索引都在一个列表中。

然后,我们只需要在所有这些列表中找到一个公共索引即可产生:

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

这是我上面的替代17字节解决方案的输出。然后将其转换为[1,3,4,6]

代码细目

mhh@Fd.TmmxkmbhdedQ#Q =输入

m Q#带有d的地图输入
        med#用k映射每个缩写
            mbhd#将单词映射到字符列表
         mxk#将每个缩写char映射到索引列表
      .T#转置
    Fd#折叠所有元素
   @#并根据状态过滤
 hh#将结果的第一个元素und递增

您还不能删除“” dm之前的权利@吗?
门把手

@门把手我可以。感谢您发现!
Denker

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>)函数的“沿第一个非单维工作”的默认行为。这些是语句tv:合并自身的副本以确保至少两行);

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选项可以隐式地对单词进行逐一处理。列字符串是使用重复的串联构造的,而每个单词都使用进行遍历s#.# ...code.. #eg,因此每一列都需要一个可重复的ID。我用的是减去列号,然后减去行号模2。可以使用列号构造该列号,该列号--$_从当前字开始,由于仅使用字,a-z可以保证在数字上下文中将其评估为0。这样我就知道了-1, -2, -3, ...。我真的很想使用1, 2, 3, ...,但是使用$_++会触发perl魔术字符串增量,而不是普通的数字计数器。我想用$_ 而不是其他变量,因为在每个占用太多字节的循环中,我必须将其他任何变量初始化为零。

行号取模2是为了确保完整单词的id和缩写的id不冲突。注意,我不能在一个字符串上使用完整的单词和缩写来使列号遍及合并的字符串,因为完整的单词的长度并不都相同,因此缩写的单词列不会对齐。我也不能将缩写词放在首位(它们都具有相同的长度),因为我需要完整词的第一列的计数为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]]

该函数期望输入始终为字符串二维数组,如:,[[word, abbr],...]并返回整数列表。

附:即将进行详细的解释

附注2:欢迎提出更多高尔夫建议!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.