Enseñas a una clase de estudiantes con preferencias interesantes sobre cómo están dispuestas sus sillas. Hay 3 requisitos muy específicos que tienen para la disposición de las sillas:
La mayoría de ellos están dispuestos en un rectángulo, incluso si eso significa que algunas sillas se vacían.
Debe haber tan pocas sillas vacías como sea posible.
Deben ser tan "cuadrados" como sea posible. La cuadratura está determinada por la distancia entre el ancho y la altura del rectángulo, más bajo es mejor. Por ejemplo, un rectángulo que
4x7
tiene un cuadrado de 3.
Para ser más específicos, el "puntaje" de un arreglo es la distancia entre el ancho y la altura más el número de sillas que quedarían vacías.
Pongamos un ejemplo. Digamos que tienes 13 estudiantes. Puede organizar las sillas de cualquiera de estas formas:
1x13
2x7
3x5
4x4
1x13
No es muy cuadrado. De hecho, 1 y 13 están separados por 12, por lo que le damos a este arreglo 12 puntos. También tiene 0 sillas vacías, por lo que agregamos 0 puntos, dando a este arreglo una puntuación de 12. No es tan bueno.
2x7
Ciertamente es mejor. 2 y 7 son solo 5, por lo que le damos a este arreglo 5 puntos. Sin embargo, si realmente dispusiera 2 filas de siete sillas, se necesitarían 14 sillas, lo que significa que una silla estaría vacía. Entonces agregamos un punto, dando a este arreglo una puntuación de 6.
También podríamos hacer 3x5
. 3 y 5 son 2 separados, entonces +2 puntos. Se necesitan 15 sillas, lo que significa que tendríamos dos sillas adicionales, por lo que otros +2 puntos, para una puntuación de 4.
Última opción, 4x4
. 4 y 4 están separados por 0, por lo que le damos +0 puntos. 4x4 tiene 16 sillas, por lo que 3 sillas quedan vacías, para un puntaje total de 3. Esta es la solución óptima.
En caso de empate, la solución óptima es la que tiene menos sillas vacías.
El reto
Debe escribir un programa o función que tome un número entero y genere la disposición óptima de las sillas para ese número de estudiantes. IO puede estar en cualquier formato razonable. Aquí hay una muestra de salida para cualquier número de estudiantes de 1 a 100:
1: (1, 1)
2: (1, 2)
3: (2, 2)
4: (2, 2)
5: (2, 3)
6: (2, 3)
7: (3, 3)
8: (3, 3)
9: (3, 3)
10: (2, 5)
11: (3, 4)
12: (3, 4)
13: (4, 4)
14: (4, 4)
15: (4, 4)
16: (4, 4)
17: (3, 6)
18: (3, 6)
19: (4, 5)
20: (4, 5)
21: (3, 7)
22: (5, 5)
23: (5, 5)
24: (5, 5)
25: (5, 5)
26: (4, 7)
27: (4, 7)
28: (4, 7)
29: (5, 6)
30: (5, 6)
31: (4, 8)
32: (4, 8)
33: (6, 6)
34: (6, 6)
35: (6, 6)
36: (6, 6)
37: (5, 8)
38: (5, 8)
39: (5, 8)
40: (5, 8)
41: (6, 7)
42: (6, 7)
43: (5, 9)
44: (5, 9)
45: (5, 9)
46: (7, 7)
47: (7, 7)
48: (7, 7)
49: (7, 7)
50: (5, 10)
51: (6, 9)
52: (6, 9)
53: (6, 9)
54: (6, 9)
55: (7, 8)
56: (7, 8)
57: (6, 10)
58: (6, 10)
59: (6, 10)
60: (6, 10)
61: (8, 8)
62: (8, 8)
63: (8, 8)
64: (8, 8)
65: (6, 11)
66: (6, 11)
67: (7, 10)
68: (7, 10)
69: (7, 10)
70: (7, 10)
71: (8, 9)
72: (8, 9)
73: (7, 11)
74: (7, 11)
75: (7, 11)
76: (7, 11)
77: (7, 11)
78: (9, 9)
79: (9, 9)
80: (9, 9)
81: (9, 9)
82: (7, 12)
83: (7, 12)
84: (7, 12)
85: (8, 11)
86: (8, 11)
87: (8, 11)
88: (8, 11)
89: (9, 10)
90: (9, 10)
91: (7, 13)
92: (8, 12)
93: (8, 12)
94: (8, 12)
95: (8, 12)
96: (8, 12)
97: (10, 10)
98: (10, 10)
99: (10, 10)
100: (10, 10)
Como de costumbre, este es el código de golf, por lo que se aplican las lagunas estándar, y el ganador es la respuesta más corta en bytes.
Respuestas:
Jalea ,
161514 bytesPruébalo en línea! o verificar todos los casos de prueba .
Cómo funciona
fuente
Python 2, 68 bytes
Equivalente a lo más "obvio":
fuente
range(-n,0)
, como hago en mi respuesta . Banco de pruebas.Haskell, 65 bytes
Ejemplo de uso:
map f [1..5]
->[(1,1),(1,2),(2,2),(2,2),(2,3)]
.Pasa por un bucle externo
a
de1
ax
(x -> número de estudiantes) y un bucle internob
de1
aa
. Mantiene todos los(b,a)
lugaresa*b>=x
y construye pares de los((arrangement points,seats left), (b,a))
cuales siguen el orden lexicográfico que necesitamos para encontrar el mínimo. Nota:a
siempre es mayor queb
, por lo que no necesitamosabs
cuadratura. No es necesario restarx
el puntaje de "asientos restantes", porque solo importa el orden relativo. Finalmente eliminamos el par de puntuación consnd
.fuente
a*b
(número de asientos libres) es el desempate si el puntaje principal es igual. Por ejemplon=43
: a)a=7, b=7
, la puntuación:(49,49)
b)a=9, b=5
, la puntuación:(49,45)
. La puntuación principal es igual, el desempate decide, b) gana.a*b
, los números(b,a)
que tengo que llevar de todos modos actúan como el desempate y dan los mismos resultados (al menos)n=1..300
. Un producto es pequeño si uno de los factores (aquíb
) es pequeño. Pero mientras no tenga pruebas formales, no quiero usar este hecho. A ver si encuentro uno.Ruby, 64 bytes
Una lambada que toma el número de personas como argumento y devuelve una matriz con ancho y alto de la solución óptima.
fuente
w*h
como segundo elemento en su matriz? No creo que cambie particularmente nada cuando llamasmin
porque minimizas la puntuación, también conocido como el primer elemento.In case of a tie, the optimal solution is the one with less empty chairs
MATL , 18 bytes
Pruébalo en línea!
Explicación
fuente
Javascript, 98 bytes
Mi primer código de golf, así que publico de todos modos!
Inicialmente, mi
o
era un objeto vacío y comprobé sio.a
estaba vacío, por lo que fue un caso especial en la primera ronda. Pero encontré el truco 1/0 en la respuesta de edc65 para inicializar la variable a Infinito.fuente
Pyth,
242221 bytesEditar : en la clave de clasificación, me doy cuenta de que no hay necesidad de encontrar el número de sillas vacías. Es equivalente a puntuar el número total de sillas. Esto me ahorró 2 bytes.
Pruébalo en línea!
fuente
Matlab
(174) (146)121truco 1: agregué la cantidad
1-1/length*width
como empateTruco 2: i calculado
number_students/length
artesonadas para el ancho de rectángulo,el límite superior es el cuadrado pero artesonadas demasiadoEstoy seguro de que se puede jugar más golf ...
intentalo
Editar: referenciado a los comentarios de @StewieGriffin.
Edición 2:
1
yn
son constantes, no es necesario agregarlos a la puntuación general.Edición 3: prueba de rendimiento.
fuente
unique
Python 2, 64 bytes
Esta es una amalgama de la respuesta Python de @ Lynn (de donde tomé el
max(...)[1:]
truco) y el algoritmo de mi respuesta de Julia (que permite una implementación un poco más corta).Pruébalo en Ideone .
fuente
Julia,
6159555352 bytesPruébalo en línea!
Cómo funciona
El código es equivalente a la siguiente versión sin golf, donde
cld
está la división del techo.Para encontrar la disposición óptima, es claramente suficiente para examinar los pares [i, j] , donde 1 ≤ i ≤ n y j = ⌈n / i⌉ .
El puntaje para tal arreglo es | j - i | + (ij - n) , donde el segundo sumando es el número de sillas vacías. En lugar de los puntajes reales, podemos comparar puntajes aumentados por una constante, como ij + | j - i | + 1 .
Es suficiente considerar los pares [i, j] donde i ≤ j ya que las disposiciones [i, j] y [j, i] son igualmente válidas. En su lugar, tratamos con pares estrictamente descendentes estableciendo j = max (⌈n / i⌉, i) , lo que garantiza que j ≥ i dará un puntaje subóptimo si ⌈n / i⌉ <i .
Como j - i ≥ 0 , tenemos ij + | j - i | + 1 = ij + j - i + 1 = (i + 1) × (j - 1) , que se puede calcular en menos bytes de código.
Finalmente
indmin
/indmax
da el índice m (y por lo tanto el valor de i ) de la disposición óptima, que es m por ⌈n / m⌉ . Los empates se rompen por primera aparición, que corresponde al valor más bajo de i , por lo tanto, el valor más alto de j - i y, por lo tanto, el valor más bajo de ij - n (sillas vacías).fuente
JavaScript (ES6) 74
78Edite manteniendo el resultado temporal como una matriz en lugar de 2 vars, tomado de la respuesta de Thiht
Menos golf
Prueba
fuente
PHP, 129 bytes
Sin golf:
fuente
PHP, 104 bytes
El algoritmo que resuelve este problema es simple y probablemente lo utilicen otras respuestas en lenguajes similares a PHP (JavaScript, fe):
n
es lo suficientemente grande (donden
está el valor de entrada); la puntuación de la disposición calculada en la primera iteración (1, n
) es(n-1)+0
;1
yn
; calcule la altura mínima comoceil(n/width)
, calcule la puntuación de disposición utilizando la fórmula provista en la pregunta (es decirabs(width - height) + (width * height - n)
); Si la puntuación es mejor que la mejor puntuación anterior, recuerde el ancho, la altura y la nueva mejor puntuación; En los lazos, utilice el valor dewidth * height - n
para el arreglo actual y el mejor arreglo previo para detectar el nuevo mejor arreglo;Después del golf, este algoritmo produce algo como esto (envuelto aquí para facilitar la lectura):
Utiliza 137 bytes (cuando se coloca en una sola línea) y está lejos de los 104 bytes anunciados en el título. El código probablemente se puede acortar en otros 2-3 bytes, pero la gran fuente de mejora está en otro lugar: en los detalles del algoritmo.
El algoritmo revisado:
Hay varios lugares donde se puede mejorar el algoritmo eliminando el código inútil.
1
a$n
; para la velocidad, el ancho ($i
) debe iterar entre1
yfloor(sqrt($n))
pero esto hace que el código sea aún más largo en lugar de acortarlo; pero si el ancho no excedesqrt($n)
, la altura mínima ($j
) siempre será mayor quesqrt($n)
(su producto debe ser al menos$n
);$i <= $j
(ancho <= alto) como la condición de terminación para el bucle; de esta manera, el ancho iterará de1
afloor(sqrt($n))
y la altura obtendrá valores que comienzan$n
y bajan aceil(sqrt($n))
(no necesariamente todos);abs(width - height)
siempre esheight - width
($j-$i
); 5 bytes guardados de esta manera;$n
se usa en el cálculo de la puntuación (el número de asientos desocupados eswidth * height - n
) pero no es necesario; no es necesario que se muestre el puntaje, se calcula solo para la comparación de los arreglos; Al eliminar- n
de la fórmula de puntuación, guardamos otros 3 bytes (el código PHP es-$n
) sin perder nada;height - width + width * height
($j-$i+$i*$j
);height - width
parte de la puntuación disminuye en cada paso;||$c==$s&&$i*$j<$w*$h
- muchos bytes);-$n
la fórmula del puntaje, el puntaje para el primer arreglo (1x$n
) es$n-1+1*$n
( es decir2*$n-1
); el valor inicial de la mejor puntuación ($s
) puede ser cualquier valor mayor o igual que2*$n
; la primera iteración tiene una mejor puntuación y se convierte en la mejor disposición que permite que el algoritmo se ejecute sin problemas de inicialización.El nuevo código ( 104 bytes ), después de aplicar las mejoras descritas anteriormente es:
Está envuelto aquí para facilitar la lectura. Anteponga el código anterior con el marcador PHP
<?php
(técnicamente, no es parte del código), colóquelo en un archivo (digamosarrange-your-chairs.php
) y ejecútelo con un número entero mayor que cero como argumento. Mostrará el ancho y la altura de la disposición calculada, separados por comas:Otra solución (116 bytes)
Otra solución que usa un algoritmo diferente:
Pone todas las combinaciones de al menos
$n
asientos en una lista asociativa; la clave es la representación de texto del arreglo, el valor es el puntaje del arreglo. Luego ordena la lista (ascendente por valor) y obtiene la clave de la primera entrada.Uno más (115 bytes)
Esta es la versión PHP de la respuesta de @ Neil (JavaScript / ES6, 85 bytes).
Hay algunas diferencias notables debido a las características de cada idioma:
n
valores (indefinidos) y luego usa sus claves para iterar de0
an-1
; incrementai
(d=(n+i++)/i|0
) para hacerlo iterar de1
an
; la solución PHP no necesita incrementarse; utilizarange()
para generar una matriz y luego utiliza los valores generados (1
an
) para iterar;(n+i)/i
luego convierte el valor a entero usando|0
para obtener el entero más pequeño más grande quen/i
; la respuesta PHP resuelve este problema fácilmente con la función PHPceil()
; JavaScript también proporcionaMath.ceil()
pero usa 5 bytes más que la solución encontrada por Neil;array_map()
que de alguna manera es similar con JSArray.map()
pero no ayuda aquí; su sintaxis es detallada, aforeach
produce código más corto; sin embargo, es más grande que el código JS;||
no es posible en PHP porque carece del operador de coma; Tradujea||b||c
aif(!a&&!b)c
entonces, porquea
yb
son comparaciones, negué sus operadores (reemplazados<
por>=
); esto también produce código más grande que la versión JS;$
.Las versiones no protegidas de todas las soluciones y el conjunto de pruebas se pueden encontrar en Github .
fuente
JavaSCript (ES6), 83 bytes
fuente
m
para compensar.Julia, 87
Creo que este es un paso en la dirección para encontrar una función mágica para el problema:
Solo mira pares
(i, j=(i+n)/(i+1))
o(i, j+1)
fuente
n
ninguna parte, y parece que no está tomando información.n
como entrada. Uno necesitaría envolverlon->...
. Es bueno que puedas hacer que funcione.Oracle SQL 11.2, 173 bytes
Sin golf
fuente
Q 58 Bytes
Lamba que calcula el costo mínimo para un valor dado (x) y devuelve una secuencia de dos valores (ancho, alto)
Agregar nombre a esa lambda requiere otros dos caracteres (por ejemplo, f: {..} en lugar de {..})
Prueba
donde {..} es la lambda. Lea como "aplica lambda a cada valor de 1 + primeros 100 ints" (en otras palabras, a cada valor 1..100)
Genera
Explicación
Lamdba anidada
{((b<a)?1b)#+(b:-_-x%a;a:1+!x)}
genera todos los pares de candidatos (ancho, alto) para las sillas x como dos secuencias (w1 w2 w3 ..; h1 h2 h3 ..) (anchos y alturas). Lee de izquierda a derecha, pero evalúa de derecha a izquierdaa:1+!x
genera valores 1..x y asigna esa secuencia a un-_-
es negate floor negate e implementa ceil (ceil no es un primitivo del lenguaje)b:-_-x%a
aplica ceil a cada valor de x dividido por cualquier elemento im a, y asigna la secuencia resultante a b. En otras palabras, b es ceil cada x dividido Por cada 1..x+(b;a)
devuelve una secuencia compuesta de seq a y seq b, y luego la voltea (el resultado es una secuencia de par donde i-pair contiene el elemento i de a y el elemento i de b)b<a
compara elemento por elemento de bya, y genera una secuencia de valores lógicos (verdadero = 1b para cada índice donde b [i]s?x
devuelve la primera posición del elemento x en la secuencia s. Con(b<a)?1b
Buscamos 1b (valor verdadero) en secuencia como resultado de comparar by a, y obtenemos la primera posición donde bn#s
toma n primeros n elementos de las secuencias s. Queremos descartar pares duplicados, por lo que nos detenemos cuando el primer elemento de un par <segundo elemento (por ejemplo, considere 13,1 pero no 1,13).Como efecto secundario, cada par de la secuencia resultante tiene una distancia decreciente entre ayb (ex (13 1; 7 2; 5 3; 4 4)
El par candidato generado por lambda anidado se asigna a c. Luego volteamos c (obtiene b, a de nuevo) y aplica dos funciones a ese argumento:
*/
multiplica y-/
resta. El resultado de(-/;*/)@\:+c
es la diferencia y el producto de cada par.+/
se suma y calcula el costo final. El costo de cada patrón se asigna a d& / es mínimo, entonces
&/
d es el costo mínimo. Cond?&/d
encontramos la primera aparición del costo mínimo en d, y con c @ .. recuperamos el par en esa posición. Como cada par tiene una distancia decreciente entre ayn, el primer mínimo encontrado tiene la distancia máxima entre otros pares mínimos, por lo que aplicamos la regla de empate correctamentefuente