g | x | w | all
Bytes Lang Time Link
216Python 3230719T101617Zkeymasta
145Scala230720T115141Z138 Aspe
076Python 3230719T181158Zxnor
037Charcoal230718T103318ZNeil
090JavaScript ES6230718T084659ZArnauld
04705AB1E230718T080244ZKevin Cr
096Raku230718T050447Zbb94

Python 3, 222 216 bytes

r=[];z=(0,3,4,7);m=-1
for i in range(8):
	r.append([]);s=i*2-(i+1)//4
	for q in range(7):d=q-3-int(q>3)+int(q<2 and i in z);r[m]+=[s+d];r[m][m]="-"if(q in(2,4)and i in z)or q==3 and i in(1,2,5,6)else r[m][m]
print(r)

Try it online!

Scala, 145 bytes

Port of @xnor's Python answer in Scala.


Golfed version. Try it online!

var n=0;for(r<-Seq(21,40,40,36)++Seq(21,40,40,36)){n+= -4|r;println(Seq(1,1,5,3,5,1,1).map(c=>if(r%c==0){n+=1;n.toString}else"-").mkString(","))}

Ungolfed version. Try it online!

object Main {
  def main(args: Array[String]): Unit = {
    var n = 0
    val rs = List(21, 40, 40, 36) ++ List(21, 40, 40, 36)
    val cs = List(1, 1, 5, 3, 5, 1, 1)

    for (r <- rs) {
      n += -4 | r
      val result = cs.map { c =>
        if (r % c == 0) {
          n += 1
          n.toString
        } else "-"
      }
      println(result.mkString(", "))
    }
  }
}

Python 3, 76 bytes

n=0
for r in b"(($"*2:n+=-4|r;print([r%c*'-'or(n:=n+1)for c in b""])

Try it online!

This prints each row as its own list. The two bytestrings contain unprintable characters -- here's the code with their ASCII values shown:

n=0
for r in[21,40,40,36]*2:n+=-4|r;print([r%c*'-'or(n:=n+1)for c in[1,1,5,3,5,1,1]])

Try it online!

The r's in [21,40,40,36]*2 correspond to the 8 rows, and the c's in [1,1,5,3,5,1,1] to the 7 columns. They are chosen to make a "modulo table" producing the positions of the dashes, with a dash where r%c==1 and r%c==0 elsewhere.

           c
     1 1 5 3 5 1 1 
r  %--------------
21 | 0 0 1 0 1 0 0
40 | 0 0 0 1 0 0 0
40 | 0 0 0 1 0 0 0
36 | 0 0 1 0 1 0 0
21 | 0 0 1 0 1 0 0
40 | 0 0 0 1 0 0 0
40 | 0 0 0 1 0 0 0
36 | 0 0 1 0 1 0 0

Each non-dash position is filled with the number n, which is first incremented. Changes to n persist between rows, so before the start of each row we decrease n from the end of the previous row by substracting either 3 or 4, noting that it will increment by 1 before the first value is produced.

These deltas are encoded per-row by the r's as -4|r, which produces [-4,-3,-3,-3,-4,-3,-3,-3]. Because this pattern repeats in 2 blocks of 4 for the 8 rows, as did the dash pattern, we write the r's list as a four-entry list repeated twice, saving bytes.

Here are all the properties we needed the hardcoded r's and c's to satisfy:

-4|21 == -3
-4|40 == -4
-4|36 == -4

 21%5 == 36%5 == 1
 40%3 == 1
 21%1 == 40%1 == 36%1 == 40%5 == 21%3 == 36%3 == 0

I found these with a brute-force search, and many other options were possible.

Charcoal, 47 39 37 bytes

E⁸E⁺Σ…68ι⊕E⁷Σ…432234λ⎇﹪λ⁴⁺⊖⊖÷λ⁴…*‹λ⁸-

Try it online! Link is to verbose version of code. Outputs a Charcoal array, i.e. each element on its own line and each row double-spaced from the previous. Explanation:

 ⁸                                      Literal integer `8`
E                                       Map over implicit range
           ⁷                            Literal integer `7`
          E                             Map over implicit range
              432234                    Literal string `432234`
             …                          Truncated to length
                    λ                   Current column
            Σ                           Digital sum
         ⊕                              Vectorised increment
   ⁺                                    Vectorised add
      68                                Literal string `68`
     …                                  Extended to length
        ι                               Current row
    Σ                                   Digital sum
  E                                     Map over list
                       λ                Inner value
                      ﹪                 Modulo
                        ⁴               Literal integer `4`
                     ⎇                  If divisible then
                                    -   Literal string `-` otherwise
                             λ          Current value
                            ÷           Integer divided by
                              ⁴         Literal integer `4`
                           ⊖            Incremented
                          ⊖             Incremented
                         ⁺              Concatenated with
                                *       Literal string `*`
                               …        Truncated to length
                                  λ     Current value
                                 ‹      Is less than
                                   ⁸    Literal integer `8`

The program works by generating the following table, where the headers are generated from a list of differences:

+ 1 5 8 10 12 15 19
0 1 5 8 10 12 15 19
6 7 11 14 16 18 21 25
14 15 19 22 24 26 29 33
20 21 25 28 30 32 35 39
28 29 33 36 38 40 43 47
34 35 39 42 44 46 49 53
42 43 47 50 52 54 57 61
48 49 53 56 58 60 63 67

Multiples of 4 are replaced with - while the remaining numbers are integer divided by 4 and then decremented twice, appending a * if this reduces them below zero.

JavaScript (ES6), 90 bytes

Returns a single string, using commas and line feeds as delimiters.

f=(n=7)=>~n--?[..."0024200"].map(j=>4-(n&2)&j?'-':v+["**"[++v+1]],v=34-n*7>>2)+`
`+f(n):''

Try it online!

Or 78 bytes without the asterisks:

f=(n=7)=>~n--?[..."0024200"].map(j=>4-(n&2)&j?'-':v++,v=34-n*7>>2)+`
`+f(n):''

Try it online!

How?

We iterate from \$n=6\$ to \$n=-1\$. The starting value of each row can be obtained with:

$$v_n=\left\lfloor\frac{1}{4}(34-7n)\right\rfloor$$

There are 2 distinct row patterns:

$$\begin{cases}[v_n,v_n+1,\varnothing,v_n+2,\varnothing,v_n+3,v_n+4]&n\in\{-1,2,3,6\}\\ [v_n,v_n+1,v_n+2,\varnothing,v_n+3,v_n+4,v_n+5]&n\in\{0,1,4,5\}\end{cases}$$

We can just test the penultimate bit of \$n\$ to distinguish them. We generate \$2\$ if it's set or \$4\$ otherwise and do a bitwise AND with the digit from the lookup string "0024200" according to its position.

05AB1E, 47 bytes

6L3-D>3FDÌ}D>DÌDÌ)εƵqbNèi¨Ƶ;S£ë3ô}'-.ý˜εD0‹i'*«

Try it online.

Explanation:

6L             # Push list [1,2,3,4,5,6]
  3-           # Decrease each by 3: [-2,-1,0,1,2,3]
D>             # Duplicate it, and increase each by 1
3F  }          # Loop 3 times:
  DÌ           #  Duplicate the top list, and increase each by 2
D>DÌDÌ         # Three more duplicates with +1, +2, and +2 respectively again
)              # Wrap all lists on the stack into a list
 ε             # Map over each inner list:
  Ƶq           #  Push compressed integer 153
    b          #  Convert it to binary: 10011001
     Nè        #  Index the current map-index into it
       i       #  If this is 1:
        ¨      #   Remove the last item of the list
         Ƶ;    #   Push compressed integer 212
           S   #   Convert it to a list: [2,1,2]
            £  #   Split the list into parts of that size: [[a,b],[c],[d,e]]
       ë       #  Else:
        3ô     #   Split the list into triplets: [[a,b,c],[d,e,f]]
       }       #  After the if-else:
        '-.ý  '#  Intersperse the list of sub-lists with "-" delimiter
            ˜  #  And flatten it to a single list again
  ε            #  Map over each inner value:
   D           #   Duplicate the current value
    0‹i        #   Pop the copy, and if it's a negative integer:
       '*«    '#    Append a "*"
               # (after which the matrix is output implicitly as result)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why Ƶq is 153 and Ƶ; is 212.

Raku, 96 bytes

{map ->\i,\j {{j-3,j-2,$_&&j-1,!$_&&j-1,$_&&j,j+$_,j+1+$_}((153+>i)%%2)},<1 2 4 6 8 9 11 13>.kv}

Returns the output as a 2D list with False for the blanks.

Try it online!