Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

232
Visualizações
¿Cómo puedo simplificar este generador para eliminar la recursividad?

Estoy tratando de crear un generador que produzca valores entre un rango dado. Mis requisitos son:

  • todos los valores emitidos son únicos
  • el orden de los valores es el mismo cada vez que se ejecuta el generador
  • cada valor está lejos de los valores emitidos previamente
  • no se sabe cuantos valores se generaran

Decidí modelar esto como un árbol, y hacer algo como una búsqueda en amplitud para dividir el rango en subdivisiones de tamaño uniforme, e iterar sobre cada capa en un orden que evita la visita de nodejs adyacentes.

Se me ocurrió la siguiente solución que funciona, sin embargo, no me gusta que esté usando recursividad, y sospecho que se puede reescribir para eliminar la recursividad (¿quizás una cola?) Un poco atascado aquí. Esto es lo que tengo hasta ahora:

 function* orderedSubdivisor(start: number, end: number): Generator<number> {

 const mid = (end - start) / 2 + start
 
 yield mid

 const left = orderedSubdivisor(start, mid)
 const right = orderedSubdivisor(mid, end)

 while (true) {
 yield left.next().value
 yield right.next().value 
 }
}

const iter = orderedSubdivisor(0, 64)

console.log(Array.from({length: 63}, () => iter.next().value))

¡Gracias!

almost 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Puede modelar esto usando un contador binario para representar la posición/ruta en su árbol. El bit menos significativo decide si se encuentra en la mitad izquierda o derecha de la rama superior, el segundo bit menos significativo decide si se encuentra en la mitad izquierda o derecha del segundo nivel, y así sucesivamente:

 function* orderedSubdivisor(start, end) {
 for (let i=1; true; i++) {
 let sum = start;
 let part = end-start;
 for (let j=i; j; j=j>>>1) {
 part /= 2;
 if (j & 1) sum += part;
 }
 yield sum;
 }
}

const iter = orderedSubdivisor(0, 64)

console.log(Array.from({length: 63}, () => iter.next().value))

De hecho, puede ver que esencialmente acaba de crear un contador, pero cambia el orden de bits de cada valor obtenido:

 function* orderedSubdivisor(start, end) {
 const mid = (end - start) / 2 + start
 yield mid
 const left = orderedSubdivisor(start, mid)
 const right = orderedSubdivisor(mid, end)
 while (true) {
 yield left.next().value
 yield right.next().value 
 }
}

let i=0;
for (const v of orderedSubdivisor(0, 64)) {
 if (i++ >= 63) break;
 document.body.appendChild(document.createElement('pre')).textContent = v.toString(10).padStart(2)+': 0b'+v.toString(2).padStart(6, '0');
}

almost 4 years ago · Santiago Trujillo Relatório

0

Estoy tratando de crear un generador que produzca valores entre un rango dado. Mi requisito [es] tener cada valor lejos de los valores emitidos previamente.
Mi caso de uso real es la asignación de tonos en una rueda de colores.

Para eso, recomiendo la técnica de hashing de Fibonacci con la proporción áurea / ángulo áureo , que proporciona una salida distribuida muy uniformemente alrededor de la rueda de color:

 function* orderedSubdivisor(start, end) {
 for (let i=0; true; i+=0.6180339887498951) {
 yield start+(i%1)*(end-start);
 }
}

let i=0;
for (const v of orderedSubdivisor(0, 360)) {
 if (i++ >= 100) break;
 const p = document.body.appendChild(document.createElement('p'));
 p.textContent = v;
 p.style = `background-color: hsl(${v}deg, 100%, 50%)`;
}

almost 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda