Leaping Kangaroos

36

1

Backstory

Disclaimer: May contain made up information about kangaroos.

Kangaroos traverse several stages of development. As they grow older and stronger, they can jump higher and longer, and they can jump more times before they get hungry.

In stage 1, the kangaroo is very little and cannot jump at all. Despite this, is constantly requires nourishment. We can represent a stage 1 kangaroo's activity pattern like this.

o

In stage 2, the kangaroo can make small jumps, but not more than 2 before it gets hungry. We can represent a stage 2 kangaroo's activity pattern like this.

 o o
o o o

After stage 2 the kangaroo improves quickly. In each subsequent stage, the kangaroo can jump a bit higher (1 unit in the graphical representation) and twice as many times. For example, a stage 3 kangaroo's activity pattern looks like this.

  o   o   o   o
 o o o o o o o o
o   o   o   o   o

For stage n, the activity pattern consists of 2n-1 V-shaped jumps of height n.

For example, for stage 4, there are 8 jumps of height 4.

   o     o     o     o     o     o     o     o
  o o   o o   o o   o o   o o   o o   o o   o o
 o   o o   o o   o o   o o   o o   o o   o o   o
o     o     o     o     o     o     o     o     o

Task

Write a full program or a function that takes a positive integer n as input and prints or returns the ASCII art representation of a stage n kangaroo's activity pattern.

Surrounding whitespace and ANSI escape codes are allowed, as long as the pattern looks exactly as depicted above.

If you choose a function that returns the output, it must return a single string or character array that displays the proper output when printed. Returning an array of strings is not allowed.

You can use any printable, non-whitespace character instead of o, as long as it is consistent within the activity pattern and across all patterns in your answer.

This is ; may the shortest answer in bytes win!

Dennis

Posted 2017-01-21T20:11:36.123

Reputation: 196 637

I need some clarification. You said you can use any character to represent o. Can you also use any character to represent the spaces (as long as they are different?)? – Kodos Johnson – 2017-01-23T01:09:05.007

1The spaces have to be blank. You can use actual spaces or you can use control codes to move the cursor around, but you cannot use printable non-space characters. – Dennis – 2017-01-23T01:24:57.703

1http://codegolf.stackexchange.com/questions/96379/compute-the-kangaroo-sequence - Related. – Magic Octopus Urn – 2017-01-23T17:59:56.467

Answers

8

05AB1E, 12 10 bytes

Îj¹FÐvû},À

Explanation:

Î              # Push zero and input
 j             # Prepend input - 1 spaces
  ¹F           # Input times do..
    Ð          #   Triplicate the string
     v }       #   Length times do..
      û        #     Palindromize
        ,      #   Pop and print with a newline
         À     #   Rotate the string on to the right

Uses the CP-1252 encoding. Try it online!

Adnan

Posted 2017-01-21T20:11:36.123

Reputation: 41 965

1Interesting, smarter than zip. – Magic Octopus Urn – 2017-01-23T18:26:55.793

14

MATLAB, 92 90 86 84 bytes

n=input('');p=eye(n)+32;A=repmat([fliplr(p),p,''],1,2^n/2);A(:,n+1:n:end)=[];disp(A)

Try it online!

eye creates an identity matrix. If we flip it and concatenate the original i.e. [fliplr(p),p] we get (for n=3):

0 0 1 1 0 0
0 1 0 0 1 0
1 0 0 0 0 1

With repmat(...,1,2^n/2) we repeat this 2^(n-1) times and get

0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0
0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 ...
1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1

From this we just delete the unnecessary columns, with A(:,n+1:n:end)=[];

flawr

Posted 2017-01-21T20:11:36.123

Reputation: 40 560

8Congrats on 20k!! – Luis Mendo – 2017-01-21T22:37:08.467

​​​​​​​​​​​​​​​Thank​​​​​​​​​​​​​​​ ​​​​​​​​​​​​​​​you​​​​​​​​​​​​​​​!​​​​​​​​​​​​​​​ – flawr – 2017-01-21T22:59:03.850

9

Charcoal, 14 bytes

NλP^×λoF⁻λ¹‖O→

Try it online!

Explanation

Nλ inputs an integer into λ. P^ is a multidirectional print (SE and SW) of ×λo (string multiplication of λ with o). Then F⁻λ¹ runs a for loop λ - 1 times, in which ‖O→ reflects the whole thing to the right with overlap.

DLosc

Posted 2017-01-21T20:11:36.123

Reputation: 21 213

"P^ is a multidirectional print (SE and SW)" Cool, that's something you don't see very often in programming languages! – Kevin Cruijssen – 2017-01-23T10:56:49.707

Just leaving this here – Bassdrop Cumberwubwubwub – 2017-01-24T12:36:16.373

7

Python 2, 87 bytes

n=input()
for i in range(n):print''.join(' o'[abs(j%(2*n)-n)==i]for j in range(1,n<<n))

Try it online!

Uses a formula for the coordinates (i,j) that contain a circle, then joins and prints the grid. There's a lot of golf smell here -- ''.join, two nested ranges, for over exec, so there's likely to be improvements.

xnor

Posted 2017-01-21T20:11:36.123

Reputation: 115 687

7

Python 2, 83 81 bytes

n=input()
i=0
exec"s=' '*n+'o'+' '*i;i+=1;print(s[i:-1]+s[:i:-1])*2**~-n+s[i];"*n

Try it online!

infmagic2047

Posted 2017-01-21T20:11:36.123

Reputation: 221

3Welcome to PPCG! Nice first post! – Rɪᴋᴇʀ – 2017-01-23T06:33:57.480

3

That's kind of an understatement; outgolfing xnor in Python is no small feat. I do see some room for improvement. A while loop should save a byte and the exec trick can save a few more.

– Dennis – 2017-01-23T17:42:06.160

5

Befunge, 98 91 bytes

This uses a , in place of the o, since that enables us to save a couple of bytes.

&::1>\1-:v
+\:v^*2\<_$\1-2*::!+00p*1
:-1_@v0\-g01:%g00:-1<:\p01
 ,:^ >0g10g--*!3g,:#^_$\55+

Try it online!

Explanation

Given the stage number, n, we start by calculating the following three parameters of the pattern:

jump_count = 2 ^ (n - 1)
jump_len   = (n - 1) * 2
width      = (jump_len * jump_count) + 1

The jump_len is normalised to avoid it being zero for a stage 1 kangaroo with:

jump_len += !jumplen    

We can then output the jump pattern by iterating over the x and y coordinates of the output area, and calculating the appropriate charater to output for each location. The y coordinate counts down from n - 1 to 0, and the x coordinate counts down from width - 1 to 0. We determine whether a dot needs to be shown with the following formula:

jump_off = x % jump_len
show_dot = (jump_off == y) or (jump_off == (jump_len-y))

The show_dot boolean is used as a table index to determine actual character to output at each location. To save on space, we use the start of the last line of source as that table, which is why our o character ends up being a ,.

James Holderness

Posted 2017-01-21T20:11:36.123

Reputation: 8 298

5

J, 28 25 bytes

' o'{~]_&(](|.,}.)"1)=@i.

Saved 3 bytes thanks to @Conor O'Brien.

This is based on the palindrome trick from @muddyfish's solution.

Try it online!

Explanation

' o'{~]_&(](|.,}.)"1)=@i.  Input: integer n
                       i.  Form the range [0, 1, ..., n-1]
                     =@    Equality table with itself.
                           Creates an identity matrix of order n
      ]                    Get n
       _&(          )      Repeat n times on x = identity matrix
           (     )"1         For each row
            |.                 Make a reversed copy
               }.              Get a copy with the head removed
              ,                Append them
          ]                  Use that as the new value of x
' o'{~                     Index into the char array

miles

Posted 2017-01-21T20:11:36.123

Reputation: 15 654

An alternate approach for 31 bytes: ' o'{~3 :'(}."1,.~|."1)^:y=i.y'. I wish I could find a way to remove that explicit verb... Darn ^:. – Conor O'Brien – 2017-01-23T17:31:18.113

@ConorO'Brien Thanks, that does help, I think it will be shorter if tacit – miles – 2017-01-23T17:56:08.947

@ConorO'Brien I made it tacit, it is indeed shorter! – miles – 2017-01-23T18:31:33.463

Awesome! This is pretty awesome. I keep forgetting the dyadic usage of u&v--quite nice. – Conor O'Brien – 2017-01-23T18:37:31.243

4

C#, 180, 173 171 bytes

Wont win this, posting for other C# contestants as something they can beat.

n=>{var s=new string[n];for(int a=-1,j=0,i,m=n-1,x=m;j<=m*(Math.Pow(2,n)*n+1);){i=j++%n;s[i]+=x==i?"o":"_";if(i==m&n>1){x+=a;a*=x%m==0?-1:1;}}return string.Join("\n",s);};

complete program:

using System;
public class P
{
    public static void Main()
    {
        Func<int, string> _ = n =>
        {
            var s = new string[n];
            for (int a = -1, j = 0, i, m = n - 1, x = m; j <= m * (Math.Pow(2, n) * n + 1);)
            {
                i = j++ % n;
                s[i] += x‌​ == i ? "o" : "_";
                if (i == m & n > 1)
                {
                    x += a;
                    a *= x % m == 0 ? -1 : 1;
                }
            }
            return string.Join("\n", s);
        };

        Console.Write(_(4));
        Console.ReadKey();
    }
}

edit: -7 bytes thanks to @KevinCruijssen

edit: -2 bytes, simplified if

CSharpie

Posted 2017-01-21T20:11:36.123

Reputation: 381

1+1 Some things to golf: The ints can be placed inside the for-loop, and you can also add ,i; you can reuse i instead of n-1 after the if-check; || can be |; j++ can be removed and ++ can be added to j. So in total: (n)=>{var s=new string[n];for(int x=0,a=1,j=0,i;j<=Math.Pow(2,n)*(n*n-n);){i=j++%n;s[n-i-1]+=x%n==i?'o':' ';if(i==n-1){x+=a;a*=x==i|x==0?-1:1;}}return string.Join("\n",s);}; (173 bytes) – Kevin Cruijssen – 2017-01-23T11:13:52.727

@KevinCruijssen Nice catch! I'll update once i'm back from work. – CSharpie – 2017-01-23T11:16:23.253

@KevinCruijssen I allready golfed out the || and && but kept then in the complete program. – CSharpie – 2017-01-23T16:27:45.340

4

Pyke, 11 bytes

XFd*\o+Q^Vs

Try it here!

 F          -  for i in range(input)
  d*\o+     -     " "*i+"o"
       Q^   -    ^.lpad(input)
         Vs -   repeat len(^): palindromise()
X           - print(reversed(^))

Blue

Posted 2017-01-21T20:11:36.123

Reputation: 26 661

4

Haskell, 100 bytes

k 1="o"
k n|n<-n-1,m<-n*2=unlines[[last$' ':['o'|mod c m`elem`[m-r,r]]|c<-[0..m*2^n]]|r<-[n,n-1..0]]

Try it online! Usage: k 3.

Explanation:

Given a row r, a column c and m = 2(n-1) an o is set if c mod m equals r or m-r. The outermost list comprehension sets the range of r from n-1 to 0, the next one sets the range of c from 0 to m*2^(n-1) and the innermost acts as conditional returning 'o' if the above formula is fulfilled and ' ' otherwise. This yields a list of strings which is turned into a single newline separated string by unlines. For n=1 the function produces a division-by-zero error, so this case is handled explicitly in the first line.

Laikoni

Posted 2017-01-21T20:11:36.123

Reputation: 23 676

I really like the ['o'|mod c m\elem`[m-r,r]]` part! – flawr – 2017-01-22T12:41:05.390

3

J, 58 47 bytes

' o'{&:>~[:(,.}."1)&.>/(2^<:)#<@(|.,.}."1)@=@i.

Saved 11 bytes using the identity matrix idea from @flawr's solution.

Try it online!

A straightforward application of the definition.

Explanation

For n = 3, creates the identity matrix of order n.

1 0 0
0 1 0
0 0 1

Then mirror it to make

0 0 1 0 0
0 1 0 1 0
1 0 0 0 1

Repeat that 2n-1 times and drop the head of each row on the duplicates

0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1

Use those values as indices into the char array [' ', 'o'] to output a 2d char array

  o   o   o   o  
 o o o o o o o o 
o   o   o   o   o

miles

Posted 2017-01-21T20:11:36.123

Reputation: 15 654

3

Python 2, 115 113 108 98 bytes

lambda n:'\n'.join(map(''.join,zip(*[' '*abs(i)+'o'+~-n*' 'for i in range(-n+1,n-1)*2**~-n])))+'o'

Try it online!

Using range(-n+1,n-1) to create the absolute number of spaces between the bottom and the o to generate

  o
 o
o
 o

and then appending more copies, rotating 90º everything and appending the last o at bottom right

Rod

Posted 2017-01-21T20:11:36.123

Reputation: 17 588

3

Pyth, 30 bytes

jC.<V*]+*dtQNh*tQ^2Q*+JUQtP_J^

A program that takes input of an integer and prints the result. Uses a quote mark " instead of o.

Try it online!

How it works

jC.<V*]+*dtQNh*tQ^2Q*+JUQtP_J^    Program. Input: Q
jC.<V*]+*dtQNh*tQ^2Q*+JUQtP_J^QQ  Implicit input fill
      ]                           Yield a one-element list, A
        *dtQ                      cotaining Q-1 spaces
       +    N                     appended with a quote mark.
             h*tQ^2Q              Yield 1+(Q-1)*2^Q
     *                            Repeat A that many times, giving B
                       UQ         Yield [0, 1, 2, ..., Q-1]
                      J           (Store that in J)
                     +   tP_J     Append the reverse of J, discarding the first and last
                                  elements
                    *        ^QQ  Repeat the above Q^Q times, giving C
    V                             Vectorised map. For each pair [a,b] from B and C:
  .<                               Cyclically rotate a left by b characters
 C                                Transpose
j                                 Join on newlines
                                  Implicitly print

TheBikingViking

Posted 2017-01-21T20:11:36.123

Reputation: 3 674

3

JavaScript (ES6), 83 bytes

f=
n=>` `.repeat(n).replace(/ /g,"$'o$`-$`o$'-".repeat(1<<n-1)+`
`).replace(/-.?/g,``)
<input type=number min=1 oninput=o.textContent=f(this.value)><pre id=o>

Neil

Posted 2017-01-21T20:11:36.123

Reputation: 95 035

3

Jelly, 11 bytes

ŒḄ¡ḶUz1Ṛa⁶Y

TryItOnline!

How?

The printable character used is 0.

Builds upon the method of Dennis's answer to his previous question on the subject of kangaroos.

ŒḄ¡ḶUz1Ṛa⁶Y - Main link: n                      e.g. 3
ŒḄ          - bounce, initial implicit range(n) e.g. [1,2,3,2,1]
  ¡         - repeat n times                    e.g. [1,2,3,2,1,2,3,2,1,2,3,2,1,2,3,2,1]
                  i.e. [1,2,3,2,1] bounced to [1,2,3,2,1,2,3,2,1] bounced to [1,2,3,2,1,2,3,2,1,2,3,2,1,2,3,2,1]
   Ḷ        - lowered range (vectorises)        e.g. [[0],[0,1],[0,1,2],[0,1],[0],[0,1],[0,1,2],[0,1],[0],[0,1],[0,1,2],[0,1],[0],[0,1],[0,1,2],[0,1],[0]]
    U       - upend (vectorises)                e.g. [[0],[1,0],[2,1,0],[1,0],[0],[1,0],[2,1,0],[1,0],[0],[1,0],[2,1,0],[1,0],[0],[1,0],[2,1,0],[1,0],[0]]
     z1     - transpose with filler 1
       Ṛ    - ...and reverse                    e.g. [[1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1],
                                                      [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1],
                                                      [0,1,2,1,0,1,2,1,0,1,2,1,0,1,2,1,0]]
        a⁶  - logical and with space character (all non-zeros become spaces)
          Y - join with line feeds              e.g.    0   0   0   0  
                                                       0 0 0 0 0 0 0 0 
                                                      0   0   0   0   0

Jonathan Allan

Posted 2017-01-21T20:11:36.123

Reputation: 67 804

2Nice. This ties with my reference solution, ŒḄ¡Ṭ€z0o⁶ṚY. – Dennis – 2017-01-22T05:04:57.720

3

MATL, 27 bytes

XyPt3LZ)2&Pht4LZ)lGqX"h48*c

Try it out at MATL Online

Suever

Posted 2017-01-21T20:11:36.123

Reputation: 10 257

2

Perl 6, 104 93 88 bytes

->\n{my @a;@a[$_;$++]="o" for [...] |(n-1,0,n-1)xx 2**n/2;say .join for @a».&{$_//" "}}

Inserts o's into a 2D array, and then prints it.

smls

Posted 2017-01-21T20:11:36.123

Reputation: 4 352

2

Python 3, 177 bytes

n=5;f=n-1;w=''
for i in range(n):
 s='';a=0;d='\n'
 if i==f:w='';a=-1;d=''
 for _ in range(2**f):
  s+=' '*(f-i)+'o'+' '*(2*i-1)+w+' '*(n-i-2+a)
 print(s,end=d);w='o'
print('o')

Try it online!

Henke

Posted 2017-01-21T20:11:36.123

Reputation: 41

2

05AB1E, 16 bytes

L<¹Fû}ð×'o«.BøR»

Try it online!

Why and how?

                 # Example input of n=2.
L<               # [0,1] (Push [1..a], decrement).
  ¹Fû}           # [0,1,0,1,0] (Palindromize n times).
      ð×'o«      # ['o',' o','o',' o','o'] (Push n spaces, append o's).
           .Bø   # ['o ',' o','o ',' o','o '] (Pad with spaces into 2D array, transpose).
              R» # Reverse, join and print.

Magic Octopus Urn

Posted 2017-01-21T20:11:36.123

Reputation: 19 422

1

Java 8, 254 bytes

Golfed:

n->{if(n==1)return"o";int k,x,y,m=n+n-2;char[][]p=new char[n][m];for(y=0;y<n;++y)for(x=0;x<m;)p[y][x++]=' ';for(k=0;k<m;++k)p[k<n?n-k-1:k-n+1][k]='o';String s="";for(y=0;y<n;++y){for(k=0;k<1<<(n-1);++k)for(x=0;x<m;)s+=p[y][x++];if(y==n-1)s+='o';s+='\n';}

Ungolfed:

import java.util.function.*;

public class LeapingKangaroos {

  public static void main(final String[] args) {
    for (int i = 1; i <= 4; ++i) {
      System.out.println(toString(n -> {
        if (n == 1) {
          return "o";
        }
        int k, x, y, m = (n + n) - 2;
        char[][] p = new char[n][m];
        for (y = 0; y < n; ++y) {
          for (x = 0; x < m;) {
            p[y][x++] = ' ';
          }
        }
        for (k = 0; k < m; ++k) {
          p[k < n ? n - k - 1 : (k - n) + 1][k] = 'o';
        }
        String s = "";
        for (y = 0; y < n; ++y) {
          for (k = 0; k < (1 << (n - 1)); ++k) {
            for (x = 0; x < m;) {
              s += p[y][x++];
            }
          }
          if (y == (n - 1)) {
            s += 'o';
          }
          s += '\n';
        }
        return s;
      } , i));
      System.out.println();
      System.out.println();
    }
  }

  private static String toString(final IntFunction<String> func, final int level) {
    return func.apply(level);
  }

}

Program output:

o

 o o
o o o


  o   o   o   o 
 o o o o o o o o
o   o   o   o   o


   o     o     o     o     o     o     o     o  
  o o   o o   o o   o o   o o   o o   o o   o o 
 o   o o   o o   o o   o o   o o   o o   o o   o
o     o     o     o     o     o     o     o     o

user18932

Posted 2017-01-21T20:11:36.123

Reputation:

0

PHP, 157 bytes

for($i=$n=$argv[1],$r=str_repeat;$i>0;)echo$r($r(' ',$i-1).'o'.$r(' ',2*$n-2*$i-1).($i==$n|$i==1?'':'o').$r(' ',$i-2),2**($n-1)).($i--==1&$n!=1?'o':'')."\n";

Ungolfed:

for($i=$n=$argv[1];$i>0;) {

    // Spacing from beginning of pattern to first 'o'   
    $o  = str_repeat(' ',$i-1); 

    // First 'o' for the ascent
    $o .= 'o'; 

    // Spacing between ascent and descent
    $o .= str_repeat(' ',2*$n-2*$i-1); 

    // Second 'o' for the descent, unless we are at the apex or the bottom
    $o .= ($i==$n|$i==1?'':'o'); 

    // Spacing to the end of the pattern
    $o .= str_repeat(' ',$i-2); 

    // Repeat the pattern 2^(n-1) times
    echo str_repeat($o, 2**($n-1)); 

    // Output final 'o' if we are at the bottom in the last pattern
    echo $i--==1&$n!=1?'o':''; 

    // End of line 
    echo "\n"; 

}

Kodos Johnson

Posted 2017-01-21T20:11:36.123

Reputation: 776

You can replace every 'o' with 1 and every '' with 0. Hope that works, Also, the spaces can be replaced by O or 9. The important is the pattern, according to the rules. But verify first – Ismael Miguel – 2017-01-23T00:44:41.227