)
}
}
)
(
}
{
)
)
(
)
(
(
{
}
)
(
)
}
)
)
{
(
(
)
)
}
)
(
} ### 30% Chance Math.random()

1. `// 30%`
2. `if (Math.random() < .3) {`
3. `  // 30% chance this will run`
4. `  console.log('30%');`
5. `} else {`
6. `  console.log('nope');`
7. `}`

I do this all the time when creative coding. I usually use a seeded random number generator instead of `Math.random`. It’s very useful to have something happen `X%` of the time.

Let’s run this a few times and look at the results. Click/tap try it out.

1. `for (let i = 0; i < 111; i++) {`
2. `  if (Math.random() < .3) {`
3. `    console.log('30%');`
4. `  } else {`
5. `    console.log('nope');`
6. `  }`
7. `}`

Scroll through the results of the console window. ### Cistercian Numerals (semi-golfed)

1. `N = -1`
2. `S = 30`
3. `H = 90`
4. `h = 45`
5. `d = document`
6. `b = d.body`
7. `m = _ => d.createElement(_)`
8. `a = _ => b.appendChild(_)`
9. ` `
10. `with(a(`
11. `    Object.assign(`
12. `      m`canvas`,`
13. `      { width: 80, height: 120 }`
14. `    )`
15. `  ).getContext`2d``
16. `) { `
17. `  a(m`br`)`
18. ` `
19. `  L = (a, b, C, d) => {`
20. `    moveTo(a, b)`
21. `    lineTo(C, d)`
22. `  }`
23. ` `
24. `  M = _ => L(0, 0, 0, H)`
25. `  O = _ => L(0, 0, S, 0)`
26. `  W = _ => L(0, S, S, S)`
27. `  T = _ => L(0, 0, S, S)`
28. `  F = _ => L(0, S, S, 0)`
29. `  X = _ => L(S, 0, S, S)`
30. ` `
31. `  D = [`
32. `    _ => {},`
33. `    O, W, T, F, `
34. `    [O,F],`
35. `    X,`
36. `    [O,X],`
37. `    [W,X],`
38. `    [O,W,X]`
39. `  ]`
40. ` `
41. `  n = s => {`
42. `    [...s].reverse().map((l, i) => {`
43. `      save()`
44. `      translate(S+9, h+9)`
45. `      scale(N**i, N**~~(i/2))`
46. `      translate(0, -h)`
47. `      M() ;[D[l]].flat().map(x => x && x())`
48. `      restore()`
49. `    })`
50. `  }`
51. ` `
52. `  a(m`input`).oninput = e => {`
53. `    clearRect(0, 0, 80, 120)`
54. `    beginPath()`
55. `    n(~~e.target.value+'')`
56. `    stroke()`
57. `  }`
58. `}`

Type any number from 0-9999 into the input field and see the corresponding Cistercian Numeral. This snippet is partially golfed, I left the canvas commands intact to make things a bit easier to understand.

### Simpler SVG Version

This one hardcodes all numbers 0-9 as paths, unlike the canvas version which only defines 1,2,3,4 and 6 as paths and then combines them to create 5,7,8 and 9.

1. `h='innerHTML'`
2. `C='children'`
3. ` `
4. `document.body[h]=``
5. `<svg id=G width=99 viewBox="0 0 80 120" `
6. `  style="stroke:black;fill:none;overflow:visible">`
7. `  <g transform="translate(30,2)">`
8. `    <path d="M0 0L 30 0"/>`
9. `    <path d="M0 30L 30 30"/>`
10. `    <path d="M0 0L 30 30"/>`
11. `    <path d="M0 30L30 0"/>`
12. `    <path d="M0 30L30 0 0 0"/>`
13. `    <path d="M30 0L30 30"/>`
14. `    <path d="M30 30L30 0 0 0"/>`
15. `    <path d="M0 30L30 30 30 0"/>`
16. `    <path d="M0 30L30 30 30 0 0 0"/>`
17. `  </g>`
18. `  <g transform=translate(30,2)scale(-1,1)></g>`
19. `  <g transform=translate(30,92)scale(1,-1)></g>`
20. `  <g transform=translate(30,92)scale(-1,-1)></g>`
21. `  <path id=m d="M 30 2 L 30 92"/>`
22. `</svg>`
23. `<style>path:not(#m){opacity:0}</style><br>`
24. `<input id=I>``
25. ` `
26. `c=G[C]`
27. `p=c[h] `
28. ` `
29. `n = s => `
30. `  [...s].reverse().map((l, i) => `
31. `   l-1>-1 && (c[i][C][l-1].style.opacity=1))`
32. ` `
33. `I.oninput = e => {`
34. `  for(i=0;i<4;i++)c[i][h]=p`
35. `  n(~~e.target.value+'')`
36. `}` ### Array Based Collision Cells

1. `((`
2. `  d = document,`
3. `  b = d.body,`
4. `  canvas = b.appendChild(`
5. `    d.createElement('canvas')`
6. `  ),`
7. `  c = canvas.getContext('2d'),`
8. `  r = _ => Math.random(),`
9. `  map = [`
10. `    [0, 0, 0, 0, 0, 2],`
11. `    [1, 1, 0, 0, 0, 1],`
12. `    [1, 1, 2, 0, 0, 0],`
13. `    [2, 2, 0, 0, 0, 1],`
14. `    [0, 1, 0, 0, 2, 0],`
15. `    [2, 0, 0, 0, 2, 1],`
16. `  ],`
17. `  mapW = map.length,`
18. `  mapH = map.length,`
19. `  cols = [, 'red', 'black'],`
20. `  cell = (`
21. `    x, y, idx,`
22. `    col = cols[idx],`
23. `    size = 30,`
24. `    xp = x * size,`
25. `    yp = y * size,`
26. `    dir, `
27. `    mv = f => {`
28. `      map[y][x] = 0`
29. `      f()`
30. `      map[y][x] = idx`
31. `    }`
32. `  ) => (move) => {`
33. `    if (move) {`
34. `      dir = ~~(r() * 4)`
35. `      if (dir == 0 &&`
36. `        x != 0 &&`
37. `        map[y][x - 1] == 0) {`
38. `        mv(_ => x--)`
39. `      } else if (dir == 1 &&`
40. `        x != mapW - 1 &&`
41. `        map[y][x + 1] == 0) {`
42. `        mv(_ => x++)`
43. `      } else if (dir == 2 &&`
44. `        y != 0 &&`
45. `        map[y - 1][x] == 0) {`
46. `        mv(_ => y--)`
47. `      } else if (dir == 3 &&`
48. `        y != mapH - 1 &&`
49. `        map[y + 1][x] == 0`
50. `      ) {`
51. `        mv(_ => y++)`
52. `      }`
53. `    }`
54. ` `
55. `    xp += (x * size - xp) / 4`
56. `    yp += (y * size - yp) / 4`
57. `    c.fillStyle = col`
58. `    c.fillRect(xp, yp, size, size)`
59. `    c.strokeStyle = 'gray'`
60. `    c.strokeRect(xp, yp, size, size)`
61. `  },`
62. `  cells = [],`
63. `  w, h, idx, val, i, j,`
64. `  draw = () => {`
65. `    c.fillStyle = 'gray'`
66. `    c.fillRect(0, 0, w, h)`
67. ` `
68. `    idx = ~~(r() * mapH * mapW)`
69. ` `
70. `    cells.forEach((cell, i) =>`
71. `      cell(idx == i && r() < .3))`
72. `  }`
73. `) => {`
74. `  b.style.margin = 0`
75. ` `
76. `  onresize = () => {`
77. `    w = canvas.width = innerWidth`
78. `    h = canvas.height = innerHeight`
79. `    draw()`
80. `  }`
81. `  onresize()`
82. ` `
83. `  for (i = 0; i < mapH; i++) {`
84. `    for (j = 0; j < mapW; j++) {`
85. `      val = map[i][j]`
86. `      if (val != 0) cells.push(cell(j, i, val)) `
87. `    }`
88. `  }`
89. ` `
90. `  setInterval(draw, 16)`
91. `})()`

Array based avoid. I was about to port an old thing that was similar to this and then thought it would be more fun to speedcode it instead. The result is a slightly golfed version of this old thing. ### Array.at Negative Indices

1. `const arr = [`
2. `  'one', 'two', `
3. `  'three', 'four'`
4. `];`
5. `console.log(`
6. `  arr.at(-1), `
7. `  arr.at(-2), `
8. `  arr.at(0)`
9. `);`

`Array.at` allows negative index values to be used to read elements from an array. I’ve seen this done using a Proxy in the past. ### Golfed Min/Max

1. `Math.min(a,b)  // 13 chars`
2. `a<b?a:b        //  7 chars`
3. ` `
4. `Math.max(a,b)`
5. `a>b?a:b`

Another small golfing gem from codegolf stackexchange. This isn’t immediately obvious, but cool to note when golfing.

It’s also worth mentioning that if your code is long enough, aliasing `Math.min` and/or `Math.max` may be shorter in the long run:

1. `m = Math.min`
2. `Math.min(a,b)  // 13 chars`
3. `a<b?a:b        //  7 chars`
4. `m(a,b)         //  6 chars` snippet.zone ~ 2021-22 /// {s/z}