AdventJS 2023: Reto del Día 10
Tags: spanish, javascript, webdev, challenge
Published: 2023-12-12 05:17:11

Solución al [reto #10](https://adventjs.dev/es/challenges/2023/10) del [AdventJS 2023](https://adventjs.dev/es)

[Solución del reto anterior](https://dev.to/fenriuz/adventjs-2023-reto-del-dia-8-i44)

[Solución del siguiente reto](https://dev.to/fenriuz)

{%- # TOC start (generated with https://github.com/derlin/bitdowntoc) -%}

- [Descripción del Reto](#descripción-del-reto)
- [Análisis](#análisis)
   * [Entrada](#entradas)
   * [Salida](#salida)
   * [Consideraciones](#consideraciones)
- [Solución](#solución)
   * [Código](#código)
   * [Soluciones de la comunidad](#soluciones-de-la-comunidad)

{%- # TOC end -%}


## Descripción del Reto

¡Vaya idea ha tenido Sam Elfman! Quiere ofrecer un servicio que te crea un árbol de Navidad 🎄 personalizado en cuestión de segundos.

Para crearlo nos pasan una cadena de caracteres para formar el árbol y un número que indica la altura del mismo.

Cada carácter de la cadena representa un adorno del árbol, y vamos utilizándolos de forma cíclica hasta llegar a la altura indicada. Como mínimo siempre nos pasarán uno.

Debemos devolver un string multilínea con el árbol de Navidad formado con los adornos, la altura indicada más una última línea con el tronco formado por el carácter | en el centro y, finalmente, un salto de línea \n.

Por ejemplo si recibimos la cadena "123" y el número 4 como altura, tendríamos que construir este árbol:

   1
  2 3
 1 2 3
1 2 3 1
   |
Si recibimos la cadena *@o y el número 3, el árbol que debemos devolver es:

  *
 @ o
* @ o
  |
Nota:

El árbol siempre debe estar centrado, para ello añade espacios en blanco a la izquierda de cada línea.
Crea espacios sólo a la izquierda de cada línea del árbol. No dejes espacios en blanco a la derecha.
Los adornos tienen un espacio en blanco entre ellos de separación.

## Análisis
¡Y volvemos a dibujar! Esta vez serán los árboles de navidad, los cuáles debemos dibujar utilizando los strings que nos pasen como parámetro y haciéndolos del tamaño que nos indiquen

### Entrada

1. Ornaments(`ornaments`): Un string donde vendrá la secuencia de caracteres que llenará el árbol
2. Height(`height`): El tamaño en altura y máxima anchura que tendrá el árbol

### Salida

- Un string con el dibuj del árbol.

### Consideraciones

- Debemos agregar los espacios al principio para darle forma de árbol navideño
- Al final debemos colocar salto de línea

## Solución
Una manera sencilla de poder hacer el reto es tener una idea de cuántos caracteres se ocuparán en total, para eso podemos hacer uso de las matemáticas. Una vez obteniendo se puede iterar e ir rellenando cada fila del árbol.

### Código

```javascript
function createChristmasTree(ornaments, height) {
  let tree = "";
  const totalOrnaments = (height * (height + 1)) / 2;
  const allOrnaments = ornaments.repeat(totalOrnaments);

  let lastIndex = 0;

  for (let i = 1; i <= height; i += 1) {
    const spaces = " ".repeat(height - i);
    const ornamentRow = allOrnaments
      .slice(lastIndex, lastIndex + i)
      .split("")
      .join(" ");

    tree += spaces + ornamentRow + "\n";

    lastIndex += i;
  }

  tree += "|".padStart(height, " ") + "\n";
  return tree;
}
```

### Soluciones de la comunidad

Solución por [iswilljr](https://github.com/iswilljr/adventjs/blob/master/2023/challenge-10/challenge-10.ts):

```javascript
function createChristmasTree(ornaments, height) {
  let result = ''
  const spaces = ' '.repeat(height - 1)

  const ornamentsArray = [...ornaments.repeat(height)].join(' ')
  let currentPosition = 0

  for (const index of new Array(height).keys()) {
    const length = index + 1
    const total = currentPosition + length

    result +=
      spaces.slice(index) +
      ornamentsArray.slice(currentPosition * 2, total * 2 - 1) +
      '\n'

    currentPosition = total % ornaments.length
  }

  return result + spaces + '|\n'
}
```

Solución por [yasai](https://github.com/yasai):

```javascript
function createChristmasTree(ornaments, height) {
    let tree = "";
    let count = 0;

    // pyramid
    for (let i = 0; i < height; i++) {
      let line = "";
      // spaces
      line += " ".repeat(height - i - 1);
      // ornaments
      for (let j = 0; j < i + 1; j++) {
        let dec = ornaments[count];
        count++;
        if (count == ornaments.length) count = 0;
         if (j == i) {
          line += `${dec}`;
          break;
        }
        line += `${dec} `;
      }
      // add to the tree
      tree += line + "\n";
    }

    // trunk
    tree += " ".repeat(height - 1) + "|\n";

    return tree;
  }
```

Y ese fue el reto para el 10 de diciembre y sus soluciones. Dale like si te ha gustado el reto o la solución!
¿Tienes otra solución alternativa? ¡Déjala en los comentarios!