Genera un triángulo rectángulo

10

En este desafío, debe tomar dos números (separados por un espacio) como entrada y salida de un triángulo rectángulo ASCII, compuesto de xs.

El primer número será el ancho y la altura del triángulo que debe generar. El segundo número será en qué esquina estará el ángulo recto. Las esquinas están numeradas del 1 al 4, comenzando en la esquina superior izquierda y siguiendo el orden de lectura en inglés:

1    2



3    4

Por ejemplo (entradas y sus respectivas salidas triangulares):

INPUT | 3 1 | 3 2 | 3 3 | 3 4
------+-----+-----+-----+----
 OUT- | xxx | xxx | x   |   x
 PUT  | xx  |  xx | xx  |  xx
      | x   |   x | xxx | xxx

La salida de su programa debe coincidir con estos ejemplos exactamente para sus respectivas entradas.

La entrada siempre será válida: el primer número será un entero ≥1, y el segundo número será 1, 2, 3 o 4.

Este es el ; el código más corto (en el recuento de caracteres) gana.

Pomo de la puerta
fuente

Respuestas:

9

APL (30)

{' x'[1+(⍎⍵⌷'⌽+⍉⊖')≤/¨⍳2⍴⍺]}/⎕

Explicación:

  • {... }/⎕: reduce la función dada sobre la entrada (por lo tanto, si la entrada tiene 2 números, solo llama a la función con esos dos números, siendo el número izquierdo y el número derecho)
  • ≤/¨⍳2⍴⍺: Hacer una -by- matriz coordinar y establecer las posiciones donde la coordenada x no es mayor que la coordenada Y, dando un campo de bits.
  • (⍎⍵⌷'⌽+⍉⊖'): selecciona una función de transformación dada por para poner el triángulo del lado derecho hacia arriba.
  • ' x'[1+... ]: agregue uno al campo de bits y use el resultado como un índice en la cadena ' x', de modo que ponga espacio para 0 y xpara 1.
marinus
fuente
1
Cuanto más APL leo, más me doy cuenta de que APL es una pesadilla de análisis. ¿No tendría que evaluar realmente la (⍎⍵⌷'functions')parte antes de decidir cómo interpretar toda la declaración? Considere por ejemplo 1+(⍵⌷'12+')|40. Ni siquiera sabría si |es monádico o diádico antes de poner esa porción entre paréntesis. Todo el árbol de sintaxis abstracta cambia según la evaluación.
protist
Quise decir 1+(⍎⍵⌷'12+')|40... no me dejarás editar.
protista
2
@protist: Dato curioso: ¡ f ← { [ }no da un error! f 1÷0da ... un error de dominio ! (debido a la división por cero). Solo cuando llama a la función como f 123si recibiera un error de sintaxis . He aquí: imgur.com/jtmdi4B
marinus el
Por todos los dioses !!!! Eso me rompe un poco el corazón. He estado jugando a escribir algunos intérpretes APL, y eso demuestra un gran mal en las implementaciones actuales. jajaja
protista
Casi parece que las funciones se implementan rutinariamente por algún tipo de proceso feo de macroexpansión. De alguna manera indicaría la expansión de texto en el lugar.
protist
6

Ruby, 116 115 109 96

Comenzaré con mi propia solución.

i=gets.split
s=i[0].to_i
(i[1]<?3?s.downto(1):1..s).map{|x|t=?x*x
puts /2|4/=~i[1]?t.rjust(s):t}

Solo sé que me vencerá una solución GolfScript de 30 caracteres casi al instante: P

¡Gracias a Minitech por eliminar 19 personajes (wow)!

Pomo de la puerta
fuente
En lugar de ==0, puedes usar <1. ?x*xsalva a otro personaje. Además, puts i[1]%2<1?t.rjust(s):t}haría el truco, ¿verdad?
Ry-
Hmm ... tienes espacios alrededor del ?? ¿Es eso necesario? Además, creo que puedes hacer lo mismo con el r=.
Ry-
@minitech Es necesario: el espacio inicial porque de lo contrario se analiza 1?como un token único, y el espacio final porque de lo contrario se analiza como ?t(que es equivalente a 't'). ¿Cómo propones reestructurar la rpieza?
Pomo de la puerta
¿Lo intentaste? ¿Bajo qué versión de Ruby? Funciona bien para mí en 2.0.
Ry-
@minitech Odd, antes no funcionaba y ahora sí: P Gracias
Pomo
4

GolfScript ( 34 33 caracteres)

~\:^,{)' x'^*$>^<0(2$?%}%\(2&(%n*

Es una pena que las esquinas no estén numeradas en rotación, porque eso permitiría un enfoque más elegante de construir una matriz y luego rotarla nveces:

~\:^,{)' x'^*$>^<}%{-1%zip}@)*n*
Peter Taylor
fuente
3

C # - 195

using System;class P{static void Main(string[]a){int G=int.Parse(
a[0]),O=int.Parse(a[1]),L=O<3?0:G+1,F=O<3?-G:1;G=O%2>0?-G:G;for(;
F<L;F++)Console.Write("{0,"+G+"}\n","".PadRight(F<0?-F:F,'x'));}}

Formateado:

using System;
class P
{
    static void Main(string[] a)
    {
        int G = int.Parse(a[0]),
            O = int.Parse(a[1]),
            L = O < 3 ? 0 : G + 1,
            F = O < 3 ? -G : 1;

        G = O % 2 > 0 ? -G : G;

        for(; F < L; F++)
            Console.Write("{0," + G + "}\n", "".PadRight(F < 0 ? -F : F, 'x'));
    }
}

ingrese la descripción de la imagen aquí

Igby Largeman
fuente
La entrada debe estar delimitada por espacios, no separada por comas.
Pomo de la puerta
@Doorknob: la captura de pantalla es de un programa de prueba donde elegí mostrar la entrada con una coma. La entrada en realidad está delimitada por espacios cuando ejecuta el programa, aunque el punto es discutible porque todas las aplicaciones de consola de C # reciben la entrada como una matriz de cadenas.
Igby Largeman
2

Golfscript, 39 36 35 caracteres

~\:y,{' '*'x'y*+y<0~2$?%}%-1@2>?%n*

demostración en vivo: http://golfscript.apphb.com/?c=OyczIDInCn5cOnkseycgJyoneCd5Kit5PC0xIDIkPyV9JS0xQDI%2BPyVuKgo%3D

lástima que no sean 30 caracteres según lo solicitado

John Dvorak
fuente
Reemplazar 1${-1%}*con -1 2$?%y \2>{-1%}*con \2>-1\?%te dará 2 personajes.
Volatilidad
@Volatility gracias, incorporado
John Dvorak
Se -1 2puede escribir @Volatility0~2
Howard
Y para otro personaje tenemos que reestructurar un poco más:~(\:y,{{>'x '=}+y,%0~2$?%}%\2&(%n*
Howard
2

Mathematica 122 (104?)

g@s_ := ({w, p} = ToExpression@StringSplit@s; 
   Array[If[Switch[p, 1, # <= (w + 1 - #2), 2, # <= #2, 3, # >= #2, 4, # > (w - #2)],
   "X", ""] &, {w, w}]) // Grid

GraphicsGrid[{{g["12 1"], g["12 3"]}}]

otro método


Bajo una interpretación liberal de "salida", funcionará lo siguiente (104 caracteres).

f@s_ := ({w, p} = ToExpression@StringSplit@s; 
  Graphics[Polygon@Delete[{{w, 0}, {0, 0}, {w, w}, {0, w}}, p], Axes -> True])


f["50 4"]

triángulo


Si se permitiera la entrada en forma de una lista, bastaría lo siguiente (75 caracteres):

f[{w_, p_}] := 
 Graphics[Polygon@Delete[{{w, 0}, {0, 0}, {w, w}, {0, w}}, p], Axes -> True]

DavidC
fuente
Técnicamente esto va en contra de las reglas: P
Pomo de la puerta
¿Qué regla viola?
DavidC
La tabla de entrada / salida que puse. Sin embargo, el 122 char one es bueno. Edité la pregunta para aclararla
Pomo de la puerta
Ups Pensé que la tabla era simplemente un ejemplo.
DavidC
Acabo de colocar la versión artística ASCII en primer lugar.
DavidC
2

J, 59 55 42 38 37 36 caracteres

Si se permite tener la entrada al final del programa:

(|:@|.@]^:([:|[+_7*2<[)[:[\'x'$~])~/

Si no (para 3 caracteres adicionales):

t=.(|:@|.@]^:([:|[+_7*2<[)[:[\'x'$~])~/

Uso:

   (|:@|.@]^:([:|[+_7*2<[)[:[\'x'$~])~/3 4
  x
 xx
xxx

o

   t 3 4
  x
 xx
xxx

Creo que esto podría ser un poco más corto ya que la mayoría de los personajes son corchetes y mayúsculas para mantenerlo en un estilo implícito.

Editar
Usando un gerundio y el verbo del orden del día ha cortado algunos caracteres, pero todavía hay demasiadas mayúsculas para mi gusto.

Edición 2
Eso es un poco más parecido. Volcar la agenda para obtener una lista de cuántas rotaciones son necesarias elimina la mayoría de los corchetes adicionales y algunos topes.

Editar 3
Se deshizo del último límite extraño y un par de paréntesis en el proceso. Necesita encontrar una forma más barata de codificar el número de rotaciones requeridas.

Edición 4 Use el prefijo en lugar del sufijo para cortar un personaje. Permite una forma diferente de crear la lista que no guarda ningún carácter. Tío.

Edición 5
Usando una fórmula para cortar otro personaje. Todavía siento que esta parte podría ser más corta.

Gareth
fuente
1

Python 106 Personajes

w,d=map(int,raw_input().split())
for e in range(1,w+1)[::d/3*2-1]:print('%'+'-+'[d%2]+str(w)+'s')%('*'*e)
Abhijit
fuente
1

Pitón 3, 91

Basado en la respuesta de Abhijit.

Se modificó la creación de la cadena de salida para evitar la suma de cadenas y los 1s feos en range. Python 3 se deshace de la raw_de raw_input, pero no hace necesario el uso //de División de enteros y añadir los paréntesis para print, de manera que sólo guarda un carácter.

w,d=map(int,input().split())
for e in range(w)[::d//3*2-1]:print('%*s'%(w-d%2*2*w,'x'*-~e))
Reinstalar a Mónica
fuente
0

Gatito , 140

def s{><replicate}
getLine{' 'neChar}span{readInt fromSome}toBoth->{w n}
w 0 if(n 2>){><}..
{<>w>< -{'X's}{' 's}both if(n 2%0=){><}cat say}each

Sin golf:

getLine
{' ' neChar} span
{readInt fromSome} toBoth
->{ width corner }

width 0
if (corner 2 >):
  swap
..

{ ->index
  'X' index replicate
  ' ' (width index -) replicate
  if (corner 2 % 0 =):
    swap
  cat say
} each

Evidencia de que necesito implementar una sobrecarga y desarrollar la biblioteca estándar.

Jon Purdy
fuente