In this challenge, you must take two numbers (separated by a space) as input and output an ASCII right triangle, made up of x
s.
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 code-golf; shortest code (in character count) wins.
10 Answers 10
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 andx
for 1.
-
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 example1+(⍵⌷'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– protist2013年11月20日 12:13:36 +00:00Commented Nov 20, 2013 at 12:13 -
\$\begingroup\$ I meant
1+(⍎⍵⌷'12+')|40
...will not let me edit. \$\endgroup\$protist– protist2013年11月20日 12:58:52 +00:00Commented 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 likef 123
you get syntax error. Behold: imgur.com/jtmdi4B \$\endgroup\$marinus– marinus2013年11月20日 18:11:47 +00:00Commented 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\$protist– protist2013年11月20日 18:59:10 +00:00Commented 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\$protist– protist2013年11月20日 19:00:44 +00:00Commented Nov 20, 2013 at 19:00
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)!
-
\$\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-– Ry-2013年08月25日 00:31:41 +00:00Commented 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 ther=
. \$\endgroup\$Ry-– Ry-2013年08月25日 03:55:16 +00:00Commented 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 ther
part? \$\endgroup\$Doorknob– Doorknob2013年08月25日 14:07:20 +00:00Commented Aug 25, 2013 at 14:07 -
\$\begingroup\$ Did you try it? Under which version of Ruby? Works fine for me on 2.0. \$\endgroup\$Ry-– Ry-2013年08月25日 14:12:54 +00:00Commented Aug 25, 2013 at 14:12
-
\$\begingroup\$ @minitech Odd, it didn't work before and now it does :P Thanks \$\endgroup\$Doorknob– Doorknob2013年08月25日 14:15:30 +00:00Commented Aug 25, 2013 at 14:15
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*
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
-
\$\begingroup\$ Input has to be space-delimited, not comma separated. \$\endgroup\$Doorknob– Doorknob2013年08月24日 13:13:04 +00:00Commented 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\$Igby Largeman– Igby Largeman2013年08月25日 06:48:57 +00:00Commented Aug 25, 2013 at 6:48
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
-
\$\begingroup\$ Replacing
1${-1%}*
with-1 2$?%
and2円>{-1%}*
with2円>-1\?%
will net you 2 characters. \$\endgroup\$Volatility– Volatility2013年08月24日 09:54:08 +00:00Commented Aug 24, 2013 at 9:54 -
\$\begingroup\$ @Volatility
-1 2
can be written0~2
\$\endgroup\$Howard– Howard2013年08月24日 10:27:21 +00:00Commented 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\$Howard– Howard2013年08月24日 10:39:53 +00:00Commented Aug 24, 2013 at 10:39
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]
-
\$\begingroup\$ Technically this is against the rules :P \$\endgroup\$Doorknob– Doorknob2013年08月24日 04:58:16 +00:00Commented Aug 24, 2013 at 4:58
-
\$\begingroup\$ What rule does it violate? \$\endgroup\$DavidC– DavidC2013年08月24日 04:58:54 +00:00Commented 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\$Doorknob– Doorknob2013年08月24日 04:59:24 +00:00Commented Aug 24, 2013 at 4:59
-
\$\begingroup\$ Oops. I thought the chart was simply an example. \$\endgroup\$DavidC– DavidC2013年08月24日 05:00:57 +00:00Commented Aug 24, 2013 at 5:00
-
\$\begingroup\$ I just placed the ASCII art version in first place. \$\endgroup\$DavidC– DavidC2013年08月24日 11:15:20 +00:00Commented Aug 24, 2013 at 11:15
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.
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)
Python 3, 91
Based on Abhijit's answer.
Modified the creation of the output string to avoid the sum of strings and the ugly 1
s 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))
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.