Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Creating a Crossed Square

You are to take input of an integer of one or more and output a square made of any printable character of your choice with a diagonal cross through the centre.

The general idea is for the output to be a hollow square that has a diagonal cross through it.:

Input: 7
Output:
*******
*#   #*
* # # *
*  #  *
* # # *
*#   #*
*******

In the above example the '*'s represent the outer box and the '#'s represent the diagonal cross.

Note that the above example uses two different characters so that it is easier to see what the output looks like, your program should use one character only.

Input

An integer of 1 or more, it is guaranteed to be odd.

Output

A square that is made up of a character of your choice with a cross through the middle.

  • The cross must be diagonal
  • The square may be output via the function or written to output
  • Trailing newlines are okay
  • Can output as a graphic, diagram or image if you wish too

Examples

Input: 1
Output:
*

Input: 3
Output:
***
***
***

Input: 5
Output:
*****
** **
* * *
** **
*****

Input: 7
Output:
*******
**   **
* * * *
*  *  *
* * * *
**   **
*******

Specs

  • Functions or full programs are allowed
  • You can get input by your preferred means
  • Standard loopholes are disallowed
  • Programs must work without any additional statements i.e. usings in C#, they must be included in the entry
  • You can output from a function or print the result

This is code golf so the shortest solution wins.

share|improve this question
1  
Could we also index these outputs with 0,1,2,3,...? – flawr 14 hours ago
    
@flawr I'm not 100% sure what you mean – TheLethalCoder 14 hours ago
    
@TheLethalCoder He asks whether he can take input n and print a square of size 2n+1. – Martin Ender 14 hours ago
    
@MartinEnder Oh so in my examples input 1 gives * but for him it will be input 0? – TheLethalCoder 14 hours ago
1  
@TheLethalCoder Yes, and input 1 would yield your example for 3. – Martin Ender 14 hours ago

16 Answers 16

MATL, 20 19 17 bytes

2-:XdtP!+~TTYa1YG

You can try it experimentally in MATL online. You may need to refresh the page if it doesn't work.

Sample run:

enter image description here

ASCII version: 19 bytes

2-:XdtP!+~TTYa~42*c

Try it online!

share|improve this answer
    
But at least make sure that the lines are parallel & rectangular. :D – flawr 13 hours ago
    
@flawr Hm? What do you mean? – Luis Mendo 13 hours ago
    
At least in the middle looks as if the sides of the squares are slanted, but it's just an illusions. Or is it? (Might also be a black hole behind my screen, warping space time.) – flawr 11 hours ago
    
@flawr Or maybe go to the eye doctor :-P – Luis Mendo 10 hours ago

JavaScript (ES6), 96 bytes

f=
n=>[...Array(n--)].map((_,i,a)=>a.map((_,j)=>i&&j&&n-i&&n-j&&i-j&&n-i-j?' ':'*').join``).join`
`
;
<input type=number min=1 step=2 oninput=  o.textContent=f(this.value)><pre id=o>

share|improve this answer

Java 7, 131 130 128 125 bytes

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

3 bytes saved thanks to @LeakyNun.

Ungolfed & test code:

Try it here.

class M{
  static String c(int n){
    String r = "";
    for(int i = -1, j; ++i < n; r += "\n"){
      for(j = 0; j < n;
            r += i < 1      // Responsible for the first horizontal line
               | j < 1      // Responsible for the first vertical line
               | n-i < 2    // Responsible for the last horizontal line
               | n-j < 2    // Responsible for the last vertical line
               | i == j     // Responsible for the top-left to bottom-right diagonal line
               | i == n-++j // Responsible for the top-right to bottom-left diagonal line (and increasing j)
             ? "*"
             : " ");
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c(1));
    System.out.println(c(3));
    System.out.println(c(5));
    System.out.println(c(7));
  }
}

Output:

*

***
***
***

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

*******
**   **
* * * *
*  *  *
* * * *
**   **
*******
share|improve this answer
1  
String c(int n){String r="";for(int i=-1,j;++i<n;r+="\n")for(j=0;j<n;r+=i<1|j<1|n-i<2|n-j<2|i==j‌​|i==n-++j?"*":" ")return r;} 4 bytes saved – Leaky Nun 13 hours ago
    
@LeakyNun 3 actually. You'd still need the ; behind the inner for-loop. – Kevin Cruijssen 12 hours ago

C#, 112 101 bytes

Thanks to TheLethalCoder for reminding me that these anonymous lambda statement-nor-expression things are allowed in C#.

n=>{var r="";for(int y=n--,x;y-->0;r+="*\n")for(x=0;x<n;r+=y%n*x<1|y==x|y==n-x++?"*":" ");return r;};

Who said C# isn't a fun golfing language?

share|improve this answer
    
I know, right? 27591 bytes :p – Jonathan Allan 8 hours ago

Python, 114 110 96 bytes

Totally changed:

def b(n):m=n-1;g=range(n);return[bin(sum(2**p for p in 0<r<m and{0,m,r,m-r}or g))[2:]for r in g]

Returns a list of strings, characters using 1 and 0.

Test it at ideone


Previous Python 2 @110

def f(n):g=range(n);n-=1;print'\n'.join(''.join((c in(r,n-r,0,n)or r in(0,n))and'#'or' 'for c in g)for r in g)

Test it on ideone

share|improve this answer
    
Save 6 bytes by converting to a lambda and restructuring the and-or expression: lambda n:[bin(sum(2**p for p in[range(n),{0,n-1,r,n-1-r}][0<r<n-1]))[2:]for r in range(n)]. – TheBikingViking 5 hours ago

Matlab, 68 66 64 58 bytes

Since graphical output is allowed too:

k=input('');[x,y]=ndgrid(abs(-k:k));spy(~(max(x,y)<k&x-y))

Which outputs e.g.

enter image description here

The ascii only versions would be:

This is using the indexing 0,1,2,3,...

k=input('');[x,y]=ndgrid(abs(-k:k));[(max(x,y)==k|~(x-y))*42,'']

Alternatively with the indexing 1,3,7,...:

n=input('');k=1:n;m=eye(n);m([k,end-k+1])=1;[(m|flip(m'))*42,'']
share|improve this answer
    
Nice, not only does the graphical output look better imo, it's cool that it's also shorter in terms of bytes. Usually making something more graphical instead of plain ASCII would only increase the byte-count (usually by a lot). – Kevin Cruijssen 13 hours ago

R, 102 bytes

    n=scan();for(i in 1:n){for(j in 1:n){z=" ";if(i%in%c(1,n,n-j+1)|j%in%c(1,i,n))z="*";cat(z)};cat("\n")}

Note that it is more efficient to express the condition using %in% than i==1|j==1|...

share|improve this answer
    
It is possible to golf away one character if the input is guaranteed to be more than one: n=scan();for(i in n:1){for(j in n:2){z=" ";if(i%in%c(1,n,n-j+1)|j%in%c(i,n))z="*";cat(z)};cat("*\n")} – JDL 13 hours ago

Java, 130 bytes

s->{for(int i=0;i<s;i++)for(int j=0;j<s;j++)System.out.print((s-1-i==j||i==j||i==0||j==0||i==s-1||j==s-1)?j==s-1?"*\n":"*":" ");};

Test Program

Consumer<Integer> consumer = s -> {
        for (int i = 0; i < s; i++) {
            for (int j = 0; j < s; j++) {
                System.out.print((s - 1 - i == j || i == j || i == 0 || j == 0 || i == s - 1 || j == s - 1) ? j == s - 1 ? "*\n" : "*" : " ");
            }
        }
    };

    consumer.accept(20);
share|improve this answer
    
+1! I would specify that it's Java 8, btw. Also, you can golf it a bit by removing the int before j and use int i=0,j; instead. You can also replace all || with | and remove the parenthesis in the ternary-check. Also, you use s-1 four times, so I would put this in a variable. Also, you can change the ==0 to <1. So in total it becomes s->{for(int i=0,j,x=s-1;i<s;i++)for(j=0;j<s;j++)System.out.print(x-i==j|‌​i==j|i<1|j<1|i==x|j=‌​=x?j==x?"*\n":"*":" ");} (116 bytes) Quite a bit shorter than my Java 7 answer, so nice approach! – Kevin Cruijssen 13 hours ago
1  
@KevinCruijssen I always end up with a shorter answer, but with more room for improvement than you LMAO. Well golfed my friend. – Sean Bean 13 hours ago
    
Hehe. xD Feel free to use the 116 byte version btw. It's your code, just golfed down some more. ;) My Java 7 answer (which is unfortunately longer) uses a slightly different approach. If I would edit it into the 116 byte version I would basically steal your answer, which I don't want to. – Kevin Cruijssen 13 hours ago
    
No point just copying and pasting your golfs, I normally post a quick mock up and then come back to it later on to see if I missed anything that could be golfed. But you RUINED IT FOR MEE :( haha jk – Sean Bean 13 hours ago
    
Ah sorry. Most of the tips I gave are actually present in the Tips for golfing in Java. I guess I'm just 2quick4u. ;) – Kevin Cruijssen 12 hours ago

Pyth, 27 25 bytes

jmsm?|qFKaLJ/Q2,dk}JKN\ Q

Try it online!

Probably golfable.

share|improve this answer

Haskell, 102 bytes 100 bytes

Saved 2 bytes, thanks to flawr.

c s=unlines$f(\m->f(m#))where f=(<$>[1..s]);m#n|or((==)<$>[n,m]<*>[1,s])||n==m||n==s-m+1='*'|1>0=' '

Ungolfed version:

cross :: Int -> String
cross s = unlines $ map line [1..s]
    where line m = map (pos m) [1..s]
          pos m n | n == m = '*'
                  | n == s - m + 1 = '*'
                  | elem m [1, s] = '*'
                  | elem n [1, s] = '*'
                  | otherwise = ' '

I'm sure this can still be improved, but this is what I've come up with for now.

share|improve this answer
2  
You're using [1..s] twice, I think you could define that in where. – flawr 11 hours ago
    
It would result in 102 bytes too, since we'd have to add an extra space before the where keyword. c s=unlines$(\m->(m#)<$>z)<$>z where z=[1..s];m#n|or((==)<$>[n,m]<*>[1,s])||n==m||n==s-m+1='*'|1>‌​0=' ' – sudee 5 hours ago
1  
Ah right, but you can pack <$>[1..s] into a function, right? Like c s=unlines$f(\m->f(m#))where m#n|or((==)<$>[n,m]<*>[1,s])||n==m||n==s-m+1='*'|1>0=' ';f=(<$>[1..s]) – flawr 4 hours ago
    
Good point, that does work indeed. :) – sudee 4 hours ago

Scala, 141 137 bytes

val s=args(0).toInt-1;val t=0 to s;print(t.map{x=>t.map{y=>if(x==0||x==s||y==0||y==s||x==y||x==s-y)"*" else " "}.mkString+"\n"}.mkString)

Run:

$ scala cross.scala 10

Technically I could remove the print stuff and go to something like

def c(n:Int)={val (s,t)=(n-1,0 to n-1);t.map{x=>t.map{y=>if(x==0||x==s||y==0||y==s||x==y||x==s-y)"*" else " "}.mkString+"\n"}.mkString}

This would make it 135 or 121 bytes depending on whether you count the function syntax stuff.

Readable version:

def cross(n: Int) = {
   // Declares both s and t as variables with tuple expansion
   // s is the zero-based size and t is a range from 0 to s
   val (s,t) = (n-1, 0 to n-1)

   // Maps all rows by mapping the columns to a star or a space
   t.map { x =>
      t.map { y =>
        if (x == 0 || x == s || y == 0 || y == s || x == y || x == s-y) "*" 
        else " "
      }.mkString+"\n" // Concatenate the stars and spaces and add a newline
   }.mkString         // Concatenate the created strings
 }
share|improve this answer

C, 140 121 114 bytes

19 bytes thanks to Quentin.

7 bytes saved by switching from a double-nested loop to one loop.

main(a){scanf("%d",&a);for(int i=0;i<a*a;i++,i%a||puts(""))putchar(i/a&&i/a^a-1&&i%a&&-~i%a&&i%-~a&&i%~-a?32:42);}

Golfing suggestions welcome.

share|improve this answer
    
I never program in C, but isn't it possible to place the int in the first for-loop like in Java? I.e. int i,j;for(i=0; to for(int i=0,j; – Kevin Cruijssen 14 hours ago
    
The last time I used C you couldn't even put the int i,j; after the scanf! – Neil 14 hours ago
    
Try n+~i-j etc. – Neil 14 hours ago
    
GCC is fine with removing the #include completely. – Quentin 13 hours ago
    
@Neil What do you mean by you couldn't put that after that? – Leaky Nun 13 hours ago

Logo, 155 bytes

Graphical solution, implemented as a function

I retooled my answer for Alphabet Triangle and changed the angles around a bit. As before, r draws a line of characters. This time, the b function draws a box by drawing one straight edge and one diagonal, rotating, and repeating four times. This causes the diagonals to be drawn twice (on top of each other), but it was less code than handling it separately. This answer also properly handles even numbers. I had to add special handling for an input of 1 to prevent it from going forward.

I implemented it as a function, b which takes the size as an argument:

pu
to r:n:b:l repeat:n[rt:b label "A lt:b if repcount>1[fd:l]] end
to b:s
repeat 4[rt 90
r:s 90-heading 20 rt 135
r:s 90-heading 20*sqrt 2 rt 45]
end

Try it out on Calormen.com's Logo interpreter. To call it, append a line and call b in the following format:

b 7

Sample of size 7

... or try the sampler platter, which draws four samples in sizes 5, 7, 9, and 11, rotating 90 degrees in between:

repeat 4[
  b repcount*2+3
  rt 90
]

Sample of multiple sizes

share|improve this answer

PowerShell (133)

filter s($x){1..$x|%{$o="";$r=$_;1..$x|%{if($_-eq1-or$r-eq1-or$_-eq$x-or$r-eq$x-or$r-eq$_-or$r-1-eq$x-$_){$o+="*"}else{$o+="_"}};$o}}

Clunky, but it works well enough.

s(11)
***********
**_______**
*_*_____*_*
*__*___*__*
*___*_*___*
*____*____*
*___*_*___*
*__*___*__*
*_*_____*_*
**_______**
***********

Golfing suggestions definitely welcome, it's been too long since I've PowerShell'd.

share|improve this answer

Python 2, 83 bytes

i=n=input()
while i:l=['* '[1<i<n]]*n;i-=1;l[0]=l[~0]=l[i]=l[~i]='*';print`l`[2::5]

Modifies a list of the row's characters to put a * into the first, last, i'th, and i'th-to-last place. The first and last row start as all *, and the rest as all spaces. Works for evens too. A lambda expression is probably shorter than modification, but I like this method.

share|improve this answer

Python 2, 65 bytes

i=n=2**input()/2
while i:print bin((n>i>1or~-n)|n|i|n/i)[2:];i/=2

Uses Jonathan Allan's idea of outputting binary numbers like:

11111
11011
10101
11011
11111

The rows are created with bit arithmetic and displayed in binary. Each part it or'ed into the rest. The part are are produced by powers of 2 n (fixed) and i (falling) via

  1. Left side 1
  2. Right side n
  3. Diagonals i and n/i
  4. Top and bottom by n-1 when i==1 or i==n.

Actually, (1) and (4) are combined by producing 1 when 1<i<n and n-1 otherwise.

share|improve this answer

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.