Trouvez un criminel à l'oreille, au doigt et à la tête

17

Avant la découverte des empreintes digitales et des tests ADN, la police britannique a utilisé un système anthropométrique pour identifier les récidivistes. Certaines parties du corps des criminels ont été mesurées et stockées dans des dossiers - ces parties du corps ne devaient pas changer de taille après l'âge adulte. Ce système était connu sous le nom de bertillonnage .

Le diagramme ci-dessous montre un système de classement utilisé par la police pour accéder rapidement à ces dossiers.

Table Schéma 1: Un système de classement avec tiroirs numérotés.
Remarque: si vous ne pouvez pas voir l'image, essayez le miroir imgur ou compilez-le vous-même .

Le classeur se compose de 81 tiroirs numérotés. Chaque tiroir contient des cartes, et chaque carte a des mesures de parties particulières du corps d'un criminel:

  • La longueur de leur tête ( H)
  • L'étendue de leur tête ( B)
  • La largeur de leur oreille droite ( E)
  • La longueur de leur index ( F)

Chaque mesure est classée comme petite, moyenne ou grande.

Par exemple, le tiroir 56 contient des cartes avec les caractéristiques suivantes: petite H, un grand B, E moyen et petit F. Cela peut être transcrite en utilisant les lettres S, Met Là la place des petites, moyennes et grandes:

SH,LB,ME,SF

Notez que la lettre de taille va d'abord, puis quelle est la mesure. De plus, un point d'exclamation !peut être placé devant pour provoquer un négatif:

!SH,LB,!ME,SF

Cela indique des cartes qui ont les caractéristiques suivantes: pas petit H, grand B, pas moyen E et petit F. Il y a quatre tiroirs qui contiennent des cartes avec ces caractéristiques - 58, 60, 61 et 63.

Votre tâche consiste à écrire un programme qui, lorsqu'il reçoit une chaîne notant certaines caractéristiques, génère tous les tiroirs contenant des cartes avec ces caractéristiques. S'il n'y a pas de tiroirs contenant des cartes avec les caractéristiques données, sortez 0.

Voici quelques exemples d'entrées et de sorties.

  1. Entrée: SH,LB,ME,SF
    Sortie:56
  2. Entrée: !SH,LB,!ME,SF
    Sortie:58,60,61,63
  3. Entrée: SB,!MF,!LF
    Sortie:1,2,3,4,5,6,7,8,9
  4. Entrée: MH,!MH
    Sortie:0

C'est le golf de code, donc l'entrée la plus courte gagne. Posez des questions dans les commentaires si la spécification n'est pas claire.

Absinthe
la source
En tant que note historique pour la précision, les systèmes de bertillonnage étaient en réalité beaucoup plus compliqués que cette version simplifiée, utilisant 9 mesures au lieu de 4, et donc utilisant un système de classement plus complexe que celui représenté ici.
absinthe
4
Oh non! pas UNE AUTRE question de Sudoku ;-)
Level River St
1
@steveverrill J'ai fait le diagramme à partir d'un modèle de sudoku, donc il y a du vrai: o
absinthe

Réponses:

1

GolfScript 95 ( DEMO )

','/:r;81,{r{1$[[.9%3/\.3%\.27/\9/3%]{'SML'=}%'HEBF']zip{''+}%\.,3=\1${(;}*@?)!!=},!\;},{)}%0or
Cristian Lupascu
la source
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

Éditer:

  • appliqué les conseils de Three If By Whisky .
  • pris des paramètres de la ligne de commande pour enregistrer plus de caractères

Démo en ligne: http://ideone.com/lodTLt

Cristian Lupascu
la source
selectest un synonyme plus court pour find_all. Vous pouvez couper deux autres caractères en remplaçant y[-2..-1]par y[-2,2], et trois autres encore en utilisant ==[]au lieu de .empty?.
Three If By Whisky
@ThreeIfByWhiskey Grands conseils, merci! J'ai édité ma réponse.
Cristian Lupascu
2

Scala - 951

Je ne gagnerai certainement pas celui-ci, principalement en raison des noms des fonctions intégrées, je pense.

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

L'argument est passé dans la fonction f

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

Bakerg
la source
2

T-SQL - 547 544

Pas une entrée gagnante, mais adaptée à ce type de problème.

Configuration de la table de grille - 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)

Requête - 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)

L'entrée se fait en déclarant @i avant la requête

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

Je pourrais enregistrer encore 89 caractères si la sortie ne doit pas être une ligne séparée par des virgules

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
la source
1

Mathematica 191 235

Représente chaque numéro de cellule dans la base 3. Chaque position de chiffre représente une caractéristique corporelle. La valeur du chiffre, {0,1,2}, représente respectivement "Petit", "Moyen", "Grand".

Les caractéristiques correspondent aux chiffres comme suit:

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

Par exemple, l'entrée,

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

signifie:

"LB" implique la largeur de la tête = 2 (grand)

"SF" implique IndexFingerLength = 0 (petit)

"SH" implique LengthOfHead = 0 (petit)

"ME" implique WidthOfRightEar = 1 (moyen)

2001en base 3 est 55 en base 10.

Nous devons en ajouter un car nous comptons les cellules à partir de 1 et non de zéro.


Code

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

Cas de test

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
la source
1

Python 3 - 192 - Essayez-le!

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
la source
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]

La sortie a des crochets, et ne se soucie pas de l'ordre de sortie.
Quelques suggestions de Falko, et un couple de moi-même pour enlever 10 caractères.

Bizangles
la source
Oui, il est normal que l’entrée soit placée entre crochets.
absinthe
Doivent-ils être en règle?
Bizangles
Bonne question. En fait, la sortie ne doit pas être pour - bien que je ne suis pas sûr de savoir comment les sortir dans un ordre différent sauverait des personnages.
absinthe
J'utilise python set () s, les reconvertit en listes, récupère le produit, convertis en nombres de base 3 en pouces. Dans tout cela, la commande est un peu brouillée et je dois utiliser sorted () si je veux les remettre dans le bon ordre.
Bizangles
Je vois. L'ordre n'est pas important, donc trié () peut être supprimé. Belle solution.
absinthe