Inspektur Ruby Resmi


30

Berikut ini adalah rubi seni ASCII yang sederhana :

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_\/

Sebagai penjual perhiasan untuk ASCII Gemstone Corporation, pekerjaan Anda adalah memeriksa batu rubi yang baru diperoleh dan meninggalkan catatan tentang segala cacat yang Anda temukan.

Untungnya, hanya 12 jenis cacat yang mungkin, dan pemasok Anda menjamin bahwa tidak ada ruby ​​yang memiliki lebih dari satu cacat.

12 cacat sesuai dengan penggantian salah satu dari 12 bagian _, /atau \karakter dari ruby dengan karakter spasi ( ). Garis luar rubi tidak pernah memiliki cacat.

Cacat diberi nomor sesuai dengan karakter mana yang memiliki ruang di tempatnya:

angka cacat

Jadi ruby ​​dengan cacat 1 terlihat seperti ini:

  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/

Rubi dengan cacat 11 terlihat seperti ini:

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/

Itu ide yang sama untuk semua cacat lainnya.

Tantangan

Tulis program atau fungsi yang mengambil string dari satu ruby, berpotensi rusak. Nomor cacat harus dicetak atau dikembalikan. Angka cacat adalah 0 jika tidak ada cacat.

Ambil input dari file teks, stdin, atau argumen fungsi string. Kembalikan nomor yang rusak atau cetak ke stdout.

Anda dapat berasumsi bahwa ruby ​​memiliki baris baru. Anda tidak boleh berasumsi bahwa ia memiliki spasi tambahan atau memimpin baris baru.

Kode terpendek dalam byte menang. ( Penghitung byte berguna. )

Uji Kasus

13 jenis rubi yang tepat, diikuti langsung oleh hasil yang diharapkan:

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_\/
0
  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/
1
  ___
 /\ /\
/_/ \_\
\ \_/ /
 \/_\/
2
  ___
 /\_/\
/_  \_\
\ \_/ /
 \/_\/
3
  ___
 /\_/\
/_/ \_\
\  _/ /
 \/_\/
4
  ___
 /\_/\
/_/ \_\
\ \ / /
 \/_\/
5
  ___
 /\_/\
/_/ \_\
\ \_  /
 \/_\/
6
  ___
 /\_/\
/_/ \ \
\ \_/ /
 \/_\/
7
  ___
 /\_ \
/_/ \_\
\ \_/ /
 \/_\/
8
  ___
 / _/\
/_/ \_\
\ \_/ /
 \/_\/
9
  ___
 /\_/\
/ / \_\
\ \_/ /
 \/_\/
10
  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/
11
  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_ /
12

Untuk memperjelas, ruby tidak dapat memiliki ruang trailing, kan?
Pengoptimal

@Optimizer Benar
Hobi Calvin

@ CalvinHobbies Semoga kami juga menganggap input tidak memiliki baris baru?
orlp

@ Atau Ya. Itulah inti dari bulan Mei .
Hobi Calvin

Rubi itu simetris. Jadi tidak seharusnya kesalahan # 7 sama dengan kesalahan # 10, misalnya?
DavidC

Jawaban:


13

CJam, 27 23 byte

F7EC5ZV4DI8G6]qBb67%J%#

Konversikan basis 11, ambil mod 67, ambil mod 19 dari hasilnya lalu cari indeks dari apa yang Anda miliki dalam array

[15, 7, 14, 12, 5, 3, 0, 4, 13, 18, 8, 16, 6]

Sihir!

Cobalah online .


34

Ruby 2.0, 69 byte

#!ruby -Kn0rdigest
p'×ñF<ìX‚ɲŸ_'.index Digest::MD5.digest(gets)[0]

Hexdump (untuk menampilkan data biner dalam string dengan setia):

00000000  23 21 72 75 62 79 20 2d  4b 6e 30 72 64 69 67 65  |#!ruby -Kn0rdige|
00000010  73 74 0a 70 27 d7 f1 46  3c 1f ec 58 82 c9 b2 9f  |st.p'..F<..X....|
00000020  5f 02 27 2e 69 6e 64 65  78 20 44 69 67 65 73 74  |_.'.index Digest|
00000030  3a 3a 4d 44 35 2e 64 69  67 65 73 74 28 67 65 74  |::MD5.digest(get|
00000040  73 29 5b 30 5d                                    |s)[0]|

Penjelasan:

  1. The -Knpilihan membaca file sumber sebagai ASCII-8BIT(binary).
  2. The -0pilihan memungkinkan getsuntuk membaca di seluruh input (dan bukan hanya satu baris).
  3. The -rdigestpilihan load digestmodul, yang menyediakan Digest::MD5.
  4. Kode kemudian melakukan MD5 input, mengambil byte pertama dari intisari, dan mendapatkan indeksnya dalam string biner yang diberikan.

Beruntung MD5 unik pada karakter pertama itu sendiri
Pengoptimal

15
Tidak diperlukan keberuntungan. Setiap byte memiliki 256 kemungkinan, jadi byte pertama berbeda untuk 13 hash tidaklah aneh. Tetapi jika mereka bertabrakan dengan alasan apa pun, saya hanya akan menggunakan byte kedua dari hash.
Chris Jester-Young

14
Tulis inspektur Ruby di Ruby. Tentu saja!
Tiang

Tantangan berikutnya: Periksa pos ini sendiri
Program Redwolf

7

Julia, 90 59 byte

Jelas bukan yang terpendek, tetapi gadis yang cantik, Julia, sangat berhati-hati dalam memeriksa batu delima kerajaan.

s->search(s[vec([18 10 16 24 25 26 19 11 9 15 32 34])],' ')

Ini menciptakan fungsi lambda yang menerima string sdan mengembalikan nomor cacat ruby ​​yang sesuai. Untuk menyebutnya, berikan nama, mis f=s->....

Penjelasan + tidak dikumpulkan:

function f(s)
    # Strings can be indexed like arrays, so we can define d to
    # be a vector of indices corresponding to potential defect
    # locations

    d = vec([18 10 16 24 25 26 19 11 9 15 32 34])

    # Check the specified locations for defects, returning the
    # defect number as the index where a space was found and
    # was not expected. If no spaces are found, 0 is returned.

    search(s[d], ' ')
end

Contoh:

julia> f("  ___
 /\\ /\\
/_/ \\_\\
\\ \\_/ \/
 \\/_\\/")
2

julia> f("  ___
 /\\_/\\
/_/ \\_\\
\\ \\_/ \/
 \\/_\\/")
0

Perhatikan bahwa garis miring terbalik harus lolos dalam input. Saya mengonfirmasi dengan @Cobin'sHobbies bahwa tidak apa-apa.

Beri tahu saya jika Anda memiliki pertanyaan atau saran!


Sunting: Disimpan 31 byte dengan bantuan dari Andrew Piliser!


Anda dapat menyingkirkan for for loop dengan searchdan pengindeksan array. s->(d=reshape([18 10 16 24 25 26 19 11 9 15 32 34],12);search(s[d],' ')). Saya tidak suka bentuk ulang, tapi saya tidak bisa memikirkan cara yang lebih pendek untuk mendapatkan array 1d.
Andrew mengatakan Reinstate Monica

@AndrewPiliser: Terima kasih, saya sangat menghargai masukan Anda! Saya mengedit untuk menggunakan saran Anda. Juga, cara yang lebih pendek daripada reshape()menggunakan vec(). :)
Alex A.

7

> <> (Ikan) , 177 byte

Ini adalah solusi yang panjang namun unik. Program tidak mengandung aritmatika atau percabangan selain memasukkan karakter input ke tempat-tempat tetap dalam kode.

Perhatikan bahwa semua karakter ruby-building yang diperiksa ( / \ _) dapat berupa "mirror" dalam kode> <> yang mengubah arah penunjuk instruksi (IP).

Kita dapat menggunakan karakter input ini untuk membangun labirin dari mereka dengan instruksi pengubah kode pdan di setiap jalan keluar (yang dibuat oleh cermin yang hilang pada input) kita dapat mencetak nomor yang sesuai.

iiiiiiiii19pi1cpi18piiii2bpi27pii28pi3apiiiii37pi49pi36piiiii00pi45pii46p

    ;
   ;n
  ;nb
 ;n6S    0n;
 n3SB   cn;
 8SB!  4n;
 SB!  1n;
>B! U9n;
 ! U5
  U7n
 Uan;
 2n;
 n;
 ;

Para S B Uhuruf adalah orang-orang berubah menjadi / \ _masing-masing. Jika input adalah ruby ​​penuh, kode terakhir menjadi:

\iiiiiiii19pi1cpi18piiii2bpi27pii28pi3apiiiii37pi49pi36piiiii00pi45pii46p

    ;
   ;n
  ;nb
 ;n6/    0n;
 n3/\   cn;
 8/\!  4n;
 /\!  1n;
>\! _9n;
 ! _5
  _7n
 _an;
 2n;
 n;
 ;

Anda dapat mencoba program ini dengan penerjemah visual online yang hebat ini . Karena Anda tidak dapat memasukkan baris baru di sana, Anda harus menggunakan beberapa karakter dummy sebagai gantinya sehingga Anda dapat memasukkan ruby ​​penuh seperti misalnya SS___LS/\_/\L/_/S\_\L\S\_/S/LS\/_\/. (Spasi juga berubah menjadi S karena penurunan harga.)


5

CJam, 41 31 29 28 byte

"-RI)11a!"q103b1e3%A/c#

Seperti biasa, untuk karakter yang tidak dapat dicetak, ikuti tautan ini .

Cobalah online di sini

Penjelasan segera


Pendekatan sebelumnya:

Cukup yakin ini dapat dikurangi dengan mengubah digit / konversi logika. Tapi begini usahanya yang pertama:

"<KJ[]\"O=":iqN-"/\\_ "4,er4b1e3%A/#

Seperti biasa, gunakan tautan ini untuk karakter yang tidak diinginkan.

Logikanya cukup sederhana

  • "Hash for each defect":i - Ini membuat saya hash per cacat sebagai indeks
  • qN-"/\\_ "4,er - ini mengubah karakter menjadi angka
  • 4b1e3%A/ - ini adalah nomor unik dalam basis angka yang dikonversi
  • # Maka saya hanya menemukan indeks nomor unik di hash

Cobalah online di sini


Begitu dekat, saya 1 karakter lebih pendek dari Anda!
orlp

Oh, saya sudah punya 28. Terlalu sibuk untuk memperbarui
Pengoptimal

Saya pikir jawaban saya optimal untuk Pyth. Pyth benar-benar membutuhkan fungsi hash ( .hsaat ini tidak berguna karena menggunakan built-in tidak dapat diandalkan dan buruk hash()), sampai saat itu saya tidak dapat berbuat lebih baik.
orlp

4

Slip , 123 108 + 3 = 111 byte

^6 (`\\`_.?<?.?[ _]?|`_(`\.?(<.?|>)|`/.?.?>.?.?).?)| `_(`\.?<.?>?.?.?|`/(.?>.?.?.?|<`_))| `/\`_.?(.<.?>?.?)?

Jalankan dengan ndan obendera, yaitu

py -3 slip.py regex.txt input.txt no

Atau, cobalah secara online .


Slip adalah bahasa mirip regex yang dibuat sebagai bagian dari tantangan pencocokan pola 2D . Slip dapat mendeteksi lokasi cacat dengan pbendera posisi melalui program berikut:

^6? `_[/\]|( `/|^6 `\)\`_

yang mencari salah satu pola berikut (di sini Smenunjukkan di sini pertandingan dimulai):

S_/    S_\    /_S    \_S    S/      _
                              _      \S

Coba online - koordinat dihasilkan sebagai pasangan (x, y). Semuanya berbunyi seperti regex normal, kecuali bahwa:

  • ` digunakan untuk melarikan diri,
  • <> putar pointer pertandingan ke kiri / kanan masing-masing,
  • ^6 mengatur pointer pertandingan menghadap ke kiri, dan
  • \ menyelipkan pointer pertandingan secara ortogonal ke kanan (mis. jika pointer mengarah ke kanan maka turun satu baris)

Namun sayangnya, apa yang kita butuhkan adalah satu nomor 0-12 pepatah yang cacat terdeteksi, tidak di mana itu terdeteksi. Slip hanya memiliki satu metode untuk menghasilkan angka tunggal - nbendera yang menampilkan jumlah kecocokan yang ditemukan.

Jadi untuk melakukan ini, kami perluas regex di atas agar sesuai dengan jumlah kali yang tepat untuk setiap cacat, dengan bantuan omode pertandingan yang tumpang tindih. Rusak, komponennya adalah:

1 11:    `_`\.?<.?>?.?.?
2 10:    `/\`_.?(.<.?>?.?)?
4 9:     `_`/(.?>.?.?.?|<`_)
3 12:   ^6 `_`/.?.?>.?.?.?
5 7:    ^6 `\\`_.?<?.?[ _]?
6 8:    ^6 `_`\.?(<.?|>).?

Ya, itu penggunaan yang berlebihan ?untuk mendapatkan angka yang benar: P


Haha, luar biasa. Saya perlu menambahkan lebih banyak jenis output ke bahasa saya.
BMac

4

JavaScript (ES6), 67 72

Cukup cari tempat kosong di 12 lokasi yang diberikan

Edit Disimpan 5 byte, thx @apsillers

F=b=>[..."0h9fnopia8evx"].map((v,i)=>b[parseInt(v,34)]>' '?0:d=i)|d

Uji di Firefox / konsol FireBug

x='  ___\n /\\_/\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/' // no defects
;[...x].forEach((c,p,a)=>{
  a[p]=' ' // put a blank
  y=a.join('') // rebuild a string
  d=F(y) // check
  if (d) console.log('\n'+y+'\n'+d) // if defect, output
  a[p]=c // remove the blamk
})

Keluaran

  ___
 / _/\
/_/ \_\
\ \_/ /
 \/_\/
9

  ___
 /\ /\
/_/ \_\
\ \_/ /
 \/_\/
2

  ___
 /\_ \
/_/ \_\
\ \_/ /
 \/_\/
8

  ___
 /\_/\
/ / \_\
\ \_/ /
 \/_\/
10

  ___
 /\_/\
/_  \_\
\ \_/ /
 \/_\/
3

  ___
 /\_/\
/_/  _\
\ \_/ /
 \/_\/
1

  ___
 /\_/\
/_/ \ \
\ \_/ /
 \/_\/
7

  ___
 /\_/\
/_/ \_\
\  _/ /
 \/_\/
4

  ___
 /\_/\
/_/ \_\
\ \ / /
 \/_\/
5

  ___
 /\_/\
/_/ \_\
\ \_  /
 \/_\/
6

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \ _\/
11

  ___
 /\_/\
/_/ \_\
\ \_/ /
 \/_ /
12

@apsillers bagus dan bahkan lebih baik, terima kasih. Karena string input selalu dimulai dengan '', 0 yang memimpin memaksa inisialisasi d ke i pada loop pertama, sehingga 'd = 0' dapat dihapus.
edc65

2

C, 98 84 byte

g(char*b){char*c="/'-5670(&,=?",*a=c;for(;*c&&!(*b=b[*c++-30]-32?0:c-a););return*b;}

PEMBARUAN: Sedikit lebih pintar tentang string, dan memperbaiki masalah dengan rubi yang tidak cacat.

Terurai:

g(char*b){
    char*c="/'-5670(&,=?",*a=c;
    for(;*c&&!(*b=b[*c++-30]-32?0:c-a);)
        ;
    return*b;
}

Cukup mudah, dan hanya di bawah 100 byte.

Untuk pengujian:

#include "stdio.h"
int main() {
    char b[100];
    scanf("%35c", b);
    printf("%d\n", g(b));
    return 0;
}

Masukan ke STDIN.

Bagaimana itu bekerja

Setiap cacat di ruby ​​terletak pada karakter yang berbeda. Daftar ini menunjukkan di mana setiap cacat terjadi di string input:

Defect 1: 17
Defect 2: 9
Defect 3: 15
Defect 4: 23
Defect 5: 24
Defect 6: 25
Defect 7: 18
Defect 8: 10
Defect 9: 8
Defect 10: 14
Defect 11: 31
Defect 12: 33

Karena membuat array {17,9,15,23,24,25,18,10,8,14,31,33}biaya banyak byte, kami menemukan cara yang lebih pendek untuk membuat daftar ini. Perhatikan bahwa menambahkan 30 ke setiap nomor menghasilkan daftar bilangan bulat yang dapat direpresentasikan sebagai karakter ASCII yang dapat dicetak. Daftar ini adalah sebagai berikut: "/'-5670(&,=?". Jadi, kita dapat mengatur array karakter (dalam kode, c) ke string ini, dan cukup kurangi 30 dari setiap nilai yang kita ambil dari daftar ini untuk mendapatkan array integer asli kita. Kami mendefinisikan asama dengan cuntuk melacak sejauh mana daftar yang kami dapatkan. Satu-satunya yang tersisa dalam kode adalah forloop. Itu memeriksa untuk memastikan kami belum mencapai akhir ke nomor cacat dan mengembalikannya.c , dan kemudian memeriksa apakah karakter bpada saat ini cadalah spasi (ASCII 32). Jika ya, kita setel elemen pertama darib


2

Python 2, 146 88 86 71 byte

Fungsi fmenguji setiap lokasi segmen dan mengembalikan indeks segmen cacat. Pengujian pada byte pertama dalam string input memastikan bahwa kami kembali 0jika tidak ada cacat yang ditemukan.

Kami sekarang mengemas offset segmen menjadi string yang ringkas dan digunakan ord()untuk memulihkannya:

f=lambda s:sum(n*(s[ord('ARJPXYZSKIO`b'[n])-65]<'!')for n in range(13))

Pengujian dengan ruby ​​sempurna:

f('  ___\n /\\_/\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/')
0

Pengujian dengan segmen 2 diganti dengan spasi:

f('  ___\n /\\ /\\\n/_/ \\_\\\n\\ \\_/ /\n \\/_\\/')
2

Sunting: Terima kasih kepada @xnor untuk sum(n*bool for n in...)teknik yang bagus .

EDIT2: Terima kasih kepada @ Sp3000 untuk tips golf tambahan.


2
Saya pikir Anda dapat menyimpan karakter dengan menggunakan indikator-jumlah sum(n*(s[...]==' ')for ...).
xnor

1
Menimbang bahwa karakter yang diganti adalah semua ruang setelah, Anda mungkin dapat melakukan sesuatu seperti <'!'bukan ==' 'untuk byte Anda juga dapat membuat daftar dengan map(ord, ...), tetapi saya tidak yakin bagaimana perasaan Anda tentang yang tidak
diinginkan

1

Pyth, 35 31 28 byte

hx"*6#,54@"C%imCds.zT67

Membutuhkan Pyth yang ditambal , versi terbaru dari Pyth memiliki bug .zyang menghilangkan karakter yang tertinggal.

Versi ini tidak menggunakan fungsi hash, ia menyalahgunakan fungsi konversi basis di Pyth untuk menghitung hash yang sangat bodoh, tetapi bekerja. Kemudian kita mengonversi hash itu menjadi karakter dan mencari indeksnya dalam sebuah string.

Jawabannya berisi karakter yang tidak diinginkan, gunakan kode Python3 ini untuk menghasilkan program secara akurat di mesin Anda:

garbage = [42, 22, 54, 35, 44, 28, 31, 53, 52, 64, 16, 11]
prg = 'hx"' + "".join(chr(c) for c in garbage) +'"C%imCds.zT67'
open("golf_gen.pyth", "w").write(prg)
print(len(prg))

1

Haskell, 73 byte

f l=last[x|x<-[0..12],l!!([0,17,9,15,23,24,25,18,10,8,14,31,33]!!x)==' ']

Strategi yang sama dengan banyak solusi lain: mencari ruang di lokasi yang diberikan. Pencarian mengembalikan daftar indeks dari mana saya mengambil elemen terakhir, karena selalu ada hit untuk indeks 0.


0

05AB1E , 16 byte

•W)Ì3ô;4(•₆вèðk>

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

W3ô;4(•        # Push compressed integer 2272064612422082397
          ₆в      # Converted to Base-36 as list: [17,9,15,23,24,25,18,10,8,14,31,33]
            è     # Index each into the (implicit) input-string
             ðk   # Get the 0-based index of the first space in the indexed characters
                  # (-1 if not found, which means the ruby had no defects)
               >  # And increase it by 1 (which is output implicitly as result)

Lihat tip tambang 05AB1E ini (bagian Bagaimana cara mengompresi bilangan bulat besar? Dan Cara mengompresi daftar bilangan bulat? ) Untuk memahami mengapa •W)Ì3ô;4(•ini 2272064612422082397dan •W)Ì3ô;4(•₆вsekarang [17,9,15,23,24,25,18,10,8,14,31,33].

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.