12
\$\begingroup\$

In this challenge, you must take two numbers (separated by a space) as input and output an ASCII right triangle, made up of xs.

The first number will be the width and height of the triangle you should output. The second number will be which corner the right angle will be in. The corners are numbered 1 to 4, starting in the top left and going in English reading order:

1 2
3 4

For example (inputs and their respective triangle outputs):

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

Your program's output must match these examples exactly for their respective inputs.

The input will always be valid: the first number will be an integer ≥1, and the second number will be 1, 2, 3, or 4.

This is ; shortest code (in character count) wins.

asked Aug 23, 2013 at 23:45
\$\endgroup\$

10 Answers 10

9
\$\begingroup\$

APL (30)

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

Explanation:

  • {...}/⎕: reduce given function over the input (so if the input has 2 numbers, just calls the function with those two numbers, being the left number and the right number)
  • ≤/ ̈⍳2⍴⍺: Make an -by- coordinate matrix and set those positions where the X coordinate is not greater than the Y coordinate, giving a bitfield.
  • (⍎⍵⌷'⌽+⍉⊖'): select a transformation function given by to put the triangle right-side-up.
  • ' x'[1+...]: add one to the bitfield, and use the result as an index into the string ' x', so putting space for 0 and x for 1.
answered Aug 24, 2013 at 14:56
\$\endgroup\$
7
  • 1
    \$\begingroup\$ The more APL I read, the more I realize APL is a parsing nightmare. Wouldn't it have to actually evaluate the (⍎⍵⌷'functions') part before it decides how to interpret the whole statement? Consider for example 1+(⍵⌷'12+')|40. It wouldn't even know if | is monadic or dyadic before ing that parenthesized portion. The whole abstract syntax tree changes depending on the evaluation. \$\endgroup\$ Commented Nov 20, 2013 at 12:13
  • \$\begingroup\$ I meant 1+(⍎⍵⌷'12+')|40...will not let me edit. \$\endgroup\$ Commented Nov 20, 2013 at 12:58
  • 2
    \$\begingroup\$ @protist: Fun fact: f ← { [ } does not give an error! f 1÷0 gives... a domain error! (because of the division by zero). Only when you call the function like f 123 you get syntax error. Behold: imgur.com/jtmdi4B \$\endgroup\$ Commented Nov 20, 2013 at 18:11
  • \$\begingroup\$ By all the gods!!!! That breaks my heart a little. I have been playing with writing APL interpreters some, and that demonstrates a great evil in the current implementations. hahaha \$\endgroup\$ Commented Nov 20, 2013 at 18:59
  • \$\begingroup\$ It almost seems like functions are put in place routinely by some sort of ugly macro-expansion-like process. It would somewhat indicate in-place text expansion. \$\endgroup\$ Commented Nov 20, 2013 at 19:00
6
\$\begingroup\$

Ruby, (削除) 116 (削除ここまで) (削除) 115 (削除ここまで) (削除) 109 (削除ここまで) 96

I shall start with my own solution.

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}

I just know that I'll get beat by a 30 character GolfScript solution almost instantly :P

Thanks to minitech for shaving off 19 characters (wow)!

answered Aug 23, 2013 at 23:45
\$\endgroup\$
10
  • \$\begingroup\$ Instead of ==0, you can use <1. ?x*x saves another character. Also, puts i[1]%2<1?t.rjust(s):t} would do the trick, right? \$\endgroup\$ Commented Aug 25, 2013 at 0:31
  • \$\begingroup\$ Hmm... you have spaces around the ?? Is that necessary? Also, I think you can do the same thing with the r=. \$\endgroup\$ Commented Aug 25, 2013 at 3:55
  • \$\begingroup\$ @minitech It is necessary - the leading space because otherwise it parses 1? as a single token, and the trailing space because otherwise it parses as ?t (which is equivalent to 't'). How do you propose restructuring the r part? \$\endgroup\$ Commented Aug 25, 2013 at 14:07
  • \$\begingroup\$ Did you try it? Under which version of Ruby? Works fine for me on 2.0. \$\endgroup\$ Commented Aug 25, 2013 at 14:12
  • \$\begingroup\$ @minitech Odd, it didn't work before and now it does :P Thanks \$\endgroup\$ Commented Aug 25, 2013 at 14:15
4
\$\begingroup\$

GolfScript ((削除) 34 (削除ここまで) 33 chars)

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

It's a shame that the corners aren't numbered in rotation, because that would allow a more elegant approach of building one array and then rotating it n times:

~\:^,{)' x'^*$>^<}%{-1%zip}@)*n*
answered Aug 24, 2013 at 11:34
\$\endgroup\$
3
\$\begingroup\$

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

Formatted:

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

enter image description here

answered Aug 24, 2013 at 10:17
\$\endgroup\$
2
  • \$\begingroup\$ Input has to be space-delimited, not comma separated. \$\endgroup\$ Commented Aug 24, 2013 at 13:13
  • \$\begingroup\$ @Doorknob: The screenshot is from a test program where I chose to show the input with a comma. The input actually is space delimited when you execute the program, although the point is moot because all C# console applications receive input as an array of strings. \$\endgroup\$ Commented Aug 25, 2013 at 6:48
2
\$\begingroup\$

Golfscript, (削除) 39 36 (削除ここまで) 35 characters

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

live demo: http://golfscript.apphb.com/?c=OyczIDInCn5cOnkseycgJyoneCd5Kit5PC0xIDIkPyV9JS0xQDI%2BPyVuKgo%3D

too bad it's not 30 characters as requested

answered Aug 24, 2013 at 7:08
\$\endgroup\$
3
  • \$\begingroup\$ Replacing 1${-1%}* with -1 2$?% and 2円>{-1%}* with 2円>-1\?% will net you 2 characters. \$\endgroup\$ Commented Aug 24, 2013 at 9:54
  • \$\begingroup\$ @Volatility -1 2 can be written 0~2 \$\endgroup\$ Commented Aug 24, 2013 at 10:27
  • \$\begingroup\$ And for another char we have to restructure a bit more: ~(\:y,{{>'x '=}+y,%0~2$?%}%2円&(%n* \$\endgroup\$ Commented Aug 24, 2013 at 10:39
2
\$\begingroup\$

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"]}}]

another method


Under a liberal interpretation of "output", the following (104 chars) will work.

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

triangle


If input in the form of a list were permitted, the following (75 chars) would suffice:

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

answered Aug 24, 2013 at 4:12
\$\endgroup\$
5
  • \$\begingroup\$ Technically this is against the rules :P \$\endgroup\$ Commented Aug 24, 2013 at 4:58
  • \$\begingroup\$ What rule does it violate? \$\endgroup\$ Commented Aug 24, 2013 at 4:58
  • \$\begingroup\$ The input/output chart thingy I put. The 122 char one is good though. I edited the question to clarify \$\endgroup\$ Commented Aug 24, 2013 at 4:59
  • \$\begingroup\$ Oops. I thought the chart was simply an example. \$\endgroup\$ Commented Aug 24, 2013 at 5:00
  • \$\begingroup\$ I just placed the ASCII art version in first place. \$\endgroup\$ Commented Aug 24, 2013 at 11:15
2
\$\begingroup\$

J, (削除) 59 (削除ここまで) (削除) 55 (削除ここまで) (削除) 42 (削除ここまで) (削除) 38 (削除ここまで) (削除) 37 (削除ここまで) 36 characters

If it's permitted to have the input at the end of the program:

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

If not (for an extra 3 characters):

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

Usage:

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

or

 t 3 4
 x
 xx
xxx

I think this could be a fair bit shorter since most of the characters are brackets and caps to keep it in an implicit style.

Edit
Using a gerund and the agenda verb has chopped off a few characters, but there's still too many caps in there for my liking.

Edit 2
That's a bit more like it. Dumping the agenda for a list of how many rotations are required gets rid of most of the extra brackets and a few caps.

Edit 3
Got rid of the last extraneous cap and a pair of brackets in the process. Need to find a cheaper way of encoding the number of rotations required.

Edit 4 Use prefix instead of suffix to chop off a character. Enables a different way of creating the list which doesn't save any characters. Bugger.

Edit 5
Using a formula to chop off another character. Still feel this bit could be shorter.

answered Aug 24, 2013 at 14:30
\$\endgroup\$
1
\$\begingroup\$

Python 106 Characters

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)
answered Aug 24, 2013 at 18:20
\$\endgroup\$
1
\$\begingroup\$

Python 3, 91

Based on Abhijit's answer.

Modified the creation of the output string to avoid the sum of strings and the ugly 1s in the range. Python 3 gets rid of the raw_ in raw_input, but makes necessary to use // for integer divison and to add parantheses for print, so that saves only one character.

w,d=map(int,input().split())
for e in range(w)[::d//3*2-1]:print('%*s'%(w-d%2*2*w,'x'*-~e))
answered Aug 24, 2013 at 23:17
\$\endgroup\$
0
0
\$\begingroup\$

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

Evidence that I need to implement overloading and flesh out the standard library.

answered Aug 24, 2013 at 22:17
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.