Island Golf # 1: Circunnavegación

43

Este es el primero de una serie de desafíos de Island Golf. Siguiente reto

Dada una isla en el arte ASCII, genera una ruta óptima para circunnavegarla.

Entrada

Su entrada será una cuadrícula rectangular que consta de dos caracteres, que representan tierra y agua. En los ejemplos a continuación, la tierra es #y el agua es ., pero puede sustituir cualquiera de los dos caracteres distintos que desee.

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

Siempre habrá al menos una ficha de tierra. Todas las fichas de tierra serán contiguas (es decir, solo hay una isla). Las baldosas de agua también serán contiguas (es decir, no hay lagos). El borde exterior de la cuadrícula será de baldosas de agua. Las fichas de tierra no se conectarán en diagonal: es decir, nunca verás algo como

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

Salida

Su código debe generar la misma cuadrícula, con una circunnavegación más corta dibujada en ella. En los ejemplos a continuación, se dibuja la ruta de circunnavegación o, pero puede sustituir cualquier personaje siempre que sea distinto de sus caracteres de tierra y agua.

Una circunnavegación es una curva cerrada simple, dibujada completamente en baldosas de agua, que rodea completamente todas las baldosas terrestres en la cuadrícula. Se permiten conexiones diagonales . Por ejemplo, esta es una circunnavegación de la isla anterior (pero no la más corta):

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

La longitud de una circunnavegación se calcula de la siguiente manera: por cada par de mosaicos adyacentes en el camino, si están conectados horizontal o verticalmente, agregue 1; si están conectados en diagonal, agregue √2. La longitud de la ruta anterior es 22 + 7√2 (≈ 31.9).

Una circunnavegación más corta es una circunnavegación con la menor longitud posible. Su programa debe generar cualquier ruta que satisfaga esta condición. Para la mayoría de las islas, habrá múltiples soluciones posibles. Aquí hay una solución para la isla anterior, con longitud 10 + 13√2 (≈ 28.4):

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

Detalles

Su solución puede ser un programa completo o una función . Cualquiera de los métodos de entrada y salida predeterminados son aceptables.

Su entrada y salida puede ser una cadena multilínea o una lista de cadenas. Si su idioma tiene un tipo de caracteres distinto de las cadenas de un solo carácter, puede sustituir "lista de caracteres" por "cadena" en la oración anterior. Si su idioma necesita ingresar el alto y / o ancho de la cuadrícula, puede hacerlo. Su salida puede (opcionalmente) tener una nueva línea final. Como se mencionó anteriormente, puede usar tres caracteres distintos en lugar de #.o(especifique en su envío qué caracteres está usando).

Casos de prueba

A. Islas con circunnavegaciones más cortas y ú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. Ejemplo de una isla con múltiples soluciones posibles:

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

Salidas posibles:

....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. Gran caso de prueba como Gist


Este es el : gana el código más corto en cada idioma.

DLosc
fuente
1
¡La circunnavegación más corta para el tercer caso de prueba es el patrón 'pan' en el Juego de la vida de Conway!
Camarada SparklePony

Respuestas:

18

Mathematica (versión 9), 165 bytes

La ConvexHullMeshfunción corta y agradable que usó Greg Martin solo se introdujo en la versión 10 de Mathematica, así que pensé en intentarlo sin ella, usando mi antigua versión 9. de Mathematica. Es una función que toma y devuelve una lista de cadenas (con ., #y oque los símbolos).

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

Explicación:

  • Primero, Characters@# /. {"."->0, "#"->1}convierte la entrada en una matriz de 0sy 1s.
  • "o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#luego usa las poderosas capacidades de procesamiento de imágenes de Mathematica (pero extremadamente pesadas en bytes ...) para llenar primero el casco convexo de la isla (que es la forma que obtendría si estirara un trozo de cuerda a su alrededor), y luego tome su límite. Luego multiplicamos esta matriz por la cadena "o"para obtener una matriz de 0sys "o"(gracias a la impresionante adaptabilidad de Mathematica sobre los tipos), y agregamos esto a "#"veces la matriz de la isla.
  • Finalmente, ""<>#& /@ (... /. {0->"."})convierte esta matriz de "o"s, "#"sy 0s en una matriz de "o"s, "#"sy "."s, y une cada fila en una cadena.

Cuando probamos esto en el ejemplo B , obtenemos la salida

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

[Editar, gracias a Greg Martin:] Si se nos permite usar matrices de caracteres en lugar de listas de cadenas, podemos reducir esto a 144 bytes:

"o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#/.{0->"."}&[#/.{"."->0,"#"->1}]&
No un arbol
fuente
1
¡Bien hecho! Nunca supe sobre MorphologicalComponents[#, Method->"ConvexHull"] :) Puede guardar aún más bytes suponiendo que la entrada ya está dividida en caracteres y devolviendo también una matriz 2D de caracteres.
Greg Martin
@ GregMartin, ¡no sabía sobre ese uso MorphologicalComponentshasta hoy!
No es un árbol
Novato de Mathematica aquí: ¿cómo debo llamar a esta función? Lo intenté f[{"...",".#.","..."}]y obtuve algunos errores.
DLosc
@DLosc, la función es todo, no solo f. (Bueno, estrictamente hablando, son las cosas después del punto y coma.) Para llamar a la función, escriba todo en una ventana de Mathematica, seguido de [su entrada y ], por lo tanto, debería verse algo así como f@m_:=m(1-m[[2,2]]) . . . #/.{"."->0,"#"->1}]&[{"...", ".#.", "..."}](abreviado por espacio).
No es un árbol
@DLosc Bueno, eso es porque el código está roto. ¡Creo que lo he solucionado ahora! (No tengo idea de lo que sucedió allí; lo siento ...)
No es un árbol
11

(Pero vota la solución de Notatree , ¡es mejor!)

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)&

Función pura que toma una matriz 2D de caracteres como entrada y devuelve una matriz 2D de caracteres. Una versión más fácil de leer:

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) &

La línea 1 define una función nque produce la distancia (más pequeña) entre un punto xen el plano y un conjunto yde otros puntos. La línea 2 inicializa la variable ia la entrada, tanto para resolver una ambigüedad curry más tarde como para poder modificarla para producir la salida final; La línea 2 también define una función pque devuelve las coordenadas de todas las ocurrencias de su entrada i.

En la línea 3, p["#" | "."]representa cada coordenada del mapa de entrada (ya que todos sus caracteres son "#"o "."), por lo que tes una función que selecciona solo aquellas coordenadas que satisfacen una propiedad aún no especificada. En la línea 4, i~Part~## = "o"va a cambiar un montón de entradas del ipersonaje "o"; esos caracteres se seleccionarán del conjunto de coordenadas posibles de acuerdo con las cosas en las líneas 5-8. Y la línea 9 solo devuelve la respuesta una vez que se calcula.

Bien, infraestructura hecha, ahora a la computación real. ConvexHullMeshes la función integrada de Mathematica para calcular el casco convexo de un conjunto de puntos (el polígono convexo más pequeño que contiene esos puntos). Hablando moralmente, esto debería "completar" las calas y los fiordos de la isla (que es s = p@"#"), para descartarlos de nuestra navegación en bicicleta. Hay un pequeño problema con ConvexHullMeshcuando ese conjunto de puntos está todo en una línea (gracias, caso de prueba # 2), que resolvemos agregando una versión ligeramente desplazada de ssí mismo en la línea 7. Esta salida es un polígono, por lo que las líneas 7 -9 (t[...~RegionMember~# &]) produce una lista de los puntos con coordenadas enteras en ese polígono. Finalmente, la línea 5 y el final de la línea 9 calculan todos los puntos que están a una distancia exactamente 1 (por lo tanto, no 0) de este conjunto de puntos enteros; ese conjunto se convierte en el camino de circunnavegación.

A continuación se muestra la salida para el caso de prueba grande en el enlace del OP. Observe en la esquina superior izquierda, las elecciones inusuales de cuándo ir al oeste versus suroeste insinúan el hecho de que está sombreando una línea invisible de pendiente -2/3 entre dos penínsulas (dicho segmento de línea es parte del límite del 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................
Greg Martin
fuente
¿Mathematica generalmente representa cadenas como matrices 1D de caracteres? De lo contrario, deberá tomar / devolver una matriz 1D de cadenas en su lugar. (Además, ¡espero la explicación! No creo que pueda ejecutar esto sin tener Mathematica, ¿verdad?)
DLosc el
Mathematica tiene un tipo de datos de cadena, pero parece que una matriz de caracteres también es válida para los propósitos de este sitio (es decir, aprendí esto cuando comencé con PPCG, pero olvido las legalidades de por qué). Sí, desafortunadamente, Mathematica no es libre y, por lo tanto, no es accesible para muchas personas :(
Greg Martin
1
@ GregMartin Siempre pruebo las soluciones de Mathematica en sandbox.open.wolframcloud.com
ovs el
El consenso actual dice que las listas de cadenas de un solo carácter no se pueden usar en lugar de una cadena. Por lo que puedo decir, los "caracteres" en Mathematica son solo cadenas de un solo carácter, como en Python. La situación es diferente en un lenguaje como Java, que tiene un chartipo separado ; en ese caso, se charpodría usar una matriz en lugar de una cadena.
DLosc
1
Así es como lo leí: la respuesta votada principal se publicó en 2014. La respuesta que vinculé se publicó en 2016, como un intento de aclarar la ambigüedad en la respuesta anterior. Entonces leí el puntaje negativo en la respuesta más reciente cuando la gente decía: "No, no queremos que la respuesta anterior signifique que las listas de cadenas de caracteres únicos están bien". Pero independientemente de lo meta, no estoy permitiendo listas de cadenas de caracteres únicos en esta pregunta (y aclaré la redacción para reflejar eso).
DLosc
10

Python 3, 779 bytes (sangría con pestañas)

Este es todo el programa. Lee la entrada de stdin y la imprime en stdout. Stdin debe terminar con EOF. Ejemplo ejecutado con la entrada grande: 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))

La idea es simple: calcula los límites octogonales más pequeños y dibuja celdas que están dentro de todos los límites calculados e intersectan al menos uno de los bordes.

Lera
fuente
1
Realmente no necesita usar sys.stdincomo entrada. input(), Conseguir de varias líneas haría el trabajo y cuestan menos bytes
Dead Possum
2
Puede ser reemplazado R(0,x)porR(x)
ceilingcat el
+1 por no usar un incorporado.
Robert Fraser
1
¡Agradable! Algunos consejos de golf más: ahorre 5 bytes cada uno usando lambdas para definir Py f; L(generator expression)=> [generator expression]; F, rY Bparecen ser utilizados una sola vez cada uno y por lo tanto puede ser inline.
DLosc
8

JavaScript (ES6), 369343 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`
`)

Explicación: La cadena se divide en una matriz de caracteres (no estoy claro si la entrada de la matriz de caracteres es aceptable). La matriz se repite y se ubican las posiciones de todos los cuadrados de tierra. Las líneas que limitan dadas por las ecuaciones x - y = o, x = p, x + y = q, y = r, y - x = t, -x = u, -x - y = v, -y = wse determinan de tal manera que el parámetro máximo posible se elige donde todas mentiras la tierra más allá de la línea. Esto tiene el efecto de encerrar la isla en un octágono. Las coordenadas de las esquinas del octágono se calculan fácilmente a partir de los parámetros y las celdas en su borde se rellenan. La matriz se vuelve a unir en una cadena. La razón por la que es suficiente un octágono es la siguiente:

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

Considere una esquina del octágono. En algún punto a lo largo de los dos bordes, el camino estará limitado por la tierra porque construimos el octágono para tocar la tierra lo más cerca posible. Si no hay tierra en la esquina, el camino podría tomar las rutas alternativas como se muestra a la derecha, pero sigue siendo el mismo número de pasos ortogonales y diagonales, por lo que la distancia no cambia.

Neil
fuente
¿Qué hace ´ ... p´?
Robert Fraser
@RobertFraser El nombre técnico es desestructuración de matrices. Sin embargo, en este caso, solo actúa como un rest of argumentsparámetro.
Neil
@Neil En realidad, el nombre técnico es parámetro de reposo . Se utiliza la misma sintaxis para el operador de propagación . (Usas ambos como ...pen diferentes lugares). La desestructuración es otra cosa (aunque el operador de propagación se puede usar en la desestructuración).
Brian McCutchon el
@BrianMcCutchon Tienes razón, quise decir operador de propagación, pero la desestructuración funciona en las listas de argumentos de todos modos.
Neil
6

Python 3.5, 224, 263, 234 218 bytes

Aprovechó otros 16 bytes eliminando la función anidada y convirtiéndola en una sola línea.

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]

Golfed de 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)

La entrada es una sola cadena que usa '~' para el océano, 'X' para la tierra y 'o' para el límite. (El uso de 'X' guarda un byte para '>' en lugar de '==')

Versión menos golfista con comentarios:

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)
RootTwo
fuente
@DLosc corregido. (¿debería eliminar la respuesta anterior?)
RootTwo
¡Agradable! (Sí, se debe eliminar la respuesta de edad - si alguien quiere verlo, pueden mirar el historial de revisiones del puesto.)
DLosc
5

C # 7 - 414 369 327 bytes

Editar : cambió a 1D looping, informática iy jsobre la marcha

Editar : cambió el método de entrada, contrajo la tabla de búsqueda y cambió a límites iniciales bien definidos ... y eliminó el espacio sin sentido en el último for-loop 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;}}

Pruébalo en línea

Programa completo, toma la entrada en el estándar, lo imprime a cabo estándar, usos #, .y o. Para cada celda, calcula un 'perfil' (que es la distancia sobre 8 direcciones (parece calcular una novena por conveniencia, pero esto es siempre 0), y registra un máximo de cada una de ellas. Luego escribe todo el mapa nuevamente, y reemplaza cualquier celda que esté en un límite y no fuera de ninguna con una 'o'. El código comentado a continuación explica cómo funciona todo.

Según mi respuesta a Save the Geese from Extinction , esto produce el octágono más pequeño (circunnavegación válida con el área más grande) que limita la isla.

Nota : que por una vez en mi vida estoy usando algo de la década actual, y este código requiere C # 7 para compilar. Si no tiene C # 7, hay una línea que deberá reemplazarse, que está claramente marcada en el código.

Ejemplo de uso y salida:

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 formateado y 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)
    }
}
VisualMelon
fuente
octágono más grande? o el más pequeño?
Sarge Borsch
@SargeBorsch gracias, arregló el texto.
VisualMelon