Desenhe-me o (estranho) círculo unitário!

20

Introdução

Você pode conhecer e amar seu círculo unitário normal. Mas os matemáticos são loucos e, portanto, abstraíram o conceito a qualquer ponto que o satisfaça x*x+y*y=1. Como os Criptógrafos 1 também são estranhos, eles adoram campos finitos e, às vezes, anéis finitos (não é como se eles tivessem muita escolha), então vamos combinar isso!

O desafio

Entrada

Um número inteiro positivo maior que um na sua codificação favorita. Vamos chamar esse número n.

Saída

Você exibirá a "imagem" (que consiste em n vezes n caracteres) do círculo unitário, modulando o número inteiro de entrada como ASCII-Art usando "X" (letras maiúsculas em latim X) e "" (um espaço). Espaços à direita e novas linhas são permitidos.

Mais detalhes

Você precisa abranger um sistema de coordenadas da parte inferior esquerda para a parte superior direita. Sempre que um ponto cumprir a equação do círculo, coloque um X na posição, caso contrário, coloque um espaço.

A condição para um ponto que deve ser considerado parte da fronteira círculo é:
mod(x*x+y*y,n)==1.

Aqui está uma rápida ilustração do sistema de coordenadas:

(0,4)(1,4)(2,4)(3,4)(4,4)
(0,3)(1,3)(2,3)(3,3)(4,3)
(0,2)(1,2)(2,2)(3,2)(4,2)
(0,1)(1,1)(2,1)(3,1)(4,1)
(0,0)(1,0)(2,0)(3,0)(4,0)

Se isso lhe ajudar, você também pode inverter a direção de qualquer um dos eixos, mas os exemplos assumem essa orientação.

Quem ganha?

Isso é então o código mais curto em byte vence! Apenas os métodos de E / S padrão são permitidos e todas as brechas padrão são proibidas.

Exemplos

Entrada: 2

X 
 X

Entrada: 3

X  
X  
 XX

Entrada: 5

X    


X    
 X  X

Entrada: 7

X      
  X  X 


  X  X 
X      
 X    X

Entrada: 11

X          

     XX    

   X    X  
   X    X  

     XX    

X          
 X        X

Entrada: 42

X                                         
         X                       X        


            X                 X           
       X                           X      
      X                             X     
                     X                    
  X             X         X             X 


     X             X   X             X    
X                                         
               X           X              
              X             X             
         X                       X        


            X                 X           
                     X                    
        X           X X           X       
                     X                    
            X                 X           


         X                       X        
              X             X             
               X           X              
X                                         
     X             X   X             X    


  X             X         X             X 
                     X                    
      X                             X     
       X                           X      
            X                 X           


         X                       X        
X                                         
 X           X               X           X

1 Eu sugiro que você dê uma olhada no meu perfil, se você está se perguntando aqui.

SEJPM
fonte
Parece muito melhor se você usar o domínio [0, n] na minha opinião. Aqui está um exemplo com entrada 42.
R. Kap
Por "E / S padrão", você quer dizer métodos de E / S padrão, ou você quer dizer STDIN / STDOUT real? Estou assumindo o primeiro, mas acho que alguém abaixo o interpretou como o último.
Ørjan Johansen
@ ØrjanJohansen de fato o primeiro.
SEJPM
As novas linhas anteriores são permitidas?
Fergusq #
@fergusq como eles (drasticamente) alteram a figura de saída de maneira visível, não.
SEJPM

Respostas:

6

Utilitários Bash + GNU, 59

x={0..$[$1-1]}d*
eval echo $x$x+$1%1-0r^56*32+P|dc|fold -$1

Entrada nfornecida como um parâmetro da linha de comandos. O eixo y está invertido.

Experimente online .

Trauma Digital
fonte
4

Oitava , 45 44 bytes

@(n)[(mod((x=(0:n-1).^2)+x',n)==1)*56+32,'']

Experimente online!

flawr
fonte
Isso também funciona: @(n)[(mod((x=(0:n-1).^2)+x',n)==1)*88,'']. Em certos sistemas caráter Octave trata 0como um espaço
Luis Mendo
3

Haskell , 68 bytes

f n|r<-[0..n-1]=unlines[[last$' ':['X'|mod(x*x+y*y)n==1]|y<-r]|x<-r]

Experimente online! O eixo y é invertido. Uso: f 42retorna uma string delimitada por nova linha.

Esta é uma compreensão de lista aninhada em que ambos xe ysão extraídos do intervalo [0..n-1]. last$' ':['X'|mod(x*x+y*y)n==1]é uma forma mais curta de if mod(x*x+y*y)n==1 then 'X' else ' '. A compreensão da lista é avaliada como uma lista de cadeias de caracteres que é transformada em uma única cadeia de nova linha separada por unlines.

Laikoni
fonte
3

Mathematica, 56 48 bytes

Edit: Obrigado a Greg Martin e Martin Ender por salvar 8 bytes.

Grid@Array[If[Mod[#^2+#2^2,x]==1,X]&,{x=#,#},0]&

Solução original:

Grid@Table[If[Tr[{i-1,j-1}^2]~Mod~#==1,X,],{i,#},{j,#}]&
ngenisis
fonte
Comentário divertido: você não precisa da vírgula depois X:)
Greg Martin
1
Eu acho que você está melhor com Arraye Norm:Grid@Array[If[Mod[Norm@{##}^2,x]==1,X]&,{x=#,#},0]&
Martin Ender
2
Ainda pensando demais ... #^2+#2^2é o mais curto.
Martin Ender
@ GregMartin Portanto, se o primeiro argumento para Iffor nem Trueou False, você precisará do quarto argumento ou ele permanecerá sem avaliação, mas If[False,_]retornará Null. Esquisito.
Ngenisis
@ MartinEnder Inicialmente tentei, Arraymas não pensei em definir o argumento para uma variável.
Ngenisis
2

CJam , 23 bytes

ri:X,2f#_ff{+X%(S'X?}N*

Experimente online!

ri:X    e# Read input, convert to integer, store in X.
,       e# Turn into range [0 1 ... X-1].
2f#     e# Square each value in the range.
_ff{    e# 2D map over all pairs from that list.
  +     e#   Add the two values in the current pair.
  X%    e#   Take the sum modulo X.
  (     e#   Decrement, so that x^2+y^2==1 becomes 0 (falsy) and everything
        e#   else becomes truthy.
  S'X?  e#   Select space of 'X' accordingly.
}
N*      e# Join rows with linefeeds.
Martin Ender
fonte
2

JavaScript (ES6), 81 bytes

f=
n=>[...Array(n)].map((_,x,a)=>a.map((_,y)=>(x*x+y*y)%n-1?` `:`X`).join``).join`
`
<input type=number oninput=o.textContent=f(+this.value)><pre id=o>

O eixo Y é o inverso do OP.

Neil
fonte
2

Röda , 74 bytes

f n{seq n-1,0|{|y|seq 0,n-1|{|x|["X"]if[(x^2+y^2)%n=1]else[" "]}_;["
"]}_}

Experimente online!

Ungolfed:

function f(n) {
    seq(n-1, 0) | for y do
        seq(0, n-1) | for x do
            if [ (x^2 + y^2) % n = 1 ] do
                push("X")
            else
                push(" ")
            done
        done
        print("")
    done
}
fergusq
fonte
2

Python 3 , 87 83 bytes

lambda n:"\n".join("".join(" X"[(y*y+x*x)%n==1]for x in range(n))for y in range(n))

Experimente online!

O eixo y é invertido

ovs
fonte
2

Geléia , 14 13 bytes

R²+þ`%=1ị⁾X Y

O eixo x está invertido.

Experimente online!

Como funciona

R²+þ`%=1ị⁾X Y  Main link. Argument: n

R              Range; yield [1, ..., n].
 ²             Square; yield [1², ..., n²].
  +þ`          Self table addition; compute x+y for all x and y in [1², ..., n²],
               grouping by the values of y.
     %         Take all sums modulo n.
      =1       Compare them with 1, yielding 1 or 0.
        ị⁾X    Index into "X ".
            Y  Separate by linefeeds.
Dennis
fonte
1

dc , 79 bytes

?dsRsQ[88P]sl[32P]sH[0sM[lM2^lR2^+lQ%d1=l1!=HlM1+dsMlQ>c]dscx10PlR1-dsR0<S]dsSx

O yeixo está invertido, enquanto o xeixo não é.

Experimente online!

R. Kap
fonte
1

MATL , 13 bytes

:qU&+G\1=88*c

A origem está no canto superior esquerdo. Portanto, a saída é invertida em comparação com os exemplos do desafio.

Experimente o MATL online!

Explicação

:      % Input n implicitly. Push [1 2 ... n]
q      % Subtract one (element-wise)
U      % Square (element-wise)
&+     % Matrix of pairwise sums
G      % Push n
\      % Modulo
1=     % Equal to 1? (element-wise)
88*    % Multiply by 88 (ASCII code of 'X')
c      % Convert to char. Char 0 will be displayed as a space
       % Display implicitly
Luis Mendo
fonte
1

Python 3 , ( 102 98 95 bytes)

eixo y invertido

n=int(input());r=range(n);p=print
for i in r:
 for j in r:p(end=' 'if(i*i+j*j)%n-1else'X')
 p()

Experimente online!

  • salvou 4 bytes: variável omitida c em c = '' if (i i + j j)% n-1else'X '
  • salvou 3 bytes: Graças a ovs (declaração de impressão modificada)
officialaimm
fonte
1
p(end=' 'if(i*i+j*j)%n-1else'X')para 95 bytes
ovs
1

Lit , 125 bytes

#N::((join(map(seq(- N 1)0)(scope #Y::((join(map(seq 0(- N 1))(scope #X::
((?(== 1(@(+(* X X)(* Y Y))N))"X" " "))))""))))"\n")

Quebra de linha para facilitar a leitura.

Experimente online!

Não é o mais curto. Eu acho que preciso de algum tipo de módulo de taquigrafia. Veja o link Try it Online para obter mais explicações, versão não destruída e alguns testes. Para obter melhores resultados, expanda a janela de saída para ver mais.

Andrakis
fonte
1

Python 3 , 82 bytes

f=lambda n,k=0:k<n>f(n,k+1)!=print(''.join(' X'[(k*k+j*j)%n==1]for j in range(n)))

Experimente online!

Dennis
fonte
1

GNU APL , 41 caracteres, 59 bytes

Lê um número inteiro e exibe o círculo.

N←⎕◊⌽{(⍵+1)⊃' ' 'X'}¨{1=(N|(+/⍵*2))}¨⍳N N

Ungolfed

N←⎕
⌽                           ⍝ flip the X axis so 0,0 is bottom left
{
    (⍵+1) ⊃ ' ' 'X'         ⍝ substitute space for 0, X for 1
} ¨ {
    1=(N|(+/⍵*2))           ⍝ mod(x*x+y*y, 1)==1
} ¨ ⍳N N                    ⍝ generate an NxN grid of coordinates
Megashroom
fonte
0

Haskell, 115 bytes

n#(a,b)|mod(a*a+b*b)n==1='X'|1>0=' '
m n=map(n#)<$>zipWith(zipWith(,))(replicate n[0..n-1])(replicate n<$>[0..n-1])

O eixo y é invertido.

Experimente online!

Todos esses parênteses são meio que me irritando ...

Explicação

n#(a,b)|mod(a*a+b*b)n==1='X'|1>0=' '
n#(a,b)                                 --Operator #, takes a number n and a tuple (a,b)
       |mod(a*a+b*b)n==1                --Test if the mod equals 1
                        ='X'            --If so, return 'X'
                            |1>0=' '    --Otherwise, return ' '

m n=map(n#)<$>zipWith(zipWith(,))(replicate n[0..n-1])(replicate n<$>[0..n-1])
m n=                                                                           --Make a new function m with argument n
                                 (replicate n[0..n-1])                         --Make a list of [[0,1,2,3..n-1],[0,1,2,3..n-1],(n times)]
                                                      (replicate n<$>[0..n-1]) --Make a list of [[0,0,0(n times)],[1,1,1(n times)]..[n-1,n-1,n-1(n times)]
              zipWith(zipWith(,))                                              --Combine them into a list of list of tuples
    map(n#)<$>                                                                 --Apply the # operator to every tuple in the list with the argument n
Nome de exibição genérico
fonte
Você pode substituir o último mappor um <$>, certo?
k_g
A menos que eu esteja interpretando mal as regras da pergunta, não acho que você precise de todas as E / S de golfe de E / S no PPCG com padrões especiais para permitir a participação do maior número possível de idiomas. Por exemplo, sua função principal pode pegar um argumento inteiro e retornar uma string.
Ørjan Johansen
@k_g yes thank you
Nome genérico para exibição
@ ØrjanJohansen devidamente anotado :)
Nome genérico para exibição
0

GolfScript , 34 bytes

~:c,{.*}%:a{:b;a{b+c%1=' x'=}%}%n*

Experimente online!

Eu realmente não gosto de usar variáveis ​​...

Freira Furada
fonte