24
\$\begingroup\$

Given an integer n ≥ 1, output a 2D representation of a percent sign of width n. The construction goes as follows:

  1. Create an n by n matrix (or list of lists) filled with zeroes.
  2. Insert ones in the top-left and bottom-right corners.
  3. Place ones on the diagonal from the bottom-left to the top-right.

For input n = 4, this construction would look like:

1. 4x4 matrix of 0s
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
2. 1s in TL and BR corners
1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 1
3. 1s across BL-TR diagonal
1 0 0 1
0 0 1 0
0 1 0 0
1 0 0 1

This is a , so the shortest program in bytes wins.

I use a matrix of 1s and 0s, but it is also acceptable to use a string of any non-whitespace character and spaces. So, the example above could look like:

#  #
  # 
 #  
#  #

or

#     #
    #
  # 
#     #

Test cases

n
output

1
1

2
1 1
1 1

3
1 0 1
0 1 0
1 0 1

4
1 0 0 1
0 0 1 0
0 1 0 0
1 0 0 1

10
1 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 1

Final note

Adding an explanation would be greatly appreciated.

\$\endgroup\$
  • \$\begingroup\$ Can our solutions be 0-indexed? \$\endgroup\$ – Kritixi Lithos Jul 21 '17 at 17:41
  • 5
    \$\begingroup\$ @Cowsquack I'd say no. You're receiving the width, not an index. \$\endgroup\$ – Conor O'Brien Jul 21 '17 at 17:44
  • \$\begingroup\$ Can we output a list of lists? \$\endgroup\$ – xnor Jul 21 '17 at 18:02
  • \$\begingroup\$ @xnor Yes; list of lists and matrix are synonymous in my post. I'll add that to the question \$\endgroup\$ – Conor O'Brien Jul 21 '17 at 18:15
  • \$\begingroup\$ Note that this is '1'+'0'*(n-2) with whitespace inserted \$\endgroup\$ – CalculatorFeline Jul 21 '17 at 21:30

44 Answers 44

2
\$\begingroup\$

C, 216 212 186 155 145 Bytes

Just as a function that takes a matrix as input

f(int i,int **m){for(int a=0;a<i;a++){for(int b=0;b<i;b++){m[a][b]=((a+b+1==i)||(!a&&!b)||(a==i-1&&b==i-1))?1:0;printf("%d ",m[a][b]);}puts();}}

6 Bytes thanks to Conor O'Brien!

4 Bytes thanks to Zacharý!

Old Answer

main(int i){int**m=malloc(8*i);for(int a=0;a<i;a++){m[a]=malloc(4*i);for(int b=0;b<i;b++){m[a][b]=((a+b+1==i)||(a==0&&b==0)||(a==i-1&&b==i-1))?1:0;printf("%d ",m[a][b]);}printf("\n");}}

Instead of taking an array of arguments in the main function, it uses the length of arguments instead so the input for a 4x4 matrix would be:

enter image description here

Old Answer

main(int c,char **v){int i=atoi(v[1]);int**m=malloc(8*i);for(int a=0;a<i;a++){m[a]=malloc(4*i);for(int b=0;b<i;b++){m[a][b]=((a+b+1==i)||(a==0&&b==0)||(a==i-1&&b==i-1))?1:0;printf("%d ",m[a][b]);}printf("\n");}}

If only I could get rid of of those mallocs, I know C is not a great golfing language, but whatever!

Compiled with GCC on macOS Sierra.

Ungolfed

main(int i) {
int **m = malloc(8 * i);    // Create n*n matrix
for(int a=0; a<i; a++) {    // Iterate through rows
    m[a] = malloc(4 * i);   // Allocate rows
    for(int b=0; b<i; b++) {    // Iteratre columns
        // Add a 1 to cell if its start or finish, or diagnol
        m[a][b]=((a+b+1==i)||(a==0&&b==0)||(a==i-1&&b==i-1))?1:0;
        printf("%d ",m[a][b]); // Print cell
    }
    printf("\n");           // Print row
}

Usage

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Awesome thanks I just got start golfing, thanks for the help! \$\endgroup\$ – Asleepace Aug 1 '17 at 6:11
  • 1
    \$\begingroup\$ If you change your IO method to accepting a parameter as input, then outputting to STDOUT, then I think f(i){int a,b;for(a=0;a<i;a++){for(b=0;b<i;b++)printf("%d ",a+b+1==i||!a&&!b||a==i-1&&b==i-1);printf("\n");}} works. \$\endgroup\$ – Zacharý Aug 1 '17 at 14:33
  • \$\begingroup\$ Instead of printf("\n") you can do puts("") \$\endgroup\$ – Conor O'Brien Aug 1 '17 at 16:51
  • \$\begingroup\$ Okay, is it okay if I post my solution separately due to the differing IO method? \$\endgroup\$ – Zacharý Aug 1 '17 at 18:27
  • \$\begingroup\$ Ya sure it's all casual for me \$\endgroup\$ – Asleepace Aug 1 '17 at 18:29
2
\$\begingroup\$

Mathematica, 59 56 48 bytes

(x=Sort@IdentityMatrix@#;x[[1,1]]=x[[#,#]]=1;x)&

The identity matrix has a diagonal of 1s, but it's going the wrong way. Sorting the rows fixes this. Then we set the corners to be 1 as well, and return the matrix.

You can test this out in the Wolfram Cloud sandbox by pasting code like the following and clicking "Evaluate cell" or hitting Shift+Enter or the numpad Enter:

(x=Sort@IdentityMatrix@#;x[[1,1]]=x[[#,#]]=1;x)&@5//ArrayPlot


Longer solutions

SparseArray[#->1&/@{Band[{1,#},{#,1},{1,-1}],{1,1},{#,#}}]&

The #->1& is an anonymous function that associates the input with 1, and the Band represents the coordinates from {1,#} to {#,1} going in steps of {1,-1}.

f[n_]:=Boole[#==#2==1||#==#2==n||#+#2==n+1]&~Array~{n,n}

This builds an n by n array where the values are 1 or 0 depending on the truth of "both indices are 1 or both indices are n or both indices sum to n+1".

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

Retina, 44 bytes

\d+
$* 
 $
#
+` ( *)#( *)$
$&¶$1#$2 
^ | $
#

Try it online!

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

Retina, 24 bytes

.+
$* 
.
$'#$`¶
^ | ¶$
#

Try it online! Explanation: The second line ends in a space, so the first stage converts the input into a row of spaces. The second stage then replaces each space in the row with a # in turn, collecting the resulting lines together. The final stage then adds the corner #s.

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

R (+pryr), 36 bytes

pryr::f(matrix(c(1,rep(0,n-1)),n,n))

Evaluates to the function:

function (n) 
matrix(c(1, rep(0, n - 1)), n, n)

Which is a port from this APL answer.

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

PHP, 131 bytes

<?$m=$n=0;while($m<$argv[1]){while($n<$argv[1]){echo($m==$n&&(!$m||$m==$argv[1]-1)||$m+$n==$argv[1]-1)*1;$n++;}echo"\n";$m++;$n=0;}

Exploded view

<?  $m = $n = 0;
    while ($m < $argv[1]) {
        while ($n < $argv[1]) {
            echo ($m == $n && (!$m || $m == $argv[1]-1) ||
                  $m + $n == $argv[1]-1) * 1;
            $n++;
        }
        echo "\n";
        $m++;
        $n = 0;
    }

Not my best work, I'm certain I can golf this down.

\$\endgroup\$
  • \$\begingroup\$ Add $a=$argv[1]; at the beginning and replace all $argv[1] with $a to save several bytes. \$\endgroup\$ – manassehkatz-Reinstate Monica Jul 23 '17 at 4:15
  • \$\begingroup\$ Also take $n= out of the top 0 assignment and move $n=0; from the end of the outer loop to the beginning to save another 3 bytes. \$\endgroup\$ – manassehkatz-Reinstate Monica Jul 23 '17 at 5:36
1
\$\begingroup\$

Actually, 14 18 bytes

A simple algorithm.

Edit: Fixing a bug for n == 1

;;D╤$0D@H@u*'1@+╪i

Ungolfing

                    Implicit input: n
;;                  Duplicate n twice.
  D╤$               Push str(10**(n-1))
     0D@H           Push str(10**(n-1))[:-1]
         @u*        Push str * (n+1)
            '1@+    Append a "1"
                ╪   Split into chunks of length n
                 i  Flatten this list onto the stack
                    Implicit print

Try it online!

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

Gaia, 7 bytes

s…@(Ė¦/

Try it online!

Explanation

s        Square n
 …       Get the range from 0 to n^2-1
  @(     Push n-1
    Ė¦   For each number in the range, check if n-1 divides it
      /  Split into slices of size n
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 67 + 1 (-n) = 68 bytes

$_=($_>1).0 x($_-2).1;for$i(2..length){say;s/^.//;$_.=0}s/0$/1/;say

Try it online!

Takes the input implicitly (-n). Converts that to a string of 1 (iff input > 0) followed by n-2 zeros, followed by a 1. Outputs the string, then removes first character and appends a 0, looping until it has output n-1 rows. For the last row, replace the final character with a 1 before printing.

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

Google Sheets, 58 bytes

=If(A1=1,1,RegexReplace(Rept(10^(A1-2),A1+1)&1,"(.{"&A1&"})","$1
"))

Input is in A1.

Explanation:

  • 10^(A1-2) generates a one followed by n-1 zeroes.
  • Rept(10^(A1-2),A1+1)&1 generates n+1 copies of that sequence with an extra one at the end. For n=5 as an example, that string is 1000100010001000100010001.
  • RegexReplace(~,"(.{"&A1&"})","$1\n") replaces every grouping of n characters with itself plus a line break. (In the actual formula, I use a literal line break rather than the escaped \n.)
  • This breaks on n=1 because 10^-1 = 0.1 so the string is 0.10.11. The If at the beginning escapes that special case.

Results:

Result

I took the screenshot of exactly those cells and the image turned out to be 323 x 232 pixels. I think that's neato.

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

WC, 92 bytes

;>_0|$-$-!!_1|;>@5|$''[<]!!$!_1|;>(?##@2|;>@5|$''[<<<]!!$!_1|?$-[>>>];</#)*$?!!_1|[>]!!$!_1|

Input

Artifact 0: a number ex. 5

Artifact 1: a string ex. #

Output

#   #
   #
  #
 #
#   #

Explanation

;>_0|                  Create variable set to artifact 0
$-$-                   Decrement twice
!!_1|                  Print artifact 1 with no newline
;>@5|                  Create variable set to global 5 (the space character)
$''[<]                 Repeat variable times the previous variable
!!$                    Print with no newline
!_1|                   Print artifact 1 with newline
;>(                    Create variable as function
   ?                   Reset variable index to 0
   ##@_2|              Start if-not statement, runs if not global 2 (zero)
      ;>@5|            Create variable set to global 5 (the space character)
      $''[<<<]         Repeat variable times index-3 (first variable)
      !!$              Print with no newline
      !_1|             Print artifact 1 with newline
      ?$-              Reset index to 0 and decrement
      [>>>]            Move index up 3
      ;<               Delete at index
      /                Restart context
   #                   End statement
)                      End function
*$?                    Call function and reset index
!!_1|                  Print artifact 1 with no newline
[>]!!$                 Move index up 1 and print with no newline
!_1|                   Print artifact 1 with newline

NOTE: Do NOT set artifact 1 to 1, it will freeze. Works for n > 1

Try it online!

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

Perl 5, 66 bytes

$n=pop;$_='#';for$x(0..$n){$_.=$"x($n-2).'#'};s/(.{$n})/$1\n/g;say

Takes input as first command line argument.

Builds up a string of length n^2 with # at the proper spots, then inserts newlines at the right places.

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

Python 3, 71 67 65 76 bytes

lambda n:n>1and''.join(' #'[i%~-n<1]+'\n'*(-~i%n<1)for i in range(n*n))or'#'

Try it online!

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

Java 8, 74 bytes

Essentially just a port of Kamil's second C# solution here.

n->{int g[][]=new int[n][n],i=0;for(;i<n*n;i+=n-1)g[i/n][i%n]=1;return g;}

Try It Online

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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