11
\$\begingroup\$

Most people are familiar with the trope about counting sheep to fall asleep. There's a herd of sheep, some of them jumping over a fence, and you count the sheep as they jump. Supposedly, this helps quiet your mind and gets you into a sleep-like state so that you'll fall asleep.

Here's an ASCII sheep facing to the right, waiting to be counted:

'00^>
 ||

Here's an ASCII sheep jumping over a fence:

'00^>
 /\
 ++

Here's one facing to the left, having already been counted:

<^00'
  ||

The Challenge

Given two input integers, n and m, with n > 2 describing how many sheep total, and m > 0 saying how many sheep have already been counted, output an ASCII art representation of counting sheep to fall asleep.

Now for the twist:

  • Due to the size of the pens the sheep are in, the top row can only hold a maximum of 10 sheep, not counting the currently jumping sheep which must also always be in the top row.
  • The subsequent rows cannot have the sheep outside their respective pens (you can't have more sheep on the left in the second row than you do in the first row, and same for the right).
  • If there are 11 or more total sheep, the top row must have 10 plus the jumping sheep in it.
  • Leading/trailing whitespace, and whitespace between the sheep doesn't matter, so long as:
    1. There is a minimum of one whitespace character between sheep
    2. All the characters line up appropriately.

So long as these rules are met, the actual arrangement of the sheep is up to your implementation.

Examples

For example, here is n=3 and m=1, the simplest case.

         '00^>
'00^>     /\      <^00'
 ||       ++        ||

Here is n=11 and m=6, the most sheep that can fit on one horizontal line.

                        '00^>
'00^> '00^> '00^> '00^>  /\   <^00' <^00' <^00' <^00' <^00' <^00'
 ||    ||    ||    ||    ++     ||    ||    ||    ||    ||    ||

Here's a different example of that, with n=11 and m=1

                                                      '00^>
'00^> '00^> '00^> '00^> '00^> '00^> '00^> '00^> '00^>  /\   <^00'
 ||    ||    ||    ||    ||    ||    ||    ||    ||    ++     || 

A bigger example with n=30 and m=12

                                                '00^>
'00^> '00^> '00^> '00^> '00^> '00^> '00^> '00^>  /\   <^00' <^00'
 ||    ||    ||    ||    ||    ||    ||    ||    ++     ||    || 

'00^> '00^> '00^> '00^> '00^> '00^> '00^> '00^>       <^00' <^00'
 ||    ||    ||    ||    ||    ||    ||    ||           ||    || 

'00^>                                                 <^00' <^00'
 ||                                                     ||    || 

                                                      <^00' <^00'
                                                        ||    || 

                                                      <^00' <^00'
                                                        ||    || 

                                                      <^00' <^00'
                                                        ||    || 

Here's an example with n=17 and m=2

                                                '00^>
'00^> '00^> '00^> '00^> '00^> '00^> '00^> '00^>  /\   <^00' <^00'
 ||    ||    ||    ||    ||    ||    ||    ||    ++     ||    ||

'00^> '00^> '00^> '00^> '00^> '00^>
 ||    ||    ||    ||    ||    ||  

Here's an example with n=19 and m=3

                                          '00^>
'00^> '00^> '00^> '00^> '00^> '00^> '00^>  /\   <^00' <^00' <^00'
 ||    ||    ||    ||    ||    ||    ||    ++     ||    ||    || 

'00^> '00^> '00^> '00^> '00^> '00^> '00^>
 ||    ||    ||    ||    ||    ||    ||  

'00^>
 ||  

Note that all of these are examples. For the last one, you may wind up creating a vertical array of sheep on the right-hand side, which will allow the left hand side to fit onto two rows instead. Or maybe a 2x2 square of sheep on the right-hand side, which would also fit the left-hand side sheep onto two rows. Etc.

I/O and Rules

  • Input can be taken in any reasonable format and by any convenient method.
  • Leading/trailing newlines or other whitespace are optional, provided that the characters line up appropriately.
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • Output can be to the console, returned as a list of strings, returned as a single string, etc.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.
\$\endgroup\$
9
  • 2
    \$\begingroup\$ @Rod I added a bigger example, but note that it's only an example and your output could be different. \$\endgroup\$ Commented Feb 28, 2018 at 14:50
  • \$\begingroup\$ Related. \$\endgroup\$
    – Mr. Xcoder
    Commented Feb 28, 2018 at 15:29
  • \$\begingroup\$ Recommended test case: n=11 and m=9 \$\endgroup\$
    – Adám
    Commented Feb 28, 2018 at 16:08
  • \$\begingroup\$ @Adám There can be 10 test cases for n=11 such that 0<m<=10. This forces you to have all the sheep on the top row and a dynamic number of sheep on the left (n-1-m) and right (m) of the fence and cannot use fixed pen sizes. \$\endgroup\$
    – MT0
    Commented Feb 28, 2018 at 16:15
  • \$\begingroup\$ @MT0 True, but one or two test cases should be enough to show that a solution works. \$\endgroup\$
    – Adám
    Commented Feb 28, 2018 at 16:16

6 Answers 6

9
\$\begingroup\$

APL (Dyalog Unicode), 118 bytesSBCS

Anonymous infix lambda. Takes n as left argument and m as right argument. Returns a nested array result, but the default display of this nested array follows specifications. Uses up to nine columns for counted sheep and remaining columns for waiting sheep.

{(r⍴(×/r←d,⍨⌈w÷d←10-⍵⌊⊢/r)↑w⍴(w←⍺-⍵+1)⍴⊂s@2⌽S)(↑(s←'>',⍨¯1↓b)' /\' ' ++')(r⍴(×/r←9,⍨⌈⍵÷9)↑⍵⍴⊂S←⌽↑''(b←'''00^<')' ||')}

Try it online!

{} anonymous lambda; is left argument, is right argument

This function has three distinct parts: Waiting, Jumping, and Counted. Each one is parenthesised, causing the result to be a three-element list.

Counted (r⍴(×/r←9,⍨∘⌈⍵÷9)↑⍵⍴⊂S←⌽↑''(b←'''00^<')' ||')

''()' ||' the three lines of a mirrored counted sheep, the middle one being:

b←'''00^<' the body and is assigned to b

 mix the list of strings into a character matrix (padding with spaces)

 mirror that

S← assign to S (big Sheep)

 enclose it so we can deal with it as a unit

⍵⍴ use the number of counted sheep to cyclically reshape that

()↑ take the following number of elements from that (padding with prototypical items, i.e. the same array but with all characters replaced by spaces)

⍵÷9 a ninth of the number of counted sheep

 round up

9,⍨ append 9 to that

r← assign to r (what we will reshape with; rows and columns)

×/ product of that list (this is how many elements we need, including fills)

r⍴ reshape that to an array with the dimension lengths r

Jumping (↑(s←'>',⍨¯1↓b)' /\' ' ++')

()' /\' ' ++' the three lines of a jumping sheep, the first one being:

¯1↓b drop the last character from b

'>',⍨ append a right-facing head

s← store in s (small sheep)

 mix the list of strings into a character matrix (padding with spaces)

Waiting (r⍴(×/r←d,⍨⌈w÷d←10-⍵⌊⊢/r)↑w⍴(w←⍺-⍵+1)⍴⊂s@2⌽S)

⌽S mirror S

s@2 put s at line 2 of that (replacing the current data there)

 enclose it so we can deal with it as a unit

()⍴ cyclically reshape that to the following size:

⍵+1 the number of counted sheep plus one

⍺- subtract that from the total

w← assign to w (waiting)

()↑ take the following number of elements from that (padding with prototypical items)

⊢/r the rightmost element of r (i.e. the number of used columns for counted sheep)

⍵⌊ the minimum of total and that

10- subtract that from ten

d← assign to d (difference; missing columns)

 divide w by that

 round up (gives number of needed rows)

d,⍨ append d

r← assign to r (what we will reshape with; rows and columns)

×/ product of that list (this is how many elements we need, including fills)

r⍴ reshape that to an array with the dimension lengths r

\$\endgroup\$
4
  • 1
    \$\begingroup\$ @WeijunZhou You're right, will fix. \$\endgroup\$
    – Adám
    Commented Feb 28, 2018 at 15:20
  • 1
    \$\begingroup\$ I was wondering how the heck I would answer this challenge. I guess that's how :p \$\endgroup\$
    – J. Sallé
    Commented Feb 28, 2018 at 15:26
  • 1
    \$\begingroup\$ @WeijunZhou Fixed. \$\endgroup\$
    – Adám
    Commented Feb 28, 2018 at 15:31
  • \$\begingroup\$ "Always reserves nine columns for waiting sheep and a single column for counted sheep." Does this work for n=11,m=9 and the rule "the top row must have 10 plus the jumping sheep in it."? \$\endgroup\$
    – MT0
    Commented Feb 28, 2018 at 16:05
3
\$\begingroup\$

Javascript, 281, 293, 288 Bytes

a="      ";c=((n,m)=>{b="";for(i=0;i<(q=m>(o=(l=(t=n-m-1)?t:0)/9)?m:o);++i){for(j=0;j<3;++j){b+=[a,"'00^> "," ||   "][j].repeat(r=l>i*9?(z=o-i)>1?9:Math.ceil(z*9):0)+a.repeat((l>9?9:l)-r)+(i?"     ":["'00^>"," /\\  "," ++  "][j])+[a," <^00'","   || "][j].repeat(m>i?1:0)+"\n"}}return b});

Be careful when using the below snippet, there's a heavy risk of sudden induced narcolepsy.

  <form id="form">
    <input type="text" name="n" placeholder="n (sheep total)">
    <input type="text" name="m" placeholder="m (sheep in right hand field)">
    <button type="submit">Let's Go!</button>    
  </form>

  <pre id="output">
  </pre>

  <script>
    a="      ";c=((n,m)=>{b="";for(i=0;i<(q=m>(o=(l=(t=n-m-1)?t:0)/9)?m:o);++i){for(j=0;j<3;++j){b+=[a,"'00^> "," ||   "][j].repeat(r=l>i*9?(z=o-i)>1?9:Math.ceil(z*9):0)+a.repeat((l>9?9:l)-r)+(i?"     ":["'00^>"," /\\  "," ++  "][j])+[a," <^00'","   || "][j].repeat(m>i?1:0)+"\n"}}return b});
      form.addEventListener("submit", function(e){
        e.preventDefault();
  
        var n = parseInt(form.n.value);
        var m = parseInt(form.m.value);
  
        if(n != NaN && m != NaN){
          if(m > n){
            output.innerText = "C'mon man, how can you have more sheep in the right hand field than there are sheep in general?";
          }
          else{
            output.innerText = c(n, m);
          }
        }
        else{
          output.innerText = "Numbers only please.";
        }
      });
    </script>

\$\endgroup\$
4
  • 2
    \$\begingroup\$ This shows 4 counted sheep for n=50, m=3 and also has misaligned sheep for n=20, m=3. Also n=20, m=1 shows 2 counted sheep. \$\endgroup\$
    – ale10ander
    Commented Mar 1, 2018 at 0:11
  • 2
    \$\begingroup\$ Fixed those errors. Also found some sheep were escaping due to rounding errors. \$\endgroup\$
    – Jhal
    Commented Mar 1, 2018 at 10:46
  • \$\begingroup\$ If m = n you get an error. \$\endgroup\$
    – aimorris
    Commented Mar 1, 2018 at 21:03
  • \$\begingroup\$ This is a scenario that i assumed could be ignored. The way the question was written stated that: m = The count of sheep on the right hand side n = The count of sheep in total And that there's a sheep also jumping the fence. Therefore n cannot be equal to m, i therefore didn't account for it. \$\endgroup\$
    – Jhal
    Commented Mar 1, 2018 at 21:40
2
\$\begingroup\$

C, 392 bytes

Thanks to @Jonathan Frech for saving a byte!

#define F;for(
x,y,k;p(L,a,b,t)char L[][78];{F k=5;k--;)L[x=a*4+(t<2)][y=b*6+k]=t?"'00^>"[k]:"<^00'"[k];L[++x][y-=~!t]=47;L[x][++y]=92;L[x][--y]=L[x+=(t>1)][y]=t<2?'|':43;}i,l;f(n,m){char L[i=n*4][78]F;i--;){F L[i][l=77]=0;l--;)L[i][l]=32;}F l=n+~m;++i<l&&i<9+!m;)p(L,0,i,1);l-=i;p(L,0,i++,2)F;i<11&&m--;)p(L,0,i++,0)F i=0;l--;)p(L,++i,0,1)F i=1;m-->0;)p(L,i++,10,0)F l=0;l<i*4;)puts(L+l++);}

Try it online!

Unrolled:

#define F;for(

x, y, k;
p(L, a, b, t) char L[][78];
{
    F k=5; k--;)
        L[x=a*4+(t<2)][y=b*6+k] = t ? "'00^>"[k] : "<^00'"[k];

    L[++x][y-=~!t] = 47;
    L[x][++y] = 92;
    L[x][--y] = L[x+=(t>1)][y] = t<2 ? '|' : 43;
}

i, l;
f(n, m)
{
    char L[i=n*4][78]
    F; i--;)
    {
        F L[i][l=77]=0; l--;)
            L[i][l] = 32;
    }

    F l=n+~m; ++i<l&&i<9+!m;)
        p(L,0,i,1);

    l-=i;
    p(L,0,i++,2)

    F; i<11&&m--;)
        p(L,0,i++,0)

    F i=0; l--;)
        p(L,++i,0,1)

    F i=1; m-->0;)
        p(L,i++,10,0)

    F l=0; l<i*4;)
        puts(L+l++);
}
\$\endgroup\$
2
  • \$\begingroup\$ y+=1+!t can be y-=~!t. \$\endgroup\$ Commented Feb 28, 2018 at 18:49
  • \$\begingroup\$ @JonathanFrech Yep, thanks! \$\endgroup\$
    – Steadybox
    Commented Feb 28, 2018 at 18:52
1
\$\begingroup\$

Python 2, 222 277 bytes

n,m=input();n-=m+1
s=" '00^>"
j=1;L='  ||  '
a,b=[[[5,5],[10-m,m]][m<9],[n,10-n]][n<9]
print' '*6*a+s
while n>0 or 0<m:N,M=min(n,a),min(m,b);n-=a;m-=b;print '%-*s'%(6*a,N*s),'%5s'%('/\  '*j)+'%*s'%(6*b,M*" <^00'")+'\n'+'%*s'%(-6*a,N*L),'%5s'%('++  '*j),'%*s'%(6*b,M*L)+'\n';j=0

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Fails on n=11 and m=2. \$\endgroup\$
    – Adám
    Commented Mar 1, 2018 at 19:48
  • \$\begingroup\$ I don't get 11 sheep on the first row when I ran this. \$\endgroup\$ Commented Mar 1, 2018 at 21:49
  • 1
    \$\begingroup\$ @RobertBenson Thanks, fixed \$\endgroup\$
    – TFeld
    Commented Mar 2, 2018 at 8:15
0
\$\begingroup\$

AWK, 293 bytes

{f=" '00^>"
l="  ||  " 
L="  /\\   "
p="  ++   "
Y=$2
X=$1-Y-1
E="      "
x=$1>11?Y<5?10-Y:X>5?5:X:X
y=$1>11?X<5?10-X:5:Y
printf"%"6*(x+1)"s\n",f
for(;X>0||Y>0;A=B=""){for(i=0;i++<x;B=B (X>=0?l:E))A=A (--X>=0?f:E)
A=A L
B=B p
for(i=0;i++<y&&--Y>=0;B=B l)A=A"<^00' "
print A"\n"B"\n"
L=p=E" "}}

Try it online!

I tried using string substitutions to avoid some loops, but it took a lot more code.

Explanation

{f=" '00^>"    Let's assign
l="  ||  "     some variables
L="  /\\   "   for the ASCII
p="  ++   "    pieces
Y=$2        The number of sheep that have already jumped
X=$1-Y-1    Sheep patiently waiting to jump
E="      "  A string to keep things spaced properly
x=$1>11?Y<5?10-Y:X>5?5:X:X  If there's enough sheep, let's use 5 per column
y=$1>11?X<5?10-X:5:Y        Otherwise, use enough to get 11 sheep in first row
printf"%"6*(x+1)"s\n",f     Print the top part of the jumping sheep
for(;X>0||Y>0;A=B=""){      Loop until we've printed all the sheep
  for(i=0;i++<x;              Loop over waiting sheep in this row
    B=B (X>=0?l:E))             Build the "legs" string
      A=A (--X>=0?f:E)            Build the "bodies" string
  A=A L                       Add the legs and post 
  B=B p                       for the jumping sheep
  for(i=0;i++<y&&--Y>=0;   Loop over the jumped sheep in this row
    B=B l) A=A"<^00' "     Add to the "legs" and "bodies" string 
  print A"\n"B"\n"         Print what we've got so far
  L=p=E" "                 Prevent the jumping sheep's parts from printing lots of times
}}

I must say the sheep art is rather cute. :)

\$\endgroup\$
0
\$\begingroup\$

Charcoal, 98 bytes

Nθ≔⁻⊖NθηF⟦⟦00¶/\¶++ θ⌊⟦⌈⟦⁵⁻χη⟧θ⟧⟧⟦0^>¶\¶+  η⌊⟦⌈⟦⁵⁻χθ⟧η⟧⟧⟧«J⁰¦⁰‖T§ι⁰↗F§ι¹«<^00'¶  || ↗¿¬﹪⊕κ§ι²”|I4O

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

Nθ

Input the number of sheep that have already been counted.

≔⁻⊖Nθη

Input the total number of sheep and calculate how many still need to be counted.

F⟦⟦00¶/\¶++ θ⌊⟦⌈⟦⁵⁻χη⟧θ⟧⟧⟦0^>¶\¶+  η⌊⟦⌈⟦⁵⁻χθ⟧η⟧⟧⟧«

Create an array of two arrays. Each array has the following elements:

  • A string containing half of the jumping sheep
  • The number of sheep on that side of the fence
  • The number of sheep in one row on that side of the fence, which is either
    • the number of sheep on that side of the fence, if fewer than 5, or
    • 10 - the number of sheep on the other side of the fence, if fewer than 5, or
    • 5, if both sides have at least 5 sheep
J⁰¦⁰‖T§ι⁰↗

Reflect the canvas and print the half jumping sheep.

F§ι¹«

Loop through the sheep on that side.

<^00'¶  || ↗

Print a sheep.

¿¬﹪⊕κ§ι²”|I4O

If this is the end of the row then print some newlines and spaces to get to the start of the next sheep.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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