|
| 1 | +# Reto 06: Regalo-dentro-de-la-caja |
| 2 | + |
| 3 | +Ya hemos empaquetado cientos de regalos 🎁… pero **a un elfo se le ha olvidado revisar si el regalo**, representado por un asterisco `*`, está dentro de la caja. |
| 4 | + |
| 5 | +La caja tiene un regalo `(*)` y cuenta como dentro de la caja si: |
| 6 | + |
| 7 | +- Está rodeada por # en los bordes de la caja. |
| 8 | +- El `*` no está en los bordes de la caja. |
| 9 | + |
| 10 | +Ten en cuenta entonces que el `*` puede estar dentro, fuera o incluso no estar. Y debemos devolver `true` si el `*` está dentro de la caja y false en caso contrario. |
| 11 | + |
| 12 | +Ejemplos: |
| 13 | + |
| 14 | +```js |
| 15 | +inBox([ |
| 16 | + "###", |
| 17 | + "#*#", |
| 18 | + "###" |
| 19 | +]) // ➞ true |
| 20 | + |
| 21 | +inBox([ |
| 22 | + "####", |
| 23 | + "#* #", |
| 24 | + "# #", |
| 25 | + "####" |
| 26 | +]) // ➞ true |
| 27 | + |
| 28 | +inBox([ |
| 29 | + "#####", |
| 30 | + "# #", |
| 31 | + "# #*", |
| 32 | + "#####" |
| 33 | +]) // ➞ false |
| 34 | + |
| 35 | +inBox([ |
| 36 | + "#####", |
| 37 | + "# #", |
| 38 | + "# #", |
| 39 | + "# #", |
| 40 | + "#####" |
| 41 | +]) // ➞ false |
| 42 | +``` |
| 43 | + |
| 44 | +## Mi solución explicada |
| 45 | + |
| 46 | +```js |
| 47 | +function inBox(box) { |
| 48 | + return box |
| 49 | + .slice(1, -1) |
| 50 | + .some( |
| 51 | + (line) => |
| 52 | + line.includes('*') && |
| 53 | + line.indexOf('*') > 0 && |
| 54 | + line.indexOf('*') < line.length - 1, |
| 55 | + ); |
| 56 | +} |
| 57 | +``` |
| 58 | + |
| 59 | +Para resolver este problema, tomaremos de ejemplo la siguiente entrada (caja): |
| 60 | + |
| 61 | +```js |
| 62 | +const box = [ |
| 63 | + '####', |
| 64 | + '#* #', |
| 65 | + '# #', |
| 66 | + '####' |
| 67 | +]; |
| 68 | +``` |
| 69 | + |
| 70 | +Analizando la caja podemos partir diciendo que la busqueda del asterisco `*` se hará en las lineas interiores de la caja, es decir, no se buscará en los bordes superiores e inferiores de la caja, ya que si el asterisco está en los bordes de la caja, no se considerará como dentro de la caja. |
| 71 | + |
| 72 | +Para esto, eliminamos el primer y último elemento de la caja, ya que no necesitamos verificar los bordes de la caja: |
| 73 | + |
| 74 | +```js |
| 75 | +box.slice(1, -1); |
| 76 | +``` |
| 77 | + |
| 78 | +`slice(1, -1)` nos permite obtener un nuevo arreglo que comienza desde el índice 1 y termina en el penúltimo elemento. Esto nos dará: |
| 79 | + |
| 80 | +```js |
| 81 | +[ |
| 82 | + '#* #', |
| 83 | + '# #' |
| 84 | +] |
| 85 | +``` |
| 86 | + |
| 87 | +Luego, verificamos si alguna de las líneas interiores contiene un asterisco `*` y si el asterisco no está tanto en el borde izquierdo como en el borde derecho de la caja. Para esto, utilizamos las siguientes condiciones: |
| 88 | + |
| 89 | +```js |
| 90 | +line.includes('*') && |
| 91 | +line.indexOf('*') > 0 && |
| 92 | +line.indexOf('*') < line.length - 1 |
| 93 | +``` |
| 94 | + |
| 95 | +Para este ejemplo utilizamos el método `some` para verificar si alguna de las líneas cumple con las condiciones mencionadas. Si es así, devolvemos `true`, de lo contrario, devolvemos `false`. Hay que tener en cuenta que el método `some` se detiene en cuanto encuentra un valor verdadero. |
| 96 | + |
| 97 | +Para este caso el arreglo se recorreria 2 veces, entonces tenemos que para la primera linea `#* #` se cumple la condición de que el asterisco no está en los bordes de la caja, pero si dentro de ella, por lo que devolvemos `true`. ¿Por qué? |
| 98 | + |
| 99 | +Validamos la primera iteracion donde tenemos la linea `#* #`: |
| 100 | + |
| 101 | +Tenemos que para la primera condición `line.includes('*')` es verdadera, ya que la linea contiene un asterisco `*`. |
| 102 | + |
| 103 | +Para la segunda condición `line.indexOf('*') > 0` es verdadera, ya que el asterisco no está en el borde izquierdo de la caja. |
| 104 | + |
| 105 | +```js |
| 106 | +// Reemplazamos los valores de la linea por sus indices |
| 107 | +// #* # |
| 108 | +// 0123 |
| 109 | + |
| 110 | +line.indexOf('*') = 1; |
| 111 | + |
| 112 | +// 1 > 0 |
| 113 | +line.indexOf('*') > 0; // true |
| 114 | +``` |
| 115 | + |
| 116 | +Para la tercera condición `line.indexOf('*') < line.length - 1` es verdadera, ya que el asterisco no está en el borde derecho de la caja. |
| 117 | + |
| 118 | +```js |
| 119 | +// Reemplazamos los valores de la linea por sus indices |
| 120 | +// #* # |
| 121 | +// 0123 |
| 122 | + |
| 123 | +line.indexOf('*') = 1; |
| 124 | +line.length - 1 = 3; |
| 125 | + |
| 126 | +// 1 < 3 |
| 127 | +line.indexOf('*') < line.length - 1; // true |
| 128 | +``` |
| 129 | + |
| 130 | +Tenemos que para la primera iteración nos devolvería `true`, ya que tenemos lo siguiente: |
| 131 | + |
| 132 | +```js |
| 133 | +// Line: #* # |
| 134 | + |
| 135 | +line.includes('*') = true; |
| 136 | +line.indexOf('*') > 0 = true; |
| 137 | +line.indexOf('*') < line.length - 1 = true; |
| 138 | + |
| 139 | +// true && true && true = true |
| 140 | +``` |
| 141 | + |
| 142 | +Como la primera iteración nos devolvió `true`, el método `some` se detiene y no sigue iterando sobre las demás lineas. |
| 143 | + |
| 144 | +Por lo que el resultado final sería `true`. |
| 145 | + |
| 146 | +**Probemos ahora con una entrada que nos devuelva `false`**: |
| 147 | + |
| 148 | +```js |
| 149 | +const box = [ |
| 150 | + '#####', |
| 151 | + '# #', |
| 152 | + '# #', |
| 153 | + '# #', |
| 154 | + '#####' |
| 155 | +]; |
| 156 | +``` |
| 157 | + |
| 158 | +Primero, eliminamos el primer y último elemento de la caja: |
| 159 | + |
| 160 | +```js |
| 161 | +box.slice(1, -1); |
| 162 | +``` |
| 163 | + |
| 164 | +Esto nos dará: |
| 165 | + |
| 166 | +```js |
| 167 | +[ |
| 168 | + '# #', |
| 169 | + '# #', |
| 170 | + '# #' |
| 171 | +] |
| 172 | +``` |
| 173 | + |
| 174 | +Luego, verificamos si alguna de las líneas contiene un asterisco `*` y si el asterisco no está en los bordes de la caja: |
| 175 | + |
| 176 | +```js |
| 177 | +line.includes('*') && |
| 178 | +line.indexOf('*') > 0 && |
| 179 | +line.indexOf('*') < line.length - 1 |
| 180 | +``` |
| 181 | + |
| 182 | +Para este caso el arreglo se recorreria 3 veces. |
| 183 | + |
| 184 | +Validamos la primera iteracion donde tenemos la linea `# #`: |
| 185 | + |
| 186 | +Tenemos que para la primera condición `line.includes('*')` es falsa, ya que la linea no contiene un asterisco `*`. |
| 187 | + |
| 188 | +Para la segunda condición `line.indexOf('*') > 0` es falsa, ya que el asterisco no está en el borde izquierdo de la caja. |
| 189 | + |
| 190 | +```js |
| 191 | +// Reemplazamos los valores de la linea por sus indices |
| 192 | +// # # |
| 193 | +// 01234 |
| 194 | + |
| 195 | +line.indexOf('*') = -1; |
| 196 | + |
| 197 | +// -1 > 0 |
| 198 | +line.indexOf('*') > 0; // false |
| 199 | +``` |
| 200 | + |
| 201 | +Para la tercera condición `line.indexOf('*') < line.length - 1` es verdadera, Aunque la linea no contiene un asterisco, la condición se cumple, ya que el asterisco no está en el borde derecho de la caja. |
| 202 | + |
| 203 | +```js |
| 204 | +// Reemplazamos los valores de la linea por sus indices |
| 205 | +// # # |
| 206 | +// 01234 |
| 207 | + |
| 208 | +line.indexOf('*') = -1; |
| 209 | +line.length - 1 = 4; |
| 210 | + |
| 211 | +// -1 < 4 |
| 212 | +line.indexOf('*') < line.length - 1; // true |
| 213 | +``` |
| 214 | + |
| 215 | +Para esta primera iteración nos devolvería `false`, ya que tenemos lo siguiente: |
| 216 | + |
| 217 | +```js |
| 218 | +// Line: # # |
| 219 | + |
| 220 | +line.includes('*') = false; |
| 221 | +line.indexOf('*') > 0 = false; |
| 222 | +line.indexOf('*') < line.length - 1 = true; |
| 223 | + |
| 224 | +// false && false && true = false |
| 225 | +``` |
| 226 | + |
| 227 | +Es curioso como es que la tercera condición se cumple, aunque la linea no contiene un asterisco `*`. Sin embargo, como la primera condición es falsa, el resultado final sería `false`. |
| 228 | + |
| 229 | +Como las demás lineas son iguales, el resultado para las tres iteraciones restantes sería `false`, ya que no se cumple la condición de que el asterisco no está en los bordes de la caja. Por lo que el resultado final sería `false`. |
| 230 | + |
| 231 | +**Veamos este caso curioso**: |
| 232 | + |
| 233 | +```js |
| 234 | +const box = [ |
| 235 | + "#####", |
| 236 | + "# #", |
| 237 | + "# #*", |
| 238 | + "#####" |
| 239 | +] |
| 240 | +``` |
| 241 | + |
| 242 | +Primero, eliminamos el primer y último elemento de la caja: |
| 243 | + |
| 244 | +```js |
| 245 | +box.slice(1, -1); |
| 246 | +``` |
| 247 | + |
| 248 | +Esto nos dará: |
| 249 | + |
| 250 | +```js |
| 251 | +[ |
| 252 | + '# #', |
| 253 | + '# #*' |
| 254 | +] |
| 255 | +``` |
| 256 | + |
| 257 | +Tomamos la primera iteración donde tenemos la linea `# #`: |
| 258 | + |
| 259 | +Como este caso ya lo hemos analizado anteriormente, sabemos que el resultado sería `false`. |
| 260 | + |
| 261 | +Para la segunda iteración donde tenemos la linea `# #*`: |
| 262 | + |
| 263 | +Tenemos que para la primera condición `line.includes('*')` es verdadera, ya que la linea contiene un asterisco `*`. |
| 264 | + |
| 265 | +Para la segunda condición `line.indexOf('*') > 0` es verdadera, ya que el asterisco no está en el borde izquierdo de la caja, pero al parecer está dentro de la caja. |
| 266 | + |
| 267 | +```js |
| 268 | +// Reemplazamos los valores de la linea por sus indices |
| 269 | +// # #* |
| 270 | +// 012345 |
| 271 | + |
| 272 | +line.indexOf('*') = 4; |
| 273 | + |
| 274 | +// 4 > 0 |
| 275 | +line.indexOf('*') > 0; // true |
| 276 | +``` |
| 277 | + |
| 278 | +Para la tercera condición `line.indexOf('*') < line.length - 1` es falso, ya que el asterisco está en el borde derecho de la caja. |
| 279 | + |
| 280 | +```js |
| 281 | +// Reemplazamos los valores de la linea por sus indices |
| 282 | +// # #* |
| 283 | +// 012345 |
| 284 | + |
| 285 | +line.indexOf('*') = 4; |
| 286 | +line.length - 1 = 4; |
| 287 | + |
| 288 | +// 4 < 4 |
| 289 | +line.indexOf('*') < line.length - 1; // false |
| 290 | +``` |
| 291 | + |
| 292 | +Para esta segunda iteración nos devolvería `false`, ya que tenemos lo siguiente: |
| 293 | + |
| 294 | +```js |
| 295 | +// Line: # #* |
| 296 | + |
| 297 | +line.includes('*') = true; |
| 298 | +line.indexOf('*') > 0 = true; |
| 299 | +line.indexOf('*') < line.length - 1 = false; |
| 300 | + |
| 301 | +// true && true && false = false |
| 302 | +``` |
| 303 | + |
| 304 | +Como la primera iteración nos devolvió `false`, el método `some` se detiene y no sigue iterando sobre las demás lineas. Pero como solo tenemos dos lineas, el resultado final sería `false`. |
0 commit comments