Crie uma grade o mais próximo possível de um quadrado

10

Crie uma função ou programa que torne a grade o mais próximo possível de um quadrado

  • Você receberá um número inteiro N como entrada, números inteiros (1,2,3,25, etc)
  • A saída deve ser uma grade retangular perfeita de N letras o mais próximo possível de um quadrado
  • O quadrado (pretendido) deve consistir em uma das letras O ou X, conforme especificado pelo usuário

Pontos :

  • Codificado para apenas O ou X: +1
  • Um parâmetro (0/1, verdadeiro / falso, algo semelhante) para girar a saída (como em 5 ou 8): -10
  • Projete o quadrado (use O e X em algum tipo de padrão): -5

Um padrão é considerado válido se contiver os dois tipos de caracteres (onde o eixo x / y> = 3) e o padrão permanecerá o mesmo quando invertido horizontal ou verticalmente (é permitido trocar Xs por Os)

Exemplos

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

Exemplos que não são permitidos (sem o mesmo comprimento de linha ou coluna)

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

Se possível, forneça um exemplo online.

Martijn
fonte
Uma função é suficiente ou você deseja um programa completo?
John Dvorak
"Projete o quadrado ... no caso de 9, mude o centro" - sob quais circunstâncias exatas o padrão não é um tabuleiro de xadrez? você pode dar um exemplo?
John Dvorak
re a edição: eu li corretamente que recebo três pontos por fazer em "xo"[i]vez de i? Isso não parece valer a pena. Em geral, todas as suas recompensas parecem um pouco baixas.
John Dvorak
"algum tipo de padrão" é meio vago. Isso conta se eu substituir o primeiro 'x' por 'o'?
John Dvorak
Boa pergunta. O único bônus / penalidade interessante é o da rotação. Pessoalmente, eu continuaria com um personagem codificado (ou seja, tornaria a penalidade o padrão) e eliminaria todos os bônus / penalidades, exceto talvez o da rotação. Não é uma boa ideia ter muitos bônus ou penalidades. O importante é especificar claramente o principal problema.
Level River St

Respostas:

6

CJam, 16 (31-10-5)

Isso leva dois inteiros são introduzidos, primeiro ser um 0ou 1para a direção e segundo sendo um deles o número de Oou Xna grade.

Imprime uma alternativa Oe X.

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

Este é apenas o corpo da função, para experimentá-lo, adicione l~na frente do código, como:

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

e dar entrada como

0 10

para obter saída como

OXOXO
XOXOX

ou entrada como

1 10

para

OX
OX
OX
OX
OX

Experimente online aqui


Como 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";

Exemplo de execução:

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
Optimizer
fonte
3

APL (36 - 5 - 10 = 21)

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

O argumento da esquerda é rotação, o argumento da direita é o tamanho. Ele também usa um padrão simples (apenas alterna 'X' e '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       

Explicação:

  • ∆←,⍳2/⍵: Gerar todos os possíveis pares de números a partir 1de e armazenar em .
  • ∆←∆[⍋|-/¨∆... ]: classifica em ascensão na diferença absoluta dos dois números em cada par e armazena o resultado novamente .
  • ⊃∆/⍨⍵=×/¨∆: para cada par, multiplique os números juntos. Selecione apenas os pares que se multiplicam e pegue o primeiro que corresponder (que é o "mais quadrado" por causa da classificação).
  • ⍺⌽: gire a lista de comprimentos (que possui 2 elementos) por .
  • 'OX'⍴⍨: crie uma matriz desse tamanho e preencha com alternando Oe X.
marinus
fonte
2

Haskell, 59 caracteres

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

CJam, 25 22 21 (31 - 10)

Este é um corpo funcional. Se você deseja um programa completo, adicione ririà frente. Se você quiser usá-lo como um bloco de código, coloque-o dentro {}. Teste-o em cjam.aditsu.net .

Ele recebe a entrada como dois argumentos inteiros: a opção para saber se o retângulo é vertical (qualquer valor diferente de zero) ou horizontal (zero) e o número de Os a serem usados.

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

Explicação

: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";

fonte
11
Decremento deve ser muito mais rápido para grandes números, sem perda na contagem de bytes
edc65
11
Quem votou mal? Por quê?
2
Só posso acho que é porque alguém não considera CJam uma linguagem real
John Dvorak
Sua explicação está meio quebrada. Você está editando atualmente?
John Dvorak
@JanDvorak Sim, eu estava no meio da edição e pressionei Tab e Enter acidentalmente. Está consertado agora.
2

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

Padrão + rotação (parâmetro f, 0 ou 1) - bônus 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)
}

Sem padrão, sem rotação - penalidade 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));
}

Teste no console do FireFox / FireBug

F(30,0)

OXOXOX
XOXOXO
OXOXOX
XOXOXO
OXOXOX

F(30,1)

OXOXO
XOXOX
OXOXO
XOXOX
OXOXO
XOXOX
edc65
fonte
2

Python, 79 75 (sem bônus)

Os bônus parecem complicados, então aqui está uma função Python bastante simples:

def f(N):c=max(x*((x*x<=N)>N%x)for x in range(1,N+1));print(N/c*'O'+'\n')*c
Emil
fonte
Exemplo online para os interessados: repl.it/Zq9
Martijn
11
Você mudou isso após o teste? Eu tentei isso e não funciona, por exemplo, f(8)me deu uma coluna de 8 Os, que está incorreta.
marinus
@ Marinus: Eu testei, mas parece ter copiado uma versão errada. Havia um >onde deveria ter havido <. Está consertado agora. Obrigado pela observação!
Emil
1

Ruby, 74

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

Explicação

  • A entrada é tomada como argumento para uma lambda. Espera um Integer.
  • Verifique se n(a entrada) é divisível por todo número inteiro de 1 a n.
    • Se for, calcule a diferença entre o comprimento e a largura.
    • Caso contrário, retorne um número grande ( n).
  • Faça a menor das diferenças de comprimento e largura para se parecer melhor com um quadrado.
  • Use o String#*método (excessivamente conciso) para "desenhar" o quadrado.
britishtea
fonte
Por que eu fui derrotado? Minha resposta contém um erro?
britishtea
Você tem um erro de digitação. A última palavra deve ser "quadrado" e você tem "quadrado". (Eu não sou o derrotador, estou apontando esse erro).
Ismael Miguel
1

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

Infix anônimo lambda. Toma N como argumento da direita e param como argumento da esquerda. Os retângulos terão faixas de X e O ou serão quadriculados.

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

Experimente online!

{... } "dfn"; é argumento à esquerda (param), é argumento à direita ( N ):

⍳⍵índices 1… N

∘.×⍨ tabuada de multiplicação desse

⍵= mascarar onde N é igual a

índices de valores verdadeiros na máscara

c← armazenar isso em c(para c andidates)

 registro dos candidatos

.5× metade multiplicada por isso

 teto (arredondado para cima)

⊃∘c escolha esse elemento c

⍴∘'XO' use isso para remodelar ciclicamente "XO"

⍉⍣⍺ transpor se param

Adão
fonte
1

05AB1E (legado) , pontuação: 7 (22 bytes - 15 bônus)

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

Experimente online ou verifique mais alguns casos de teste .

Toma as entradas Nprimeiro, depois o booleano ( 0/ 1), se deve girar ou não.

Usa a versão herdada do Python do 05AB1E, já que o zip com uma lista de cadeias achata implicitamente e junta os caracteres, ao contrário da versão mais recente do Elixir, reescrita do 05AB1E.

Explicação:

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)
Kevin Cruijssen
fonte
0

GolfScript 26 (41-10-5)

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

Espera que dois parâmetros estejam na pilha:

  • 0para normal ou 1para transposto
  • o nvalor

O padrão é que o quadro esteja cheio de Xseo canto superior esquerdo seja um O. Escusado será dizer que esse padrão é mantido ao transpor a placa.

Demonstração: regular , transposta

Cristian Lupascu
fonte
0

Mathematica, 71 caracteres

f@n_:=#<>"\n"&/@Array["O"&,{#,n/#}&[#[[⌊Length@#/2⌋]]&@Divisors@n]]<>""
alefalpha
fonte
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)
12Me21
fonte
0

J , 32 bytes - 15 = 17 bytes

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

Experimente online!

A rotação é controlada por um sinalizador 0/1 tomado como argumento à esquerda

Jonah
fonte
0

Retina 0.8.2 , 66 bytes + penalidade de 1 byte = 67

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

Experimente online! Explicação:

.+
$*X

Converta a entrada em uma sequência de Xs.

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

A primeira passagem da captura externa corresponde ao início da sequência, enquanto nas passagens subsequentes o valor anterior da captura interna é correspondido. A captura interna é então incrementada e correspondida. O resultado disso é que a quantidade de cadeia consumida pela captura externa é o quadrado da captura interna, que, portanto, não pode exceder a raiz quadrada da entrada. Enquanto isso, a repetição subsequente garante que a captura interna seja um fator do comprimento da corda.

$3 $3$#4$*X

Salve o fator descoberto e calcule o outro divisor adicionando o número de repetições subsequentes.

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

Reorganize os fatores em um retângulo.

Neil
fonte
0

Carvão , 33 bytes - 10-5 = 18

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

Experimente online! Link é a versão detalhada do código. Explicação:

Nθ

Entrada N.

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

Pegue o intervalo 0.. N, mantenha apenas os números cujos quadrados não sejam menores que Ne divida Ne use o mínimo desses números.

E÷θη⭆η§XO⁺ιλ

Use o fator descoberto para gerar um retângulo da largura e altura apropriadas usando um padrão de tabuleiro de damas. (Isso deve ser UOη÷θηXO¶OXpara uma economia de 1 byte, mas é um buggy no momento.)

¿N⟲

Se a segunda entrada for diferente de zero, gire a saída. (Se exigir que a segunda entrada seja 0ou 2seja aceitável, isso pode ser ⟲Numa economia de 1 byte.)

Neil
fonte