Cree una cuadrícula lo más cerca posible de un cuadrado


10

Cree una función o programa que haga que una cuadrícula esté lo más cerca posible de un cuadrado

  • Se le dará un número entero N como entrada, números enteros (1,2,3,25, etc.)
  • La salida debe ser una cuadrícula rectangular perfecta de N letras lo más cerca posible de un cuadrado
  • El cuadrado (aspirante) debe consistir en una de las letras O o X según lo especificado por el usuario

Puntos :

  • Codificado solo para O o X: +1
  • Un parámetro (0/1, verdadero / falso, algo similar) para rotar la salida (como con 5 u 8): -10
  • Diseñe el cuadrado (use O y X en algún tipo de patrón): -5

Un patrón se considera válido si contiene ambos tipos de caracteres (donde el eje x / y> = 3) y el patrón permanece igual cuando se voltea horizontal o verticalmente (se permite el intercambio de Xs con Os)

Ejemplos

INPUT: 4         INPUT: 5       INPUT: 8              INPUT: 9
OO               OOOOO          XXXX                  XOX
OO                              XXXX                  OXO  
                                or rotated 90deg      XOX

Ejemplos que no están permitidos (no filas o columnas de la misma longitud)

BAD RESULT: 5a        BAD RESULT: 5b      BAD RESULT: 8
OOO                   OO                  OOO
OO                    OO                  OOO
                      O                   OO

Si es posible, proporcione un ejemplo en línea.


¿Es suficiente una función o quieres un programa completo?
John Dvorak

"Diseñe el cuadrado ... en caso de que 9 cambie el centro", ¿en qué circunstancias exactas el patrón no es un tablero de ajedrez? ¿Puede dar un ejemplo?
John Dvorak

re la edición: ¿leo correctamente que obtengo tres puntos por hacer en "xo"[i]lugar de hacerlo i? Eso no parece valer la pena. En general, todas sus recompensas parecen un poco bajas.
John Dvorak

"algún tipo de patrón" es algo vago. ¿Cuenta si reemplazo la primera 'x' con 'o'?
John Dvorak

Buena pregunta. El único bono / penalización interesante es el de rotación. Personalmente, me quedaría con un personaje codificado (es decir, convertir la penalización en el valor predeterminado) y eliminaría todas las bonificaciones / penalizaciones, excepto quizás la rotación. No es una buena idea tener demasiados bonos o penalizaciones. Lo importante es especificar claramente el problema principal.
Level River St

Respuestas:


6

CJam, 16 (31-10-5)

Esto toma dos números enteros de entrada, el primero es 0o 1para dirección y el segundo es el número Oo Xen la cuadrícula.

Imprime una alternativa Oy X.

:X"OX"*X<\Xmqi){(_X\%}g_X\/?/N*

Este es solo el cuerpo de la función, para probar agregue l~delante del código como:

l~:X"OX"*X<\Xmqi){(_X\%}g_X\/?/N*

y dar entrada como

0 10

para obtener salida como

OXOXO
XOXOX

o entrada como

1 10

para

OX
OX
OX
OX
OX

Pruébalo en línea aquí


Cómo funciona:

l~                                 "Put the two input integers to stack";
  :X                               "Assign the number of cells to X";
    "OX"*                          "Take string "OX" and repeat it X times";
         X<                        "Slice it to take only first X characters";
           \                       "Swap top two stack elements, now string is at bottom";
            Xmqi)                  "Take square root of X, ceil it and put on stack";
                 {(_X\%}g          "Keep decrementing until it is perfectly divisible by X";
                         _X\/      "Copy it, divide X by that and put it on stack";
                             ?     "Based on first input integer, take either of numbers";
                              /    "Divide the XOXO string that many times";
                               N*  "Join the string parts with a new line";

Ejemplo de ejecución:

l~ed:X"OX"*edX<ed\edXmqi)ed{(_X\%}ged_edXed\ed/ed?ed/edN*ed

#INPUT:
1 10

#OUTPUT:
Stack: [1 10]

Stack: [1 "OXOXOXOXOXOXOXOXOXOX"]

Stack: [1 "OXOXOXOXOX"]

Stack: ["OXOXOXOXOX" 1]

Stack: ["OXOXOXOXOX" 1 4]

Stack: ["OXOXOXOXOX" 1 2]

Stack: ["OXOXOXOXOX" 1 2 2]

Stack: ["OXOXOXOXOX" 1 2 2 10]

Stack: ["OXOXOXOXOX" 1 2 10 2]

Stack: ["OXOXOXOXOX" 1 2 5]

Stack: ["OXOXOXOXOX" 2]

Stack: [["OX" "OX" "OX" "OX" "OX"]]

Stack: ["OX
OX
OX
OX
OX"]

OX
OX
OX
OX
OX

3

APL (36-5-10 = 21)

{'OX'⍴⍨⍺⌽⊃∆/⍨⍵=×/¨∆←∆[⍋|-/¨∆←,⍳2/⍵]}

El argumento izquierdo es la rotación, el argumento derecho es el tamaño. También usa un patrón simple (solo alterna 'X' y 'O').

      0{'OX'⍴⍨⍺⌽⊃∆/⍨⍵=×/¨∆←∆[⍋|-/¨∆←,⍳2/⍵]}¨4 5 8 9
 OX  OXOXO  OXOX  OXO 
 OX         OXOX  XOX 
                  OXO 
      1{'OX'⍴⍨⍺⌽⊃∆/⍨⍵=×/¨∆←∆[⍋|-/¨∆←,⍳2/⍵]}¨4 5 8 9
 OX  O  OX  OXO 
 OX  X  OX  XOX 
     O  OX  OXO 
     X  OX      
     O       

Explicación:

  • ∆←,⍳2/⍵: Generar todas las posibles parejas de números a partir 1de y almacenar en .
  • ∆←∆[⍋|-/¨∆... ]: ordena de forma ascendente en la diferencia absoluta de los dos números en cada par, y almacena el resultado nuevamente .
  • ⊃∆/⍨⍵=×/¨∆: para cada par, multiplique los números juntos. Seleccione solo aquellos pares que se multipliquen y tome el primero que coincida (que es el 'más cuadrado' debido al tipo).
  • ⍺⌽: gira la lista de longitudes (que tiene 2 elementos) por .
  • 'OX'⍴⍨: crea una matriz de ese tamaño y llénalo con alternancia Oy X.

2

Haskell, 59 caracteres

r=replicate
f n=[r x$r y '0'|x<-[1..n],y<-[1..x],x*y==n]!!0

2

CJam, 25 22 21 (31-10)

Este es un cuerpo funcional. Si desea un programa completo, agréguelo ririal frente. Si desea usarlo como un bloque de código, introdúzcalo {}. Pruébelo en cjam.aditsu.net .

Toma la entrada como dos argumentos enteros: el cambio de si el rectángulo es vertical (cualquier valor distinto de cero) u horizontal (cero), y la cantidad de Os que se utilizará.

:Xmqi){(_X\%}g_X\/@{\}{}?'O*N+*

Explicación

:X "Assign the top item on the stack (the second input) to variable X";
mq "Take its square root";
i  "Convert to integer (round)";
)  "Increment it";

{  "Start code block";
  (  "Decrement";
  _X "Duplicate top item on stack; push X to the stack";
  \% "Swap top 2 items and take division remainder";
}g "Loop until top item on stack is 0; pop condition after checking it";

_X "Duplicate top item on stack; push X to the stack";
\/ "Swap top 2 items and divide";

"OMIT THIS BIT TO GET A 25-CHAR FUNCTION WITHOUT THE 10PT BONUS";
 @  "Rotate top 3 items on stack";
 {\}"Code block 1: swap top two items";
 {} "Code block 2: do nothing";
 ?  "If top item of stack is 0, run code block 1, otherwise run code block 2";

'O "Push the character O to the stack";
*  "Repeat it N times, where N is the second item from the top of the stack (O is first)";
N+ "Push a new line and concatenate it with the string on the top of the stack";
*  "Repeat the string N times";

1
La disminución debería ser bastante más rápida para números grandes, sin pérdida en el recuento de bytes
edc65

1
¿Quién votó en contra? ¿Por qué?

2
Solo puedo adivinar que es porque alguien no considera a CJam un lenguaje real
John Dvorak

Tu explicación está un poco rota. ¿Estás editando actualmente?
John Dvorak

@ JanDvorak Sí, estaba a mitad de la edición y accidentalmente presioné Tab e Intro. Ya está arreglado.

2

JavaScript (E6) 84 (83 + 1) o 101 (116-10-5)

Patrón + rotación (parámetro f, 0 o 1) - bono 15

F=(n,f)=>{
  for(r=x=0;y=n/++x|0,x<=y;)x*y-n?0:z=f?x:y;
  for(o='';n;)o+=(n--%z?'':(r^=1,c='\n'))+'OX'[r^(c^=1)];
  alert(o)
}

Sin patrón, sin rotación - penalización 1

F=n=>{
  for(x=0;y=n/++x|0,x<=y;)x*y-n?0:z=y;
  alert(('O'.repeat(z)+'\n').repeat(n/z));
}

Prueba en la consola FireFox / FireBug

F(30,0)

OXOXOX
XOXOXO
OXOXOX
XOXOXO
OXOXOX

F(30,1)

OXOXO
XOXOX
OXOXO
XOXOX
OXOXO
XOXOX

2

Python, 79 75 (sin bonificaciones)

Los bonos parecen complicados, así que aquí hay una función de Python bastante simple:

def f(N):c=max(x*((x*x<=N)>N%x)for x in range(1,N+1));print(N/c*'O'+'\n')*c

Ejemplo en línea para los interesados: repl.it/Zq9
Martijn

1
¿Cambiaste esto después de probar? Intenté esto y no funciona, por ejemplo, f(8)me dio una columna de 8 Os, que es incorrecta.
marinus

@marinus: Lo probé pero parece que he copiado una versión incorrecta. Había un lugar >donde debería haber habido un <. Ya está arreglado. Gracias por la nota!
Emil

1

Rubí, 74

f=->n{w=(1..n).min_by{|z|n%z>0?n:(n/z-n/(n/z))**2};$><<("X"*w+"\n")*(n/w)}

Explicación

  • La entrada se toma como argumentos para una lambda. Se espera un Integer.
  • Compruebe si n(la entrada) es divisible por cada entero de 1 a n.
    • Si es así, calcule la diferencia entre el largo y el ancho.
    • Si no es así, devuelve un gran número ( n).
  • Tome la más pequeña de las diferencias de ancho y largo para parecerse mejor a un cuadrado.
  • Use el String#*método (demasiado conciso) para "dibujar" el cuadrado.

¿Por qué me rechazaron? ¿Mi respuesta contiene un error?
britishtea

Tienes un error tipográfico. La última palabra debe ser "cuadrado" y usted tiene "cuadrado". (No soy el votante, estoy señalando este error).
Ismael Miguel

1

APL (Dyalog Unicode) , 30-15 = 15 bytes SBCS

Anónimo infijo lambda. Toma N como argumento derecho y param como argumento izquierdo. Los rectángulos tendrán rayas de X y O o serán a cuadros.

{⍉⍣⍺⍴∘'XO'⊃∘c⌈.5×≢c←⍸⍵=∘.×⍨⍳⍵}

Pruébalo en línea!

{... } "dfn"; es argumento izquierdo (param), es argumento derecho ( N ):

⍳⍵d ndices 1 ... N

∘.×⍨ tabla de multiplicar de eso

⍵= máscara donde N es igual a eso

ɩ ndices de valores verdaderos en la máscara

c← almacenar eso en c(para c andidates)

 cuenta los candidatos

.5× la mitad multiplicada por eso

 techo (redondeado)

⊃∘c elegir ese elemento de c

⍴∘'XO' use eso para reformar cíclicamente "XO"

⍉⍣⍺ transponer si param


1

05AB1E (heredado) , puntuación: 7 (22 bytes - 15 bonus)

„OXI∍¹tï[D¹sÖ#<}äIiø}»

Pruébelo en línea o verifique algunos casos de prueba más .

NPrimero toma las entradas , luego el booleano ( 0/ 1) si debe rotar o no.

Utiliza la versión heredada de Python de 05AB1E ya que zip con una lista de cadenas se aplana y une implícitamente a los caracteres, a diferencia de la nueva versión de reescritura de Elixir de 05AB1E.

Explicación:

OX         # Push string "OX"
   I       # Extend it to a size equal to the first input
            #  i.e. 9 → "OXOXOXOXO"
            #  i.e. 10 → "OXOXOXOXOX"
¹t          # Take the first input again, and square-root it
            #  i.e. 9 → 3.0
            #  i.e. 10 → 3.1622776601683795
  ï         # Then cast it to an integer, removing any decimal digits
            #  i.e. 3.0 → 3
            #  i.e. 3.1622776601683795 → 3
   [        # Start an infinite loop:
    D       #  Duplicate the integer
     ¹sÖ    #  Check if the first input is evenly divisible by that integer
            #   i.e. 9 and 3 → 1 (truthy)
            #   i.e. 10 and 3 → 0 (falsey)
        #   #  And if it is: stop the infinite loop
    <       #  If not: decrease the integer by 1
            #   i.e. 3 → 2
   }        # After the infinite loop:
ä           # Divide the string into that amount of equal sized parts
            #  i.e. "OXOXOXOXO" and 3 → ["OXO","XOX","OXO"]
            #  i.e. "OXOXOXOXOX" and 2 → ["OXOXO","XOXOX"]
 Ii }       # If the second input is truthy:
   ø        #  Zip/transpose; swapping rows/columns of the strings
            #   i.e. ["OXOXO","XOXOX"] → ["OX","XO","OX","XO","OX"]
»           # And finally join the strings in the array by newlines
            #  i.e. ["OXO","XOX","OXO"] → "OXO\nXOX\nOXO"
            #  i.e. ["OX","XO","OX","XO","OX"] → "OX\nXO\nOX\nXO\nOX"
            # (and output the result implicitly)

0

GolfScript 26 (41-10-5)

:x),1>{x\%!},.,2/=.x\/@{\}*'X'*n+*1>'O'\+

Espera que dos parámetros estén en la pila:

  • 0para normal o 1para transpuesto
  • el nvalor

El patrón es que el tablero está lleno de Xsy la esquina superior izquierda es un O. No hace falta decir que este patrón se mantiene al transponer el tablero.

Demostración: regular , transpuesta


0

Mathematica, 71 caracteres

f@n_:=#<>"\n"&/@Array["O"&,{#,n/#}&[#[[⌊Length@#/2⌋]]&@Divisors@n]]<>""

0

Petit Computer BASIC, 72 bytes

INPUT N,S$FOR I=1TO SQR(N)IF N%I<1THEN M=I
NEXT
?(S$*M+" "*(32-M))*(N/M)

0

J , 32 bytes - 15 = 17 bytes

'XO'$~[|.](%,])i.@]{~0 i:~i.@]|]

Pruébalo en línea!

La rotación está controlada por un indicador 0/1 tomado como argumento izquierdo


0

Retina 0.8.2 , 66 bytes + 1 byte de penalización = 67

.+
$*X
((^|\3)(X(?(3)\3)))+(\3)*$
$3 $3$#4$*X
X(?=X* (X+))| X+
$1¶

Pruébalo en línea! Explicación:

.+
$*X

Convierta la entrada en una cadena de Xs.

((^|\3)(X(?(3)\3)))+(\3)*$

La primera pasada de la captura externa coincide con el inicio de la cadena, mientras que en las pasadas posteriores el valor anterior de la captura interna coincide. La captura interna se incrementa y se compara. El resultado de esto es que la cantidad de cadena consumida por la captura externa es el cuadrado de la captura interna, que por lo tanto no puede exceder la raíz cuadrada de la entrada. Mientras tanto, la repetición posterior asegura que la captura interna sea un factor de la longitud de la cuerda.

$3 $3$#4$*X

Guarde el factor descubierto y calcule el otro divisor sumando el número de repeticiones posteriores.

X(?=X* (X+))| X+
$1¶

Reorganizar los factores en un rectángulo.


0

Carbón de leña , 33 bytes - 10 - 5 = 18

Nθ≔⌊Φ⊕θ¬∨‹×ιιθ﹪θιηE÷θη⭆η§XO⁺ιλ¿N⟲

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

Nθ

Entrada N.

≔⌊Φ⊕θ¬∨‹×ιιθ﹪θιη

Tome el rango 0... N, conserve solo los números cuyos cuadrados no sean menores que Ny divida N, y tome el mínimo de esos números.

E÷θη⭆η§XO⁺ιλ

Utilice el factor descubierto para generar un rectángulo del ancho y la altura apropiados utilizando un patrón de tablero de ajedrez. (Esto debería ser UOη÷θηXO¶OXpara un ahorro de 1 byte, pero eso es defectuoso en este momento).

¿N⟲

Si la segunda entrada no es cero, gire la salida. (Si requiere que la segunda entrada sea 0o 2sea ​​aceptable, esto podría ser ⟲Npara un ahorro de 1 byte).

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.