Debería escribir un programa o función que reciba una cadena que represente un polígono ascii-art como entrada y salida ot devuelve el área del polígono.
La entrada es una cadena que consta de los caracteres _ / \ L V space
y newline
define un polígono simple (lo que significa que no hay segmentos adicionales, ni auto-toque ni auto-intersección).
El área de una celda de un solo carácter es 2
_
divide la celda en tamaños0
y2
\
divide la celda en tamaños1
y1
/
divide la celda en tamaños1
y1
L
divide la celda en tamaños0
y2
V
divide la celda en tamaños1
y1
(los dos lados delV
siempre estarán en el mismo lado del polígono para que se traten juntos en la lista).
Cada personaje conecta las dos esquinas de su celda de caracteres que espera (por ejemplo, arriba a la izquierda y arriba a la derecha en caso de V
).
Un ejemplo con área de 7 ( 1+2+1
en la segunda fila y 1+1+1
en la tercera):
_
/ \
V\/
Entrada
- La entrada formará un rectángulo, es decir, habrá el mismo número de caracteres entre las nuevas líneas.
- Puede haber espacios en blanco adicionales en cualquier lado del polígono.
- La nueva línea final es opcional.
Salida
- Un solo entero positivo, el área del polígono.
Ejemplos
Las salidas son posteriores a la última fila de sus entradas.
_
V
1
/L
\/
3
/VV\
L /
L/
14
____/\
\ /
/\/ /
\____/
32
/V\
/ \__
\ /
/\/ /V
L____/
45
Este es el código de golf, por lo que gana la entrada más corta.
^
intencionalmente?Respuestas:
CJam,
48 4329 bytesActualización : Golfé mucho usando las matemáticas y el truco del estado * 2 de la respuesta de orlp.
Cómo funciona (desactualizado, se actualizará pronto)
Dividimos la entrada en nueva línea y luego para cada parte mantenemos un contador de ocurrencias de caracteres de límite
L\/
. Este contador% 2 nos dirá cuál de las dos particiones equivale a elegir para todos los personajes. Luego encontramos el índice de cada carácter en la cadenaL _
.\/V
dará-1
referencia al último elemento en una matriz. Después de obtener el índice, usamos4558Zb2/
para crear la matriz[[2 0] [0 2] [0 2] [1 1]]
y luego elegimos el recuento correcto usando el contador.Pruébalo en línea aquí
fuente
Pyth,
4746453630Explicación:
Tenemos dos estados, "dentro del polígono" y "fuera del polígono". Cada uno de los siguientes caracteres hace lo siguiente cuando los lee de arriba a la izquierda a la derecha:
Tenga en cuenta que "agregar uno al área" y "si está en el polígono, agregar dos al área" son mutuamente excluyentes.
fuente
x=
funciona. ¿Está esto documentado en alguna parte?+=
o*=
o lo que sea. En este casox
se está utilizando como xor, por lo que es exactamente lo mismo que Python^=
.Retina , 293 + 15 = 308
314385bytesCada línea va en un archivo separado, así que agregué 13 al conteo de bytes. Alternativamente, puede poner todo eso en un solo archivo tal como está y usar la
-s
bandera. El<empty>
soporte para archivos o líneas realmente vacías.Desafortunadamente, necesito 187 bytes solo para convertir el resultado de unario a decimal. Creo que realmente debería implementar esto pronto .
Explicación
La retina es un lenguaje basado en expresiones regulares (que escribí exactamente para poder hacer cosas como esta con expresiones regulares). Cada par de archivos / líneas define una etapa de reemplazo, siendo la primera línea el patrón y la segunda línea la cadena de reemplazo. Los patrones pueden estar precedidos por una
`
cadena de configuración delimitada, que puede contener los modificadores de expresiones regulares habituales, así como algunas opciones específicas de Retina. Para el programa anterior, las opciones relevantes son;
, que suprime la salida de esa etapa y+
, que aplica el reemplazo en un bucle hasta que el resultado deja de cambiar.La idea de la solución es contar cada línea por separado, porque siempre podemos decidir por los caracteres ya encontrados si estamos dentro o fuera del polígono. Esto también significa que puedo unir todo en una sola línea, porque ir al principio y al final de una línea siempre está fuera del polígono. También podemos observar que
_
y el espacio son completamente idénticos para un algoritmo de barrido de línea, así como\
y/
. Por lo tanto, como primer paso sustituyo todos los saltos de línea y espacios por_
y todo\
por/
simplificar algo de código más adelante.Estoy realizando un seguimiento del estado actual interno / externo con los caracteres
i
yo
, al mismo tiempo, uso eli
s para registrar el área. Para hacerlo, empiezo anteponiendo unao
a la línea unida para marcar que estamos fuera del polígono. También estoy agregando uniio
al final de la entrada, que usaré como una búsqueda para generar nuevos caracteres.Luego, el primer reemplazo grande simplemente reemplaza uno
i
oo
seguido por uno de/V_L
los siguientes caracteres, inundando y contando todo. La tabla de reemplazo se ve de la siguiente manera, donde las columnas corresponden al último carácter en esa línea y las filas al siguiente carácter (dondeS
es para el espacio y<>
para una cadena vacía). He incluido todos los caracteres de la entrada para mostrar las equivalencias que ya utilicé:Tenga en cuenta que el carácter final siempre indica si después del carácter estamos dentro o fuera del polígono, mientras que el número de
i
s corresponde al área que debe agregarse al polígono. Como ejemplo, aquí están los resultados de las primeras cuatro iteraciones en la última entrada de ejemplo (esto fue generado por una versión anterior que en realidad inundó cada línea por separado, pero el principio sigue siendo el mismo):Por último, me deshago de todos los
o
s y los saltos de línea eliminando todo lo que coincide[^i]
, y el resto es la conversión de decimal a unario, que es bastante aburrida.fuente
Perl,
6558 bytesfuente
$/=\1;$-^=2*y,/\\L,,,$a+=y,/\\V,,||$-for<>;print$a
GNU sed, 290 + 1
El + 1 es para tener en cuenta el
-r
cambio pasado a sed. Comentarios y espacios en blanco adicionales no contados en la puntuación.No he mirado con gran detalle, pero creo que esto es probablemente similar a la respuesta de Martin Retina :
Visión general
:
Notas
sed
está orientado a líneas, por lo que necesita algo de trabajo para procesar varias líneas a la vez. ElN
comando hace esto agregando una nueva línea y luego la siguiente línea al espacio de patrón actual. La dificultadN
es que una vez que llega al flujo de entrada EOF, se cierra porsed
completo sin ninguna opción para realizar un procesamiento adicional. Para evitar esto, contamos el conjunto actual de dos puntos al final de cada línea, justo antes de leer en la siguiente línea.Salida:
fuente
C, 93
96108bytesEditar: Tomó en cuenta las sugerencias en los comentarios, convirtió el while en una sola declaración para el bucle y eliminó por completo la variable "i".
Publicación original:
Esto parecía un problema bastante divertido y simple como para finalmente lograr que creara una cuenta aquí.
El texto del polígono debe pasarse como el primer argumento de línea de comandos; Esto debería funcionar con o sin ninguna cantidad de líneas nuevas / espacios en blanco.
Esto solo lee en el polígono un carácter a la vez, s cambia si actualmente está dentro o fuera del polígono en '/', 'L' o '\', y t aumenta en 1 en '/', 'V', y '\', o por 2 si está dentro / 0 si está afuera en 'L', '_', espacio y nueva línea.
Esta es la primera vez que pruebo mi mano en cualquier tipo de "golf" (o C, en la medida en que difiere de C ++), por lo que cualquier crítica es apreciada.
fuente
i=t=s=0;
Creo que C inicializa todos losint
s a 0 de todos modos. Además, vea si puede convertir elwhile
bucle en unfor
bucle; eso a menudo ahorra unos pocos bytes....int i,t,s;for(i=t=s=0;c=v[1][i++];t+=s+(c>46^!(c%19)^s))s^=c>13^c%9>4;...
que debería ahorrar 4 bytes; uno {, uno} y dos;int i,t,v;
se pusiera delante ymain
no dentro, podríamos deshacernos dei=t=s=0
guardar otros 7 bytes.POSIX sed,
245244POSIX sed, sin extensiones o expresiones regulares extendidas. La entrada está limitada al tamaño máximo de espacio de retención de sed: POSIX exige al menos 8192; GNU logra más. Esta versión asume que no habrá líneas en blanco antes o después de la forma; un extra de 10 bytes de código, indicado en la expansión, puede acomodar eso si es un requisito (la pregunta original no especifica).
Ampliado y anotado
fuente
C, 84 bytes
Cambiamos de lado cada vez que vemos
\
,/
oL
; siempre agregamos uno para\\
,/
oV
, pero agregamos 2 (si está dentro) o 0 (si está afuera) para espacio, nueva líneaL
o_
.Las variables
a
yi
se supone que son cero en la entrada: deben restablecerse si la función se llama más de una vez.Sin golf:
Programa de prueba:
fuente