Code golf:查找所有字谜

时间:2010-04-02 09:23:10

标签: code-golf anagram

如果该单词中的字母可以重新排列以形成不同的单词,则单词为anagram

任务:

  • 字符数最短的源代码,用于查找给出单词列表的所有字符集。
  • 空格和新行应计为字符
  • 使用代码标尺

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

输入:

来自stdin的list of words,每个单词用新行分隔。

e.g。

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 char perl解决方案,我会在更多人发布后发布:)

玩得开心!

编辑:澄清

  • 假设anagrams不区分大小写(即大写和小写字母相同)
  • 只能打印超过1件的套装
  • 每组字谜只能打印一次
  • 字谜集中的每个单词只应出现一次

EDIT2:更多澄清

  • 如果两个单词仅在大小写方面有所不同,则应将它们折叠为同一个单词,由您自行决定将哪个大小写方案用于折叠单词
  • 只要每个单词以某种方式分开,
  • 单词组只需以新行结尾。逗号分隔或空格分隔有效。我知道有些语言内置了快速阵列打印方法,所以如果它不输出空格分隔的数组,这应该允许你利用它。

8 个答案:

答案 0 :(得分:12)

Powershell, 104 97 91 86 83 chars

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

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

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

$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,但是我找到了一种将每个字符串转换为字符串的简短方法,即将其他内容连接到字符串,在本例中为整数0,因此{{1 }}。这不会影响排序顺序,实际的键最终会像:[char[]]$_|%{$_+0}|sort。它并不漂亮,但它可以完成工作:)

答案 1 :(得分:12)

Perl,59个字符

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

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

答案 2 :(得分:5)

Haskell,147个字符

之前的尺寸: 150 159 chars

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. 输出需要是每行一个字谜集,但可以接受额外的标点符号

答案 3 :(得分:4)

Ruby,94个字符

h={};(h[$_.upcase.bytes.sort]||=[])<<$_ while gets&&chomp;h.each{|k,v|puts v.join' 'if v.at 1}

答案 4 :(得分: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]))

没有输入代码(即如果我们假设单词列表已在列表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]))

答案 5 :(得分: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没有像Python这样的join函数,或者可能更短......

它将大写和小写视为不同。

答案 6 :(得分: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";}

答案 7 :(得分:1)

Python,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])