Flaming Klawiatury Klamki!


21

Okazuje się, że nazwa użytkownika Doorknob na GitHub, Reddit i innych stronach to KeyboardFire . To daje mi pomysł ...

Zadanie

Pracujesz w KeyboardFire Inc., firmie produkującej specjalne klawiatury. I przez „specjalne” rozumiem, że za każdym razem, gdy naciskasz klawisz, coś w twoim domu zapala się! Dzięki nowej serii klamek KeyboardFire obiektami zapalającymi się są klamki.

Jednak z powodu głupich przepisów rządowych użytkownicy muszą wiedzieć, które klamki w ich domu zapalą się.

Rozważ tę grafikę ASCII części klawiatury 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

(Te |reprezentują granice między kluczami.)

Możemy traktować ten dokładny rysunek ASCII jako swego rodzaju „wykres”, w którym każdy znak w zakresie [a-z0-9] ma indeks x (poziomy) i y (pionowy), gdzie (0,0)jest 1. Na przykład litera dma współrzędne (2,6)(rury i spacje są uwzględniane w obliczeniach współrzędnych).

Pomyślmy teraz o domu każdego użytkownika. Każdy dom może być narysowany w widoku z góry jako grafika 20x4 ASCII (w tym świecie, gdzie legalna jest sprzedaż niszczących klawiatur, każdy dom ma ten sam rozmiar). Możemy użyć Dznaku do oznaczenia pozycji każdej klamki w domu. Oto przykład:

D         D  D     D
    D               

              D  D  

Nazwiemy to „mapą domu”. (Tak, to dużo klamek!)

Naciśnięcie dowolnego klawisza zapali najbliższą klamkę w ogniu. Na przykład, jeśli weźmiemy poprzednie współrzędne litery d, najbliższa klamka (według odległości Manhattanu) znajduje się na współrzędnych (1,4). To jest klamka, która zapali się, gdy litera dzostanie trafiona. Gdybyśmy oznaczyli płonącą klamkę za pomocą F, wynik byłby następujący:

D         D  D     D
    F               

              D  D  

Specyfikacja

Twój program pobierze dwa dane wejściowe:

  • Ciąg pasujący do wzorca [a-z0-9]+.
  • Mapa domu Może to być ciąg, lista ciągów lub coś równoważnego.

Musisz przejrzeć każdą literę sznurka i zapalić odpowiednią klamkę w ogniu (zmień jej literę na F). Jeśli najbliższa klamka już się pali, pozostaw ją taką, jaka jest. Jeśli za pomocą tej metody można podpalić więcej niż 1 klamkę, możesz zapalić dowolną.

Po przetworzeniu całego łańcucha w ten sposób musisz wydrukować wynikową mapę domu.

Code-golf, więc wygrywa najkrótszy program. Standardowe luki zakazane jak zwykle.

Przykład

Strunowy:

helloworld123

Mapa domu:

D    D       D     D
    D

              D  D  

Możliwe wyniki:

F    F       F     D
    F

              D  F

Lub:

F    D       F     D
    F

              D  F

Lub:

F    F       D     D
    F

              F  F

Lub:

F    D       D     D
    F

              F  F

EDYCJA: Uh ... czy jest powód, dla którego mam jedną odpowiedź, nawet z nagrodą +50? Jeśli uznasz, że wskazówki są skomplikowane / niejasne, byłbym zadowolony, gdybyś zamieścił w komentarzach lub coś ... lub że robię coś złego ...

EDYCJA 2: Nagroda wygasa za niecały dzień! Opublikuj coś innego! Proszę! PROSZĘ!!!! :(


1
Jest kilka rzeczy, które są dla mnie mylące: 1) Dlaczego dwspółrzędne (2, 6), a nie (2, 2)? 2) Dlaczego przykład ma tak wiele możliwych odpowiedzi? 3) Kiedy wyjaśnisz, w jaki sposób zapali się ogień, dlaczego w ogóle mówisz d? Dlaczego po prostu nie powiedzieć wprost, że naciśnięcie azapali jakiś dom w ogniu? Czy dto też robi?
Quelklef

@Quelklef Czy to trochę lepsze? Dzięki za opinie!
kirbyfan64sos

Jeśli „h” kończy się dokładnie między dwoma klamkami, a „h” jest wywoływany dwukrotnie, czy oba klamki powinny się zapalić? lub czy program może odpalić tę samą klamkę?
Grant Davis

@GrantDavis Program może odpalić tę samą klamkę.
kirbyfan64sos

Odpowiedzi:


3

JavaScript (ES6), 204 bajty

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

Dobrze, odpowiem na to. ;)

Wyjaśnienie

(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

Test

<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
W końcu dostałem kolejną odpowiedź !!! : D
kirbyfan64sos

12

Rubinowy, 229 bajtów

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

Nie bardzo dobre, ale ja po prostu miał dostać pierwszą odpowiedź w.

Wersja nieco nieoznaczona / skomentowana:

#!/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']]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.