Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Simple problem: print an n by n box from a function.

A couple caveats:
 -You may not use any loops
 -The function must have exactly one parameter of type int (or the equivalent in your chosen language)
 -You may not partition data into this parameter (including switching it between negative and positive)
 -No global variables
 -The program must exit without an error
 -You may only use the following:
      Print a string (a single asterisk or, if needed, multiple (but must be hard-typed: e.g. print("**"); may also print a newline)
      If-then-else/switch statements
      Recursive calls
      Returning values (if needed: function may or may not return a value)
      (Local) Variable declaration/assignment/usage

Keep the spirit of the challenge, good luck!

(Preference given to most elegant/clever solution: not shortest code -- make it readable!)

share|improve this question
6  
-1 badly specified. What does an n x n box look like? What does "partition[ing] data" mean? What counts as a loop? What "usage" of a variable is permitted? – Peter Taylor Dec 13 '11 at 21:58
The problem with trivial questions is the answers tend to get out of hand. At least, I feel creative. – J B Dec 14 '11 at 0:30
@J B How many languages do you know? Haskell, Brainfuck, Unlambda, J, Logo, SQL, Lisp, sed... That's crazy! – FUZxxl Dec 14 '11 at 16:43
@FUZxxl I try not to count, it's hard to keep track of the variants and dialects. But then again, take a second look at the list, most of them anybody kind of knows. Hmmm, this reminds me of two or three I could sneak in here... – J B Dec 14 '11 at 16:55
1  
Lee: are we supposed to write only one function or more? I believe the former, but a clarification would be nice. – tzot Dec 15 '11 at 13:03
show 4 more comments

32 Answers

1 2

Logo

Definitely the right tool for the job.

TO BOX :n
  FD :n RT 90
  FD :n RT 90
  FD :n RT 90
  FD :n RT 90
END
share|improve this answer
+1 lol, you nailed it :) – jjmontes Dec 15 '11 at 1:06
+1 for choosing the right tool! – Chris Browne Jan 22 '12 at 18:19

Python

I'm pretty sure this follows all rules and completes all objectives.

def f(n):
    print "A %s by %s box"%(n,n)
share|improve this answer
1  
does not conform exactly: OP said "print an n by n box from a function" – jjmontes Dec 15 '11 at 1:10
+1 for the clever implementation that would leave me without a job. ;) – Alpha Dec 20 '11 at 1:34
Should be 'An' ;) – MrZander Jan 9 '12 at 19:47
3  
I disagreed with the choice of article in the spec. Most numbers start with consonants, so my implementation would be grammatical most of the time. – boothby Jan 17 '12 at 8:26
@boothby your choice is proper for all numbers not beginning pronounciation with 'eight' (all but {8, 18, 800, ...}). The OP's choice is proper, as 'n' is pronounced 'en'. – Darthfett Jun 14 '12 at 2:35
show 1 more comment

Brainfuck

That whole "function" concept is a bit far-fetched to me, but if you happen to leave n under the cursor, this program will print a few asterisks in a box conformation:

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

Plus, the program kinda looks like a box itself.

share|improve this answer
3  
Some would argue that any [] construct constitues a loop. Still +1 for masochism. – CMP Dec 15 '11 at 21:14
2  
Others would argue that Brainfuck isn't Turing-complete without them. Some would even go as far as saying that excluding a language from a CG.SE problem by limiting it to a subset of itself that provably can't solve said problem is, like, totally unfair. Cue endless flaming on meta. This submission was tongue-in-cheek. Or maybe it was this comment. – J B Dec 15 '11 at 23:35

SQL (Oracle syntax)

  • no loops
  • no functions (argument is to be replaced in first line)
  • no variables
  • recursive call with CONNECT BY

SQL is the language for the task.

WITH n AS (SELECT 10 FROM dual)
SELECT LPAD('*', (SELECT * FROM n), '*') FROM dual
CONNECT BY level <= (SELECT * FROM n);
share|improve this answer

Haskell

Haskell doesn't have loops. Only functions. Oh, and monads.

import Control.Monad
box n = replicateM_ n (putStrLn (replicate n '*'))
main = box 10
share|improve this answer
2  
BTW, you need replicateM_ to do this, since your code won't compile if main has a type different from IO (). – FUZxxl Dec 14 '11 at 17:55
@FUZxxl It compiled fine... but I only tested it in GHCi :D Fixing, thanks. – J B Dec 14 '11 at 22:15
I have to say, I am somewhat disappointed that my highest-voted answer in that page is (arguably) the most mainstream language of them all. The Unlambda one is a much better abuse of the rules, upvote that! The sed one required the most debugging, upvote that! The SQL one is the dirtiest, upvote that! – J B Dec 14 '11 at 22:21
Can be shorted using $ sugar instead parentheses. – Łukasz Niemier Dec 15 '11 at 18:09
1  
Point-free style in this instance would be very unreadable indeed :) – J B Dec 15 '11 at 23:31
show 2 more comments

Unlambda

I wasn't quite sure what counted as iteration or whether defining named functions counted against the global variables, so I picked Unlambda. This way, we're sure there'll be:

  • no if/then/else
  • no recursive calls
  • no variables at all
  • no functions of more than one parameter

The function takes one parameter of type int (encoded as a Church numeral).

``s``si``s`kd``s`kr``s``si`k.*`ki`ki

Ironically, it seems like this brings me the shortest answer as well, despite this not being a code golf :D

share|improve this answer

sed

Parameter is given on standard input. The last two lines are only needed to make multiple boxes possible in a single run; they're not necessary in one-shot mode.

:d
x
s/\(.*\)/\1\1\1\1\1\1\1\1\1\1/
x
/^1/ { x ; s/$/*/         ; x }
/^2/ { x ; s/$/**/        ; x }
/^3/ { x ; s/$/***/       ; x }
/^4/ { x ; s/$/****/      ; x }
/^5/ { x ; s/$/*****/     ; x }
/^6/ { x ; s/$/******/    ; x }
/^7/ { x ; s/$/*******/   ; x }
/^8/ { x ; s/$/********/  ; x }
/^9/ { x ; s/$/*********/ ; x }
s/.//
/[0-9]/ b d
g
:p
/./ { x ; p ; x ; s/.// ; b p }
x
d

Adding it here because they could be misinterpreted at first glance: the nine digit-numbered lines are part of the bignum decoding process, not (well, not really) of the box-printing one. The script handles box sizes OVER NINE without breaking a sweat. I'll limit it to 13 for presentation purposes, but I've tested sizes up to 11111111. Larger might work, but then it's too slow for my impatient self.

$ sed -f box.sed <<<13
*************
*************
*************
*************
*************
*************
*************
*************
*************
*************
*************
*************
*************
share|improve this answer
Boo... do you hardcode the boxes size? – FUZxxl Dec 14 '11 at 17:53
@FUZxxl What makes you say that? As the answer says, the box size, aka the parameter, is taken from standard input. Any non-negative integer will do, the only limitation is that one row has to fit in memory. – J B Dec 14 '11 at 22:23
@J Sorry. I did not understand your code completely... – FUZxxl Dec 15 '11 at 6:05

Emacs-Lisp

It's no fun if it doesn't move. So let's animate that a bit!

(defun box (n)
  "Create a buffer containing a asterisk box of side n.  With animation."
  (interactive "NBox size? ")
  (animate-sequence (make-list n (make-string n (string-to-char "*"))) 0))

For Emacs newcomers, here's a quick quide of how to try it. C- is Control; M- is Meta (if you don't have it use Alt.)

  • if you aren't already there (it's the default buffer in most releases of Emacs), go to the *scratch* buffer: C-x b *scratch* RET
  • copy-paste the code above
  • evaluate it using any one of C-j, C-M-x or C-x C-e
  • run it with M-x box RET
  • follow the interactive instructions from there on
  • optionally, destroy the newly created buffer with C-x k RET
share|improve this answer
Wow! Everything and the kitchen sink, indeed. (Ps. For other Lisp noobs like me, you might want to include an example of how to actually call your function. Took me a minute or two to figure it out.) – Ilmari Karonen Dec 16 '11 at 14:10
@IlmariKaronen I think I actually should have made it a defun instead of a lambda, this one isn't code golf. Maybe I was still in my Unlambda mood when I wrote that. – J B Dec 16 '11 at 16:14
1  
@IlmariKaronen there. Better? – J B Dec 16 '11 at 16:27
1  
emacs is awesome, and you can even use it as a text editor! – jsvnm Mar 12 '12 at 9:58

Ruby, 38 29 28 23 chars

->(_){$><<[?**_]*_*?\n}

Runs in Ruby 1.9

More readable version

def box(n)
  print (['*' * n] * n).join "\n"
end
share|improve this answer
1  
Instead of join use *"\n", shorter by 4 – st0le Dec 15 '11 at 8:53

Python 2.7

def box(n):
    print ('*'*n+'\n')*n
share|improve this answer

D

void main(string[] a){
    int n=to!int(a[1]);
    void f(int i=0){
        if(n==i)return;
        void lf(int i=0){
            if(i==n)return;
            write("*");
            lf(i+1);
        }
        lf();
        writeln;
        f(i+1);
    }    
    f();
}

getting around no globals with closures

share|improve this answer
If one can use two or more functions, the task is much easier. As I understand the question, it must be a single function. – tzot Dec 15 '11 at 12:59

ASM

Source = 237 characters

Executable = 60 bytes, as assembled by A86

Size of output is specified as the first (and only) parameter on the command line.

        mov si,82h
        xor ax,ax
        xor cx,cx
    l1: imul cx,10
        add cx,ax
        lodsb
        sub al,48
        jnc l1
        push cx
        mov di,0200
        call l2
        mov ax,0a0d
        stosw
        mov ax,49956
        stosb
        mov w[l3],21cdh
        pop cx
    l2: shr cx,1
        jnc l4
        mov ax,092a
        mov dx,0200
    l3: nop
        stosb
    l4: jcxz l2-9
        push cx
        call l2
        pop cx
        jmp l2

There is a loop, the code up to and including the jnc l1, but this bit just gets the value off the command line.

A couple of questions:

  1. How does the code output anything?
  2. How does the program exit?
share|improve this answer
ASM + command line interaction + I/O => you should really specify what OS this is supposed to run under. – J B Dec 13 '11 at 23:42
@JB: A86 is an ms-dos program. But to clarify, I built and tested using WinXP command shell. – Skizz Dec 14 '11 at 0:49

Interactive J

One function, no loops and no variables.

box =: '*' $~ ,~

This code defines a verb (function) box that can be used both monadic (one argument) to produce boxes of size y by y and dyadic (two arguments) to produce boxes of size x by y. Use it like this:

   box 4
****
****
****
****
   5 box 3
*****
*****
*****

The verb box generates a list of the two arguments or duplicates the argument if only one is given (,~). This list is used to build a matrix of stars ('*') with the given dimensions ($~). =: defines the verb.

share|improve this answer
1  
tacit and according to the task description (write a monadic verb): box=:'*'$~2$] – FUZxxl Dec 14 '11 at 16:41
@FUZxxl I could argue the problem is a bit ambiguous between function (single-parameter) and program (successful return code), but that would be a bit lame, considering I'm usually of that exact opinion. So I'll just copy-paste your version and thank you with a +1. – J B Dec 14 '11 at 16:43
This one is even better as it allows both y by y boxes as a monad and x by y boxes as a dyad: box=:'*'$~,~. Smiley included as a bonus. BTW, can I add an explanation to the code? – FUZxxl Dec 14 '11 at 17:50
1  
@FUZxxl edit all you want. Just for this once, though, try to keep the spaces in, there's no reason to make J less readable than it already is when we're not golfing ;) – J B Dec 14 '11 at 22:14

APL

 Box ← {⎕ ← ⍵ ⍵ ⍴ '*'}

This function uses the reshape function, , to form a by array of the character '*'. gives the input to the right of our function (there's also to grab the input to the left of it). It outputs the array (⎕ ←).

Example input:

Box 4

Corresponding output:

****
****
****
****

As usual, I used Dyalog APL. I found the restrictions somewhat vague, so I'm not sure if this entry is acceptable.

share|improve this answer

HTML + CSS + JS

I chose a different language, just for the sake of trying something uncommon.

This is HTML+CSS+JS, resizing a div for the correct size (in pixels). There is no current validation of the input.

<html>
    <head></head>
    <body>
        <input type="text" id="length" onkeyup="bs=document.getElementById('box').style;s=this.value+'px';bs.width=s;bs.height=s;" />
        <div id="box" style="border: 1px solid; width: 0px;" />
    </body>
</html>

The javascript is (to take a closer look):

bs = document.getElementById('box').style;
s = this.value+'px';
bs.width = bs.height = s;

Oh, and bs stands for "box style". Don't think weird.

You can see it in action here.

share|improve this answer

Scala

A rare occasion where Scala can do it in a quick one-liner:

def box(size:Int)=print(Array.fill(size)("*"*size).mkString("\n"))

You can test it at SimplyScala

or maybe a recursive solution?

def box(size:Int)
{
    def b1(s:Int):String=if(s<2) "*" else "*"+b1(s-1)
    def b2(s1:Int,s2:Int):String=b1(s1)+"\n"+(if(s2<2) "" else b2(s1,s2-1))

    print(b2(size,size))
}

or (ab)using foldLeft:

def box(size:Int)
{
    val a=List.fill(size)("")
    print(a.foldLeft("")(_+_+(a.foldLeft("")(_+_+"*"))+"\n"))
}

Usage in all cases: box(n)

share|improve this answer
Your ("*"*size) construct and the (multiple functions) construct are not allowed, if I understand the question correctly. – tzot Dec 15 '11 at 13:01
@tzot ...and therein lies the problem - do we understand the question correctly? It's a bit vague. I think my last solution avoids both the *size and multiple function (possible) constraints though. – Gareth Dec 15 '11 at 14:46

C

I think this follows the rules...

void box(int x) {
   static int n=0;
   static char *d=0;
   if (!x) { n=0; if(d) free(d); return; }
   if (!n) { n=x; d=memset(calloc(n+1, sizeof(char)), '*', n); }
   puts(d);
   box(--x);
}

Python

This should do it, right?

def box(n): print '\n'.join(['*'*n]*n)
share|improve this answer
I believe your C function almost does it (it's possible that the memset can be considered as string*number, according to the specification). The Python function uses string*number, so it should be disqualified. – tzot Dec 15 '11 at 13:05
Please keep it to one submission per answer. – J B Dec 15 '11 at 13:37
You should submit this as two answers so people can vote for them separately – gnibbler Dec 18 '11 at 10:45

PHP

function box($i){echo str_repeat(str_repeat('*',$i)."\n",$i);}

http://codepad.org/ygnwmg3Z

share|improve this answer

Perl

I suppose this is something like what you were looking for?

sub rep {
    my ($n, $f) = @_;
    $f->();
    rep($n-1, $f)  if $n > 1;
}

sub box {
    my ($n) = @_;
    rep $n, sub {
        rep $n, sub {
            print "*";
        };
        print "\n";
    };
}

box(8);  # print an 8x8 box

Or, if only one (named) function is allowed:

sub box {
    my ($n, $f) = @_;
    if ($f) {
        $f->();
        box($n-1, $f)  if $n > 1;
    } else {
        box( $n, sub {
            box( $n, sub {
                print "*";
            } );
            print "\n";
        } );
    }
}

Alternatively, how about abusing the regexp engine to construct pseudo-loops?

sub box {
    my ($n) = @_;
    my $x = my $y = 1 x $n;
    $x =~ s(1){
         $y =~ s(1){
             print "*";
         }eg;
         print "\n";
    }eg;
}

Or doing the same with map:

sub box {
    my ($n) = @_;
    map {
         map {
             print "*";
         } 1 .. $n;
         print "\n";
    } 1 .. $n;
}

Ps. I assumed from the task description that we were only allowed to print constant strings. If I can build a string and print it, this problem becomes remarkably simple:

sub box {
    my ($n) = @_;
    print +("*" x $n . "\n") x $n;
}
share|improve this answer
I know very little Perl; I believe that your first answer has multiple functions (sub) defined plus loops (rep), your second answer has inner loops (in the regexp code) and your last answer has string multiplication, so they're probably invalid. We need the OP to clarify our questions, that's for certain :) – tzot Dec 16 '11 at 7:32
The first version indeed has two functions; I could easily rewrite it to use only one, at the expense of some clarity. (Perl functions are all variadic by default, so it's easy to check whether box is called with one or two arguments and act accordingly.) Whether the second solution has loops or not really depends on your definition of "loop": the s/RE/CODE/eg operator matches the regexp RE against a string and evaluates CODE for each match. – Ilmari Karonen Dec 16 '11 at 13:50
I really am not sure about the OP's intentions; I hope they will clarify what they consider a loop or not. I'm only discussing based on what I understood, which might be useless. However, I guess that if you change the box function to receive either one or two arguments, then you're out-of-spec (quoting: “-The function must have exactly one parameter of type int (or the equivalent in your chosen language)”) – tzot Dec 16 '11 at 14:49

C#

This contest was just screaming for C# lambdas :D

    static void box(int n)
    {
        Func<int, int> Rows = null;
        Rows = r =>
            {
                Func<int, int> Columns = null;
                Columns = c =>
                    {
                        Console.Write("*");
                        if (c > 1)
                            return Columns(c - 1);
                        else
                            return 0;
                    };

                Columns(n);
                Console.WriteLine();
                if (r > 1)
                    return Rows(r - 1);
                else
                    return 0;
            };

        Rows(n);
    }

Bonus question: why do I initialize the Func<>s to null?

share|improve this answer

PHP:182 chars

Create ASCII box with edge parameters. Does squares and rectangles.

The square example shows more rectangle on SE when in code tag.

Deforms if you make it too big, starts to become a rectangle after 64x64, not sure you would need it bigger than that though.

function ASCIIbox($w,$l)
{
echo str_repeat("―",$w+($l+2))."<br/>";
echo str_repeat("|".str_repeat(" ",$l+$w)."|<br/>",$l);
echo str_repeat("―",$w+($l+2))."<br/>";
}

ASCIIbox(16,16);

Example:

――――――――――――――――――――――――――――――――――
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
|                                |
――――――――――――――――――――――――――――――――――
share|improve this answer

QBASIC - 39 Chars

SUB B(N)
LINE (0,0)-(N,N),7,B
END SUB

So nice to have drawing methods built into the lanugage. I think this even beats Logo for simplicity.

share|improve this answer

Python

I'm not sure did I get it right. Main function has one parameter, local function not.

def P(n):
 def A(n): return '*'+A(n-1) if n>0 else ''
 def R(n,m):
  if n>0: print A(n+m); R(n-1,m+1)
 R(n,0)
share|improve this answer

A little confused on the specification, maybe this perl code counts?

sub printbox
{
  print((('*' x $_[0]) . "\n") x $_[0]);
}
share|improve this answer

in REXX:

parse arg n                        
say do('say print_box('n')',n)     
exit                               

do: procedure                      
    parse arg cmd,n                
    if n < 1 then return ' '       
    interpret cmd                  
    return do(cmd,n-1)             

print_box: procedure               
    parse arg n                    
    if n <= 1 then return '*'      
    return '*'||print_box(n-1)     
share|improve this answer

Python

This is my answer (in Python), but I think I'm cheating (i.e data partitioning):

def box(n):
    if n <= 0:
        return
    elif n < 256:
        box(n*65536 + (n-1)*256 + n)
    elif n % 256 == 0:
        sys.stdout.write('\n')
        if n % 65536 != 0:
            box(n - 256 + n//65536)
    else:
        sys.stdout.write('*')
        box(n - 1)

There's an obvious limit for size (less than 256).

I find it hard to conceive a function without argument data partitioning and no other shared storage that can produce a square, although a triangle is relatively easy.

share|improve this answer

Python 3

P=lambda n:Q(n*n-1,n)
def Q(c,n):
 print('*',end='')
 if not c%n:print('')
 if c:Q(c-1,n)
share|improve this answer

Racket

Clearly not the shortest, but works good. My boxes are empty, because... I didn't think they were supposed to be full like most did. (Which complicates the code quite a bit.) I support all sizes of boxes (0+) and complain on negative sizes. Recursive calls, no loops.

(define box ; draws a square box
  (λ (side)
    (let ((char-line #\*) ; defining characters to be used below
          (char-void #\ )
          (char-rtrn #\u000A))
      (letrec ((print-multi ; prints a character many times
                (λ (n char)
                  (unless (zero? n)
                    (printf "~a" char)
                    (print-multi (- n 1) char))))
               (print-hline ; prints the horizontal lines
                (λ (n)
                  (print-multi n char-line)
                  (printf "~a" char-rtrn)))
               (print-vlines ; prints the vertical lines
                (λ (n)
                  (unless (zero? n)
                    (printf "~a" char-line)
                    (print-multi (- side 2) char-void)
                    (printf "~a~a" char-line char-rtrn)
                    (print-vlines (- n 1))))))
        (cond
          ((> side 2) ; normal case
           (print-hline side)
           (print-vlines (- side 2))
           (print-hline side))
          ((= side 2) ; 2
           (print-hline side)
           (print-hline side))
          ((>= side 0) ; 0 and 1
           (print-hline side))
          (else
           'negative-number))))))

Testing with

(box 5)
(box 4)
(box 3)
(box 2)
(box 1)
(box 0)
(box -1)

Results in the output

*****
*   *
*   *
*   *
*****
****
*  *
*  *
****
***
* *
***
**
**
*

'negative-number
share|improve this answer

Python (136 119 chars)

def b(n,m):
if n==1 or n==m:
    print '*'*m
else:
    print'*'+' '*(m-2)+'*'
if n>1:
    b(n-1,m)
n=m=int(input())
b(n,m)
share|improve this answer

Ruby, 22

->(n){$><<(?**n+$/)*n}

Today I learned that using p instead of puts doesn't parse newlines.

share|improve this answer
you don't need the () around n: ->n{$><<(?**n+$/)*n} – jsvnm Mar 12 '12 at 10:00
1 2

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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