27
\$\begingroup\$

Write the shortest code measured by byte count to generate an ASCII grid composed of rhombi, given the following parameters:

  • m - number of complete rhombi in one row
  • n - number of rows
  • s - side of the smallest rhombus
  • r - level of nesting - how many rhombi are there inside the "base ones" (which are fonud between the intersections of the grid)

Examples

1. Input: 5 3 1 0
Output:

/\/\/\/\/\
\/\/\/\/\/
/\/\/\/\/\
\/\/\/\/\/
/\/\/\/\/\
\/\/\/\/\/

A 5x3 grid of rhombi with side 1, no nesting

2. Input: 3 2 2 0
Output:

 /\  /\  /\
/  \/  \/  \
\  /\  /\  /
 \/  \/  \/ 
 /\  /\  /\
/  \/  \/  \
\  /\  /\  /
 \/  \/  \/ 
 
A 3x2 grid of rhombi with side 2, no nesting

3. Input: 5 2 1 2
Output:

///\\\///\\\///\\\///\\\///\\\
///\\\///\\\///\\\///\\\///\\\
///\\\///\\\///\\\///\\\///\\\
\\\///\\\///\\\///\\\///\\\///
\\\///\\\///\\\///\\\///\\\///
\\\///\\\///\\\///\\\///\\\///
///\\\///\\\///\\\///\\\///\\\
///\\\///\\\///\\\///\\\///\\\
///\\\///\\\///\\\///\\\///\\\
\\\///\\\///\\\///\\\///\\\///
\\\///\\\///\\\///\\\///\\\///
\\\///\\\///\\\///\\\///\\\///

A 5x2 grid of rhombi with side 1 (the smallest rhombus), level of nesting is 2

4. Input: 4 2 2 1
Output:

 //\\  //\\  //\\  //\\ 
///\\\///\\\///\\\///\\\
//  \\//  \\//  \\//  \\
\\  //\\  //\\  //\\  //
\\\///\\\///\\\///\\\///
 \\//  \\//  \\//  \\//   
 //\\  //\\  //\\  //\\ 
///\\\///\\\///\\\///\\\
//  \\//  \\//  \\//  \\
\\  //\\  //\\  //\\  //
\\\///\\\///\\\///\\\///
 \\//  \\//  \\//  \\//   
 
A 4x2 grid of rhombi with side 2 with level of nesting 1 
 
5. Input: 4 2 3 3
Output:
 
  ////\\\\    ////\\\\    ////\\\\    ////\\\\
 /////\\\\\  /////\\\\\  /////\\\\\  /////\\\\\
//////\\\\\\//////\\\\\\//////\\\\\\//////\\\\\\
//////\\\\\\//////\\\\\\//////\\\\\\//////\\\\\\
/////  \\\\\/////  \\\\\/////  \\\\\/////  \\\\\
////    \\\\////    \\\\////    \\\\////    \\\\
\\\\    ////\\\\    ////\\\\    ////\\\\    ////
\\\\\  /////\\\\\  /////\\\\\  /////\\\\\  /////
\\\\\\//////\\\\\\//////\\\\\\//////\\\\\\//////
\\\\\\//////\\\\\\//////\\\\\\//////\\\\\\//////
 \\\\\/////  \\\\\/////  \\\\\/////  \\\\\/////  
  \\\\////    \\\\////    \\\\////    \\\\////  
  ////\\\\    ////\\\\    ////\\\\    ////\\\\
 /////\\\\\  /////\\\\\  /////\\\\\  /////\\\\\
//////\\\\\\//////\\\\\\//////\\\\\\//////\\\\\\
//////\\\\\\//////\\\\\\//////\\\\\\//////\\\\\\
/////  \\\\\/////  \\\\\/////  \\\\\/////  \\\\\
////    \\\\////    \\\\////    \\\\////    \\\\
\\\\    ////\\\\    ////\\\\    ////\\\\    ////
\\\\\  /////\\\\\  /////\\\\\  /////\\\\\  /////
\\\\\\//////\\\\\\//////\\\\\\//////\\\\\\//////
\\\\\\//////\\\\\\//////\\\\\\//////\\\\\\//////
 \\\\\/////  \\\\\/////  \\\\\/////  \\\\\/////  
  \\\\////    \\\\////    \\\\////    \\\\////  

A 4x2 grid of rhombi with side 3, level of nesting 3

Be sure to display the partially visible rhombi at the edges and corners where necessary.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ @AdmBorkBork By "nesting" I mean the number of rhombi inscribed in the base ones, found between the intersections of the grid. \$\endgroup\$ Oct 31, 2017 at 17:19
  • 3
    \$\begingroup\$ Related \$\endgroup\$
    – Luis Mendo
    Oct 31, 2017 at 17:46
  • \$\begingroup\$ @Luis Mendo - yes, it's clearly related to my task. \$\endgroup\$ Oct 31, 2017 at 18:18
  • \$\begingroup\$ @Stewie Griffin: codegolf.stackexchange.com/questions/146747/… — 3rd test case \$\endgroup\$
    – sergiol
    Nov 1, 2017 at 0:29
  • 5
    \$\begingroup\$ Oh, how I miss my pillow! \$\endgroup\$ Nov 1, 2017 at 8:23

9 Answers 9

17
\$\begingroup\$

SOGL V0.12, 20 bytes

ā.I∫e+H╚╬8}:±№╬8╬¡∙*

Try it Here! Takes the input in the reversed order of what they are in the examples - r, s, n, m.

Explanation:

ā                     push an empty array - canvas
 .I∫      }           for each in range(input) (1-indexed)
    e+                  add the second input
      H                 decrement
       ╚                create a diagonal of that size
        ╬8              insert into the canvas
           :          create a duplicate of the canvas
            ±№        reverse it vertically and horizotally
              ╬8      insert that into the canvas
                έ    quad-palindromize
                  ∙   multiply vertically by the next input
                   *  multiply horizontally by the next input
\$\endgroup\$
7
  • 2
    \$\begingroup\$ This is just amazing, how do you even compress such a program in 20 bytes. \$\endgroup\$ Oct 31, 2017 at 17:45
  • 1
    \$\begingroup\$ This is just brilliant... +1 from me for beating Charcoal by a staggering 28 bytes :O \$\endgroup\$
    – Mr. Xcoder
    Oct 31, 2017 at 18:05
  • \$\begingroup\$ That''s really impressive! \$\endgroup\$ Oct 31, 2017 at 18:28
  • \$\begingroup\$ @Mr.Xcoder 19 bytes now. But then I'm up against builtins like ∙*... \$\endgroup\$
    – Neil
    Oct 31, 2017 at 19:57
  • 1
    \$\begingroup\$ Vectorised string repeating is reasonably short in Charcoal; if I could build up a string representation of the diamond it would only cost me 6 bytes to repeat it. Unfortunately it takes me 50 bytes to do that. On the other hand, drawing the diamond only takes me 17 bytes, just 1 more than SOGL... but it then takes 20 bytes to multiply the canvas. \$\endgroup\$
    – Neil
    Nov 1, 2017 at 10:26
9
\$\begingroup\$

Charcoal, 48 39 37 bytes

UO⊕Iε\F⊖IζC¹¦¹‖ML≔⊗⁺IζIεδF⊖NCδ⁰F⊖NC⁰δ

Try it online! Link is to verbose version of code. Explanation:

UO⊕Iε\

Draw a square of size r + 1. This is a quarter of a nested diamond of size 1.

F⊖IζC¹¦¹

Copy the square 1 square right and down s - 1 times to get it to the right size.

‖ML

Reflect it to become a full nested diamond.

≔⊗⁺IζIεδ

Compute the size of this nested diamond.

F⊖NCδ⁰

Copy the diamond to the right m - 1 times.

F⊖NC⁰δ

Copy the diamond downwards n - 1 times.

\$\endgroup\$
8
\$\begingroup\$

Python 2, 160 159 158 bytes

-1 byte thanks to Jonathan Frech

m,n,s,r=input()
l=~-s*' '+'/'*(r-~r)+~-s*' '
for x in range(n*2):print'\n'.join(m*(l[i:i+s+r]+l.replace(*'/\\')[i:i+s+r][::-1])for i in range(r+s))[::1-x%2*2]

Try it online!

This uses the fact that the bottom of the rhombus is the top inverted ([::-1]), iterating over range(n*2) and using ~x%2*2-1 to control if it is the top or the bottom.
For the top (and the bottom) the right side is just the left side inverted and replacing / with \ -> l.replace(*'/\\')..[::-1]
To generate the pattern / nesting ~-s*' '+'/'*(1+r*2)+~-s*' ' is used to make a string like /// that will be iterated and chopped :

   '|  //|/  '  
  ' | ///|  '  
 '  |/// | '  
'  /|//  |'  
\$\endgroup\$
1
  • \$\begingroup\$ I think (1+r*2) can be (r-~r). \$\endgroup\$ Nov 1, 2017 at 23:39
7
\$\begingroup\$

Julia 0.6, 190 bytes

g(n,m,s,r)=(s+=r+1;f(i,j,u=mod(i-j+r,2s),v=mod(j+i+r,2s))=(" \\/")[abs(u-r)<abs(v-r)?1+(u<=2r):1+2(v<=2r)];
for i=1:2(s-1)m println((f(i+(i-1)÷(s-1),s+j+(j-1)÷(s-1))for j=1:2(s-1)n)...)end)

This is a functional solution which computes for every index pair i,j what the symbol should be displayed.

Try it online!

Illustration

Start with a grid

f(i,j,u=mod(i,2s),v=mod(j,2s))=(" -|*")[1+(u==0)+2(v==0)]
for i=1:2(s-1)m println((f(i-1,j)for j=1:2(s-1)n)...)end

---------*---------*----
         |         |    
         |         |    
         |         |    
         |         |    
         |         |    
         |         |    
         |         |    
         |         |    
         |         |    
---------*---------*----
         |         |    
         |         |    
         |         |    
         |         |    
         |         |    

r > 0 means thicker lines

f(i,j,u=mod(i+r,2s),v=mod(j+r,2s))=(" -|*")[1+(u<=2r)+2(v<=2r)]
for i=1:2(s-1)m println((f(i,j)for j=1:2(s-1)n)...)end

**-----*****-----*****--
**-----*****-----*****--
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  
**-----*****-----*****--
**-----*****-----*****--
**-----*****-----*****--
**-----*****-----*****--
**-----*****-----*****--
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  
||     |||||     ||||| 

Handle the corners by checking which line on the original grid is closest

f(i,j,u=mod(i+r,2s),v=mod(j+r,2s))=(" -|")[abs(u-r)<abs(v-r)?1+(u<=2r):1+2(v<=2r)]
for i=1:2(s-1)m println((f(i,j)for j=1:2(s-1)n)...)end

|-------|||-------|||---
||-----|||||-----|||||--
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  
||-----|||||-----|||||--
|-------|||-------|||---
---------|---------|----
|-------|||-------|||---
||-----|||||-----|||||--
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  
||     |||||     |||||  

A fairy tells us to remove every s-1 line

f(i,j,u=mod(i+r,2s),v=mod(j+r,2s))=(" -|")[abs(u-r)<abs(v-r)?1+(u<=2r):1+2(v<=2r)]
for i=1:2(s-1)m println((f(i+(i-1)÷(s-1),s+j+(j-1)÷(s-1))for j=1:2(s-1)n)...)end

---||------||------||---
--||||----||||----||||--
  ||||    ||||    ||||  
  ||||    ||||    ||||  
  ||||    ||||    ||||  
  ||||    ||||    ||||  
--||||----||||----||||--
---||------||------||---
---||------||------||---
--||||----||||----||||--
  ||||    ||||    ||||  
  ||||    ||||    ||||  
  ||||    ||||    ||||  
  ||||    ||||    ||||  
--||||----||||----||||--
---||------||------||---

Traverse diagonally and done

f(i,j,u=mod(i-j+r,2s),v=mod(j+i+r,2s))=(" \\/")[abs(u-r)<abs(v-r)?1+(u<=2r):1+2(v<=2r)]
for i=1:2(s-1)m println((f(i+(i-1)÷(s-1),s+j+(j-1)÷(s-1))for j=1:2(s-1)n)...)end

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

JavaScript (ES6), 154 bytes

f=
(m,n,s,r)=>[...Array((s+=r)*n*2)].map((_,i)=>[...Array(s*m*2)].map((_,j)=>i/s&1^j/s&1?`\\ `[g(j%s)]:`/ `[g(s-1-j%s)],g=j=>i%s-j>r|j-i%s>r).join``).join`
`
<div oninput=o.textContent=f(+m.value,+n.value,+s.value,+r.value)>
m: <input type=number min=0 id=m><br>
n: <input type=number min=0 id=n><br>
s: <input type=number min=0 id=s><br>
r: <input type=number min=0 id=r></div>
<pre id=o>

Directly calculates the character at each cell of the output.

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

CJam, 44

q~:R+,_ff{-zR>}{_W%:~\+"\ /"f=}%_W%Wf%+*f*N*

Try it online

Explanation:

q~           read and evaluate the input
:R+          save the last number in variable R, then add the last 2 numbers (s+r)
,_           make an array [0 1 … s+r-1] and duplicate it
ff{…}        make a matrix, calculating for each (x,y) pair from the 2 arrays:
  -z         abs(x-y)
  R>         compared with R (1 if greater, 0 if not)
{…}%         transform each row of the matrix:
  _W%        duplicate and reverse it
  :~         bitwise-NOT each element (0 → -1, 1 → -2)
  \+         prepend to the original row
  "\ /"f=    replace numbers with characters from this string (by index):
              0 → '\'; 1, -2 → ' '; -1 → '/'
              this generates the "/\" part
_W%          duplicate the matrix and reverse the rows
Wf%+         reverse each row, then append (by rows) to the original matrix
              this adds the "\/" part
*            repeat the matrix (by rows) n times
f*           repeat each row m times
N*           join the rows with newlines
\$\endgroup\$
2
\$\begingroup\$

C# (.NET Core), 167 bytes

(c,r,s,n)=>{int w=s+n,i=0,j;var g="";for(;i<r*2*w;i++,g+="\n")for(j=0;j<c*2*w;){int y=i%w,q=(j/w+i/w+1)%2,p=~-w*q+j++%w*(1-2*q);g+=p>y+n|p<y-n?' ':"\\/"[q];}return g;}

Try it online!

I'm surprised by the size I managed; I was initially expecting a longer solution. In saying this, I'm sure there are other tricks I've missed.

DeGolfed

(c,r,s,n)=>{
    int w=s+n, // rhombus quadrant width, and height
        i=0, // string row
        j; // string column

    var g="";

    // go through every character row and column
    for(; i < r*2*w; i++, g += "\n")
        for(j = 0; j < c*2*w;)
        {
            int y = i % w, // vertical position in the quadrant
                q = ( j / w + i / w + 1) % 2, // Get the rhombus quadrant as a 0 or 1
                p = ~-w * q + j++ % w * (1-2*q); // horizontal position in quadrant. the value is either ascending or descending depending on the quadrant

            // select which character to use at this [i,j] position
            g += p > y + n | p < y - n ? ' ' : "\\/"[q];
        }

    return g;
}
\$\endgroup\$
1
1
\$\begingroup\$

Python 2, 201 189 bytes

def f(m,n,s,r):Z=range(s+r);R=[r-~min(i,s+~i+r,min(s-1,r))for i in Z];L=[m*(' '*(s+~i)+'/'*R[i]+'  '*(i-r)+'\\'*R[i]+' '*(s+~i))for i in Z];print'\n'.join((L+[l[s+r:]+l[:s+r]for l in L])*n)

Try it online!

Uses the fact that the bottom is the same as the top, but shifted:

Top:       /\/\/\
Bottom:     /\/\/\

Saved 22 bytes thanks to Jonathan Frech

\$\endgroup\$
7
  • \$\begingroup\$ s-i-1 can be s+~i, saving two bytes. r+1+min(... can be r-~min(..., saving another one. L=[(...)*m for can be L=[m*(...)for, saving one more byte. \$\endgroup\$ Nov 1, 2017 at 23:15
  • \$\begingroup\$ L+=[...];print'\n'.join(L*n) can be print'\n'.join((L+[...])*n) to save another byte, resulting in 196 bytes. \$\endgroup\$ Nov 1, 2017 at 23:18
  • \$\begingroup\$ 195 bytes, if one also replaces s+r-i-1 with s+~i+r. \$\endgroup\$ Nov 1, 2017 at 23:20
  • \$\begingroup\$ 190 bytes. \$\endgroup\$ Nov 1, 2017 at 23:22
  • \$\begingroup\$ Alternative 192 bytes version or 191 bytes version using exec and string formatting. \$\endgroup\$ Nov 1, 2017 at 23:28
1
\$\begingroup\$

Perl 5, 159 + 3 (-anl) bytes

($m,$n,$s,$r)=@F;$s=$"x($s+$r-1);$_="$s/\\$s"x$m;$n*=2;{$t=$_;map$t=~s, ?(\S) ?,$1x$&=~y///c,ge,1..$r;print$t;redo if s, /,/ ,g&&s,\\ , \\,g||y,/\\,\\/,&&--$n}

Try It Online

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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