Puede escribir un programa o función que reciba un número entero impar y positivo n
, donde n >= 3
, como argumento de función, argumentos de línea de comando o en STDIN (o equivalente para su sistema), e imprima en STDOUT (o equivalente de sistema) una espiral ASCII que gira hacia adentro en el sentido de las agujas del reloj donde el borde superior tiene exactamente una n
longitud de caracteres. El primer borde derecho debe tener n+1
caracteres largos, obviamente. Por ejemplo,
Entrada:
11
Salida:
***********
*
********* *
* * *
* ***** * *
* * * * *
* * * * * *
* * *** * *
* * * *
* ******* *
* *
***********
Las capturas:
- Su programa no debe usar más que
O(log n)
memoria . - Su programa solo puede imprimir los caracteres
*
(ASCII 42),(ASCII 32),
<CR>
(ASCII 13) y<LF>
(ASCII 10). - Su programa debe imprimir la cadena, no devolverla de la función.
- La restricción Big-O solo está en la memoria , no hay restricciones en el tiempo de ejecución .
- Una nueva línea final es opcional.
- Si su idioma no admite tipos enteros grandes, no tiene que admitir más de lo que admite, pero no puede usar esto como un truco para decir "oh, bueno, no tengo que admitir por encima de X, así que puede hacer que una gran variedad sea el tamaño máximo cada vez "
Las lagunas estándar están prohibidas, como de costumbre.
n
en la memoria O (1).n
tomalog n
bits. A medida quen
crece, también lo hace el espacio necesario para almacenarlo. ¿Tal vez estás diciendo que hagas esto con un número limitado de variables?n
?Respuestas:
C,
125121 bytesVersión de golf Esto no tiene variable
k
. La variablek
se usa en la versión sin golf solo para facilitar la legibilidad. Tambiénfor
se reacomodan los condicionales de bucle y se{}
elimina un conjunto de innecesarios . Se{}
puede eliminar otro conjunto migrandoputs("")
dentro de los corchetes delj
bucle en la posición de inicialización, pero esto significaría una nueva línea al comienzo de la salida, por lo que no lo he hecho.Imprime una espiral
n
ancha porn+1
alta como el ejemplo.Explicación
Básicamente, reducir a la mitad el valor de
n
(redondeando hacia abajo) y corro dos bucles: una exteriori
a partir-n/2-1
den/2+1
imprimir las filas (i=0
se suprime por lo que obtenern+1
filas) y uno internoj
a partir de (-n/2
an/2
Utilizamos para imprimir los caracteres.)expression & 1
Para imprimir rayas y la condiciónj*j<i*i
para decidir si se imprimen rayas verticales u horizontales (vertical en los lados donde la magnitud absolutai
es mayor y horizontal en la parte superior e inferior). Se+n
requiere un ajuste para ayudar con la terminación correcta dependiendo de sin/2
es impar o no. incluso.k
normalmente es 1 y proporciona un ajuste por el hecho de que los valores absolutos dei
rango de 1 an/2+1
mientras que los valores absolutos dej
rango de 0 an/2
. Sik
siempre fuera 1 obtendríamos rectángulos concéntricos, pero se invierte a 0 cuando se inviertei==j&i<=0
una fila diagonal de celdas, produciendo la espiral.sin golf en el programa de prueba
Salida
fuente
C, 118 bytes
Código antes del golf final:
La observación clave es que el patrón es casi una serie de cuadrados concéntricos. Con un par de pequeñas arrugas:
y = x + 1
diagonal deben invertirse hasta la mitad de la forma.Por lo demás, el código simplemente se repite en todas las posiciones, calcula la distancia de Chebyshev desde el centro para cada posición y emite uno de los dos caracteres dependiendo de si la distancia es par o impar. Y emitiendo una nueva línea para la última posición de cada línea.
Como solo hay unas pocas variables escalares y los caracteres se emiten uno por uno, el uso de la memoria es obviamente constante.
fuente
p
, creo que no cumple con meta.codegolf.stackexchange.com/q/4939/15599 . Tampoco estoy seguro de declarar variables globales al enviar una función. Obviamente mi respuesta sería 4 bytes más corta si hiciera esto. Empecé una meta publicación meta.codegolf.stackexchange.com/q/5532/15599p
.C ++, 926 bytes
Esto no es elegante, pero no ocupa mucha memoria para grandes n. Además, hay (casi con certeza) alrededor de 20 personajes que se pueden jugar más, pero no puedo soportar verlo más.
Breve explicación:
Esto divide las líneas en las espirales en dos tipos: las que tienen ****** en el medio y las que tienen \ s \ s \ s \ s \ s en el medio. Entonces está claro que cada línea está compuesta por varios "*", el medio y algunos "*". Averiguar exactamente cuántas de cada cosa es simple si observa el patrón durante el tiempo suficiente. Lo complicado fue imprimir el centro de la espiral, que básicamente codifiqué usando un condicional. Esto terminó siendo útil porque las líneas *** y \ s \ s \ s cambian siendo impares / pares allí.
Pruebas:
Entrada:
55
(creo que los grandes se ven más geniales)Salida:
Entrada:
3
Salida:
Nota: No soy un estudiante de informática / CS, y no sé cómo demostrar que esto usa memoria O (log n). Solo puedo averiguar qué hacer en función de los enlaces de la pregunta. Estaría agradecido si alguien pudiera confirmar / negar si esta respuesta es válida. Mi lógica para la validez de esta respuesta es que nunca almacena ninguna variable de tamaño basada en n, excepto la entrada en sí. En cambio, un bucle for que se ejecuta n veces calcula valores enteros basados en n. Hay el mismo número de esos valores independientemente de la entrada.
Nota 2: Esto no funciona para n = 1 debido a mi método de tratar con el medio. Esto sería fácil de solucionar con condicionales, así que si alguien está dentro de unos pocos caracteres de mi respuesta, lo arreglaré;)
Juega con él en ideone.
fuente
n
. Un ejemplo típico que no cumple con el requisito sería algún tipo de cadena / búfer / matriz que contenga una línea completa de salida.n=1
, ya que no considero que una carcasa especial sea interesante.Haskell, 151 bytes
Ejemplo de uso:
Gracias a la pereza de Haskell, esto se ejecuta en la memoria constante. Se utiliza el enfoque obvio, es decir, un bucle sobre
y
yx
y elegir entre*
y, en función de
x
resp.y
es par o imparn/2
es par o imparfuente
Lisp común - 346
Solución iterativa con uso constante de memoria. Lo anterior hace uso de pesados
#n=
y#n#
las variables de lectores. A pesar de que hay enfoques más directos, aquí comencé con una función recursiva y la modifiqué para simular la recursividad congoto
declaraciones: esto probablemente no se pueda leer.Salida para todos los valores de entrada de 0 a 59 .
Versión recursiva original, con información de depuración.
(nota:
terpri
significanewline
)Por ejemplo:
Vea también esta pasta con todos los resultados del 0 al 59 (no es lo mismo que el anterior, este es más detallado).
Versión iterativa, con información de depuración.
fuente
n
y la pila de llamadas crece en consecuencia, pero en este caso, podemos simular la recursión con dos bucles: uno conn
disminución yd
aumento (hasta n <= 3 ), y otro cond
disminución a cero. No tengo mucho tiempo para trabajar en esto en este momento, pero intentaré actualizar la respuesta en consecuencia. Por cierto, hay formas más directas de imprimir la espiral, pero fue divertido tratar de definirla de forma recursiva.CJam, 72 bytes
Esta es una conversión bastante directa de mi solución C a CJam. No es tan corto como normalmente esperaría de una solución CJam, pero esta realmente sufre de la restricción de memoria. Los beneficios comunes de acumular resultados en la pila que se vuelca automáticamente al final, y usar operaciones sofisticadas de lista / cadena, todo se va por la ventana. Esto genera y genera la solución de un carácter a la vez. La pila solo contiene unos pocos enteros en tiempo de ejecución y está vacía al final.
Aunque no es una gran muestra del uso de un lenguaje de golf, sigue siendo considerablemente más corto que el código C solo porque la notación es más compacta.
Explicación:
fuente