Encuentra un criminal de su oreja, dedo y cabeza


17

Antes del descubrimiento de las huellas digitales y las pruebas de ADN, la policía británica utilizó un sistema antropométrico para identificar a los delincuentes reincidentes. Ciertas partes de los cuerpos de los delincuentes se midieron y almacenaron en registros; se supuso que estas partes del cuerpo no cambiarían de tamaño después de la edad adulta. Este sistema se conocía como bertillonnage .

El siguiente diagrama muestra un sistema de archivo utilizado por la policía para acceder a estos registros rápidamente.

Mesa Diagrama 1: Un sistema de archivo con cajones numerados.
Nota: si no puede ver la imagen, pruebe el espejo imgur o compílelo usted mismo .

El archivador consta de 81 cajones numerados. Cada cajón contiene cartas, y cada carta tiene medidas de partes particulares del cuerpo de un criminal:

  • La longitud de su cabeza ( H)
  • La anchura de su cabeza ( B)
  • El ancho de su oreja derecha ( E)
  • La longitud de su dedo índice ( F)

Cada medida se clasifica como pequeña, mediana o grande.

Por ejemplo, el cajón 56 contiene tarjetas con las siguientes características: pequeña H, B grandes, medio E, y pequeña F. Esto se puede notated usando las letras S, My Len lugar de pequeñas, medianas y grandes:

SH,LB,ME,SF

Tenga en cuenta que la letra de tamaño va primero, luego cuál es la medida. Además, !se puede colocar un signo de exclamación delante para causar un negativo:

!SH,LB,!ME,SF

Esto indica cartas que tienen las siguientes características: no pequeña H, grande B, no mediana E y pequeña F. Hay cuatro cajones que contienen cartas con estas características: 58, 60, 61 y 63.

Su tarea es escribir un programa que, cuando se le da una cadena que anota algunas características, genera todos los cajones que contienen tarjetas con esas características. Si no hay cajones que contengan cartas con las características dadas, salida 0.

Aquí hay algunas entradas y salidas de muestra.

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

Este es el código de golf, por lo que gana la entrada más corta. Haga preguntas en los comentarios si la especificación no es clara.


Como nota histórica de precisión, los sistemas de bertillonnage eran en realidad mucho más complicados que esta versión simplificada, utilizando 9 mediciones en lugar de 4, y por lo tanto utilizando un sistema de archivo más complicado que el que se muestra aquí.
ajenjo

44
¡Oh no! no es OTRA pregunta de Sudoku ;-)
Level River St

1
@steveverrill Realmente hice el diagrama a partir de una plantilla de sudoku, así que hay algo de verdad en eso: o
ajenjo

Respuestas:


1

GolfScript 95 ( DEMO )

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

6

Rubí 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

Editar:

  • aplicó las puntas de Three If By Whiskey .
  • parámetros tomados de la línea de comando para guardar más caracteres

Demostración en línea: http://ideone.com/lodTLt


selectes un sinónimo más corto para find_all. Puede recortar otros dos caracteres reemplazándolos y[-2..-1]con y[-2,2], y tres más aún utilizando en ==[]lugar de .empty?.
Three If By Whisky

@ThreeIfByWhiskey Grandes consejos, gracias! He editado mi respuesta.
Cristian Lupascu

2

Scala - 951

Definitivamente no ganará este, principalmente debido a los nombres de las funciones integradas, creo.

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

El argumento pasa a la función. f

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


2

T-SQL - 547 544

No es una entrada ganadora, pero es adecuada para este tipo de problema.

Configuración de tabla de cuadrícula - 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)

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

La entrada se realiza declarando @i antes de la consulta

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

Podría guardar otros 89 caracteres si la salida no tiene que ser una fila delimitada por comas

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

Representa cada número de celda en la base 3. Cada posición de dígito representa una característica corporal. El valor del dígito, {0,1,2}, representa "Pequeño", "Medio", "Grande", respectivamente.

Las características corresponden a los dígitos de la siguiente manera:

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

Por ejemplo, la entrada,

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

significa:

"LB" implica breadthOfHead = 2 (grande)

"SF" implica IndexFingerLength = 0 (pequeño)

"SH" implica LengthOfHead = 0 (pequeño)

"ME" implica WidthOfRightEar = 1 (medio)

2001en la base 3 es 55 en la base 10.

Necesitamos agregar uno porque estamos contando celdas desde 1, no desde cero.


Código

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

Casos de prueba

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 0


1

Python 3 - 192 - ¡ Pruébalo!

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

Pitón 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 salida tiene paréntesis, y no me importa el orden de salida.
Algunas sugerencias de Falko y un par de mí para sacar 10 caracteres.


Sí, está bien tener la entrada entre paréntesis.
absenta

¿Necesitan estar en orden?
Bizangles

Buena pregunta. En realidad, la salida no tiene que estar en orden - aunque no estoy seguro de cómo dar salida en un orden diferente que ahorraría caracteres.
absenta

Estoy usando python set () s, convirtiéndolos de nuevo en listas, obteniendo el producto, convirtiendo a números de base 3 de nuevo a ints. En todo eso, el orden se confunde un poco y necesito usar sorted () si quiero que vuelvan en el orden correcto.
Bizangles

Veo. El orden no es importante, por lo que se puede eliminar el ordenado (). Buena solución
ajenjo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.