Flaming Doorknob Keyboards!

21

Bueno, resulta que el nombre de usuario de Doorknob en GitHub, Reddit y otros sitios es KeyboardFire . Eso me da una idea...

La tarea

Usted trabaja en KeyboardFire Inc., una compañía que fabrica teclados especiales. Y, por "especial", quiero decir que, cada vez que presionas una tecla, ¡algo en tu casa se enciende! Con la nueva serie KeyboardFire Doorknob, los objetos que se encienden son pomos de las puertas.

Sin embargo , debido a las estúpidas regulaciones gubernamentales, sus usuarios necesitan saber qué pomos de las puertas de sus casas se encenderán.

Considere este arte ASCII de una parte de un teclado QWERTY:

1|2|3|4|5|6|7|8|9|0
 q|w|e|r|t|y|u|i|o|p
  a|s|d|f|g|h|j|k|l
   z|x|c|v|b|n|m

(Los |'s representan los límites entre las teclas).

Podemos tratar este dibujo ASCII exacto como una especie de "gráfico", donde cada carácter en el rango [a-z0-9] tiene un índice x (horizontal) e y (vertical), donde (0,0)está 1. Por ejemplo, la letra dtiene las coordenadas (2,6)(las tuberías y los espacios se incluyen en el cálculo de coordenadas).

Ahora pensemos en la casa de cada usuario. Cada casa se puede dibujar desde arriba hacia abajo como un arte ASCII 20x4 (en este mundo donde es legal vender teclados destructivos, cada casa es del mismo tamaño). Podemos usar D's para marcar las posiciones de cada pomo de la puerta de la casa. Aquí hay un ejemplo:

D         D  D     D
    D               

              D  D  

Llamaremos a esto el "mapa de la casa". (Sí, ¡son muchos pomos de las puertas!)

Al presionar cualquier tecla, se encenderá el pomo de la puerta más cercano. Por ejemplo, si tomamos las coordenadas anteriores de la letra d, el pomo de la puerta más cercano (por distancia de Manhattan) está en las coordenadas (1,4). Este es el pomo de la puerta que se encenderá cuando dse golpee la letra . Si marcamos el pomo de la puerta con un F, el resultado sería:

D         D  D     D
    F               

              D  D  

Las especificaciones

Su programa tomará dos entradas:

  • Una cadena que coincide con el patrón [a-z0-9]+.
  • Un mapa de la casa. Puede ser una cadena, una lista de cadenas o algo equivalente.

Debe pasar por cada letra de la cadena y encender el pomo de la puerta respectivo (cambie su letra a F). Si el pomo de la puerta más cercano ya está en llamas, déjelo como está. Si hay más de 1 pomo de la puerta que se puede encender con este método, puede encender el que desee.

Después de que toda la cadena se procesa de esta manera, debe imprimir el mapa de la casa resultante.

Code-golf, por lo que gana el programa más corto. Lagunas estándar prohibidas como de costumbre.

Ejemplo

Cuerda:

helloworld123

Mapa de la casa:

D    D       D     D
    D

              D  D  

Posibles resultados:

F    F       F     D
    F

              D  F

O:

F    D       F     D
    F

              D  F

O:

F    F       D     D
    F

              F  F

O:

F    D       D     D
    F

              F  F

EDITAR: Uh ... ¿hay alguna razón por la que tengo una respuesta, incluso con una recompensa de +50? Si encuentra las instrucciones complicadas / vagas, me alegraría si publicara en los comentarios o algo ... o si estoy haciendo algo mal ...

EDIT 2: ¡La recompensa caduca en menos de un día! ¡Publica algo más! ¡Por favor! ¡¡¡¡POR FAVOR!!!! :(

kirbyfan64sos
fuente
1
Hay algunas cosas que me parecen confusas: 1) ¿Por qué dlas coordenadas de (2, 6) y no (2, 2)? 2) ¿Por qué el ejemplo tiene tantas respuestas posibles? 3) Cuando explicas cómo se encenderán las cosas, ¿por qué estás hablando d? ¿Por qué no decir directamente que presionar aencenderá una casa en llamas? ¿Lo dhace también?
Quelklef
@Quelklef ¿Es esto un poco mejor? ¡Gracias por la respuesta!
kirbyfan64sos
Si 'h' termina exactamente entre dos pomos de las puertas y se llama a 'h' dos veces, ¿deberían incendiarse ambos pomos de las puertas? o puede el programa elegir disparar el mismo pomo?
Grant Davis
@GrantDavis El programa puede elegir disparar el mismo pomo de la puerta.
kirbyfan64sos

Respuestas:

3

JavaScript (ES6), 204 bytes

(s,h)=>[...s].map(c=>(o="1234567890qwertyuiopasdfghjkl_zxcvbnm".search(c),y=o/10|0,x=o%10*2+y,n=a=Math.abs,h.map((k,i)=>k.match(/\s/)||(d=a(x-i%21)+a(y-i/21|0))>n||(n=d,p=i)),h[p]="F"),h=[...h])&&h.join``

Bien, lo responderé. ;)

Explicación

(s,h)=>
  [...s].map(c=>(                     // iterate through each character of the input

    // Get X and Y coordinates of the character input
    o="1234567890qwertyuiopasdfghjkl_zxcvbnm".search(c),
    y=o/10|0,
    x=o%10*2+y,

    // Find the nearest doorknob
    n=                                // n = Manhattan distance to nearest doorknob
      a=Math.abs,
    h.map((k,i)=>                     // iterate through each character of the house
      k.match(/\s/)||                 // do not check distance to whitespace characters
        (d=a(x-i%21)+a(y-i/21|0))>n|| // d = distance to the current doorknob
          (n=d,                       // set the nearest doorknob to this one
          p=i)                        // p = position of the doorknob
    ),
    h[p]="F"                          // update the doorknob to "F" in the house string
  ),h=[...h])&&h.join``               // return the house map as a string

Prueba

<input type="text" id="input" value="helloworld123" /><br />
<textarea id="house" rows="4" cols="20">D    D       D     D
    D               
                    
              D  D  </textarea><br />
<button onclick='result.innerHTML=(

(s,h)=>[...s].map(c=>(o="1234567890qwertyuiopasdfghjkl_zxcvbnm".search(c),y=o/10|0,x=o%10*2+y,n=a=Math.abs,h.map((k,i)=>k.match(/\s/)||(d=a(x-i%21)+a(y-i/21|0))>n||(n=d,p=i)),h[p]="F"),h=[...h])&&h.join``

)(input.value,house.value)'>Go</button>
<pre id="result"></pre>

usuario81655
fuente
2
¡Finalmente recibí otra respuesta! : D
kirbyfan64sos
12

Rubí, 229 bytes

->s,m{c=m.flat_map.with_index{|x,i|x.size.times.select{|j|x[j]==?D}.map{|y|[i,y]}}
s.chars{|h|x='1234567890qwertyuiop*asdfghjkl*zxcvbnm'.index h
x,y=(x%10)*2,x/10
a,b=c.min_by{|a,b|(y-a).abs+((y%2>0?x+1:x)-b).abs}
m[a][b]='F'}
m}

No muy bueno, pero solo tenía que obtener la primera respuesta.

Versión ungolfed / comentada:

#!/usr/bin/ruby

f = -> s, m {
    # get knob coords
    c = m.flat_map.with_index {|x, i| x.size.times.select{|j| x[j] == ?D }.map{|y| [i, y] } }
    # for each char in the string
    s.chars {|h|
        # note the asterisks to correct for offsets
        x = '1234567890qwertyuiop*asdfghjkl*zxcvbnm'.index h
        # get un-"staggered" x and y coords
        x, y = (x % 10) * 2, x / 10
        # add one to x for every other row to fit keyboard
        x += 1 if y % 2 > 0
        # find closest knob by Manhattan distance
        a, b = c.min_by{|a, b| (y - a).abs + (x - b).abs }
        # LIGHT IT ON FIRE!
        m[a][b] = 'F'
    }
    # return new map
    m
}

puts f['helloworld123', ['D    D       D     D', '    D', '', '              D  D']]
Pomo de la puerta
fuente