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

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. }
  25. window.addEventListener('resize', resize);
  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}