5
\$\begingroup\$

Given two inputs, a distance \$d\$ and a number \$n\$ output a list of \$n\$ random colors which each have distance \$d\$ from the previous.

Background

A random walk is a path which is defined by choosing a random direction and (usually) fixed distance to go at each step. We will be taking a random walk through the RGB color space using Euclidean distance as our metric.

The challenge

For this challenge you will take two inputs, \$n\$ and \$d\$. Let \$n\$ be the number of colors to output, this will always be an integer \$1 \leq n\$, and \$d\$ be the distance between consecutive elements, which will always be \$0 \leq d \leq 128\$. You may additionally assume that \$d\$ is an integer.

For each consecutive pair of elements \$(r_1, g_1, b_1), (r_2, g_2, b_2)\$ of the \$n\$ element sequence output, it must be the case that all values are between 0 and 255 inclusive (or \$[0,256)\$ for floats), and the distance between elements must be within 1 of d, that is \$|\sqrt{(r_1-r_2)^2+(g_1-g_2)^2+(b_1-b_2)^2} - d| < 1\$. This should allow one to restrict their output to integers if they so choose. The walk need not be uniform, but it does need to be random. Specifically, there should be a non-zero chance of each step going in any direction which stays in bounds (within a distance 1 error tolerance). The starting point of the walk should be random as well.

Standard i/o rules apply, input and output can be in any reasonable format. Graphical output is allowed (and encouraged, though I doubt it will be golfy to do so) so long as the order of the sequence is clear.

This is , so the shortest answer in bytes wins.

Test cases

For these test cases input is in the order \$n,d\$ and output is (r, g, b) as integers. These are some possible results.

5, 5 -> (81, 60, 243), (81, 57, 239), (76, 60, 240), (80, 62, 241), (84, 60, 243)
4, 10 -> (163, 89, 77), (162, 83, 85), (166, 75, 79), (166, 82, 87)
4, 50 -> (212, 36, 232), (247, 1, 239), (220, 44, 243), (217, 81, 209)
\$\endgroup\$
2
  • 2
    \$\begingroup\$ The 'random'-ness doesn't seem very well specified here. Would a walk along a linear path (say, from black to red), randomly choosing steps of size d forwards & backwards, be Ok? \$\endgroup\$ Commented Mar 22, 2023 at 7:56
  • \$\begingroup\$ I clarified what exactly counts as random. Hopefully it makes sense, otherwise I could add a diagram or something. Something like a linear path would not fit what I've specified. \$\endgroup\$ Commented Mar 22, 2023 at 14:00

4 Answers 4

8
\$\begingroup\$

Wolfram Language (Mathematica), 96 bytes

(d=#2;r={0,255};NestList[⌊RandomPoint[Sphere[#,d],1,{r,r,r}][[1]]⌋&,RandomInteger[r,3],#1])&

Try it online!

Graphical output is possible with Mathematica desktop. If the above function named g:

enter image description here

And just for fun:

enter image description here

\$\endgroup\$
5
\$\begingroup\$

JavaScript (V8), 105 bytes

Expects (n)(d). Prints tuples of 3 floats.

n=>d=>{for(b=[m=Math,0,0];~~(m.hypot(...b.map((v,i)=>v-=a[i]=m.random()*256,a=[]))-d)||print(b=a)|--n;);}

Try it online!

Graphical output

This snippet generates a graphical rendering of f(4)(50).

f=
n=>d=>{for(b=[m=Math,0,0];~~(m.hypot(...b.map((v,i)=>v-=a[i]=m.random()*256,a=[]))-d)||print(b=a)|--n;);}

i = 0; print = ([r, g, b]) => document.getElementsByTagName("div")[i++].style.backgroundColor = `rgb(${r},${g},${b})`; f(4)(50)
div { float: left; width: 32px; height: 32px; margin-right: 8px; }
<div></div><div></div><div></div><div></div>

Commented

n =>                     // outer function taking n
d => {                   // inner function taking d
  for(                   // main loop:
    b = [                //   initialize b[]:
      m = Math,          //     m = alias for Math
      0,                 //     by inserting this NaN'ish value into
      0                  //     the initial b[], we force the first
    ];                   //     random RGB tuple to be accepted
    ~~(                  //   force to integer:
      m.hypot(...        //     compute the Euclidean distance:
        b.map((v, i) =>  //       for each value v at index i in b[]:
          v -=           //         subtract a[i] from v
            a[i] =       //         where a[i] is set to
              m.random() //         a random float in [0, 256[
              * 256,     //     
          a = []         //         start with a[] = []
        )                //       end of map()
      ) - d              //     subtract d from the Euclidean distance
    ) ||                 //   if the result is within ]-1,1[:
      print(b = a)       //     print a[], update b[] to a[]
      | --n;             //     and decrement n (stop if it's 0)
  );                     // end of loop
}                        //
\$\endgroup\$
3
\$\begingroup\$

Python, 123 107 111 108 bytes

-16 bytes from @xnor by using math.dist
+4 bytes from @Arnauld from correctly meeting the spec
-3 bytes from @The Thonnu

import os,math
def f(n,d,r=os.urandom):
 X=r(3)
 while n:
  if-1<math.dist(x:=r(3),X)-d<1:print(*x);X=x;n-=1

Attempt This Online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ It looks like you can use math.dist like this here. \$\endgroup\$
    – xnor
    Commented Mar 21, 2023 at 18:50
  • \$\begingroup\$ 108 \$\endgroup\$
    – The Thonnu
    Commented Mar 21, 2023 at 19:50
3
\$\begingroup\$

Charcoal, 44 bytes

NθNηW⊙Φ⊟Eθ⊞OυE³‽²⁵⁶λ‹¹↔⁻η₂ΣEκX⁻짧υλν²≔⟦⟧υIυ

Attempt This Online! Link is to verbose version of code. Explanation: Simply generates n sets of random colours until it finds a set that meets the distance criterion, which it then outputs.

Although that algorithm finishes with 100% probability, it's inordinately slow and unusable for n>3, so here's a 52-byte alternative program that randomly generates each colour in turn until it finds one that meets the distance criterion:

NθNηW‹Lυθ«⊞υE³‽²⁵⁶¿∧⊖Lυ‹¹↔⁻η₂ΣE§υ±²X⁻ꧧυ±¹λ²≔⊟υι»Iυ

Attempt This Online! Link is to verbose version of code.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.