ค้นหาอาชญากรจากหูนิ้วและหัวของเขา


17

ก่อนที่จะมีการค้นพบลายนิ้วมือและการทดสอบดีเอ็นเอตำรวจอังกฤษใช้ระบบการวัดสัดส่วนร่างกายเพื่อระบุผู้กระทำผิดซ้ำ บางส่วนของร่างกายของอาชญากรถูกวัดและเก็บไว้ในบันทึก - ส่วนต่าง ๆ ของร่างกายนี้จะไม่เปลี่ยนขนาดหลังจากผู้ใหญ่ ระบบนี้เป็นที่รู้จักกันbertillonnage

แผนภาพด้านล่างแสดงระบบจัดเก็บข้อมูลที่ตำรวจใช้เพื่อเข้าถึงบันทึกเหล่านี้อย่างรวดเร็ว

โต๊ะ แผนภาพที่ 1: ระบบจัดเก็บข้อมูลที่มีหมายเลขกำกับ
หมายเหตุ: หากคุณไม่สามารถเห็นภาพลองกระจก Imgur หรือรวบรวมมันด้วยตัวคุณเอง

ตู้เก็บเอกสารประกอบด้วย 81 หมายเลขลิ้นชัก ลิ้นชักแต่ละใบบรรจุการ์ดและการ์ดแต่ละใบมีการวัดส่วนต่าง ๆ ของร่างกายอาชญากร:

  • ความยาวของหัว ( H)
  • ความกว้างของหัว ( B)
  • ความกว้างของหูข้างขวา ( E)
  • ความยาวของนิ้วชี้ของพวกเขา ( F)

การวัดแต่ละประเภทจัดเป็นทั้งขนาดเล็กขนาดกลางหรือขนาดใหญ่

ยกตัวอย่างเช่นลิ้นชัก 56 มีบัตรที่มีลักษณะดังต่อไปนี้: H ขนาดเล็กขนาดใหญ่ B กลางอีและเอฟขนาดเล็กนี้สามารถ notated โดยใช้ตัวอักษรS, MและLในสถานที่ของขนาดเล็กขนาดกลางและขนาดใหญ่:

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

นี่คือรหัสกอล์ฟดังนั้นรายการที่สั้นที่สุดชนะ ถามคำถามในความคิดเห็นหากข้อกำหนดไม่ชัดเจน


ในฐานะที่เป็นบันทึกประวัติศาสตร์เพื่อความถูกต้องระบบ bertillonnage มีความซับซ้อนมากกว่าแบบจำลองที่เรียบง่ายกว่านี้โดยใช้การวัด 9 แทนที่จะเป็น 4 และใช้ระบบการยื่นที่เกี่ยวข้องมากกว่า หนึ่งภาพที่นี่
absinthe

4
ไม่นะ! ไม่ใช่อีกคำถามของ Sudoku ;-)
ระดับแม่น้ำเซนต์

1
@steveverrill ฉันสร้างไดอะแกรมจากแม่แบบซูโดกุดังนั้นจึงมีความจริงบางอย่างที่: o
absinthe

คำตอบ:



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

แก้ไข:

  • ใช้เคล็ดลับของThree If By Whisky
  • นำพารามิเตอร์จากบรรทัดคำสั่งเพื่อบันทึกตัวอักษรเพิ่มเติม

การสาธิตออนไลน์: http://ideone.com/lodTLt


selectfind_allเป็นคำพ้องสั้น คุณสามารถตัดอีกสองตัวละครโดยการแทนที่y[-2..-1]ด้วยy[-2,2]และสามมากขึ้นโดยยังคงใช้แทน==[] .empty?
Three If By Whisky

@ThreeIfByWhisk คำแนะนำที่ดีขอบคุณ! ฉันแก้ไขคำตอบของฉันแล้ว
Cristian Lupascu

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} หมายถึง "Small", "Medium", "Large" ตามลำดับ

คุณสมบัติที่สอดคล้องกับตัวเลขดังต่อไปนี้:

{"breadthOfHead", "IndexFingerLength", "LengthOfHead", "WidthOfRightEar"}

ตัวอย่างเช่นการป้อนข้อมูล

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

หมายถึง:

"LB" บอกถึงความกว้างของหน้าหัว = 2 (ใหญ่)

"SF" หมายถึง IndexFingerLength = 0 (เล็ก)

"SH" หมายถึง LengthOfHead = 0 (เล็ก)

"ME" หมายถึง WidthOfRightEar = 1 (ปานกลาง)

2001ในฐาน 3 คือ 55 ในฐาน 10

เราต้องเพิ่มหนึ่งอันเพราะเรานับเซลล์จาก 1 ไม่ใช่ศูนย์


รหัส

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 ตัวอักษร


ใช่มันไม่เป็นไรที่จะมีการป้อนข้อมูลในวงเล็บ
absinthe

พวกเขาจำเป็นต้องมีระเบียบหรือไม่?
Bizangles

คำถามที่ดี. ที่จริงแล้วการส่งออกไม่จำเป็นต้องอยู่ในลำดับที่ - ถึงแม้ว่าฉันไม่แน่ใจว่าวิธีการแสดงผลพวกเขาในการสั่งซื้อที่แตกต่างกันจะประหยัดตัวอักษร.
แอ็บซิน

ฉันใช้ python set () s, แปลงมันกลับเป็นรายการ, รับผลิตภัณฑ์, แปลงเป็นตัวเลขฐาน 3 กลับเป็น ints โดยรวมแล้วลำดับที่ได้รับเล็กน้อยและฉันต้องใช้ sort () ถ้าฉันต้องการให้พวกเขากลับมาในลำดับที่ถูกต้อง
Bizangles

ฉันเห็น. คำสั่งซื้อไม่สำคัญดังนั้นการเรียงลำดับ () อาจถูกลบออก ทางออกที่ดี
absinthe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.