martes, 18 de septiembre de 2012

Formula para repartir los mismos puntos en una lista de longitud variable

Enunciado:

Realizas una encuesta con preguntas donde te responde con una lista de longitud variable por orden de preferencia.
Quieres repartir una cantidad fija de puntos entre las respuestas dando mas siempre a las situadas en primer lugar.

Por ejemplo "elija su ciudad favorita". En una respuesta te dicen solo una "CASTELLÓN", otra persona te dice "MADRID", "BARCELONA", "VALENCIA" y una tercera te dice "MADRID", "VALENCIA". "SEVILLA", "BURRIANA"
Hay 100 puntos a repartir, veamos los resultados:
  • La primera respuesta dará a CASTELLÓN 100 puntos
  • La segunda entregará  50 puntos a MADRID, 33 a BARCELONA y 17 a VALENCIA.
  • La tercera entrega a 40 a MADRID,  30 a VALENCIA, 20 a SEVILLA y 10 a BURRIANA
Al final tenemos: CASTELLON (100), MADRID (73), VALENCIA (47),BARCELONA (33) y BURRIANA (10).
Gana CASTELLON a MADRID, pese que CASTELLON solo haya sido votada una vez, y MADRID dos veces y en primer lugar en ambos casos.
Se valora mas cuando solo se da una respuesta que si se responde con varias. La persona que ha votado a CASTELLON está muy convencida, mientras que las demás tienen gustos dispersos.

Se me ocurre aplicarlo en las carreras de los autos locos, los participantes puntúan mas cuantos menos coches acaban. Seria peligroso aplicarlo en la F2 (Fernando Alonso dixit).

Solución

puntuación(r,p)=2*( (r-p+1)/(r*(r+1)))

Donde r es el número de respuestas y p la posición de la respuesta que estamos puntuando.

Comentario 

Esta formula puede implantarse en SQL  o en MDX. Es fácil construir una tabla Excel para ver las puntuaciones.


Cómo puede verse me apoyo en la suma de la serie geometríca.

Archivos duplicados y hash MD5

Enunciado

Quieres detectar y mover a una carpeta todos los archivos duplicados en una carpeta y subcarpetas. 
Cuando hay duplicidados mueves el archivo con nombre mas largo o que está en una subcarpeta.
En la nueva carpeta creas las subcarpetas originales.

Solución:

Para detectar los archivos duplicados usamos el hash MD5 calculado con la clase correspondiente en el framework .NET, recorremos recursivamente las carpetas, comparando archivos  y moviendo el que tiene path completo mas largo.
Const pathdup="c:\duplicados" 'carpeta donde se moveran los duplicados
Sub procesaCarpeta(carpeta As String)
'carpeta: carpeta a recorrer
   Dim existencias As Dictionary(Of String, String)
    Dim Md5 As New MD5CryptoServiceProvider()
        Try
            Dim archivos = My.Computer.FileSystem.GetFiles(carpeta)

            For Each archivo In archivos
                Dim acont = My.Computer.FileSystem.ReadAllBytes(archivo)
                Dim clave = Convert.ToBase64String(Md5.ComputeHash(acont))
                If existencias.ContainsKey(clave) Then
                    If existencias(clave).Length <= archivo.Length Then
                        'mover nuevo
                        My.Computer.FileSystem.MoveFile(archivo, archivo.Replace("C:\", pathdup))
                    Else
                        My.Computer.FileSystem.MoveFile(existencias(clave), existencias(clave).Replace("C:\", pathdup))
                        existencias(clave) = archivo
                    End If
                Else
                    existencias.Add(clave, archivo)
                End If
            Next
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.OkOnly, carpeta)
        End Try

        For Each hija In My.Computer.FileSystem.GetDirectories(carpeta)
            procesaCarpeta(hija)
        Next
    End Sub

Comentario

Puede parecer tonto pero limpié 7 Gb del disco duro de mi casa. La explicación es simple, mi hija antes de editar copiaba todas las imágenes de una carpeta y las pegaba en la misma carpeta o en una  subcarpeta (a veces ambas cosas).