(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
1to10in 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 code-golf 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
(.,.)
( : ) _____ _____ _____
_____ _____ _____
_____ _____
_____
-
18\$\begingroup\$ Code golf? Not code bowling? \$\endgroup\$Mark– Mark2016年12月22日 05:44:42 +00:00Commented 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\$Teal pelican– Teal pelican2016年12月22日 12:08:16 +00:00Commented Dec 22, 2016 at 12:08
-
\$\begingroup\$ Perfect :D it allows me to make an easier attempt in ><> \$\endgroup\$Teal pelican– Teal pelican2016年12月22日 13:56:05 +00:00Commented Dec 22, 2016 at 13:56
-
4\$\begingroup\$ I do not approve of flattening snowmen. \$\endgroup\$user18932– user189322016年12月22日 16:16:11 +00:00Commented Dec 22, 2016 at 16:16
-
\$\begingroup\$ i identify myself as a snowman and find this flattening. \$\endgroup\$conquistador– conquistador2016年12月23日 14:17:49 +00:00Commented Dec 23, 2016 at 14:17
10 Answers 10
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*))
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
-
17\$\begingroup\$ Pretty much the only context that this will be known as "the perfect language", :P \$\endgroup\$DJMcMayhem– DJMcMayhem2016年12月21日 18:30:32 +00:00Commented Dec 21, 2016 at 18:30
-
3\$\begingroup\$ A snowman killing his own kind... You monster! \$\endgroup\$user60199– user601992016年12月22日 19:45:14 +00:00Commented Dec 22, 2016 at 19:45
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:
(.,.) (.,.) (.,.)
( : ) ( : ) ( : ) _____
(.,.)
_____ ( : ) _____
_____ _____
_____
-
\$\begingroup\$ This language looks great. The Fisher-Yates example in the wiki is beautiful. \$\endgroup\$Jordan– Jordan2016年12月21日 18:58:29 +00:00Commented Dec 21, 2016 at 18:58
-
\$\begingroup\$ @Jordan thank you so much! that means a lot to me :) \$\endgroup\$Conor O'Brien– Conor O'Brien2016年12月21日 19:07:18 +00:00Commented Dec 21, 2016 at 19:07
05AB1E, (削除) 45 (削除ここまで) 44 bytes
TF"(.,.)( : )"„ _×ばつ{«4ä2ä1N>åè})4L£Rvyø»}».c
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
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
Takes input as a list of integers. Way too big at 248 but it works.
-
\$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$PurkkaKoodari– PurkkaKoodari2016年12月22日 00:30:10 +00:00Commented Dec 22, 2016 at 0:30
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.
-
2\$\begingroup\$ Welcome to PPCG! \$\endgroup\$AdmBorkBork– AdmBorkBork2016年12月21日 21:02:48 +00:00Commented 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--)toi<9&&i%3==1||i==2\$\endgroup\$Ghost– Ghost2016年12月22日 02:23:55 +00:00Commented Dec 22, 2016 at 2:23 -
\$\begingroup\$ Can improve that by two more (for -7) with
i==7||i<5&&i!=3\$\endgroup\$Ghost– Ghost2016年12月22日 03:32:32 +00:00Commented 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\$Erresen– Erresen2016年12月22日 10:47:43 +00:00Commented Dec 22, 2016 at 10:47 -
\$\begingroup\$ You can save some bytes by replacing
var o="";var x=...bystring o="",x="".... \$\endgroup\$raznagul– raznagul2016年12月22日 11:19:27 +00:00Commented Dec 22, 2016 at 11:19
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.
-
1\$\begingroup\$ That's a slick answer. \$\endgroup\$AdmBorkBork– AdmBorkBork2016年12月21日 21:40:41 +00:00Commented Dec 21, 2016 at 21:40
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>
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.
[Explanation coming later]
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
Without unprintables, 52 bytes
jm.[23_j;m@c2?}kQr"5 5_"9").,.() : ("drFsMPBS-4/d2;8
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
}