Flaming Gagang Pintu Keyboard!

21

Ya, ternyata nama pengguna Doorknob di GitHub, Reddit, dan situs lainnya adalah KeyboardFire . Itu memberi saya ide ...

Tugas

Anda bekerja di KeyboardFire Inc., perusahaan yang membuat keyboard khusus. Dan, dengan "spesial", maksud saya, setiap kali Anda menekan tombol, sesuatu di rumah Anda menyala! Dengan seri KeyboardFire Doorknob yang baru, objek yang menyala adalah gagang pintu.

Namun , karena peraturan pemerintah yang bodoh, pengguna Anda perlu tahu gagang pintu mana yang akan menyala.

Pertimbangkan seni ASCII ini dari sebagian keyboard 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

(Tanda |mewakili batas antara kunci.)

Kita dapat memperlakukan gambar ASCII yang tepat ini sebagai "grafik" macam, di mana setiap karakter dalam rentang [a-z0-9] memiliki indeks x (horizontal) dan y (vertikal), di mana (0,0)ada 1. Misalnya surat itud memiliki koordinat (2,6)(pipa dan spasi dimasukkan dalam perhitungan koordinat).

Sekarang mari kita pikirkan rumah masing-masing pengguna. Setiap rumah dapat digambarkan dari atas ke bawah sebagai seni ASCII 20x4 (di dunia ini tempat menjual keyboard yang merusak secara legal, setiap rumah memiliki ukuran yang sama). Kita dapat menggunakan Duntuk menandai posisi setiap gagang pintu di rumah. Ini sebuah contoh:

D         D  D     D
    D               

              D  D  

Kami akan menyebutnya "peta rumah". (Ya, itu banyak kenop pintu!)

Menekan tombol apa saja akan menyalakan gagang pintu terdekat yang menyala. Misalnya, jika kita mengambil koordinat surat sebelumnya d, kenop pintu terdekat (dengan jarak Manhattan) ada di koordinat (1,4). Ini adalah gagang pintu yang akan menyala ketika surat ditu mengenai. Jika kita menandai kenop pintu yang menyala dengan F, hasilnya adalah:

D         D  D     D
    F               

              D  D  

Spesifikasi

Program Anda akan mengambil dua input:

  • String yang cocok dengan polanya [a-z0-9]+.
  • Peta rumah. Ini bisa berupa string, daftar string, atau sesuatu yang setara.

Anda harus membaca setiap huruf dari string dan menyalakan masing-masing gagang pintu terbakar (ubah hurufnya menjadi F ). Jika kenop pintu terdekat sudah terbakar, biarkan apa adanya. Jika ada lebih dari 1 kenop pintu yang dapat dinyalakan menggunakan metode ini, Anda dapat menyalakan yang mana saja yang Anda inginkan.

Setelah seluruh string diproses dengan cara ini, Anda perlu mencetak peta rumah yang dihasilkan.

Code-golf, sehingga program terpendek menang. Celah standar dilarang seperti biasa.

Contoh

Tali:

helloworld123

Peta rumah:

D    D       D     D
    D

              D  D  

Kemungkinan hasil:

F    F       F     D
    F

              D  F

Atau:

F    D       F     D
    F

              D  F

Atau:

F    F       D     D
    F

              F  F

Atau:

F    D       D     D
    F

              F  F

EDIT: Uh ... apakah ada alasan saya punya satu jawaban, bahkan dengan hadiah +50? Jika Anda menemukan arahan rumit / tidak jelas, saya akan senang jika Anda memposting di komentar atau sesuatu ... atau saya melakukan kesalahan ...

EDIT 2: Bounty berakhir dalam waktu kurang dari sehari! Posting sesuatu yang lain! Silahkan! SILAHKAN!!!! :(

kirbyfan64sos
sumber
1
Ada beberapa hal yang saya anggap membingungkan: 1) Mengapa dcoord (2, 6) dan tidak (2, 2)? 2) Mengapa contoh itu memiliki begitu banyak jawaban yang memungkinkan? 3) Ketika Anda menjelaskan bagaimana hal-hal akan menyala, mengapa Anda bahkan berbicara tentang d? Mengapa tidak langsung mengatakan bahwa menekan aakan membuat rumah terbakar? Apakah dmelakukannya juga?
Quelklef
@Quelklef Apakah ini sedikit lebih baik? Terima kasih untuk umpan baliknya!
kirbyfan64sos
Jika 'h' berakhir tepat di antara dua gagang pintu dan 'h' disebut dua kali, haruskah kedua gagang pintu terbakar? atau bisakah program memilih untuk memecat gagang pintu yang sama?
Grant Davis
@GrantDavis Program ini dapat memilih untuk mengaktifkan kenop pintu yang sama.
kirbyfan64sos

Jawaban:

3

JavaScript (ES6), 204 byte

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

Baik, saya akan menjawabnya. ;)

Penjelasan

(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

Uji

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

pengguna81655
sumber
2
Saya akhirnya mendapat jawaban lain !!! : D
kirbyfan64sos
12

Ruby, 229 byte

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

Tidak terlalu bagus, tetapi saya hanya harus mendapatkan jawaban pertama.

Versi sedikit ungolfed / berkomentar:

#!/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']]
Gagang pintu
sumber