10
\$\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.

\$\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.
\$\endgroup\$
  • 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\$ – protist Nov 20 '13 at 12:13
  • \$\begingroup\$ I meant 1+(⍎⍵⌷'12+')|40...will not let me edit. \$\endgroup\$ – protist Nov 20 '13 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\$ – marinus Nov 20 '13 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\$ – protist Nov 20 '13 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\$ – protist Nov 20 '13 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)!

\$\endgroup\$
  • \$\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\$ – Ry- Aug 25 '13 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\$ – Ry- Aug 25 '13 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\$ – Doorknob Aug 25 '13 at 14:07
  • \$\begingroup\$ Did you try it? Under which version of Ruby? Works fine for me on 2.0. \$\endgroup\$ – Ry- Aug 25 '13 at 14:12
  • \$\begingroup\$ @minitech Odd, it didn't work before and now it does :P Thanks \$\endgroup\$ – Doorknob Aug 25 '13 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*
\$\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

\$\endgroup\$
  • \$\begingroup\$ Input has to be space-delimited, not comma separated. \$\endgroup\$ – Doorknob Aug 24 '13 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\$ – Igby Largeman Aug 25 '13 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

\$\endgroup\$
  • \$\begingroup\$ Replacing 1${-1%}* with -1 2$?% and \2>{-1%}* with \2>-1\?% will net you 2 characters. \$\endgroup\$ – Volatility Aug 24 '13 at 9:54
  • \$\begingroup\$ @Volatility thanks, incorporated \$\endgroup\$ – John Dvorak Aug 24 '13 at 10:12
  • \$\begingroup\$ @Volatility -1 2 can be written 0~2 \$\endgroup\$ – Howard Aug 24 '13 at 10:27
  • \$\begingroup\$ And for another char we have to restructure a bit more: ~(\:y,{{>'x '=}+y,%0~2$?%}%\2&(%n* \$\endgroup\$ – Howard Aug 24 '13 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]

\$\endgroup\$
  • \$\begingroup\$ Technically this is against the rules :P \$\endgroup\$ – Doorknob Aug 24 '13 at 4:58
  • \$\begingroup\$ What rule does it violate? \$\endgroup\$ – DavidC Aug 24 '13 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\$ – Doorknob Aug 24 '13 at 4:59
  • \$\begingroup\$ Oops. I thought the chart was simply an example. \$\endgroup\$ – DavidC Aug 24 '13 at 5:00
  • \$\begingroup\$ I just placed the ASCII art version in first place. \$\endgroup\$ – DavidC Aug 24 '13 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.

\$\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)
\$\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))
\$\endgroup\$
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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.