从他的耳朵,手指和头部找到罪犯


17

在发现指纹和DNA测试之前,英国警察使用人体测量系统来识别重犯。对罪犯尸体的某些部位进行了测量并存储在记录中-假定这些尸体成年后大小没有变化。该系统称为bertillonnage

下图显示了警方用于快速访问这些记录的归档系统。

表 图1:带编号抽屉的归档系统。
注意:如果看不到图像,请尝试imgur镜像自己编译

文件柜由81个编号的抽屉组成。每个抽屉里都装有卡,每个卡上都有罪犯身体特定部位的尺寸:

  • 他们的头长(H
  • 他们的头宽(B
  • 右耳的宽度(E
  • 食指的长度(F

每种度量都分为小,中或大。

例如,抽屉56包含具有以下特征的卡:小H,大B,介质E和F.小这可以使用字母来谱写SML在地方小,中和大:

SH,LB,ME,SF

请注意,尺寸字母排在最前面,然后是尺寸。另外,!可能在前面放置一个感叹号,从而引起负面影响:

!SH,LB,!ME,SF

这表明,具有以下特点卡:小H,大B,介质E和F.小有包含卡具有这些特征的四个抽屉- 58,60,61,和63。

您的任务是编写一个程序,当给定一个指示某些特征的字符串时,输出包含该特征卡的所有抽屉。如果没有抽屉包含具有给定特性的卡片,则输出0

这是一些示例输入和输出。

  1. 输入:SH,LB,ME,SF
    输出:56
  2. 输入:!SH,LB,!ME,SF
    输出:58,60,61,63
  3. 输入:SB,!MF,!LF
    输出:1,2,3,4,5,6,7,8,9
  4. 输入:MH,!MH
    输出:0

这是代码高尔夫球,因此最短的入场券获胜。如果规范不明确,请在注释中提出问题。


作为准确性的历史记录,实际上,伯爵鸟笼系统比此简化版复杂得多,使用9个测量值而不是4个测量值,因此使用的卷宗系统比这里描述的那个。
2014年

4
不好了!不是另一个数独问题;-)
Level River St

1
@steveverrill我实际上是从数独模板制作的,所以有一个真相:o
苦艾酒

Answers:



6

红宝石1.9.3 - 173 157 143

x=(1..81).select{|j|$*[0].split(?,).all?{|y|i=j-1
z='SML'
[z[i%9/3]+?H,z[i%3]+?E,z[i/27]+?B,z[i/9%3]+?F].member?(y[-2,2])^y[?!]}}
p x==[]?[0]:x

编辑:

在线演示:http : //ideone.com/lodTLt


select是的缩写find_all。您可以通过替换y[-2..-1]为来修剪另外两个字符y[-2,2],而使用==[]代替来修剪另外三个字符.empty?
三瓶威士忌如果

@ThreeIfByWhiskey很棒的提示,谢谢!我已经编辑了答案。
Cristian Lupascu 2014年

2

斯卡拉-951

绝对不会赢得这一奖项,主要是因为我认为内置函数的名称。

def m(a: List[Int]) = 0 to 8 flatMap (x => a map (_ + 9*x)) toSet
var SH = m(List(1,2,3))
var MH = m(List(4,5,6))
var LH = m(List(7,8,9))
var SE = m(List(1,4,7))
var ME = m(List(2,5,8))
var LE = m(List(3,6,9))
var SB = 1 to 27 toSet
var MB = 28 to 54 toSet
var LB = 55 to 81 toSet
def l(a: List[Int]) = 0 to 2 flatMap (x => a map (_+27*x)) toSet
var SF = l(1 to 9 toList)
var MF = l(10 to 18 toList)
var LF = l(19 to 27 toList)

var j = Map(("LH",LH),("MH",MH),("SH",SH),("LB",LB),("MB",MB),("SB",SB),("LF",LF),("MF",MF),("SF",SF),("LE",LE),("ME",ME),("SE",SE))

def f(x : String) = {
  def h(i : List[String], k : Set[Int]) : Set[Int] = {
      if(i isEmpty) k
      else if(i.head.startsWith("!")) h(i.tail, k filterNot (j(i.head.replace("!","")) contains _))
      else h(i.tail, k intersect j(i.head))
  }
  h(x split "," toList, 1 to 81 toSet) mkString ","
}

参数传递给函数 f

f("SH,LB,ME,SF") = 56


2

T-SQL- 547 544

不是成功的参赛作品,但适合此类问题。

网格表设置-254

SELECT ROW_NUMBER()OVER(ORDER BY (SELECT $))I,LEFT(Z,1)E,RIGHT(Z,1)H,LEFT(Y,1)F,RIGHT(Y,1)B INTO G FROM(VALUES('SS'),('MS'),('LS'),('SM'),('MM'),('LM'),('SL'),('ML'),('LL'))FB(Y),(VALUES('SS'),('MS'),('LS'),('SM'),('MM'),('LM'),('SL'),('ML'),('LL'))EH(Z)

查询-293 290

DECLARE @S CHAR(400)='SELECT ISNULL(SUBSTRING(O,2,99),0)FROM (SELECT CONCAT('','',I)FROM G WHERE '+REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REVERSE(@i),',',' AND '),'S!','!S'),'M!','!M'),'L!','!L'),'S','=''S'''),'M','=''M'''),'L','=''L''')+' FOR XML PATH(''''))O(O)';EXEC(@S)

通过在查询之前声明@i来完成输入

DECLARE @I VARCHAR(50) = 'SB,!MF,!LF';

如果输出不必是逗号分隔的行,我可以再保存89个字符

DECLARE @S CHAR(400)='SELECT I FROM G WHERE '+REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REVERSE(@i),',',' AND '),'S!','!S'),'M!','!M'),'L!','!L'),'S','=''S'''),'M','=''M'''),'L','=''L''')

1

Mathematica 191 235

代表以3为底的每个单元格编号。每个数字位置代表一个身体特征。数字的值{0,1,2}分别代表“小”,“中”,“大”。

这些功能对应于以下数字:

{“ breadthOfHead”,“ IndexFingerLength”,“ LengthOfHead”,“ WidthOfRightEar”}

例如输入

{"SH","LB","ME","SF"}

表示:

“ LB”表示breadthOfHead = 2(大)

“ SF”表示IndexFingerLength = 0(小)

“ SH”表示LengthOfHead = 0(小)

“ ME”表示WidthOfRightEar = 1(中)

2001以3为底的基数是10以55的底数。

我们需要加1,因为我们要从1开始计数单元,而不是从0开始。


c=Characters;t=Table[IntegerDigits[k,3,4],{k,0,80}];
f@i_:=1+FromDigits[#,3]&/@Intersection@@(Cases[t,#]&/@(ReplacePart[{_,_,_,_},{#}]&/@(c/@i
/.Thread[c@"BFHESML"-> {1,2,3,4,0,1,2}]/.{{"!",v_,n_}:> (n-> Except[v]),{v_Integer,n_}:> n-> v})))
/.{}:>0

测试用例

f[{"SH","LB","ME","SF"}]

{56}


f[{"!SH","LB","!ME","SF"}]

{58,60,61,63}


f[{"SB","!MF","!LF"}]

{1,2,3,4,5,6,7,8,9}


f[{"MH","!MH"}]

0


1

Python 3-192- 试试吧!

from itertools import*
S=input().split(',')
print([i+1for i in range(81)if eval('*'.join('(list(product(*["SML"]*4))[i][%d]%s="%s")'%('BFHE'.find(s[-1]),'!='[s[0]>'!'],s[-2])for s in S))]or 0)

1

Python 2-194

from itertools import*
n=map(set,['012']*4)
for x in raw_input().split(','):n['BFHE'.find(x[-1])]&=set(`'SML'.find(x[-2])`)^set('012'*(x<'"'))
print[1+int(''.join(x),3)for x in product(*n)]or[0]

输出带有方括号,并且不关心输出的顺序
Falko的一些建议以及我本人的一些建议可以减少10个字符。


是的,可以将输入内容括在方括号中。
苦艾酒

他们需要秩序吗?
Bizangles 2014年

好问题。实际上,输出不符合规定-虽然我不知道如何以不同的顺序将节省字符输出它们。
苦艾酒

我正在使用python set()s,将它们转换回列表,获取乘积,将基数3转换为整数。在所有这些中,顺序变得有些混乱,如果我希望它们以正确的顺序返回,我需要使用sorted()。
Bizangles 2014年

我知道了。顺序并不重要,因此可以删除sorted()。不错的解决方案。
苦艾酒
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.