Island Golf # 1: Circunavegação


43

Este é o primeiro de uma série de desafios do Island Golf. Próximo desafio

Dada uma ilha na arte ASCII, produza um caminho ideal para contorná-la.

Entrada

Sua entrada será uma grade retangular composta por dois caracteres, representando terra e água. Nos exemplos abaixo, a terra é #e a água é ., mas você pode substituir quaisquer dois caracteres distintos que desejar.

...........
...##......
..#####....
..#######..
.#########.
...#######.
...#####.#.
....####...
...........

Sempre haverá pelo menos um terreno. Os ladrilhos terrestres serão todos contíguos (ou seja, há apenas uma ilha). Os ladrilhos de água também serão contíguos (ou seja, não há lagos). A borda externa da grade será todos os ladrilhos de água. Ladrilhos de terra não serão conectados na diagonal: ou seja, você nunca verá algo como

....
.#..
..#.
....

Resultado

Seu código deve gerar a mesma grade, com uma menor circunavegação desenhada nela. Nos exemplos abaixo, o caminho da circunavegação é desenhado o, mas você pode substituir qualquer caractere, desde que seja distinto dos caracteres terrestres e aquáticos.

Uma circunavegação é uma curva fechada simples, desenhada inteiramente em ladrilhos de água, que circunda totalmente todos os ladrilhos de terra na grade. Conexões diagonais são permitidas. Por exemplo, esta é uma circunavegação da ilha acima (mas não a mais curta):

.ooooo.....
o..##.oo...
o.#####.o..
o.#######o.
o#########o
ooo#######o
..o#####.#o
..oo####..o
....oooooo.

O comprimento de uma circunavegação é calculado da seguinte forma: Para cada par de blocos adjacentes no caminho, se estiverem conectados horizontal ou verticalmente, adicione 1; se eles estiverem conectados na diagonal, adicione √2. O comprimento do caminho acima é 22 + 7√2 (≈ 31.9).

Uma circunavegação mais curta é uma circunavegação com o menor comprimento possível. Seu programa deve gerar qualquer caminho que atenda a essa condição. Para a maioria das ilhas, haverá várias soluções possíveis. Aqui está uma solução para a ilha acima, com comprimento 10 + 13√2 (≈ 28,4):

...oo......
..o##oo....
.o#####oo..
.o#######o.
o#########o
.o.#######o
..o#####.#o
...o####.o.
....ooooo..

Detalhes

Sua solução pode ser um programa completo ou uma função . Qualquer um dos métodos padrão de entrada e saída é aceitável.

Sua entrada e saída podem ser uma cadeia de linhas múltiplas ou uma lista de cadeias. Se o seu idioma tiver um tipo de caractere distinto das seqüências de caracteres simples, você poderá substituir "lista de caracteres" por "sequência" na frase anterior. Se o seu idioma precisar inserir a altura e / ou largura da grade, você poderá fazê-lo. Sua saída pode (opcionalmente) ter uma única nova linha à direita. Como mencionado acima, você pode usar três caracteres distintos no lugar de #.o(especifique em seu envio quais caracteres você está usando).

Casos de teste

A. Ilhas com menores circunavegações únicas:

...
.#.
...

.o.
o#o
.o.

......
.####.
......

.oooo.
o####o
.oooo.

......
......
..##..
...#..
......
......

......
..oo..
.o##o.
..o#o.
...o..
......

.......
.#####.
...#...
...#...
.#####.
.......

.ooooo.
o#####o
o..#..o
o..#..o
o#####o
.ooooo.

.......
...#...
...#...
.#####.
...#...
...#...
.......

...o...
..o#o..
.o.#.o.
o#####o
.o.#.o.
..o#o..
...o...

.......
.#####.
.##..#.
..#..#.
.......

.ooooo.
o#####o
o##..#o
.o#..#o
..oooo.

B. Exemplo de uma ilha com várias soluções possíveis:

........
....##..
...####.
..###...
.#####..
.#####..
..##....
........

Saídas possíveis:

....oo..
...o##o.
..o####o
.o###.o.
o#####o.
o#####o.
.o##oo..
..oo....

....oo..
...o##o.
..o####o
.o###.o.
o#####o.
o#####o.
.o##.o..
..ooo...

....oo..
...o##o.
..o####o
.o###..o
o#####.o
o#####o.
.o##oo..
..oo....

....oo..
...o##o.
..o####o
.o###..o
o#####.o
o#####o.
.o##.o..
..ooo...

C. Caso de teste grande como um Gist


Este é o : o código mais curto em cada idioma vence.


1
A menor circunavegação para o terceiro caso de teste é o padrão de pão no Jogo da Vida de Conway!
Camarada SparklePony

Respostas:


18

Mathematica (versão 9), 165 bytes

A ConvexHullMeshfunção agradável e curta usada por Greg Martin foi introduzida apenas no Mathematica versão 10, então pensei em fazer uma tentativa sem ela, usando minha antiga versão 9. do Mathematica. É uma função que recebe e retorna uma lista de strings (com ., #e ocomo os símbolos).

""<>#&/@("o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#/.{0->"."})&[Characters@#/.{"."->0,"#"->1}]&

Explicação:

  • Primeiro, Characters@# /. {"."->0, "#"->1}transforma a entrada em uma matriz de 0s e 1s.
  • "o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#depois, usa os poderosos recursos de processamento de imagens do Mathematica (mas extremamente pesados ​​em bytes ...) para preencher primeiro o casco convexo da ilha (que é a forma que você obteria se esticasse um pedaço de barbante) e, em seguida, limitasse. Em seguida, multiplicar esta matriz pela cadeia "o"para obter uma matriz de 0s e "o"s (graças à adaptabilidade impressionante do Mathematica sobre os tipos), e adicione a "#"vezes a matriz da ilha.
  • Finalmente, ""<>#& /@ (... /. {0->"."})transforma essa matriz de "o"s, "#"s e 0s em uma matriz de "o"s, "#"s e "."s, e junta-se cada linha em uma string.

Quando testamos isso no exemplo B , obtemos a saída

{"....oo..",
 "...o##o.",
 "..o####o",
 ".o###..o",
 "o#####o.",
 "o#####o.",
 ".o##oo..",
 "..oo...."}

[Edit, graças a Greg Martin:] Se pudermos usar matrizes de caracteres em vez de listas de strings, podemos reduzir isso para 144 bytes:

"o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#/.{0->"."}&[#/.{"."->0,"#"->1}]&

1
Bem feito! Eu nunca soube disso MorphologicalComponents[#, Method->"ConvexHull"] :) Você pode salvar ainda mais bytes assumindo que a entrada já esteja dividida em caracteres e retornando também uma matriz 2D de caracteres.
Greg Martin

@ GregMartin, eu não sabia sobre esse uso MorphologicalComponentsaté hoje!
Não uma árvore

Iniciante no Mathematica aqui: como devo chamar essa função? Eu tentei f[{"...",".#.","..."}]e obtive alguns erros.
DLosc 24/03

@ DLosc, a função é a coisa toda, não apenas f. (Bem, estritamente falando, são as coisas depois do ponto e vírgula.) Para chamar a função, digite a coisa toda em uma janela do Mathematica, seguida de [sua entrada e ], portanto, deve parecer algo como f@m_:=m(1-m[[2,2]]) . . . #/.{"."->0,"#"->1}]&[{"...", ".#.", "..."}](abreviado para espaço).
Não uma árvore

@ DLosc Bem, isso é porque o código está quebrado. Eu acho que já consertei agora! (Eu não tenho idéia do que aconteceu lá; desculpe ...)
Não é uma árvore

11

(Mas subaprove a solução da Notatree , é melhor!)

Mathematica, 168 bytes

(x_~n~y_:=Min[Norm[x-#]&/@y];i=#;p=i~Position~#&;t=p["#"|"."]~Select~#&;(i~Part~##="o")&@@@t[#~n~t[ConvexHullMesh[Join[s=p@"#",#+{.1,.1}&/@s]]~RegionMember~#&]==1&];i)&

Função pura pegando uma matriz 2D de caracteres como entrada e retornando uma matriz 2D de caracteres. Uma versão mais fácil de ler:

1  (x_~n~y_ := Min[Norm[x - #] & /@ y];
2  i = #; p = i~Position~# &; 
3  t = p["#" | "."]~Select~# &;
4  (i~Part~## = "o") & @@@ 
5    t[#~n~
6      t[ConvexHullMesh[
7        Join[s = p@"#", # + {.1, .1} & /@ s]]
8      ~RegionMember~# &] == 1 &];
9  i) &

A linha 1 define uma função nque produz a (menor) distância entre um ponto xno plano e um conjunto yde outros pontos. A linha 2 inicializa a variável ina entrada, tanto para resolver uma ambiguidade de currying mais tarde quanto para modificá-la para produzir a saída final; A linha 2 também define uma função pque retorna as coordenadas de todas as ocorrências de sua entrada i.

Na linha 3, p["#" | "."]representa todas as coordenadas do mapa de entrada (já que todos os seus caracteres são um "#"ou "."), também té uma função que seleciona apenas as coordenadas que satisfazem uma propriedade ainda não especificada. Na linha 4, i~Part~## = "o"vai mudar um monte de entradas ipara o personagem "o"; esses caracteres serão selecionados do conjunto de coordenadas possíveis de acordo com o material nas linhas 5-8. E a linha 9 apenas retorna a resposta uma vez calculada.

Ok, infraestrutura pronta, agora para a computação real. ConvexHullMeshé o recurso do Mathematica para calcular o casco convexo de um conjunto de pontos (o menor polígono convexo que contém esses pontos). Moralmente falando, isso deve "preencher" as enseadas e os fiordes da ilha (que é s = p@"#"), para excluí-los de nossa navegação de navegação. Há um pequeno problema ConvexHullMeshquando esse conjunto de pontos está em uma linha (obrigado, caso de teste nº 2), que resolvemos anexando uma versão ligeiramente deslocada de ssi na linha 7. Essa saída é um polígono, portanto, as linhas 7 -9 (t[...~RegionMember~# &]) produz uma lista dos pontos com coordenadas inteiras nesse polígono. Finalmente, a linha 5 e o final da linha 9 calculam todos os pontos que estão distantes exatamente 1 (portanto, não 0) desse conjunto de pontos inteiros; esse conjunto se torna o caminho de circunavegação.

Abaixo está a saída do caso de teste grande no link do OP. Observe no canto superior esquerdo, as escolhas incomuns de quando ir para oeste versus sudoeste sugerem o fato de que ela está sombreando uma linha invisível da inclinação -2/3 entre duas penínsulas (o referido segmento de linha faz parte do limite do casco convexo).

........................
.............o..........
...........oo#ooooooo...
..........o#.#.##...#o..
........oo.#.#.###.##o..
.......o..########.##o..
.....oo...############o.
...oo#....############o.
..o#.###.##############o
.o##.##################o
.o####################o.
.o.##################.o.
.o##################..o.
.o..################..o.
o###################..o.
o#####################o.
o.##################.o..
o####################o..
o#...##############.o...
o##...#############o....
o#.....###....#oooo.....
.oooooo#ooooooo.........
.......o................

O Mathematica geralmente representa cadeias de caracteres como matrizes 1D de caracteres? Caso contrário, será necessário pegar / retornar uma matriz 1D de seqüências de caracteres. (! Além disso, ansioso para a explicação que eu não acho que eu vou ser capaz de executar isso sem ter Mathematica, né?)
DLosc

O Mathematica possui um tipo de dados string, mas parece que uma matriz de caracteres também é válida para os fins deste site (ou seja, eu aprendi isso quando iniciei no PPCG, mas esqueço as legalidades do motivo). Sim, infelizmente, o Mathematica não é gratuito e, portanto, não é acessível a muitas pessoas :(
Greg Martin

1
@GregMartin Eu sempre experimento as soluções Mathematica em sandbox.open.wolframcloud.com
ovs 23/03

O consenso atual diz que as listas de cadeias de caracteres únicos não podem ser usadas no lugar de uma cadeia. Até onde eu sei, os "caracteres" no Mathematica são apenas cadeias de caracteres únicos, como no Python. A situação é diferente em uma linguagem como Java, que possui um chartipo separado ; nesse caso, uma charmatriz pode ser usada no lugar de uma string.
DLosc 24/03

1
Eis como li: A principal resposta votada foi publicada em 2014. A resposta que vinculei foi publicada em 2016, como uma tentativa de esclarecer a ambiguidade na resposta anterior. Por isso, li a pontuação negativa na resposta mais recente quando as pessoas diziam: "Não, não queremos que a resposta mais antiga signifique que as listas de cadeias de caracteres simples estão corretas". Mas, independentemente da meta, estou proibindo listas de cadeias de caracteres simples nesta pergunta (e esclareci a redação para refletir isso).
DLosc 24/03

10

Python 3, 779 bytes (recuo com guias)

Este é o programa inteiro. Ele lê as entradas do stdin e as imprime no stdout. Stdin deve terminar com EOF. Exemplo de execução com a grande entrada: https://ideone.com/XIfYY0

import itertools,sys
L=list
C=itertools.count
d=L(map(L,filter(None,sys.stdin.read().split('\n'))))
X=len(d[0])
Y=len(d)
R=range
def P(r):return all(d[y][x]=='.'for x,y in r)
def S(f):
    for n in C(0):
        if P(f(n)):l=n
        else:break
    for n in C(l+1):
        if P(f(n)):return l,n
def f(V,a,*b):return L(eval('lambda '+a+':('+i+')',V)for i in b)
V=locals()
def D(n):
    y=min(n,Y-1);x=n-y
    while y>=0and x<X:yield(x,y);x+=1;y-=1
def E(n):
    x=max(0,n-Y);y=x+Y-n
    while y<Y and x<X:yield(x,y);x+=1;y+=1
F=f(V,'p','(p,y)for y in R(0,Y)','(x,p)for x in R(0,X)')+[D,E]
r=f(V,'x,y','x','y','x+y','x-y+Y')
B=L(map(S,F))
for x in R(0,X):
    for y in R(0,Y):
        z=L(zip(r,B))
        if all(g(x,y)in R(a,b+1)for g,(a,b)in z)and any(g(x,y)in e for g,e in z):d[y][x]='o'
print('\n'.join(''.join(x)for x in d))

A idéia é simples: calcula os menores limites octogonais e desenha células que estão dentro de todos os limites computados e cruzam pelo menos uma das bordas.


1
Você realmente não precisa usar sys.stdincomo entrada. input(), Recebendo várias linhas iria fazer o trabalho e custam menos bytes
Morto Possum

2
Pode substituir R(0,x)porR(x)
tetocat 23/03

+1 por não usar um built-in.
Robert Fraser

1
Agradável! Mais algumas dicas de golfe: economize 5 bytes cada usando lambdas para definir Pe f; L(generator expression)=> [generator expression]; F, rE Bparecem ser usado apenas uma vez cada e, portanto, pode ser embutido.
DLosc 27/03

8

JavaScript (ES6), 369 343 bytes

f=s=>(a=s.split`
`.map(s=>[...s]),m=Array(8),a.map((b,i)=>b.map((c,j)=>c>'#'||[i-j,i,j+i,j,j-i,-i,-i-j,-j].map((d,k)=>d>m[k]||(m[k]=d-1)))),[o,p,q,r,t,u,v,w]=m,g=(i,j,k,l,...p)=>i-k|j-l?a[i][j]=g(i+(k>i)-(k<i),j+(l>j)-(l<j),k,l,...p):1/p[0]?g(k,l,...p):'o',g(p,p-o,p,q-p,q-r,r,r-t,r,-u,t-u,-u,u-v,w-v,-w,o-w,-w,p,p-o),a.map(b=>b.join``).join`
`)

Explicação: A sequência é dividida em uma matriz de caracteres (não sei se a entrada da matriz de caracteres é aceitável). A matriz é iterada e as posições de todos os quadrados de terreno são localizadas. As linhas delimitadoras dadas pelas equações x - y = o, x = p, x + y = q, y = r, y - x = t, -x = u, -x - y = v, -y = wsão determinados de tal modo que o parâmetro máximo possível é escolhido onde todos está a terra para além da linha. Isso tem o efeito de envolver a ilha em um octógono. As coordenadas dos cantos do octógono são prontamente calculadas a partir dos parâmetros e as células em sua borda são preenchidas. A matriz é então unida novamente em uma sequência. A razão pela qual um octógono é suficiente é a seguinte:

   /o#     /o#     /o#
 |/o #   |/o #   |/ o#
 *o###   * o #   *  o#
/|o #   /|o #   /| o#
 |o#     |o#     |o#

Considere um canto do octógono. Em algum momento, ao longo das duas bordas, o caminho será limitado pela terra, porque construímos o octógono para tocar a terra o mais próximo possível. Se não houver terreno na esquina, o caminho pode seguir as rotas alternativas, como mostrado à direita, mas ainda é o mesmo número de etapas ortogonais e diagonais, portanto a distância é inalterada.


O que 'p' faz?
Robert Fraser

@RobertFraser O nome técnico é destruição de matriz. Nesse caso, no entanto, apenas atua como um rest of argumentsparâmetro.
Neil

@ Neil Na verdade, o nome técnico é parâmetro de descanso . A mesma sintaxe é usada para o operador de propagação . (Você usa ambos como ...pem lugares diferentes.) A reestruturação é outra coisa (embora o operador de propagação possa ser usado na desestruturação).
Brian McCutchon

@BrianMcCutchon Você está certo, eu quis dizer operador de spread, mas a desestruturação funciona em listas de argumentos de qualquer maneira.
Neil

6

Python 3.5, 224, 263, 234 218 bytes

Jogou mais 16 bytes ao se livrar da função aninhada e transformá-la em uma linha.

def h(s,k=0,i=0):w=s.find('\n')+1;x=s.find('X')-w;k=k or x;d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2;u=s[:k]+'o'+s[k+1:];return['X'>s[k]and i<8and(h(u,k+d[i+2],i+2)or h(u,k+d[i+1],i+1)or h(u,k+d[i],i))or'',s][s[k]>'X'and k==x]

Jogou 29 bytes:

def f(s):
 w=s.find('\n')+1;x=s.find('X')-w;d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2
 def h(s,k,i):u=s[:k]+'o'+s[k+1:];return['X'>s[k]and i<8and(h(u,k+d[i+2],i+2)or h(u,k+d[i+1],i+1)or h(u,k+d[i],i))or'',s][s[k]>'X'and k==x]
 return h(s,x,0)

A entrada é uma única string usando '~' para o oceano, 'X' para a terra e 'o' para o limite. (Usar 'X' salva um byte para '>' em vez de '==')

Versão menos golfe com comentários:

def f(s):
    w=s.find('\n')+1                         # width of one row
    x=s.find('X')-w                          # starting point
    d=[1,w+1,w,w-1,-1,-w-1,-w,-w+1]*2        # delta to add to current index to move in 
                                             # the 8 directions: E, SE, S, SW, W, NW, 
                                             # N, NE. Make it long to avoid
                                             # lots of modulo operations in 
                                             #    the recursive calls

    def h(s,k,i):                            # s is the island string, k the current
                                             # position, i the direction index
        if s[k]>'X'and k==x:                 # if back at the begining,
            return s                         #   return the map

        elif 'X'>s[k] and i<8:               # if there is water here, and haven't
                                             #  looped around,
            u=s[:k]+'o'+s[k+1:]              #  make a new map with an 'o' in the 
                                             #  current spot

            r = h(u,k+d[i+2],i+2)            # try a 90 degree right turn
            if r: return r

            r = h(u,k+d[i+1],i+1)            # try a 45 degree turn
            if r: return r

            r= h(u,k+d[i],i)                 # try straight ahead
            if r: return r

        return ''                            # this path failed

    return h(s,x,0)

@DLosc corrigido. (I deve excluir a resposta velho?)
RootTwo

Agradável! (Sim, você deve remover a velha resposta - se alguém quiser vê-lo, eles podem olhar para a história do pós revisão.)
DLosc

5

C # 7 - 414 369 327 bytes

Editar : alternado para loop 1D, computação ie jem movimento

Editar : método de entrada alterado, tabela de pesquisa recolhida e alternada para limites iniciais bem definidos ... e removeu o espaço inútil no último loop for externo

using C=System.Console;class P{static void Main(){var D=C.In.ReadToEnd().Replace("\r","");int W=D.IndexOf('\n')+1,H=D.Length,z=H,k,q,c;int P()=>z%W*(k%3-1)+z/W*(k/3-1)+H;var B=new int[9];for(;z-->0;)for(k=9;k-->0&D[z]%7<1;)if(B[k]<=P())B[k]=P()+1;for(;++z<H;C.Write(q>9?'o':D[z]))for(q=k=9;k-->0;)q*=(c=P()-B[k])>0?0:c<0?1:2;}}

Experimente Online

Programa completo, leva entrada no padrão, imprime-lo para fora standard, usos #, .e o. Para cada célula, ele calcula um 'perfil' (que é a distância em 8 direções (parece calcular uma nona por conveniência, mas isso é sempre 0)) e registra o máximo de cada uma delas e, em seguida, grava o mapa inteiro novamente e substitui qualquer célula que esteja ao mesmo tempo em um limite e não fora de um com um 'o'. O código comentado abaixo explica como tudo funciona.

Conforme minha resposta a Save the Geese from Extinction , isso produz o menor octógono (circunavegação válida com a maior área) que circunda a ilha.

Nota : pela primeira vez na vida, estou usando algo da década atual e esse código requer que o C # 7 seja compilado. Se você não possui o C # 7, há uma linha que precisará ser substituída, claramente marcada no código.

Exemplo de uso e saída:

type t7.txt | IslandGolf1.exe

.........ooooooooooo....
........o....#......o...
.......o...#.#.##...#o..
......o....#.#.###.##.o.
.....o....########.##..o
....o.....############.o
...o.#....############.o
..o#.###.##############o
.o##.##################o
o.####################.o
o..##################..o
o.##################...o
o...################...o
o###################...o
o#####################.o
o.##################..o.
o####################o..
o#...##############.o...
o##...#############o....
o#.....###....#...o.....
.o.....#.........o......
..ooooooooooooooo.......

Código formatado e comentado:

using C=System.Console;

class P
{
    static void Main()
    {
        // \n 10
        // # 35
        // . 46
        // o 111


        var D=C.In.ReadToEnd().Replace("\r",""); // map

        int W=D.IndexOf('\n')+1, // width
            H=D.Length, // length
            z=H, // position in map (decomposed into i and j by and for P)
            k, // bound index
            q, // bound distance, and later cell condition (0 -> outside, 8 -> inside, >8 -> on boudary)
            c; // (free), comparison store

        // 'indexes' into a profile for the point z at index k
        // effectively {i=z%W,j=z/W,-i,-j,i+j,j-i,-i-j,i-j,0}[k] (inside order is a bit different) (0 const is always treated as 'inside bounds')
        // each non-zero-const entry describes the distance in one of the 8 directions: we want to maximise these to find the 'outer bounds'
        // the non-zero-const bounds describe 8 lines, together an octogen
        int P()=>z%W*(k%3-1)+z/W*(k/3-1)+H; // new C#7 local method syntax (if you don't have C#7, you can test this code with the line below instead)
        //k=0;System.Func<int>P=()=>z%W*(k%3-1)+z/W*(k/3-1)+H; // old lambda syntax (must pre-assign k to make static checker happy)

        var B=new int[9]; // our current bounds, each is initially null (must only call P() when on a #)
        // B[k] starts off a 0, P() has a +H term, and W+(H/W)<H for W >= 3, so B[k] is assigned the first time we compare it (H-i-j always > 0)

        for(;z-->0;) // for each cell
            for(k=9;k-->0& // for each bound
                D[z]%7<1;) // if this cell is #
                if(B[k]<=P())B[k]=P()+1; // update bound if necessary (add one so that we define the bound _outside_ the hashes)
        // z=-1
        for(;++z<H; // for each cell
                C.Write(q>9?'o':D[z])) // print the cell (if q > 9, then we are on the bounds, otherwise, spit out whatever we were before)
            // check we are not 'outside' any of the bounds, and that we are 'on' atleast one of them
            for(q=k=9;k-->0;) // for each bound
                q*=(c=P()-B[k])>0?0: // outside bound (q=0)    (??0 is cheaper than (int) or .Value)
                    c<0?1: // inside (preserve q)
                    2; // on bound (if q != 0, then q becomes > 9)
    }
}

maior octógono? ou menor?
Sarge Borsch 23/03

@SargeBorsch obrigado, corrigiu o texto.
VisualMelon
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.