Gere um triângulo retângulo

10

Neste desafio, você deve pegar dois números (separados por um espaço) como entrada e saída de um triângulo retângulo ASCII, composto por xs.

O primeiro número será a largura e a altura do triângulo que você deve exibir. O segundo número será em qual canto o ângulo reto estará. Os cantos são numerados de 1 a 4, começando no canto superior esquerdo e seguindo a ordem de leitura em inglês:

1    2



3    4

Por exemplo (entradas e suas respectivas saídas triangulares):

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

A saída do seu programa deve corresponder a esses exemplos exatamente para as respectivas entradas.

A entrada sempre será válida: o primeiro número será um número inteiro ≥1 e o segundo número será 1, 2, 3 ou 4.

Isso é ; o código mais curto (na contagem de caracteres) vence.

Maçaneta da porta
fonte

Respostas:

9

APL (30)

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

Explicação:

  • {... }/⎕: reduz a função fornecida sobre a entrada (por isso, se a entrada tiver 2 números, basta chamar a função com esses dois números, sendo o número esquerdo e o número certo)
  • ≤/¨⍳2⍴⍺: Crie uma matriz de coordenadas -por- e defina as posições em que a coordenada X não é maior que a coordenada Y, fornecendo um campo de bits.
  • (⍎⍵⌷'⌽+⍉⊖'): selecione uma função de transformação fornecida por para colocar o triângulo com o lado direito para cima.
  • ' x'[1+... ]: adicione um ao campo de bits e use o resultado como um índice na string ' x', colocando espaço para 0 e x1.
marinus
fonte
11
Quanto mais APL eu leio, mais percebo que APL é um pesadelo de análise. Não teria que realmente avaliar a (⍎⍵⌷'functions')parte antes de decidir como interpretar toda a afirmação? Considere, por exemplo 1+(⍵⌷'12+')|40. Nem sequer saberia se |é monádico ou diádico antes de receber essa parte entre parênteses. Toda a árvore da sintaxe abstrata muda de acordo com a avaliação.
Protist #
Eu quis dizer 1+(⍎⍵⌷'12+')|40... não vai me deixar editar.
Protist #
2
@ Protist: Curiosidade: f ← { [ }não dá erro! f 1÷0dá ... um erro de domínio ! (por causa da divisão por zero). Somente quando você chama a função, f 123você recebe um erro de sintaxe . Veja: imgur.com/jtmdi4B
marinus
Por todos os deuses !!!! Isso parte meu coração um pouco. Eu tenho brincado com alguns intérpretes da APL, e isso demonstra um grande mal nas implementações atuais. hahaha
protist
Quase parece que as funções são implementadas rotineiramente por algum tipo de processo feio de expansão macro. Isso indica um pouco de expansão de texto no local.
protist
6

Ruby, 116 115 109 96

Começarei com minha própria solução.

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}

Só sei que vou ser derrotado por uma solução GolfScript de 30 caracteres quase que instantaneamente: P

Graças à minitech por cortar 19 caracteres (uau)!

Maçaneta da porta
fonte
Em vez de ==0, você pode usar <1. ?x*xsalva outro personagem. Além disso, puts i[1]%2<1?t.rjust(s):t}faria o truque, certo?
Ry-
Hmm ... você tem espaços ao redor do ?? Isso é necessário? Além disso, acho que você pode fazer a mesma coisa com o r=.
Ry-
@minitech É necessário - o espaço inicial porque, caso contrário, ele analisa 1?como um único token, e o espaço posterior, caso contrário, analisa como ?t(o que é equivalente a 't'). Como você propõe a reestruturação da rpeça?
Maçaneta
Você tentou? Sob qual versão do Ruby? Funciona bem para mim no 2.0.
Ry-
@minitech Estranho, não funcionou antes e agora ele faz: P Graças
Doorknob
4

GolfScript ( 34 33 caracteres)

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

É uma pena que os cantos não sejam numerados em rotação, porque isso permitiria uma abordagem mais elegante de criar uma matriz e depois girá-la várias nvezes:

~\:^,{)' x'^*$>^<}%{-1%zip}@)*n*
Peter Taylor
fonte
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'));}}

Formatado:

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'));
    }
}

insira a descrição da imagem aqui

Igby Largeman
fonte
A entrada deve ser delimitada por espaço, não separada por vírgula.
Maçaneta
@ Doorknob: A captura de tela é de um programa de teste em que eu escolhi mostrar a entrada com uma vírgula. A entrada, na verdade, é delimitada por espaço quando você executa o programa, embora o ponto seja discutível porque todos os aplicativos de console C # recebem entrada como uma matriz de seqüências de caracteres.
Igby Largeman
2

Golfscript, 39 36 35 caracteres

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

demonstração ao vivo: http://golfscript.apphb.com/?c=OyczIDInCn5cOnkseycgJyoneCd5Kit5PC0xIDIkPyV9JS0xQDI%2BPyVuKgo%3D

Pena que não são 30 caracteres, conforme solicitado

John Dvorak
fonte
Substituir 1${-1%}*por -1 2$?%e \2>{-1%}*com \2>-1\?%fornecerá 2 caracteres.
Volatilidade
@Volatility thanks, incorporada
John Dvorak
@Volatility -1 2pode ser escrito #0~2
Howard
E para outro caracter, temos que reestruturar um pouco mais:~(\: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"]}}]

outro método


Sob uma interpretação liberal de "saída", o seguinte (104 caracteres) funcionará.

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


Se a entrada na forma de uma lista fosse permitida, o seguinte (75 caracteres) seria suficiente:

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

DavidC
fonte
Tecnicamente, isso é contra as regras: P
Maçaneta da porta
Que regra viola?
DavidC
O gráfico de entrada / saída que eu coloquei. O 122 char é um bom embora. Eu editei a pergunta para esclarecer #
Maçaneta da porta
Opa Eu pensei que o gráfico era simplesmente um exemplo.
DavidC 24/08/13
Acabei de colocar a versão artística ASCII em primeiro lugar.
DavidC
2

J, 59 55 42 38 37 36 caracteres

Se for permitido ter a entrada no final do programa:

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

Caso contrário (para 3 caracteres adicionais):

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

Uso:

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

ou

   t 3 4
  x
 xx
xxx

Eu acho que isso poderia ser um pouco mais curto, já que a maioria dos personagens são colchetes e bonés para mantê-lo em um estilo implícito.

Editar
Usando um gerúndio e o verbo da agenda foram cortados alguns caracteres, mas ainda existem muitos limites para o meu gosto.

Edit 2
Isso é um pouco mais parecido. Despejar a agenda de uma lista de quantas rotações são necessárias elimina a maioria dos colchetes extras e alguns limites.

Editar 3
Livre-se da última tampa estranha e de um par de colchetes no processo. Precisa encontrar uma maneira mais barata de codificar o número de rotações necessárias.

Editar 4 Use prefixo em vez de sufixo para cortar um caractere. Permite uma maneira diferente de criar a lista que não salva nenhum caractere. Bugger.

Editar 5
Usando uma fórmula para cortar outro caractere. Ainda sinto que esse pedaço pode ser mais curto.

Gareth
fonte
1

Python 106 caracteres

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
fonte
1

Python 3, 91

Com base na resposta de Abhijit.

Modificou a criação da string de saída para evitar a soma de strings e os feios 1s no range. O Python 3 se livra do raw_in raw_input, mas torna necessário usar //a divisão inteira e adicionar parênteses para print, de modo que salva apenas um caractere.

w,d=map(int,input().split())
for e in range(w)[::d//3*2-1]:print('%*s'%(w-d%2*2*w,'x'*-~e))
Restabelecer Monica
fonte
0

Gatinho , 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

Ungolfed:

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

Evidência de que preciso implementar sobrecarga e detalhar a biblioteca padrão.

Jon Purdy
fonte