16

如果单词中的字母可以重新排列以形成不同的单词,则该单词就是字谜。

任务:

  • 最短的源代码通过字符数找到给定单词列表的所有字谜集。

  • 空格和换行符应该算作字符

  • 使用码尺

    ---------10--------20--------30--------40--------50---- ----60--------70--------80--------90--------100--------110- ------120

输入:

来自标准输入的单词列表,每个单词由一个新行分隔。

例如

A
A's
AOL
AOL's
Aachen
Aachen's
Aaliyah
Aaliyah's
Aaron
Aaron's
Abbas
Abbasid
Abbasid's

输出:

所有字谜集,每组由单独的行分隔。

示例运行:

./anagram < words
marcos caroms macros
lump's plum's
dewar's wader's
postman tampons
dent tend
macho mocha
stoker's stroke's
hops posh shop
chasity scythia
...

我有一个 149 字符 perl 解决方案,我会在更多人发布后立即发布 :)

玩得开心!

编辑:澄清

  • 假设字谜不区分大小写(即大小写字母是等价的)
  • 只应打印多于 1 件的套装
  • 每组字谜应该只打印一次
  • 字谜集中的每个单词只能出现一次

EDIT2:更多说明

  • 如果两个单词仅大小写不同,则应将它们折叠成同一个单词,由您决定使用哪种大写方案用于折叠单词
  • 单词集只需要换行结束,只要每个单词以某种方式分隔,例如逗号分隔或空格分隔都是有效的。我了解某些语言内置了快速数组打印方法,因此如果它不输出空格分隔的数组,这应该允许您利用它。
4

8 回答 8

12

电源外壳,104 97 91 8683 个字符

$k=@{};$input|%{$k["$([char[]]$_|%{$_+0}|sort)"]+=@($_)}
$k.Values|?{$_[1]}|%{"$_"}

新要求的更新(+8 个字符):

要排除仅大小写不同的单词,我们可以从输入列表中删除重复项(不区分大小写),即$input|sort -uwhere-u代表-unique. sort默认情况下不区分大小写:

$k=@{};$input|sort -u|%{$k["$([char[]]$_|%{$_+0}|sort)"]+=@($_)} 
$k.Values|?{$_[1]}|%{"$_"} 

[char[]]$_|%{$_+0}|sort-part的解释

它是哈希表条目的键,在该条目下存储了单词的字谜。我最初的解决方案是:$_.ToLower().ToCharArray()|sort. 然后我发现我不需要ToLower()密钥,因为哈希表查找不区分大小写。

[char[]]$_|sort将是理想的,但键的字符排序需要不区分大小写(否则Cababc存储在不同的键下)。不幸的是,sort对字符不区分大小写(仅适用于字符串)。

我们需要的是[string[]][char[]]$_|sort,但我找到了一种将每个 char 转换为字符串的更短的方法,即将其他内容连接到它,在这种情况下是整数0,因此[char[]]$_|%{$_+0}|sort. 这不会影响排序顺序,实际的键最终是这样的:d0 o0 r0 w0. 它不漂亮,但它可以完成工作:)

于 2010-04-02T12:22:09.703 回答
12

Perl,59 个字符

chop,$_{join'',sort split//,lc}.="$_ "for<>;/ ./&&say for%_

请注意,这需要 Perl 5.10(对于say函数)。

于 2010-04-02T16:28:49.257 回答
5

Haskell,147 个字符

先前的尺寸:150 159字符

import Char
import List
x=sort.map toLower
g&a=g(x a).x
main=interact$unlines.map unwords.filter((>1).length).groupBy((==)&).sortBy(compare&).lines

这个 165 个字符的版本满足了新的、明确的规则:

import Char
import List
y=map toLower
x=sort.y
g&f=(.f).g.f
w[_]="";w a=show a++"\n"
main=interact$concatMap(w.nubBy((==)&y)).groupBy((==)&x).sortBy(compare&x).lines

这个版本处理:

  1. 输入中仅大小写不同的单词应仅计为一个单词
  2. 输出需要是每行一个字谜集,但可以接受额外的标点符号
于 2010-04-02T14:20:35.743 回答
4

红宝石,94 个字符

h={};(h[$_.upcase.bytes.sort]||=[])<<$_ while gets&&chomp;h.each{|k,v|puts v.join' 'if v.at 1}
于 2010-04-02T13:33:48.910 回答
3

Python,167 个字符,包括 I/O

import sys
d={}
for l in sys.stdin.readlines():
 l=l[:-1]
 k=''.join(sorted(l)).lower()
 d[k]=d.pop(k,[])+[l]
for k in d:
 if len(d[k])>1: print(' '.join(d[k]))

如果没有输入代码(即,如果我们假设 wordlist 已经在 list 中w),它只有 134 个字符:

d={}
for l in w:
 l=l[:-1]
 k=''.join(lower(sorted(l)))
 d[k]=d.pop(k,[])+[l]
for k in d:
 if len(d[k])>1: print(' '.join(d[k]))
于 2010-04-02T10:03:22.193 回答
2

AWK-119

{split(toupper($1),a,"");asort(a);s="";for(i=1;a[i];)s=a[i++]s;x[s]=x[s]$1" "}
END{for(i in x)if(x[i]~/ .* /)print x[i]}

AWK 没有joinPython 之类的函数,或者它可能更短……

它假定大写和小写不同。

于 2010-04-02T10:33:55.403 回答
2

C++,542 个字符

#include <iostream>
#include <map>
#include <vector>
#include <boost/algorithm/string.hpp>
#define ci const_iterator
int main(){using namespace std;typedef string s;typedef vector<s> vs;vs l;
copy(istream_iterator<s>(cin),istream_iterator<s>(),back_inserter(l));map<s, vs> r;
for (vs::ci i=l.begin(),e=l.end();i!=e;++i){s a=boost::to_lower_copy(*i);
sort(a.begin(),a.end());r[a].push_back(*i);}for (map<s,vs>::ci i=r.begin(),e=r.end();
i!=e;++i)if(i->second.size()>1)*copy(i->second.begin(),i->second.end(),
ostream_iterator<s>(cout," "))="\n";}
于 2010-04-02T14:57:48.233 回答
1

蟒蛇,O(n^2)

import sys;
words=sys.stdin.readlines()
def s(x):return sorted(x.lower());
print '\n'.join([''.join([a.replace('\n',' ') for a in words if(s(a)==s(w))]) for w in words])
于 2010-04-02T10:01:51.633 回答