29
\$\begingroup\$

(related/inspired by: Draw a bowling formation)

A fun pastime in the winter months here is to perform snowman bowling, using a large ball (like a basketball) and tiny snowman figures. Let's recreate this in ASCII.

Each snowman consists of the following:

(.,.)
( : )

Here is the alignment of the ten snowman "pins"

(.,.) (.,.) (.,.) (.,.)
( : ) ( : ) ( : ) ( : )
 (.,.) (.,.) (.,.)
 ( : ) ( : ) ( : )
 (.,.) (.,.)
 ( : ) ( : )
 (.,.)
 ( : )

These "pins" are labeled from 1 to 10 as

7 8 9 10
 4 5 6
 2 3
 1

So far, so standard. However, unlike normal bowling, the snowman pins are merely flattened and not totally removed. This is done by someone needing to manually flatten the snow of any pins that were struck. A flattened snowman is represented by _____ (five underscores), with whitespace above. Here is an example with the 1 3 5 6 9 10 pins flattened (meaning only the 2 4 7 8 pins remain):

(.,.) (.,.)
( : ) ( : ) _____ _____
 (.,.)
 ( : ) _____ _____
 (.,.) 
 ( : ) _____
 _____

Input

  • A list of integers from 1 to 10 in any convenient format representing which pins were struck and thus need to be flattened.
  • Each number will only appear at most once, and the numbers can be in any order (sorted, unsorted, sorted descending) -- your choice, whatever makes your code golfier.
  • The input is guaranteed to have at least one integer.

Output

The resulting ASCII art representation of the snowman pins, with the correct pins flattened.

Rules

  • Leading or trailing newlines or whitespace are all optional, so long as the characters themselves line up correctly.
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • If possible, please include a link to an online testing environment so people can try out your code!
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

Examples

1 3 5 6 9 10
(.,.) (.,.)
( : ) ( : ) _____ _____
 (.,.)
 ( : ) _____ _____
 (.,.) 
 ( : ) _____
 _____
1 2 3
(.,.) (.,.) (.,.) (.,.)
( : ) ( : ) ( : ) ( : )
 (.,.) (.,.) (.,.)
 ( : ) ( : ) ( : )
 _____ _____
 _____
1 2 3 4 5 6 8 9 10
(.,.)
( : ) _____ _____ _____
 _____ _____ _____
 _____ _____
 _____
asked Dec 21, 2016 at 16:44
\$\endgroup\$
5
  • 18
    \$\begingroup\$ Code golf? Not code bowling? \$\endgroup\$ Commented Dec 22, 2016 at 5:44
  • \$\begingroup\$ Can we take the input numbers indexed from 0? And if possible take the input values without spaces such like 0123456789 instead of 1 2 3 4 5 6 7 8 9 10? \$\endgroup\$ Commented Dec 22, 2016 at 12:08
  • \$\begingroup\$ Perfect :D it allows me to make an easier attempt in ><> \$\endgroup\$ Commented Dec 22, 2016 at 13:56
  • 4
    \$\begingroup\$ I do not approve of flattening snowmen. \$\endgroup\$ Commented Dec 22, 2016 at 16:16
  • \$\begingroup\$ i identify myself as a snowman and find this flattening. \$\endgroup\$ Commented Dec 23, 2016 at 14:17

10 Answers 10

46
\$\begingroup\$

Snowman 1.0.2, 157 bytes

(()("789:045600230001"4aG::48nSdU][:#:]eq]/nM;AsI[:"_____"wR[" "wR/aC;:"( : )"wR["(.,.)"wR/aC;bI;:" "wRdUaC;bI\#**\;aMaZ:" "aJ1AfL;aM;aM1AfL"
"aJ1AfL*))

Try it online!

When I saw this challenge, I knew I just had to answer in the perfect language...

This is a subroutine that takes input as an array of numbers and outputs as a string via the current permavar.

Wrapped for "readability" / aesthetics:

(()("789:045600230001"4aG::48nSdU][:#:]eq]/nM;AsI[
:"_____"wR[" "wR/aC;:"( : )"wR["(.,.)"wR/aC;bI
;:" "wRdUaC;bI\#**\;aMaZ:" "aJ1AfL;aM;aM1AfL"
"aJ1AfL*))

Slightly ungolfed / commented version:

}
1wR`
3wR`aC`
5wR`aC`
6wR`aC`
9wR`aC`
*
((
 )(
 "789:045600230001" // pin layout data
 4aG // split into groups of 4; we need each row twice
 : // map over groups of 2 output lines
 : // map over pins (or whitespace)
 48nS // subtract ascii '0'
 dU][ // duplicate the pin; we need it in the if{}
 : // if (pin) {
 #:]eq]/nM;AsI[:"_____"wR[" "wR/aC;:"( : )"wR["(.,.)"wR/aC;bI
 ;: // } else {
 " "wRdUaC
 ;bI // }
 \#**\ // maneuver the permavars around to discard pin
 ;aM
 aZ:" "aJ1AfL;aM
 ;aM
 1AfL // flatten (simulate a flatmap)
 "
"aJ // join on newline
 1AfL // flatten again into a single string
 *
))
#sP
answered Dec 21, 2016 at 17:40
\$\endgroup\$
2
  • 17
    \$\begingroup\$ Pretty much the only context that this will be known as "the perfect language", :P \$\endgroup\$ Commented Dec 21, 2016 at 18:30
  • 3
    \$\begingroup\$ A snowman killing his own kind... You monster! \$\endgroup\$ Commented Dec 22, 2016 at 19:45
10
\$\begingroup\$

stacked, noncompeting, 118 bytes

I added deepmap and a few other things after this challenge, along with tons of bugfixes. Try it here!

@a((7 8 9 10)(4 5 6)(2 3)(1)){e:('(.,.)
( : )' ' 
_'5 hrep)a e has#' 'hcat
}deepmap{e i:' 
 'i 3*hrep e,$hcat#/!LF+}map

Ungolfed

{ a :
 ((7 8 9 10) (4 5 6) (2 3) (1))
 { e :
 (
 '(.,.)' LF '( : )' + + 
 ' ' LF '_' + + 5 hrep
 ) @possible
 a e has @ind
 possible ind get @res
 ' ' @padding
 res padding hcat return
 } deepmap
 { e i:
 ' ' LF ' ' + + i 3 * hrep
 e ,
 $hcat insert!
 LF +
 } map
} @:bowl
(1 2 3 4 6 10) bowl out

Output:

(.,.) (.,.) (.,.) 
( : ) ( : ) ( : ) _____ 
 (.,.) 
 _____ ( : ) _____ 
 _____ _____ 
 _____ 
answered Dec 21, 2016 at 18:33
\$\endgroup\$
2
  • \$\begingroup\$ This language looks great. The Fisher-Yates example in the wiki is beautiful. \$\endgroup\$ Commented Dec 21, 2016 at 18:58
  • \$\begingroup\$ @Jordan thank you so much! that means a lot to me :) \$\endgroup\$ Commented Dec 21, 2016 at 19:07
7
\$\begingroup\$

05AB1E, (削除) 45 (削除ここまで) 44 bytes

TF"(.,.)( : )"„ _×ばつ{«4ä2ä1N>åè})4L£Rvyø»}».c

Try it online!

Explanation

TF # for N in [0 ... 9] do:
 "(.,.)( : )" # push string
 „ _ # push the string " _"
 ×ばつ # repeat it 5 times
 { # sort
 « # concatenate the strings
 4ä # split the string in 4 parts
 2ä # split the list in 2 parts
 1N>åè # if index+1 is in the input, push the first part
 # else push the second part
 } # end loop
 ) # wrap stack in a list
 4L£ # split list in parts of size 1,2,3,4
 R # reverse list
 v # for each list in list of lists
 yø # transpose the list
 » # join by spaces and newlines
 } # end loop
 » # join by newlines
 .c # centralize
answered Dec 21, 2016 at 17:51
\$\endgroup\$
7
\$\begingroup\$

Python 2, (削除) 248 (削除ここまで) (削除) 243 (削除ここまで) (削除) 241 (削除ここまで) (削除) 226 (削除ここまで) (削除) 224 (削除ここまで) (削除) 223 (削除ここまで) (削除) 221 (削除ここまで) (削除) 210 (削除ここまで) (削除) 206 (削除ここまで) (削除) 200 (削除ここまで) 177 bytes

-5 with thanks to @Rod

-15 again thanks to Rod

-1 using space calculation again from Rod

Looks longer due to more lines and indents but surprisingly 11 bytes shorter.

I'm sure this will go under 200...

I was right but not without 23 bytes worth of serious hints from @Pietu1998. Many thanks!

i,z=input(),0;m=['']*10;n=m[:]
for x in range(11):m[x-1],n[x-1]=('(.,.)',' '*5,'( : )','_'*5)[x in i::2]
for y in 10,6,3,1:
 for q in m,n:print' '*3*z+' '.join(q[y-4+z:y])
 z+=1

Try it online!

Takes input as a list of integers. Way too big at 248 but it works.

answered Dec 21, 2016 at 18:27
\$\endgroup\$
1
6
\$\begingroup\$

C# (削除) 233 (削除ここまで) (削除) 221 (削除ここまで) (削除) 213 (削除ここまで) 203 bytes

method takes an int array a as the list of fallen pins

string S(int[]a){string o="",x=o,y=o,z=o;for(int i=10;i>0;){var c=a.Contains(i);x=(c?" ":"(.,.) ")+x;y=(c?"_____ ":"( : ) ")+y;if(i==7|i<5&i--!=3){o+=$"{z}{x}\n{z}{y}\n";x=y="";z+=" ";}}return o;}

wrapped

string S(int[]a){string o="",x=o,y=o,z=o;for(int i=10;i>0;)
{var c=a.Contains(i);x=(c?" ":"(.,.) ")+x;y=(c?"_____ ":
"( : ) ")+y;if(i==7|i<5&i--!=3){o+=$"{z}{x}\n{z}{y}\n";x=y="";
z+=" ";}}return o;}

expanded

string S(int[] a)
{
 string o = "", x = o, y = o, z= o;
 for (int i = 10; i > 0;)
 {
 var c = a.Contains(i);
 x = (c ? " " : "(.,.) ") + x;
 y = (c ? "_____ " : "( : ) ") + y;
 if (i==7|i<5&i--!=3)
 {
 o += $"{z}{x}\n{z}{y}\n";
 x = y = "";
 z += " ";
 }
 }
 return o;
}

knocked off a few bytes by suggestions in comments from Ghost, raznagul and auhmaan.

answered Dec 21, 2016 at 20:47
\$\endgroup\$
6
  • 2
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ Commented Dec 21, 2016 at 21:02
  • \$\begingroup\$ nice! You can save a few bytes (5?) if you put the i-- in the for and change new[]{7,4,2,1}.Contains(i--) to i<9&&i%3==1||i==2 \$\endgroup\$ Commented Dec 22, 2016 at 2:23
  • \$\begingroup\$ Can improve that by two more (for -7) with i==7||i<5&&i!=3 \$\endgroup\$ Commented Dec 22, 2016 at 3:32
  • \$\begingroup\$ @Ghost thanks! knocked it down a bit more by using non-shortcurcuit ors and ands, and still decrementing with the final ref to i i==7|i<5&i--!=3 \$\endgroup\$ Commented Dec 22, 2016 at 10:47
  • \$\begingroup\$ You can save some bytes by replacing var o="";var x=... by string o="",x="".... \$\endgroup\$ Commented Dec 22, 2016 at 11:19
5
\$\begingroup\$

Batch, 262 bytes

@echo off
for /l %%i in (1,1,10)do set s%%i=( : ) 
for %%i in (%*)do set s%%i=_____ 
set l=call:l 
%l%%s7%%s8%%s9%%s10%
%l%" %s4%%s5%%s6%
%l%" %s2%%s3%
%l%" %s1%
exit/b
:l
set s=%~1
set s=%s:( : )=(.,.)%
echo(%s:_____= %
echo(%~1

Note: Lines 2, 3 and 4 end in a space, and also outputs a trailing space on each line. These can be removed at a cost of 5 bytes. Works by creating variables s1...s10 as the bottom halves of the snowmen, then flattening the ones given as command-line arguments. The appropriate rows are printed twice, the first time with the bottom halves replaced with the top halves. This saves 18 bytes over using two sets of top and bottom half variables.

answered Dec 21, 2016 at 21:33
\$\endgroup\$
1
  • 1
    \$\begingroup\$ That's a slick answer. \$\endgroup\$ Commented Dec 21, 2016 at 21:40
4
\$\begingroup\$

JavaScript, (削除) 154 (削除ここまで) 149 bytes

f=
a=>`6 7 8 9
_3 4 5
__1 2
___0
`[r='replace'](/\d|_/g,m=>++m?~a.indexOf(m)?'_____':'( : )':' ')[r](/.*\n?/g,m=>m[r](/ : |_/g,s=>s=='_'?' ':'.,.')+m)
I.oninput=()=>O.innerHTML=f(JSON.parse(`[${I.value.match(/\d+/g)}]`))
I.oninput()
<input id=I value="1 3 5 6 9 10"><pre id=O>

answered Dec 21, 2016 at 19:55
\$\endgroup\$
3
\$\begingroup\$

Pyth, 63 bytes

j.ejm+**3k;j;db)_CcR[1 3 6).e:*T]btMQ@m*T]*5d,d\_kc2"(.,.)( : )

A program that takes input of a list of integers and prints the result.

Test suite

[Explanation coming later]

answered Dec 21, 2016 at 20:11
\$\endgroup\$
3
\$\begingroup\$

Pyth, 51 bytes

The code contains some unprintables, so here is an xxd hexdump.

00000000: 6a6d 2e5b 3233 5f6a 3b6d 4063 323f 7d6b jm.[23_j;m@c2?}k
00000010: 5172 2235 2035 5f22 392e 2220 3b5b 8db2 Qr"5 5_"9." ;[..
00000020: 1778 a822 6472 4673 4d50 4253 2d34 2f64 .x."drFsMPBS-4/d
00000030: 323b 38 2;8

Try it online.

Without unprintables, 52 bytes

jm.[23_j;m@c2?}kQr"5 5_"9").,.() : ("drFsMPBS-4/d2;8

Try it online.

answered Dec 21, 2016 at 21:43
\$\endgroup\$
2
\$\begingroup\$

Javascript (削除) 178 (削除ここまで) 169 bytes

Essentially a port from my C# answer.

Takes an int array as the list of flattened "pins";

f=a=>{o=x=y=z="";for(i=10;i>0;){c=a.includes(i);x=(c?" ":"(.,.) ")+x;y=(c?"_____ ":"( : ) ")+y;if(i==7|i<5&i--!=3){o+=z+x+"\n"+z+y+"\n";x=y="";z+= " ";}}return o}

Wrapped:

f=a=>{o=x=y=z="";for(i=10;i>0;){c=a.includes(i);
x=(c?" ":"(.,.) ")+x;y=(c?"_____ ":"( : ) ")+y;
if(i==7|i<5&i--!=3){o+=z+x+"\n"+z+y+"\n";x=y="";
z+= " ";}}return o}

Expanded & Explained:

// function f takes parameter a (an array of ints) 
f = a => {
 
 // four strings:
 // o: output
 // x: top row of snowmen
 // y: bottom row of snowmen
 // z: padding to indent the snowmen
 o = x = y = z = "";
 // loop from 10 to 1 (the pins)
 // remove the "afterthought" decrement - we can do that later
 for (i = 10; i > 0;) {
 // set the boolean c to whether the current pin has been flattened
 c = a.includes(i);
 // prefix x and y with the appropriate "sprite"
 // using a ternary if on c
 x = (c ? " " : "(.,.) ") + x;
 y = (c ? "_____ " : "( : ) ") + y;
 // determine if we've reached the end of a row (i equals 7, 4, 2 or 1)
 // use non shortcircuit operators to save bytes and ensure we hit the final i, because...
 // we also decrement i here 
 // (we didn't do this in the for loop declaration to save a byte)
 if (i == 7 | i < 5 & i-- != 3) {
 // concatenate our rows x & y,
 // prefixing them with the padding z,
 // postfixing them with a newline
 o += z + x + "\n" + z + y + "\n";
 
 // reset x and y rows
 x = y = "";
 
 // increase our padding for next time
 z += " ";
 }
 }
 
 // return our final string (no semicolon to save a byte)
 return o
}
answered Dec 22, 2016 at 11:09
\$\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.