# Custom Rows of Smileys Triangle

This problem is inspired from shinh's problem.

Given an input of positive integer $$\n\$$, output a smiley triangle (see below) with $$\n\$$ rows.

## Detailed rules

• Can be either a function or a full program.
• Standard I/O rules applied.
• RULE CLARIFICATION: Output as exactly a string, rather than an array of strings whose item represent a line.
• Standard loopholes are forbitten.
• This is code-golf. Shortest code wins.

# Valid output syntax

Assuming ASCII encoding. A smiley triangle with $$\n\$$ rows triangle(n), where n>=1, should be output. <0xXX> is a character with such codepoint, in hexadecimal.

triangle(n) = triangle(n) <0x0a> | triangle_(n)
triangle_(1) = <0x3a> spaces
triangle_(n) = triangle_(n-1) <0x0a> row(n) spaces
row(2) = <0x3a> <0x2d>
row(n) = row(n-1) <0x29>
spaces = <0x09> spaces | <0x20> spaces | *empty*


## Example outputs

If n is 1, then

:


If n is 2, then

:
:-


If n=5, then

:
:-
:-)
:-))
:-)))

• is returning an array of lines valid output? Aug 5 at 13:11
• @Razetime, I don't think so, as I clarified to use LFs as in "Valid output syntax". Aug 5 at 23:48

# Python 2, 41 bytes

s=':-'
exec"print s[:-1];s+=')';"*input()


Try it online!

42 bytes

s,c=':-'
exec"print s;s+=c;c=')';"*input()


Try it online!

43 bytes

s=':'
exec"print s;s+='-)'[s>':'];"*input()


Try it online!

# Jelly, 10 bytes

“:-)”ṁ«\)Y


Try it online!

        )     Map over (the range from 1 to) the input:
“:-)”ṁ        Mold ":-)" to the shape of the argument, cycling its contents.
«\      Scan by minimum: replace anything to the right of ) with ).
Y    Join on newlines.


Thanks to Jonathan Allan for salvaging my first attempt, ”)xⱮa⁾:-Y, for another 10-byter:

# Jelly, 10 bytes

”)xa⁾:-ṁ)Y


Try it online!

        )     Map over (the range from 1 to) the input:
”)x           Repeat ")" by the argument.
a⁾:-       Zipwith-vectorize logical AND with ":-":
overwrite the first two characters with ":-".
ṁ      Mold to the shape of the argument, trimming the extra "-" for 1.
Y    Join on newlines.

• Your pretty close code can also be made into this working 9 byter: ”)xa⁾:-ṁ) TIO (or ”)ṁa⁾:-ṁ)). Good spot on the order of the characters by the way! Aug 4 at 12:51
• @JonathanAllan Thanks! Checking the order of the characters was actually the first thing I thought to do, even though my initial approach didn't use it. Aug 4 at 23:27
• newlines are required in the output. Aug 6 at 2:39

# Excel, 37 49 bytes

+12 bytes to accommodate clarification that the output should be one string

=CONCAT(LEFT(":-"&REPT(")",A1),SEQUENCE(A1))&"
")


This returns one string as opposed to the earlier version which returned multiple cells each containing a string. Due to the Excel string limit, this only works for n <= 254.

=LEFT(":-"&REPT(")",A1),SEQUENCE(A1))


Previous version that works for n <= 32767.

• Why would the code fail after n=32767? Aug 4 at 17:31
• @Mohammad, it fails because of the string limit in Excel. Aug 4 at 21:16

# 05AB1E, 11 bytes

…:-).ÞI£Jη»


Try it online!

Or, for the same length:

')×„:-ì¨¨η»


Try it online!

…:-)         # string literal ":-)"
.Þ       # cycle last character to create infinite list
I£     # take the first input characters
J    # join into a string
η   # take all prefixes
»  # join by newlines

')×          # repeat ")" input times
„:-ì      # prepend ":-"
¨¨    # remove the last two characters
η»  # join the prefixes by newlines

• You can combine both of your answers in the legacy version of 05AB1E for -1 byte: ')×„:-ì£η» (the £ will implicitly use the input, even though it's the first argument instead of second). Aug 30 at 13:23

# Stax, 8 bytes

╞■¼╤╝<Ñ┬


Run and debug it

outputs with newlines.

(take(":":iterate(++")")":-"))


Try it online!

# Japt, 11 10 bytes

Outputs an array of lines.

õî":-"ú')U


Try it

õî":-"ú')U     :Implicit input of integer U
õ              :Range [1,U]
î             :For each slice the following to that length
":-"         :  Literal string
ú')U     :  Right padded with ")" to length U


# Vyxaljr, 10 bytes

ƛ?\)*‛:-+Ẏ


Try it Online!

Thanks to @emanresuA for -2 bytes

# Vyxalj, 12 bytes

‛:-?⇩\)*+¦?Ẏ


Try it Online!

# J, 17 15 bytes

-1 thanks to Jonah!

[:]\$!.'('&':-'  Try it online! Reshape :- with fill ( to length n. [:[\ return each prefix. • [:]\{.!.'('&':-' for 16. Aug 4 at 13:53 • @Jonah ah, with that $ works, too! Thanks!
– xash
Aug 4 at 16:27
• Cool, didn't realize you could use fit with $. One thing I don't understand is why you can't ]\@$!.'('&':-'? I mean, I get that ]\@$ is a new verb, which has no definition for !., but why wouldn't J just check the rightmost verb in the list of conjunctions, and if it's defined there, use that one? Aug 4 at 17:07 • @Jonah even better !. would just set the fill for the context, e.g. (…$ … {. … $)!._ would all use _. But I guess the cost of implementing it outweighs the seldom usage. – xash Aug 4 at 18:59 • Why a sad triangle instead of a smiley triangle? Isn't ) the correct fill char? Aug 5 at 13:13 # K (oK), 37 bytes {({(":-",(x-2)#")")[!x]}'!x+1)[1+!x]}  Try it online! My first non trivial K answer, a lot of room for inprovement. • Do this to surpress printing Aug 4 at 20:18 • And the f: doesn't count as part of your bytecount - it's like lambda a,b: a+b but the only difference is newlines are unescapable delimiters, so the f: has to be on the same line. Aug 4 at 20:20 • you can use # to save a lot of bytes instead of indexing with [] Aug 5 at 8:16 # Vyxalj, 9 bytes ⇩\)*‛:-p¦  Try it Online! Wasif said I should post my 9-byter as my own answer, but I thought it was too similar to his, so I got rid of the map lambda and the slice, just because why not. :P Explanation: ⇩ # x = input - 2 \)* # Push a 'x' long string of ')' ‛:-p # Prepend the string ':-' ¦ # Prefixes # 'j' flag - Join top of stack on newlines and print  # JavaScript, 37 bytes f=n=>--n?f(n)+(s=n>1?s+')': :-):':'  Try it online! # Husk, 11109 8 bytes Edit: -1 byte simultaneously spotted by Razetime ↑ḣ¡→":-)  Try it online!  ":-) # the string ":-)" ¡ # construct infinite list by repeatedly appending → # last element of list so far; ḣ # now make list of all prefixes, ↑ # and take number of elements equal to input  • remove ⁰ for -1 Aug 4 at 10:04 • @Razetime - Thanks: I was just doing it while you commented! Aug 4 at 10:14 # Python 3, 52 bytes lambda n:[print((':-'+')'*i)[:-1])for i in range(n)]  Try it online! -1 byte thanks to Mohammad • -1 instead of i+1 will save 1 character Aug 4 at 21:51 # PHP -F, 59 bytes for(;$i<$argn;)echo$i++?":-".str_repeat(")",$i-2)." ":": ";  Try it online! Straightforward stuff.. Probably golfable a bit more, I'll try other things later # M4, 88 bytes Just a port of the syntax in OP. define(g,ifelse($1,2,,)g(decr($1))')')define(f,ifelse($1,1,:,f(decr($1)) :-g($1)')')


Try it online!

## Usage

f(number here)

# Charcoal, 12 bytes

ＮθＧ↓→θ⁺:-×)θ


Try it online! Link is to verbose version of code. Explanation:

Ｎθ


Input n.

Ｇ↓→θ


Draw a triangle of size n.

⁺:-×)θ


Paint the triangle using a smiley with n chins.

# C (gcc), 63 bytes

f(x){x&&f(x-1)+g(x);}g(x){x&&g(x-1);putchar("\n:-)"[x<3?x:3]);}


Try it online!

• double recursion

f x=($":-"++cycle")").take<$>[1..x]


Try it online!

• Thanks to @Unrelated String for saving 2!

# brainfuck, 57 bytes

This assumes the initial memory location contains n in binary (0x05 == 5). The TIO link allows a single ASCII character as input and converts it to binary.

->>++++++++[-<+++++++>]<++.<[->-------------.----<[->.<]]


Try it online!

• Is it outputting a line rather than a triangle? Aug 23 at 14:10
• Ah… I misunderstood that bit. Aug 24 at 22:20

# Ruby, 40 38 bytes

->n{n.times{|i|puts":-#{?)*n}"[0..i]}}


Try it online!

• 1.upto(n) saves 1 byte
– G B
Aug 4 at 20:38
• @GB Thanks, but I found an even better way: n.times saves 2 :) Aug 5 at 6:50

':-'+')'*"$args"|% *ve @args  Try it online! Saved 10 bytes thanks to mazzy! Saved 5 bytes by: • removing gratuitous parenthesis • using Remove instead of Substring • using splatting • Aug 5 at 6:09 • awesome! ٩(^‿^)۶ Aug 6 at 4:52 # APL(Dyalog Unicode), 20 bytes SBCS {,\⍵⍴':-',')'⍴⍨|⍵-2}  Try it on APLgolf! Monadic function {...} monadic function, takes n on right ⍵-2 n minus 2 | abs (No. of braces, call it x) ⍨ swap x with ')' brace for ⍴ dyadic reshape to get x braces , concat with ':-' smiley head ⍵⍴ take first n (monadic reshape) ,\ prefixes (ravel scan) # TI-Basic, 40 35 bytes Input N ": For(I,0,N-1 Disp Ans If not(I ":- If I Ans+") End  -5 bytes thanks to MarcMush -3 bytes if the input is already stored in Ans instead of having to use Input N. • nice answer! 35 bytes Sep 7 at 10:16 # Retina 0.8.2, 25 bytes .+$*)
^.
:
:.
:-
.
$$&¶


Try it online! Explanation:

.+
$*)  Start with n chins. ^. :  Change the first chin into eyes. :. :-  Change the second chin, if any, into a nose. .$$&¶  Output all of the nontrivial prefixes. # C (gcc), 68 bytes i;f(n){char*s=calloc(n,4);for(s[i=0]=58;n--;s[i]=i++?41:45)puts(s);}  Try it online! # Wolfram Mathematica, 67 bytes Column@With[{n=#},":-"<>")"~StringRepeat~n~StringTake~#&/@Range@n]&  Try it online! For some reasons unbeknownst to me, TIO doesn't display the list in column form. But if you run it in Mathematica, it will generate the desired result. Explanation: s=":-"<>StringRepeat[")",n] (* generates the main string *) StringTake[s,#]& /@ Range[n] (* a list of substrings up to length n *)  • Column is formatted in the REPL, but doesn't actually evaluate. Use Print/@ instead. 50 bytes – att Aug 5 at 19:45 # PHP -F, 86 bytes Without any predefined funcation! for($n=0;$n<$argn;$n++){echo':';for($i=1;$i<=$n;$i++){echo$i>1?')':'-';}echo PHP_EOL;}


Try it online!

Thanks.

• Nice first answer! Here is a 68 byte version Aug 5 at 15:38
• I added some comments in the footer, I recommand reading tips for golfing in PHP, it can be useful, even if most improvements I used are "classical" tricks not in the post. Aug 5 at 15:39
• @Kaddath thank you so much! Let me learn golfing. Aug 5 at 15:41

# Perl 5, 40 bytes

sub f{map{substr':-'.')'x99,0,\$_}1..pop}


Try it online!

# Python 2, 56 bytes

i=input()
o=':-'+')'*i
for x in range(1,i+1):print o[:x]


Try it online!

# Python 2, 54 bytes

i=input()
o=':-'+')'*i
for x in range(i+1):print o[:x]


Try it online!

Never going to be a winner. Just an alternative approach.

55 bytes

lambda x:'\n'.join((':-'+')'*x)[:x]for x in range(x+1))


Try it online!

Another alternative using a lambda, surprisingly longer than using input(). It's that join() that's expensive.

• These produce leading newlines Aug 5 at 12:48
• @jitse Having read the question again several times, I don't see where it says leading newlines are disallowed. Maybe I am missing something?? Aug 6 at 21:01
• Allowed formatting is specified in the Valid output syntax block in the question. Leading spaces are specifically not included there, so I don't think they are valid. Aug 9 at 7:20