Пылающая клавиатура дверной ручки!


21

Ну, оказывается, имя пользователя Doorknob на GitHub, Reddit и других сайтах - KeyboardFire . Это дает мне идею ...

Задание

Вы работаете в KeyboardFire Inc., компании, которая производит специальные клавиатуры. И под «особенным» я имею в виду, что всякий раз, когда вы нажимаете клавишу, что-то в вашем доме загорается! С новой серией ручек KeyboardFire Doorknob - это дверные ручки.

Однако из-за глупых правительственных постановлений ваши пользователи должны знать, какие дверные ручки в их доме зажгутся.

Рассмотрим искусство ASCII части клавиатуры 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

( |Символы представляют границы между ключами.)

Мы можем рассматривать этот точный рисунок ASCII как своего рода «график», где каждый символ в диапазоне [a-z0-9] имеет индекс x (горизонтальный) и y (вертикальный), где (0,0)есть 1. Например, буква dимеет координаты (2,6)(трубы и пробелы включены в расчет координат).

Теперь давайте подумаем о доме каждого пользователя. Каждый дом может быть нарисован сверху вниз как искусство 20x4 ASCII (в этом мире, где разрешается продавать разрушительные клавиатуры, каждый дом одинакового размера). Мы можем использовать Ds, чтобы отметить позиции каждой дверной ручки в доме. Вот пример:

D         D  D     D
    D               

              D  D  

Мы назовем это «карта дома». (Да, это много дверных ручек!)

Нажатие любой клавиши зажжет ближайшую ручку двери в огне. Например, если мы берем предыдущие координаты буквы d, ближайшая ручка двери (по расстоянию до Манхэттена) находится в координатах (1,4). Это дверная ручка, которая загорается при нажатии буквы d. Если бы мы пометили пылающую ручку двери F, результат был бы:

D         D  D     D
    F               

              D  D  

Спецификации

Ваша программа будет принимать два входа:

  • Строка, которая соответствует шаблону [a-z0-9]+.
  • Карта дома. Это может быть строка, список строк или что-то эквивалентное.

Вам нужно пройти каждую букву строки и зажечь соответствующую ручку двери (измените ее букву на F). Если ближайшая дверная ручка уже горит, оставьте ее как есть. Если с помощью этого метода можно зажечь более 1 дверной ручки, вы можете зажечь любую.

После того, как вся строка обработана таким образом, вам нужно распечатать получившуюся карту дома.

Код-гольф, поэтому самая короткая программа выигрывает. Стандартные лазейки запрещены как обычно.

пример

Строка:

helloworld123

Карта дома:

D    D       D     D
    D

              D  D  

Возможные результаты:

F    F       F     D
    F

              D  F

Или:

F    D       F     D
    F

              D  F

Или:

F    F       D     D
    F

              F  F

Или:

F    D       D     D
    F

              F  F

РЕДАКТИРОВАТЬ: Э-э ... есть причина, по которой у меня есть один ответ, даже с +50 щедрости? Если вы найдете направление сложным / расплывчатым, я был бы рад, если бы вы опубликовали в комментариях или что-то ... или я делаю что-то не так ...

РЕДАКТИРОВАТЬ 2: Срок действия Bounty истекает через день! Опубликовать что-то еще! Пожалуйста! ПОЖАЛУЙСТА!!!! :(


1
Есть несколько вещей, которые меня dсмущают : 1) Почему координаты (2, 6), а не (2, 2)? 2) Почему в примере так много возможных ответов? 3) Когда вы объясняете, как все будет гореть, почему вы вообще об этом говорите d? Почему бы просто не сказать прямо, что нажатие aзажжет какой-то дом в огне? Имеет ли dэто сделать, тоже?
Quelklef

@Quelklef Это немного лучше? Спасибо за ответ!
kirbyfan64sos

Если «h» оказывается точно между двумя дверными ручками, а «h» вызывается дважды, должны ли обе дверные ручки гореть? или может программа выберет одну и ту же ручку?
Грант Дэвис

@GrantDavis Программа может выбрать одну и ту же ручку двери.
kirbyfan64sos

Ответы:


3

JavaScript (ES6), 204 байта

(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``

Хорошо, я отвечу. ;)

объяснение

(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

Тестовое задание

<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>


2
Я наконец получил другой ответ !!! : D
kirbyfan64sos

12

Рубин, 229 байт

->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}

Не очень хорошо, но мне просто нужно было получить первый ответ.

Слегка разглаженная / прокомментированная версия:

#!/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']]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.