2012-07-05 10 views
5

así que tiene un sistema de clasificación que es básicamente una pirámide:Como llegar retadores en el sistema de clasificación pirámide

 01 
    02 03 
    04 05 06 
    07 08 09 10 
11 12 13 14 15 
16 17 18 19 20 21 

Ahora, cada persona puede desafiar a cada persona a la izquierda en la misma fila, a la derecha en el fila arriba.

Entonces, por ejemplo, 18 puede desafiar 13-17
Básicamente puede desafiar más arriba en la escalera cuanto más bajo se encuentre.

¿Alguna idea sobre cómo solucionar esto como una función? Cuando pienso en el problema, me vienen algunos cálculos bastante complejos para el rango calculando la capa de la pirámide mediante la cuenta atrás, pero estoy seguro de que tiene que haber una solución fácil.

Algunos más exmaples para los rangos:
02 - 01
03 - 02
04 - 02-03
05 - 03-04
06 - 04-05
07 - 04-06
08 - 05-07
11 - 07-10
17 - 12-16

Por cierto, a pesar de que podría ser similar tarea, yo puedo asegurar que yo ya estoy fuera de la escuela desde hace algunos años. Esto realmente va a un sistema de escalera de tiro con arco que intento digitalizar para el club local de tiro con arco :)

Respuesta

9

Para el jugador x es fácil ver que el valor superior en el rango es siempre x - 1. La parte difícil es encontrar el valor más bajo.

Primero tenga en cuenta que el número de personas que puede impugnar es igual al número de personas en la fila de arriba. Puede que le resulte más fácil entender por qué esto es cierto por mirar el siguiente diagrama donde cada óvalo contiene exactamente una de las personas del jugador 13 puede desafiar (9, 10, 11, 12):

showing relationship to triangular numbers

Hay son cuatro personas que el número 13 se puede desafiar, y cuatro personas en la fila por encima de jugador 13.


Así que tenemos que encontrar el número de personas en la fila por encima de x. Observe que el número total de personas sobre x es triangular numberT(n) para algunos n. Y el valor de n es el número de personas en la fila de arriba x.

para encontrar números triangulares se puede encontrar esta fórmula útil:

T(n) = n * (n+1)/2 

El problema es encontrar el mayor n tal que T(n) < x.

Puede usar un ciclo para recorrer todos los valores posibles de n, calculando T(n) hasta que exceda x. Esto funcionaría, es simple, y casi con toda seguridad será lo suficientemente rápido para sus propósitos.

Pero también se puede llegar de forma más directa mediante el uso de la inverse of the above quadratic equation:

inverse of triangulare number formula

El único ajuste que se necesita es restar primera 1 de x porque queremos que el número triangular estrictamente menor que x. Sin ese ajuste, daría la fila actual para números triangulares exactos, en lugar de la fila anterior.

Usando esta fórmula y traducirlo a PHP podemos obtener el resultado directamente para cualquier x:

$n = floor((sqrt(1 + 8 * ($x - 1)) - 1)/2); 
$lower = $x - $n; 
$upper = $x - 1; 

Resultados:

 
2: 1 - 1 
3: 2 - 2 
4: 2 - 3 
5: 3 - 4 
6: 4 - 5 
7: 4 - 6 
8: 5 - 7 
9: 6 - 8 
10: 7 - 9 
11: 7 - 10 
12: 8 - 11 
13: 9 - 12 
14: 10 - 13 
15: 11 - 14 
16: 11 - 15 
17: 12 - 16 
18: 13 - 17 
19: 14 - 18 
20: 15 - 19 
21: 16 - 20 

ver su funcionamiento en línea: ideone

+0

Fwiw, éstos las ecuaciones provienen de algoritmos de cruce de árboles. –

+0

No estoy 100% seguro si entiendo por qué pero funciona, gracias: D – bardiir

+0

@bardiir: He publicado un poco más de explicación. ¿Eso te ayuda a entender por qué funciona? –

Cuestiones relacionadas