)
}
}
)
(
}
{
)
)
(
)
(
(
{
}
)
(
)
}
)
)
{
(
(
)
)
}
)
(
}

### Random Trick

1. // multiply math random by another math random:
2. const value = Math.random() * Math.random() * 10;
3.
4. // This makes it less likely that `value` will be 10
5.
6. // the more times you multiply, the less likely you will be to reach
7. // the maximum potential value
8. const value = Math.random() * Math.random() * Math.random() * 10;

I use this a fair amount when creating artwork with code. I’ll usually use a seeded random though for more control.

I was thinking about different icons I might use in a node based programming environment to denote this use of random and after a little futzing around created this series of histograms:

1. function rand(n = 1, f = 1) {
2.   let value = 1;
3.   for (let i = 0; i < n; i++) {
4.     value *= Math.random();
5.   }
6.   // fixing the value so that it fits
7.   // nicely as a key in the hash table
8.
9.   // hash = {
10.   //   0.2: 5,
11.   //   0.9: 8,
12.   //   etc...
13.   // }
14.   return value.toFixed(f);
15. }
16.
17. function histo(n = 1, f = 2, off, iter = 1500, size = 70) {
18.   const vals = {};
19.   const canvas = document.createElement('canvas');
20.   const c = canvas.getContext('2d');
21.
22.   canvas.width = canvas.height = size;
23.   canvas.style.margin = '.5em';
24.   document.body.appendChild(canvas);
25.
26.   for (let i = 0; i < iter; i++) {
27.     const randNum = off ? off - rand(n, f) : rand(n, f);
28.     if (vals[randNum] == null) {
29.       vals[randNum] = 1;
30.     } else {
31.       vals[randNum]++;
32.     }
33.   }
34.
35.   c.fillStyle = '#ccc';
36.   c.fillRect(0, 0, size, size);
37.   c.strokeRect(0, 0, size, size);
38.   for (let i in vals) {
39.     const x = parseFloat(i) * size;
40.     c.beginPath();
41.     c.moveTo(x, size);
42.     c.lineTo(x, size - vals[i]);
43.     c.stroke();
44.   }
45. }
46.
47. histo();
48. histo(2);
49. histo(3, 2, 1);
50. histo(5, 2, 1);
51. histo(6, 2, 0, 500);

### Match A or B

1. const aOrB = /\b(a|b)\b/g;
2.
3. const fn = '(b > .5) ? (max(a, 2. * (b - .5))) : (min(a, 2. * b))'
4.
5. const r = fn.replace(aOrB, '\$1.r');
6. const g = fn.replace(aOrB, '\$1.g');
7. const b = fn.replace(aOrB, '\$1.b');
8.
9. console.log(r);
10. console.log(g);
11. console.log(b);

Match an a or b, but not when it’s part of another word.

Found myself needing this for auto-generating some shaders recently.

### Random Walk to Target

1. const canvas = document.createElement('canvas');
2. const c = canvas.getContext('2d');
3.
4. let targetX, targetY, startX, startY;
5. const rectSize = 20;
6. const maxStep = 10;
7.
8. const matchStep = maxStep / 2;
9. const halfRectSize = rectSize / 2;
10. let matchTime = 0;
11. const resetTime = 20;
12.
13. function randX() {
14.   return innerWidth * 0.8 * Math.random() + innerWidth * 0.1;
15. }
16. function randY() {
17.   return innerHeight * 0.8 * Math.random() + innerHeight * 0.1;
18. }
19.
20. function resize() {
21.   canvas.width = innerWidth;
22.   canvas.height = innerHeight;
23.   reset();
24. }
26. resize();
27.
28. document.body.appendChild(canvas);
29. document.body.style.margin = 0;
30.
31. function reset() {
32.   matchTime = 0;
33.   targetX = randX();
34.   targetY = randY();
35.   startX = randX();
36.   startY = randY();
37.   c.fillStyle = '#ccc';
38.   c.fillRect(0, 0, innerWidth, innerHeight);
39.
40.   c.fillStyle = '#c79500';
41.   c.fillRect(
42.     targetX - halfRectSize,
43.     targetY - halfRectSize,
44.     rectSize,
45.     rectSize
46.   );
47.
48.   c.fillStyle = '#4e82c7';
49.   c.fillRect(startX - halfRectSize, startY - halfRectSize, rectSize, rectSize);
50. }
51.
52. function loop() {
53.   c.strokeStyle = 'black';
54.   c.beginPath();
55.   c.moveTo(startX, startY);
56.   if (startX < targetX) {
57.     startX += Math.random() * maxStep;
58.   } else if (startX > targetX) {
59.     startX -= Math.random() * maxStep;
60.   }
61.   if (startY < targetY) {
62.     startY += Math.random() * maxStep;
63.   } else if (startY > targetY) {
64.     startY -= Math.random() * maxStep;
65.   }
66.
67.   c.lineTo(startX, startY);
68.   c.stroke();
69.
70.   if (
71.     Math.abs(startX - targetX) < matchStep &&
72.     Math.abs(startY - targetY) < matchStep
73.   ) {
74.     matchTime++;
75.     if (matchTime > resetTime) {
76.       reset();
77.     }
78.   }
79.
80.   window.requestAnimationFrame(loop);
81. }
82. loop();

Randomly walk to a target.

### 2x mod 1 Map

1. function twoXmodMap(start = 0.2) {
2.   const seed = () => Math.random() * Math.random() * start
3.   let xn = seed()
4.   let xn1
5.   let iter = 0
6.   return () => {
7.     iter++
8.     if (iter > 50) {
9.       xn = seed()
10.       iter = 0
11.     }
12.
13.     // this is the key part:
14.     xn1 = (2 * xn) % 1
15.     xn = xn1
16.
17.     return xn1
18.   }
19. }
20.
21. const el = document.body.appendChild(document.createElement('div'))
22. el.innerHTML = `
23.   <svg>
24.     <path d="M 0 0 L 1 1" fill="none" stroke="red" />
25.   </svg>
26.   <style>
27.     svg, body, html {
28.       width: 100%;
29.       height: 100%;
30.       overflow: visible;
31.     }
32.   </style>
33. `
34.
35. const path = el.querySelector('path')
36. let pathStr = ''
37.
38. const map = twoXmodMap()
39.
40. let x = 0
41. let yo = 0
42. let y;
43. function loop() {
44.   y = map()
45.   x += 2
46.
47.   if (pathStr == '' || x > 300) {
48.     x = 10
49.     yo += 50
50.     pathStr += `M 10 \${yo}`
51.   } else {
52.     pathStr += ` L \${x} \${yo + y * 30} `
53.   }
54.
55.   path.setAttribute('d', pathStr)
56.   window.requestAnimationFrame(loop)
57. }
58. loop()

Drawing the 2x mod 1 map.

// javascript // math // svg

### Find a String Naive Hill Climbing

1. const target = 'snippetzone'.split``;
2. const leng = target.length;
3. const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split``;
4.
5. function randomString() {
6.   let str = [];
7.   for (let i = 0; i < leng; i++) {
8.     str.push(randomChar());
9.   }
10.   return str;
11. }
12.
13. function randomChar() {
14.   return alphabet[Math.floor(Math.random() * alphabet.length)];
15. }
16.
17. let iterations = 0;
18. const search = randomString();
19. const indices = [];
20. for (var i = 0; i < leng; i++) indices.push(i);
21. let found = false;
22.
23. function loop() {
24.   for (let i = 0; i < 10; i++) {
25.     if (indices.length > 0) {
26.       let ii = Math.floor(Math.random() * indices.length);
27.       let index = indices[ii];
28.       search[index] = randomChar();
29.       if (search[index] == target[index]) {
30.         indices.splice(ii, 1);
31.       }
32.       console.log(search.join(','));
33.       iterations++;
34.     } else {
35.       console.log('found after', iterations, 'iterations');
36.       found = true;
37.       break;
38.     }
39.   }
40.
41.   if (!found) {
42.     requestAnimationFrame(loop);
43.   }
44. }
45. loop();

This is a port of an old snippet of mine. It naively and randomly finds a target string. In this case the string “snippetzone”.

It’s fun to see it randomly perform better/worse…

e,f,k,w,q,s,o,h,n,r,f e,f,k,w,q,s,o,h,n,r,u k,f,k,w,q,s,o,h,n,r,u k,f,k,w,q,o,o,h,n,r,u k,f,k,w,q,o,o,v,n,r,u k,f,k,w,q,v,o,v,n,r,u ... s,e,i,p,p,e,t,z,o,n,e s,v,i,p,p,e,t,z,o,n,e s,h,i,p,p,e,t,z,o,n,e s,d,i,p,p,e,t,z,o,n,e s,s,i,p,p,e,t,z,o,n,e s,e,i,p,p,e,t,z,o,n,e s,g,i,p,p,e,t,z,o,n,e s,q,i,p,p,e,t,z,o,n,e s,m,i,p,p,e,t,z,o,n,e s,w,i,p,p,e,t,z,o,n,e s,g,i,p,p,e,t,z,o,n,e s,x,i,p,p,e,t,z,o,n,e s,t,i,p,p,e,t,z,o,n,e s,o,i,p,p,e,t,z,o,n,e s,e,i,p,p,e,t,z,o,n,e s,k,i,p,p,e,t,z,o,n,e s,p,i,p,p,e,t,z,o,n,e s,b,i,p,p,e,t,z,o,n,e s,n,i,p,p,e,t,z,o,n,e found after 176 iterations
snippet.zone ~ 2021-24 /// {s/z}