Berhenti berjalan ke dinding!

16

Beberapa suka-suka-nakal berbasis teks tidak membiarkan Anda masuk ke dinding, dan memberi Anda langkah mundur jika Anda mencobanya. Mengapa melakukan itu ketika Anda bisa membuat pemain bergerak ke arah yang sah terdekat?

Tantangan

Tulis program fungsi yang, diberi arah dan kisi karakter 3 oleh 3, menampilkan kisi yang sama setelah pemain mengambil langkah.

Sebagai contoh,

9
#..
.@#
#.#

menjadi

#.@
..#
#.#

Memasukkan

  • Arah diberikan oleh satu digit dari 1 hingga 9, masing-masing sesuai dengan 8 arah mata angin dan diam. Ini berasal dari lokasi relatif angka pada keypad:

    NW N NE
    .. \ | /
    ... 7 8 9
    W- 4 5 6 -E
    ... 1 2 3
    ../ | \
    SW S SE
    
    Namun, Anda juga dapat menggunakan angka 123, 456, 789 alih-alih 789, 456, 123. Dengan kata lain, Anda dapat menukar 2 baris atau angka atas dan bawah jika Anda memilihnya. Ini adalah satu-satunya 2 kombinasi indeks yang dapat diterima.

  • Kisi-kisi 3 oleh 3 akan terdiri dari 3 karakter ASCII yang dapat dicetak yang mewakili lantai, dinding, dan pemain yang dapat dilewati. (Dalam kasus uji, .digunakan untuk lantai, #dinding, dan @pemain)

  • Anda dapat memilih karakter apa yang digunakan oleh program Anda, tetapi Anda harus menyatakannya dalam jawaban Anda dan karakter itu harus konsisten dalam berbagai uji coba.
  • Karakter yang mewakili karakter akan selalu berada di tengah kotak 3 dengan 3, dan arahnya akan selalu antara 1 dan 9 (termasuk)
  • Anda dapat menerima input dalam urutan apa pun
  • Kisi 3 oleh 3 dapat dimasukkan sebagai array char, array string, string 9 panjang, atau alternatif lain yang masuk akal.

Keluaran

  • Kembali dari fungsi, atau output ke StdOut atau alternatif terdekat
  • Ruang tambahan dan baris baru diizinkan
  • Anda harus menggunakan representasi karakter yang sama sebagai input
  • Format yang sama diizinkan untuk input diizinkan untuk output

Bagaimana pemain bergerak

Jika arah yang ditentukan diblokir oleh dinding (misalnya jika contoh di atas memiliki arah 6), maka lihatlah 2 arah terdekat:

  • Jika satu (dan hanya satu) arah gratis, gerakkan pemain ke arah itu.
  • Jika tidak ada arah yang gratis, lihat 2 arah terdekat berikutnya (tidak termasuk arah 5). Jika Anda telah membungkus sepanjang jalan dan tidak menemukan arah terbuka (pemain dikelilingi oleh dinding), jangan gerakkan pemain
  • Jika kedua arah terbuka, pilih satu untuk dipindahkan secara acak (meskipun tidak harus seragam).

Jika arah yang diberikan adalah 5, jangan gerakkan pemain

Uji kasus

( #= dinding, .= lantai, @= pemain)

Memasukkan:

9
# ..
. @ #
#. #

Keluaran:

#. @
.. #
#. #


Memasukkan:

3
# ..
. @ #
#. #

Keluaran:

# ..
.. #
# @ #


Memasukkan:

7
##.
# @ #
.. #

Keluaran:

## @ ##.
#.# atau #.#
.. # @. #


Memasukkan:

5
...
. @.
...

Keluaran:

...
. @.
...


Memasukkan:

2
###
# @ #
###

Keluaran:

###
# @ #
###

Mencetak gol

Ini adalah , jadi jawaban tersingkat dalam byte menang.

MildlyMilquetoast
sumber
Tidak menggunakan yuhjklbn? MENINGGAL DUNIA.
Rɪᴋᴇʀ
Juga, saya tidak terlalu suka bagian "memilih arah alternatif". Ini agak berbeda dari bagian lain dari tantangan, yaitu "memindahkan pemain ke arah dan output yang ditentukan." Itu hanya preferensi pribadi.
Rɪᴋᴇʀ
1
Bagian ini membingungkan: "Jika tidak ada arah yang gratis, lihat 2 arah terdekat berikutnya."
Leaky Nun
1
Bisakah kita menetapkan angka alih-alih karakter ASCII untuk setiap elemen, lalu mengambil input sebagai daftar 2 dimensi? Atau apakah mereka harus menjadi dawai?
Scott Milner
2
Dapatkah saya menggunakan arah 123;456;789bukan 789;456;123?
Leaky Nun

Jawaban:

2

Pyth - 73 70 byte

Kmsd"78963214"DPGJXXYt@K+xKQG\@4\.R?q/J\#/Y\#Jk=YwV5=GflTmPd(N_N)IGOGB

Cobalah

Input terdiri dari dua baris:

Baris 1: arah bergerak

Baris 2: Papan (posisi 123456789, dengan 123 sebagai baris teratas)

Maria
sumber
3

JavaScript (ES6), 192 163 byte

a=>b=>a[(a[4]=0)+--b]?(A=(c,d)=>c==b|(e=a[c])-(f=a[d])|!e?(a[c-b?(e?e<f:new Date&1)?c:d:4]=2,a):A(+g[c],+h[d]))(+(g="3016X2785")[b],+(h="1250X8367")[b]):(a[b]=2,a)

Catatan

Fungsi ini menggunakan format input khusus. Input pertama adalah array bilangan bulat ( 0untuk floor, 1untuk walldan 2untuk player) yang mewakili peta. Input kedua adalah arah (terbalik): 1adalah barat laut, 2utara, 3timur laut, 4barat dll. Masukan harus diberikan melalui sintaks currying (Z(a)(b) ).

Uji kasus

Peta dan arah telah dimodifikasi agar sesuai dengan format input saya.

Z=
a=>b=>a[(a[4]=0)+--b]?(A=(c,d)=>c==b|(e=a[c])-(f=a[d])|!e?(a[c-b?(e?e<f:new Date&1)?c:d:4]=2,a):A(+g[c],+h[d]))(+(g="3016X2785")[b],+(h="1250X8367")[b]):(a[b]=2,a)

testcases = [
    [[1,0,0,0,2,1,1,0,1], 3],
    [[1,0,0,0,2,1,1,0,1], 9],
    [[1,1,0,1,2,1,0,0,1], 1],
    [[0,0,0,0,2,0,0,0,0], 5],
    [[1,1,1,1,2,1,1,1,1], 2]
]
for (test of testcases) {
    console.log(Z(test[0])(test[1]))
}

Luke
sumber
1

Python 3, 120 104 153 176 175 byte

def f(n,l):
 n-=1
 if n!=4and'.'in l:l[sorted(enumerate(l),key=lambda x:abs(x[0]%3-n%3+(x[0]//3-n//3)*1j)-ord(x[1])-__import__('random').random()/9)[1][0]],l[4]='@.'
 return l

Cobalah online!

Metode ini mendapatkan arahan dan daftar '.', '#' Dan '@'. Indeks dimulai dengan 1 hingga 9 (dengan 0 hingga 8 dalam daftar sebenarnya). Jadi ada bentuknya

123 
456
789 

Metode mengembalikan daftar baru dengan posisi baru.

Garis ini

sorted(enumerate(l),key=lambda x:abs(x[0]%3-n%3+(x[0]//3-n//3)*1j)-ord(x[1])-__import__('random').random()/9)

mengembalikan daftar jenis ini:

>>>n=7
>>> l=['#','#','#','.','@','#','.','#','.']
>>> sorted(enumerate(l),key=lambda x:abs(x[0]%3-n%3+(x[0]//3-n//3)*1j)-ord(x[1])-__import__('random').random()/9)
[(4, '@'), (8, '.'), (6, '.'), (3, '.'), (7, '#'), (5, '#'), (1, '#'), (0, '#'), (2, '#')]

Kami menghitung jarak ke poin gratis dan menambahkan keacakan. Karena ord('#') <= ord('.') - 8 and ord('.') + 8 <= ord('@')kita dapat mengatakan itu terdekat '.' untuk n = 7 (indeks dalam daftar) memiliki indeks 8.

masukkan deskripsi gambar di sini

Contoh:

>>> f(9, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '.', '.', '.', '#', '#', '@', '#']
>>> f(3, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '@', '.', '.', '#', '#', '.', '#']
>>> f(5, ['.','.','#','.','@','.','#','.','#'])
['.', '.', '#', '.', '@', '.', '#', '.', '#']
>>> f(7, ['#','#','#','#','@','#','#','#','#'])
['#', '#', '#', '#', '@', '#', '#', '#', '#']
>>> f(7, ['#','.','.','.','@','#','#','.','#'])
['#', '.', '.', '@', '.', '#', '#', '.', '#'] or ['#', '.', '.', '.', '.', '#', '#', '@', '#']
Кирилл Малышев
sumber
1) Ini tidak berfungsi untuk kasus uji di mana arah pemain ingin pindah ditempati dan posisi yang benar bukan yang pertama ','(yang merupakan kasus untuk kasus uji 2, 3 dan 5). 2) Format I / O Anda sepertinya tidak sama dengan yang ada di pertanyaan. Harap sebutkan format I / O Anda.
Lukas
Contoh f(9, ...Anda tidak berfungsi - ia menempatkan karakter pada 2 tetapi posisi terdekat ke 9 adalah 6 dan 8, jadi salah satu dari itu harus dipilih secara acak (tidak ada keacakan dalam kode Anda juga). Selanjutnya ia harus pergi berkeliling perimeter menemukan terdekat berikutnya, sehingga f(9,list("####@#.##"))harus menempatkan karakter ke satu-satunya tempat yang mungkin (7 di sini).
Jonathan Allan
Terima kasih telah menunjukkan kesalahan Bagi saya, beritanya adalah kode l [4], l [l.index ('.')] = '. @' Dan l [l.index ('.')], L [4 ] = '@.' berbeda
Кирилл Малышев
@ Jonathan Allan, awalnya saya tidak begitu mengerti aturannya. Saya harap saya dapat memperbaiki kode dengan benar.
Кирилл Малышев
Masih tidak benar, tidak. 1. contoh f(9, ...harus kembali list("#....##@#")(karena 8 gratis dan di sebelah 9). 2. Sesuatu seperti f(9,list("####@.#.#"))harus memiliki beberapa kesempatan untuk kembali list("####..#@#")(tidak selalu list("####.@#.#")) seperti yang ditentukan "Jika kedua arah terbuka, pilih satu untuk pindah secara acak".
Jonathan Allan