Temukan penjahat dari telinga, jari, dan kepalanya

17

Sebelum penemuan sidik jari dan pengujian DNA, polisi Inggris menggunakan sistem antropometrik untuk mengidentifikasi pelaku berulang. Bagian-bagian tertentu dari tubuh penjahat diukur dan disimpan dalam catatan - bagian-bagian tubuh ini diasumsikan tidak berubah ukurannya setelah dewasa. Sistem ini dikenal sebagai bertillonnage .

Diagram di bawah ini menunjukkan sistem pengarsipan yang digunakan oleh polisi untuk mengakses catatan-catatan ini dengan cepat.

Meja Diagram 1: Sistem pengarsipan dengan laci bernomor.
Catatan: jika Anda tidak dapat melihat gambar, coba cermin imgur atau kompilasi sendiri .

Lemari arsip terdiri dari 81 laci bernomor. Setiap laci berisi kartu, dan setiap kartu memiliki ukuran bagian-bagian tertentu dari tubuh penjahat:

  • Panjang kepala mereka (H )
  • Luasnya kepala mereka (B )
  • Lebar telinga kanan mereka (E )
  • Panjang jari telunjuk mereka ( F)

Setiap pengukuran diklasifikasikan sebagai kecil, sedang atau besar.

Misalnya, laci 56 berisi kartu dengan karakteristik sebagai berikut: H kecil, besar B, menengah E, dan kecil F. ini dapat dinotasikan dengan menggunakan huruf S, Mdan Ldi tempat kecil, menengah, dan besar:

SH,LB,ME,SF

Perhatikan bahwa huruf ukuran lebih dulu, lalu apa ukurannya. Selain itu, tanda seru !dapat ditempatkan di depan untuk menyebabkan negatif:

!SH,LB,!ME,SF

Ini menunjukkan kartu yang memiliki karakteristik berikut: bukan H kecil, B besar, tidak sedang E, dan kecil F. Ada empat laci yang berisi kartu dengan karakteristik ini - 58, 60, 61, dan 63.

Tugas Anda adalah menulis sebuah program, yang, ketika diberi string yang mencatat beberapa karakteristik, mengeluarkan semua laci yang berisi kartu dengan karakteristik tersebut. Jika tidak ada laci yang berisi kartu dengan karakteristik yang diberikan, output0 .

Berikut adalah beberapa contoh input dan output.

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

Ini kode golf, jadi entri terpendek menang. Ajukan pertanyaan dalam komentar jika spesifikasinya tidak jelas.

Absinth
sumber
Sebagai catatan historis untuk akurasi, sistem bertillonnage sebenarnya jauh lebih rumit daripada versi yang disederhanakan ini, menggunakan 9 pengukuran, bukan 4, dan dengan demikian menggunakan sistem pengarsipan yang lebih terlibat daripada yang digambarkan di sini.
absinthe
4
Oh tidak! bukan ANOTHER Sudoku pertanyaan ;-)
Level River St
1
@steveverrill Saya benar-benar membuat diagram dari template sudoku, jadi ada beberapa kebenarannya: o
absinthe

Jawaban:

1

GolfScript 95 ( DEMO )

','/:r;81,{r{1$[[.9%3/\.3%\.27/\9/3%]{'SML'=}%'HEBF']zip{''+}%\.,3=\1${(;}*@?)!!=},!\;},{)}%0or
Cristian Lupascu
sumber
6

Ruby 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

Edit:

  • diterapkan tips Three If By Whiskey .
  • parameter yang diambil dari baris perintah untuk menyimpan lebih banyak karakter

Demo online: http://ideone.com/lodTLt

Cristian Lupascu
sumber
selectadalah sinonim yang lebih pendek untuk find_all. Anda dapat memangkas dua karakter lainnya dengan mengganti y[-2..-1]dengan y[-2,2], dan tiga karakter lainnya dengan menggunakan ==[]alih-alih.empty? .
Three If By Whiskey
@ThreeIfByWhiskey Kiat-kiat hebat, terima kasih! Saya sudah mengedit jawaban saya.
Cristian Lupascu
2

Scala - 951

Pasti tidak akan memenangkan yang ini, terutama karena nama fungsi bawaan yang saya pikir.

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 ","
}

Argumen diteruskan ke fungsi f

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

bakerg
sumber
2

T-SQL - 547 544

Bukan entri yang menang, tetapi cocok untuk jenis masalah ini.

Pengaturan Tabel Grid - 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)

Permintaan - 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)

Input dilakukan dengan mendeklarasikan @i sebelum kueri

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

Saya dapat menyimpan 89 karakter lebih lanjut jika output tidak harus berupa baris yang dibatasi koma

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''')
MickyT
sumber
1

Mathematica 191 235

Merupakan setiap nomor sel dalam basis 3. Setiap posisi digit mewakili fitur tubuh. Nilai digit, {0,1,2}, masing-masing mewakili "Kecil", "Sedang", "Besar".

Fitur-fiturnya sesuai dengan digit sebagai berikut:

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

Misalnya, input,

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

menandakan:

"LB" menyiratkan breadthOfHead = 2 (besar)

"SF" menyiratkan IndexFingerLength = 0 (kecil)

"SH" menyiratkan LengthOfHead = 0 (kecil)

"ME" menyiratkan WidthOfRightEar = 1 (sedang)

2001di base 3 adalah 55 di base 10.

Kita perlu menambahkan satu karena kita menghitung sel dari 1, bukan nol.


Kode

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

Uji Kasus

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

DavidC
sumber
1

Python 3 - 192 - Cobalah!

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)
Falko
sumber
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]

Output memiliki tanda kurung, dan tidak peduli tentang urutan output.
Beberapa saran dari Falko, dan beberapa dari saya sendiri untuk melepas 10 karakter.

Aneh
sumber
Ya, tidak apa-apa untuk memasukkan input dalam tanda kurung.
absinthe
Apakah mereka harus teratur?
Bizangles
Pertanyaan bagus. Sebenarnya, output tidak harus dalam rangka - walaupun aku tidak yakin bagaimana keluaran mereka dalam urutan yang berbeda akan menghemat karakter.
absinthe
Saya menggunakan python set () s, mengkonversikannya kembali ke daftar, mendapatkan produk, mengubahnya menjadi basis 3 angka kembali ke ints. Dalam semua itu, pesanan menjadi sedikit campur aduk dan saya perlu menggunakan diurutkan () jika saya ingin mereka kembali dalam urutan yang benar.
Bizangles
Saya melihat. Pesanan tidak penting sehingga yang diurutkan () dapat dihapus. Solusi yang bagus.
absinthe