24
\$\begingroup\$

I got this challenge from Codingame and am curious about better solutions than mine:

Given a width via standard input draw a hollow square of '#' in given width and length.

Example:

5 results in

#####
#   #
#   #
#   #
#####

I used python to solve this so i am particulary interested in other python code. But please feel free to post your solution in any language you want.

\$\endgroup\$
13
  • 8
    \$\begingroup\$ What if input is 0 or 1? \$\endgroup\$
    – Karl Napf
    Nov 7 '16 at 14:27
  • 8
    \$\begingroup\$ Related, though this might be different enough to not be a dupe. \$\endgroup\$ Nov 7 '16 at 14:31
  • 3
    \$\begingroup\$ Welcome to PPCG! For future questions, I encourage you to use the Sandbox where you can get meaningful feedback on a challenge before posting it to the main page. \$\endgroup\$ Nov 7 '16 at 14:31
  • 4
    \$\begingroup\$ Reading through the answers, I'm not convinced it's a dupe. Most of the answers here (golfing and regular languages) are roughly half the size of the answers on "Print N Squared." \$\endgroup\$ Nov 7 '16 at 16:43
  • 1
    \$\begingroup\$ This is absolutely a duplicate. Solutions from the other challenge can be trivially modified to be valid and competitive here. \$\endgroup\$
    – user45941
    Nov 8 '16 at 10:42

45 Answers 45

12
\$\begingroup\$

Charcoal, 6 bytes

Code:

NβBββ#

Explanation:

Nβ        # Get input from the command line and store into β
   B      # Draw a hollow box with...
     β     #  Width β
      β    #  Height β
       #   #  Filled with the character '#'
           # Implicitly output the box

Try it online!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ I was trying to figure out how to read input in Charcoal. Now I know :) \$\endgroup\$
    – Emigna
    Nov 7 '16 at 15:22
  • 1
    \$\begingroup\$ @Emigna Note that can also be used in an expression, like int(input()) in Python. If this challenge were "draw a hollow rectangle with given width and height," the solution could be BNN#. \$\endgroup\$
    – DLosc
    Nov 8 '16 at 1:50
  • \$\begingroup\$ Does Charcoal use a non-UTF8 charset? \$\endgroup\$ Nov 8 '16 at 2:49
  • \$\begingroup\$ That looks like 6 characters, not 6 bytes. β is in plenty of alternate 8-bit character sets, but I'm dubious about N(which is not N) \$\endgroup\$
    – Sparr
    Nov 8 '16 at 3:22
  • 3
    \$\begingroup\$ @Sparr Charcoal uses its own codepage. \$\endgroup\$ Nov 8 '16 at 4:25
8
\$\begingroup\$

MATL, 12 bytes

:G\1>&*~35*c

Try it online!

Explanation

:     % Input n implicitly. Push range [1 2 ... n]
      % STACK: [1 2 3 4 5]
G     % Push n again
      % STACK: [1 2 3 4 5], 5
\     % Modulo
      % STACK: [1 2 3 4 0]
1>    % Does each entry exceed 1?
      % STACK: [0 1 1 1 0]
&*    % Matrix with all pair-wise products
      % STACK: [0 0 0 0 0;
                0 1 1 1 0;
                0 1 1 1 0;
                0 1 1 1 0;
                0 0 0 0 0]
~     % Negate
      % STACK: [1 1 1 1 1;
                1 0 0 0 1;
                1 0 0 0 1;
                1 0 0 0 1;
                1 1 1 1 1]
35*   % Multiply by 35
      % STACK: [35 35 35 35 35;
                35  0  0  0 35;
                35  0  0  0 35;
                35  0  0  0 35;
                35 35 35 35 35]
c     % Convert to char. 0 is interpreted as space. Display implicitly
      % STACK: ['#####';
                '#   #';
                '#   #';
                '#   #';
                '#####']
\$\endgroup\$
6
\$\begingroup\$

Jolf, 8 bytes

,ajj"###
,ajj      draw a box with height (input) and width (input)
    "###  with a hash border
\$\endgroup\$
3
  • \$\begingroup\$ The right tool for the job :) \$\endgroup\$
    – Emigna
    Nov 7 '16 at 15:05
  • \$\begingroup\$ Out of curiosity, why are three # required? \$\endgroup\$ Nov 7 '16 at 15:54
  • 3
    \$\begingroup\$ @KevinCruijssen Each specify the horizontal struts, vertical struts, and corner pieces. \$\endgroup\$ Nov 7 '16 at 16:50
6
\$\begingroup\$

Python 2, 62 54 bytes

f=lambda n:'#'*n+'\n#%s#'%(' '*(n-2))*(n-2)+'\n'+'#'*n

Returns #\n# when the input is 1

55 Bytes version that prints

def f(n):a=n-2;print'#'*n,'\n#%s#'%(' '*a)*a,'\n'+'#'*n

62 Bytes version that works for any input:

f=lambda n:'#'*n+'\n#%s#'%(' '*(n-2))*(n-2)+('\n'+'#'*n)*(n>1)
\$\endgroup\$
3
  • 2
    \$\begingroup\$ You do not have to say f= unless you use it––which you don't. \$\endgroup\$
    – Daniel
    Nov 7 '16 at 18:57
  • \$\begingroup\$ @Dopapp I know, but I think it's more fair that way (in comparison to full functions / programs) \$\endgroup\$
    – Rod
    Nov 8 '16 at 11:25
  • \$\begingroup\$ @Rod Your choice, but we have a policy about anonymous functions that allows them. \$\endgroup\$ Nov 8 '16 at 12:50
5
\$\begingroup\$

Java 7, 113 112 110 bytes

String c(int n){String r="";for(int i=n,j;i-->0;r+="\n")for(j=0;j<n;r+=i*j<1|n-i<2|n-j++<2?"#":" ");return r;}

1 byte saved thanks to @OlivierGrégoire;
2 bytes saved thanks to @cliffroot.

Derived solution based on my Creating a Crossed Square answer.

Try it here.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Could you shave a byte by doing the following for(int i=n,j;i-->0;r+="\n")? Since we don't care which is the bottom line or the top one, it doesn't make any sense to keep that order, right? \$\endgroup\$ Nov 8 '16 at 12:45
  • 1
    \$\begingroup\$ @OlivierGrégoire Thanks! I've also edited it in my Creating a Crossed Square answer, since there the same could be done. \$\endgroup\$ Nov 8 '16 at 12:56
5
\$\begingroup\$

COW, 426 405 348 330 bytes

MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMMMmoOMMMMoOMoOMoOMoOMoOMoOMoOMoOMoO
MoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMMMmoOMMMMoOMoOMoOmoOoomMMM
moOMMMMOOmOomOoMoomoOmoOMOomoomOoMMMmoOMMMMOoMOoMOOmOomOomOomOoMoo
moOmoOMoomoOMMMmoOmoOMMMMOoMOoMOOmOomOomOomOoMoomoOmoOmoOmoOMOomoo
mOomOomOoMoomoOmoOMOomoomOomOomOomOoMoomoOmoOmoOMOOmOoMoomoOMOomoo

Try it online! Change the number in the second line to any number to change the output.

The COW interpreter that I'm using here was written in Perl (and is newer than this challenge), but you can still get the same result by inputting the code here.

Explanation

; Note: [n] means "value stored in the nth block of memory".
MoOMoOMoOMoOMoOMoOMoOMoOMoOMoO                                                  ;Stores 10 in [0].  10 is the code point for carriage return
MMMmoOMMMMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoO     ;Stores 32 in [1].  32 is the code point for whitespace
MMMmoOMMMMoOMoOMoO                                                              ;Stores 35 in [2].  35 is the code point for #
moOoom                                                                          ;Reads STDIN for an integer, and stores it in [3]
MMMmoOMMM                                                                       ;Copies [3] into [4] 
MOO                                                                             ;Loop as long as [4] is non-zero
    mOomOoMoo                                                                   ;Navigate to [2] and print the character with that code point
    moOmoOMOo                                                                   ;Navigate to [4] and decrement
moo                                                                             ;End loop
mOoMMMmoOMMMMOoMOo                                                              ;Copy [3] into [4] and decrement [4] twice
MOO                                                                             ;Loop as long as [4] is non-zero
    mOomOomOomOoMoo                                                             ;Navigate to [0] and print the character with that code point
    moOmoOMoo                                                                   ;Navigate to [2] and print the character with that code point
    moOMMMmoOmoOMMMMOoMOo                                                       ;Navigate to [3] and copy it into [5], then decrement [5] twice
    MOO                                                                         ;Loop as long as [5] is non-zero
        mOomOomOomOoMoo                                                         ;Navigate to [1] and print the character with that code point
        moOmoOmoOmoOMOo                                                         ;Navigate to [5] and decrement
    moo                                                                         ;End loop
    mOomOomOoMoo                                                                ;Navigate to [2] and print the character with that code point
    moOmoOMOo                                                                   ;Navigate to [4] and decrement
moo                                                                             ;End loop
mOomOomOomOoMoo                                                                 ;Navigate to [0] and print the character with that code point
moOmoOmoO                                                                       ;Navigate to [3]
MOO                                                                             ;Loop as long as [3] is non-zero
    mOoMoo                                                                      ;Navigate to [2] and print the character with that code point
    moOMOo                                                                      ;Navigate to [3] and decrement
moo                                                                             ;End loop
\$\endgroup\$
4
\$\begingroup\$

Python 2, 59 58 bytes

n=i=input()
while i:print'#%s#'%((' #'[i%n<2])*(n-2));i-=1

repl.it

Note: An input of 1 produces an output of ##, but a hollow square would never be produced for an input less than 3, so I guess this is fine.

\$\endgroup\$
4
\$\begingroup\$

PowerShell v2+, 48 47 bytes

param($n)($z='#'*$n--);,("#$(' '*--$n)#")*$n;$z

-1 byte thanks to JohnLBevan

Takes input $n, sets $z as $n hashmarks, with $n post-decremented. Encapsulates that in parens to place a copy on the pipeline. Then uses the comma operator to create an array of pre-decremented $n lines of #,spaces,#. Those are left on the pipeline. Then places $z again on the pipeline. Output via implicit Write-Output at the end introduces a newline between elements, so we get that for free.

Since the OP's code doesn't work for input n <= 1, I took that to mean we don't need to support input 1, either.

Examples

PS C:\Tools\Scripts\golfing> 2..6|%{"$_";.\draw-a-hollow-square.ps1 $_;""}
2
##
##

3
###
# #
###

4
####
#  #
#  #
####

5
#####
#   #
#   #
#   #
#####

6
######
#    #
#    #
#    #
#    #
######
\$\endgroup\$
2
  • \$\begingroup\$ You can knock another byte off: param($n)($z='#'*$n--);,("#$(' '*--$n)#")*$n;$z \$\endgroup\$
    – JohnLBevan
    Nov 8 '16 at 19:51
  • 1
    \$\begingroup\$ @JohnLBevan Good idea with the script block. Thanks! \$\endgroup\$ Nov 8 '16 at 19:52
3
\$\begingroup\$

C, 98 bytes

f(n,i){i=n*(n+1);while(i--){putchar(i%(n+1)==n?10:i<n||i>n*n-1||i%(n+1)==0||i%(n+1)==n-1?35:32);}}

Usage:

f(5)
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 20 bytes

'#×D¹Íð×'#.ø¹Í×sJ¹ä»

Try it online!

Or 18 bytes if we can ignore 1 <= n:

F„ #N¹<%_è¹Í×'#.ø,

Try it online!

\$\endgroup\$
3
\$\begingroup\$

WinDbg, 206 200 182 170 bytes

.if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}

-6 bytes from removing parens from .if and using j instead of second .if

-18 bytes by using f instead of a .for to construct the strings.

-12 bytes by not NULL-terminating strings, instead passing length to da

Input is passed in through the pseudo-register $t0 (eg r $t0 = 5; {above-code}).

Explanation:

.if @$t0                                                *Verify width($t0) at least 1 
{                                                       *(registers have unsigned values) 
    r $t3 = 2000000;                                    *Set $t3 to address where the 
                                                        *string will be constructed
    f @$t3 L@$t0 23;                                    *Put width($t0) '#' at 2000000($t3)
    f 2 * @$t3 L@$t0 20;                                *Put width($t0) ' ' at 4000000(2*$t3)
    eb 2 * @$t3 23;                                     *Put '#' on left of ' ' string
    eb 2 * @$t3 + @$t0 - 1 23;                          *Put '#' on right of ' ' string
    da @$t3 L@$t0;                                      *Print the top of the box
    j 1 < @$t0                                          *If width($t1) at least 2
    '
        .for (r $t1 = @$t0 - 2; @$t1; r $t1 = @$t1 - 1) *Loop width($t0)-2 times to...
        {
            da 2 * @$t3 L@$t0                           *...print the sides of the box
        };
        da @$t3 L@$t0                                   *Print the bottom of the box
    '
}

Sample output:

0:000> r$t0=0
0:000> .if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}

0:000> r$t0=1
0:000> .if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}
Filled 0x1 bytes
Filled 0x1 bytes
02000000  "#"

0:000> r$t0=2
0:000> .if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}
Filled 0x2 bytes
Filled 0x2 bytes
02000000  "##"
02000000  "##"

0:000> r$t0=5
0:000> .if@$t0{r$t3=2000000;f@$t3 L@$t0 23;f2*@$t3 L@$t0 20;eb2*@$t3 23;eb2*@$t3+@$t0-1 23;da@$t3 L@$t0;j1<@$t0'.for(r$t1=@$t0-2;@$t1;r$t1=@$t1-1){da2*@$t3 L@$t0};da@$t3 L@$t0'}
Filled 0x5 bytes
Filled 0x5 bytes
02000000  "#####"
04000000  "#   #"
04000000  "#   #"
04000000  "#   #"
02000000  "#####"
\$\endgroup\$
3
\$\begingroup\$

JavaScript, 61 58 bytes

Saved 3 bytes thanks to @lmis!

n=>(b='#'[r='repeat'](n))+`
#${' '[r](n-=2)}#`[r](n)+`
`+b

(Doesn't handle 0 or 1)

For 13 extra bytes (at 71 bytes), you can!

n=>n?n-1?(b='#'[r='repeat'](n))+`
#${' '[r](n-=2)}#`[r](n)+`
`+b:'#':''

These solutions are fairly simple: they do a lot of storage to not repeat themselves to save a few bytes. Unminified without the variablsm it would look like:

n => // Anonymous function definition (Param `n` is the size)
    '#'.repeat(n) +      // # `n` times to form the top
    `
#${' '.repeat(n - 2)}#`  // Followed by a newline followed by a hash and `n` - 2 spaces and
                         // another hash to make one of the middle lines
    .repeat(n - 2) +     // The above middle lines repeated `n` - 2 times
    '#'.repeat(n)        // Followed by the top line again

Try it!

<script type="text/babel">var f=n=>n?n-1?(b='#'[r='repeat'](n))+`\n#${' '[r](n-=2)}#`[r](n)+`\n`+b:'#':'',b,r;function c(){document.getElementById('pre').textContent = f(+document.getElementById('input').value);}</script><input id="input" onkeydown="c();" onkeyup="c();" onchange="c();" onclick="c();" placeholder="Size"><pre id="pre"></pre>

\$\endgroup\$
2
  • \$\begingroup\$ By adding !n?'':n==1?'#':, an extra 15 bytes at the beginning of the function body, you can handle inputs 0 and 1. \$\endgroup\$
    – Kayla
    Nov 8 '16 at 5:12
  • 1
    \$\begingroup\$ n=>(b='#'[r='repeat'](n)) and then #${" "[r](n-=2)} etc. saves you 3 bytes by avoiding to repeat repeat :) \$\endgroup\$
    – Lmis
    Nov 8 '16 at 10:15
2
\$\begingroup\$

Python, 109 bytes

n=int(input())
for x in range(n):
 r=list(' '*n);r[0]=r[-1]='#'
 if x%(n-1)==0:r='#'*n
 print("".join(r))
\$\endgroup\$
4
  • 1
    \$\begingroup\$ You can replace list(' '*n) with [' ']*n. You can also replace x%(n-1) with x%~-n \$\endgroup\$
    – Wheat Witch
    Nov 7 '16 at 14:58
  • 1
    \$\begingroup\$ also, if you turn the for block into a list comprehension you can save more than 20 bytes \$\endgroup\$
    – Rod
    Nov 7 '16 at 15:11
  • 1
    \$\begingroup\$ Also, swith to Python 2, drop int() and the brackets around print. \$\endgroup\$
    – Artyer
    Nov 7 '16 at 19:16
  • 1
    \$\begingroup\$ Use <1 instead of ==0. \$\endgroup\$
    – mbomb007
    Nov 7 '16 at 19:55
2
\$\begingroup\$

Ruby, 39 bytes

->n{puts a=?#*n,[?#+' '*(n-=2)+?#]*n,a}

Turns out to be shorter this way than all the fancy stuff I was trying. Be advised that this doesn't handle 0 or 1 at all.

\$\endgroup\$
2
\$\begingroup\$

Python 2, 50 bytes

m=input()-2
for c in'#'+' '*m+'#':print'#'+m*c+'#'

Works for n>=2. Prints each line with a pound sign, n-2 of the appropriate symbol, then another pound sign.

Aliasing the pound symbol gives same length:

m=input()-2;p='#'
for c in p+' '*m+p:print p+m*c+p

Other attempts:

lambda n:'#'*n+('\n#'+' '*(n-2)+'#')*(n-2)+'\n'+'#'*n

lambda n:'#'*n+'\n#%s#'%((n-2)*' ')*(n-2)+'\n'+'#'*n

lambda n:'\n'.join(['#'*n]+['#'+' '*(n-2)+'#']*(n-2)+['#'*n])

n=input();s='#'+' '*(n-2)+'#'
for c in s:print[s,'#'*n][c>' ']

s='##'+' #'*(input()-2)+'##'
for c in s[::2]:print s[c>' '::2]

s='#'+' '*(input()-2)+'#'
for c in s:print s.replace(' ',c)
\$\endgroup\$
1
  • \$\begingroup\$ I'm unsure whether this qualifies for your bounty, but I was able to find a lambda solution giving 47 bytes. \$\endgroup\$ Oct 2 at 17:36
2
\$\begingroup\$

Haskell, 49 bytes

n%b='#':(b<$[3..n])++"#\n"
f n=(n%)=<<init(n%' ')

Works for n>=2. Defines the operation of sandwiching a character between # for an n-character newline-terminated string, then applies it twice to make a 2D grid.

Call like:

*Main> putStrLn$ f 5
#####
#   #
#   #
#   #
#####
\$\endgroup\$
2
\$\begingroup\$

C, 83 82 80 78 77 Bytes

i,j;f(n){for(i=n;i--;puts(""))for(j=n;j--;putchar(i*j&&i^n-1&&j^n-1?32:35));}

Sneak in a multiply and save a byte...

i,j;f(n){for(i=n;i--;puts(""))for(j=n;j--;putchar(i&&j&&i^n-1&&j^n-1?32:35));}

Also count down j and save a few more...

i,j;f(n){for(i=n;i--;puts(""))for(j=0;j++<n;putchar(i&&j^1&&i^n-1&&j^n?32:35));}

Count down i from n to zero and save a few bytes...

i,j;f(n){for(i=0;i++<n;puts(""))for(j=0;j++<n;putchar(i^1&&j^1&&i^n&&j^n?32:35));}

A bit easier to understand and 1 byte more

i,j;f(n){for(i=0;i++<n;puts(""))for(j=0;j++<n;putchar(i==1|i==n|j==1|j==n?35:32));}
\$\endgroup\$
2
  • \$\begingroup\$ Do you need && instead of &? \$\endgroup\$
    – corvus_192
    Nov 7 '16 at 20:56
  • \$\begingroup\$ Yes, it needs to be logical &. I can use multiply but it requires too many parenthesis... \$\endgroup\$
    – cleblanc
    Nov 7 '16 at 21:23
2
\$\begingroup\$

Python 2, 47 bytes

Works for all n greater than 1.

lambda n:'#'*n+('#%*s'%(n,'#\n')*~-n)[n:]+'#'*n

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Nice answer! This definitely qualifies for the bounty but I can't start one because the question is closed. Maybe I can post it for some other answer of yours you want highlighted and link here? \$\endgroup\$
    – xnor
    Oct 6 at 8:49
  • \$\begingroup\$ @xnor I have an answer here on a similar challenge. Perhaps you can bounty that one instead. \$\endgroup\$ Oct 6 at 23:00
2
\$\begingroup\$

K (ngn/k), 17 bytes

{"# "x*/:x#:!x-1}

Try it online!

Or tacit, 20 bytes:

" #"@|/(+|:)\^ :':=:
"# "@&/(+|:)\=':1|=:  / similar

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Groovy, 51 50 bytes

{n->a="*"*n+"\n";n-=2;print(a+"*${' '*n}*\n"*n+a)}
\$\endgroup\$
1
\$\begingroup\$

PHP, 81 69 bytes

for($n=-1+$i=$argv[1];$i--;)echo str_pad("#",$n," #"[$i%$n<1]),"#\n";

Run with -r; provide input as argument.

Throws a DivisionByZeroError for input=1.

\$\endgroup\$
1
\$\begingroup\$

Pyke, 11 bytes

ttDd*n+*.X#

Try it here!

ttDd*n+*    - a square of spaces n-2*n-2 big
        .X# - surround in `#`
\$\endgroup\$
1
\$\begingroup\$

R, 68 70 bytes

Works for n > 1. Thanks to @Billywob for a couple of bytes swapping out the array for a matrix.

cat(rbind(b<-'#',cbind(b,matrix(' ',n<-scan()-2,n),b),b,'
'),sep='')

Uses rbind and cbind to put rows and columns of #'s around an n-2 square matrix of spaces. Newlines are bound to the rows as well. The newline in the source is significant. Input is from STDIN

\$\endgroup\$
1
  • \$\begingroup\$ Nice! I had no idea that a newline in a string implicitly adds \n. You could save two bytes by using matrix instead of array though. \$\endgroup\$
    – Billywob
    Nov 8 '16 at 8:54
1
\$\begingroup\$

Common Lisp, 150 130 bytes

-20 thanks to @Cyoce and @AlexL.

(defun s(v)(format t"~v,,,vA~%"v #\# #\#)(dotimes(h(- v 2))(format t"~v,,,vA~A~%"(- v 1)#\  #\# #\#))(format t"~v,,,vA"v #\# #\#))

Usage:

* (s 5)
#####
#   #
#   #
#   #
#####

Basically uses format twice for the top and bottom and a loop for the rows in between. The format call for the top and bottom outputs a line starting with # and padded to the appropriate width with #s. The format call for the rows in between works similarly, except the padding is spaces and a # gets printed at the end of the line.

Note: I'm rather new to Lisp and expect to have a lot of room for improvement on this.

\$\endgroup\$
3
  • \$\begingroup\$ Why not name it s? Or do am anonymous function? \$\endgroup\$
    – Cyoce
    Dec 2 '16 at 0:52
  • \$\begingroup\$ I don't know Lisp, but are all of the spaces between a word and an open bracket to its right necessary? Like, does it have to be dotimes (h (- v 2)) or could it be dotimes(h(- v 2))? \$\endgroup\$
    – hyper-neutrino
    Dec 2 '16 at 2:12
  • \$\begingroup\$ @AlexL. yeah, there are a lot of opportunities for improvement here. A ton of whitespace can be removed between parentheses and other symbols. I'll just do that really quickly \$\endgroup\$ Dec 2 '16 at 2:23
1
\$\begingroup\$

Dyalog APL, 20 bytes

{' #'[1+∘.∨⍨1⍵∊⍨⍳⍵]}

Try it online!

This is an improved version on my first attempt suggested by dzaima on the APL Orchard, so all credit goes to him.

Takes an integer n as input. Using 5 as an example:

                ⍳⍵   integers from 1 to n
                      1 2 3 4 5
            1⍵∊⍨     check whether each integer is 1 or n
                      1 0 0 0 1
        ∘.∨⍨         generate all possible pairs of the
                     0s and 1s in a matrix, or'ing each pair:
                      ∨ | 1 0 0 0 1
                      --+----------
                      1 | 1 1 1 1 1
                      0 | 1 0 0 0 1
                      0 | 1 0 0 0 1
                      0 | 1 0 0 0 1
                      1 | 1 1 1 1 1
      1+             add 1 to each number
                      2 2 2 2 2
                      2 1 1 1 2
                      2 1 1 1 2
                      2 1 1 1 2
                      2 2 2 2 2
 ' #'[            ]  turn 1 into space (the first character)
                     and 2 into # (the second character)
\$\endgroup\$
0
\$\begingroup\$

Haskell, 67 bytes

l#n=l<$[1..n]
f n=unlines$'#'#n:('#':' '#(n-2)++"#")#(n-2)++['#'#n]

Usage example:

Prelude> putStrLn $ f 4
####
#  #
#  #
####

How it works:

l#n=l<$[1..n]                      -- helper function that makes n copies of l

   '#'#n                           -- make a string of n copies of #, followed by
                        #(n-2)     -- n-2 copies of
     '#':' '#(n-2)++"#"            -- # followed by n-2 times spaces, followed by #
                           ['#'#n] -- and a final string with n copies of #
unlines                            -- join with newlines in-between
\$\endgroup\$
0
\$\begingroup\$

Jelly, 13, bytes

,þ%µỊṀ€€ị⁾# Y

TryItOnline! or try 0 to 15

How?

,þ%µỊṀ€€ị⁾# Y - Main link: n
 þ            - outer product with
,             -    pair:   [[[1,1],[2,1],...,[n,1]],[[1,2],[2,2],...,[n,2]], ... ,[[1,n],[2,n],...,[n,n]]]
  %           - mod n:     [[[1,1],[2,1],...,[0,1]],[[1,2],[2,2],...,[0,2]], ... ,[[1,0],[2,0],...,[0,0]]]
   µ          - monadic chain separation
    Ị         - abs(z)<=1: [[[1,1],[0,1],...,[1,1]],[[1,0],[0,0],...,[1,0]], ... ,[[1,1],[0,1],...,[1,1]]]
      €€      - for each for each
     Ṁ        - maximum:   [[1,    1,    ...,1],    [1,    0,    ..., 1],    ... ,[1,    1,    ..., 1]   ]
        ị     - index into (1 based)
         ⁾#   - "# ":      ["##...#","# ...#", ...,"##...#"]
           Y  - join with line feeds
\$\endgroup\$
0
\$\begingroup\$

Pip, 16 bytes

15 bytes of code, +1 for -n flag.

(Y_Xa-2WR'#s)My

Works for input >= 2. Try it online!

Explanation of somewhat ungolfed version

First, we define a function y that takes a string argument, repeats it a-2 times (where a is the first command-line input), and wraps the result in #.

Y _ X a-2 WR '#
  _              Identity function
    X a-2        String-repeated by a-2
          WR '#  Wrapped in #
Y                Yank the resulting function into y

Next, we apply this function twice--once normally, then again with map--to obtain the square as a list of strings:

y M (y s)
    (y s)  Call function y with s (preinitialized to " ") as argument
y M        Map y to each character of the resulting string

For input of 4, (y s) results in "# #" and y M (y s) in ["####"; "# #"; "# #"; "####"]. This latter value is then printed, with the -n flag causing it to be newline-separated.

Golfing tricks

To get from the ungolfed to the golfed version:

  • Remove spaces.
  • Y is an operator, which means we can use it in an expression. Instead of Y... followed by (ys), we can just do (Y...s).
  • The problem is, we have to yank the function before we reference it again as y; so yM(Y_Xa-2WR'#s) won't work. Solution: swap the operands of the Map operator. As long as one of them is a function and the other is an iterable type, it doesn't matter what order they come in.
\$\endgroup\$
0
\$\begingroup\$

Racket 113 bytes

(let*((d display)(g(λ()(for((i n))(d"#")))))(g)(d"\n")(for((i(- n 2)))(d"#")(for((i(- n 2)))(d" "))(d"#\n"))(g))

Ungolfed:

(define (f n)
  (let* ((d display)
         (g (λ () 
              (for ((i n))
                (d "#"))
              (d "\n"))))
    (g)
    (for ((i (- n 2)))
      (d "#")
      (for ((i (- n 2)))
        (d " ") )
      (d "#\n"))
    (g)))

Testing:

(f 5)

Output:

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

SpecBAS - 57 bytes

1 INPUT n: a$="#"*n,n-=2,b$="#"+" "*n+"#"#13: ?a$'b$*n;a$

? is shorthand for PRINT, #13 is carriage return which can be tacked on to the end of a string without needing a + to join them.

The apostrophe moves print cursor down one line.

\$\endgroup\$

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