| Bytes | Lang | Time | Link |
|---|---|---|---|
| 216 | Python 3 | 230719T101617Z | keymasta |
| 145 | Scala | 230720T115141Z | 138 Aspe |
| 076 | Python 3 | 230719T181158Z | xnor |
| 037 | Charcoal | 230718T103318Z | Neil |
| 090 | JavaScript ES6 | 230718T084659Z | Arnauld |
| 047 | 05AB1E | 230718T080244Z | Kevin Cr |
| 096 | Raku | 230718T050447Z | bb94 |
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)
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""])
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]])
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):''
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):''
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'*«
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.