Hitung hamantaschen ASCII!

18

Hari ini adalah Purim di mana satu kebiasaan adalah untuk memberikan kue berbentuk segitiga dengan isian yang disebut hamantaschen (tunggal: hamantasch ). Kebiasaan lain adalah minum banyak.

Saya bukan tukang roti yang paling sempurna .... Saya memiliki begitu banyak hamantaschen berukuran tidak teratur untuk diberikan dan begitu banyak teman untuk diberikan kepada mereka! Jika saya mengirimi Anda gambar cookie saya, dapatkah Anda memberi tahu saya berapa banyak ukuran dan isinya? Tetapi karena Purim dan saya terlalu mabuk untuk membaca banyak kode, perlu kode sekecil yang Anda bisa.

Definisi

Ukuran

Hamantasch bisa berukuran berapa saja . Hamantasch terkecil adalah ukuran 1 dan terlihat seperti ini:

/\  --
--  \/

Terkadang, beberapa hamantaschen bisa tumpang tindih . Bentuk di bawah ini dihitung sebagai dua hamantaschen (satu ukuran 1, satu ukuran 2):

 /\
/\ \
----

Beberapa hamantaschen telah diisi . Ini akan ditunjukkan dengan mengisi semua spasi putih di dalam dengan karakter. Perhatikan bahwa hamantaschen ukuran 1 tidak dapat diisi.

Kami akan memberi nama hamantaschen berdasarkan pengisian dan ukuran. Mari kita gunakan format <filling> <size>dan jika tidak terisi, - <size>(Anda bisa menggunakan spasi alih-alih -, tetapi penurunan harga tidak seperti itu).

Inilah a . 2, a . 4, dan a - 3:

          /\
         /./\
 ----   /./  \
 \../  /./    \
  \/   --------

Ini adalah @ 3, a . 2dan a - 4:

          /\
         / /\
  /\    / /@@\
 /..\  / /@@@@\
 ----  --------

Ini sesuatu yang lebih sulit. Lihat bagaimana & 2pengisian kurang dari yang Anda harapkan karena miring dari tumpang tindih - 3? Memiliki - 1, sebuah & 2sebuah - 3dan & 4:

--------
\   \/&/
 \  /\/
  \/&/
   \/

Memasukkan

Anda akan diberikan file teks atau string tunggal hamantaschen (opsional trailing newline dan opsional spasi tambahan spasi kosong untuk menjadi rata).

Batas

  • Anda dapat mengharapkan string valid - yaitu, setiap karakter non-spasi putih berkontribusi pada hamantasch yang manis dan manis (mengapa membuang-buang adonan?).
  • Anda juga dapat berharap itu diisi dengan benar atau tidak - yaitu, setiap hamantasch itu akan sepenuhnya diisi dengan karakter ASCII yang konsisten - ASCII 32 untuk tidak terisi, atau apa pun 32..127 untuk diisi (tidak termasuk /, \dan -).
  • Hamantaschen ini tidak ditumpuk dalam 3 ruang. Semua /dan \akan terlihat. Semua -yang tidak diblokir oleh /dan \akan terlihat. Pengisian terakhir datang.
  • Semua hamantaschen akan memiliki setidaknya setengah dari garis horizontal mereka (pembulatan ke atas) terlihat.
  • Blok pengisian yang berdekatan hanya mengisi hamantasch terkecil yang mengelilinginya.

Keluaran

Kembalikan daftar "nama" semua hamantaschen yang dapat ditemukan memenuhi kriteria di atas. Outputnya bisa dalam bentuk apa pun yang Anda suka (string, hash, stdout, dll).

Uji kasus

Uji kasus # 1

Input # 1:

          /\
         / /\
  /\    / /@@\
 /..\  / /@@@@\
 ----  --------
    /\
   /**\
  /*/\*\
 /*/..\*\
 --------

Output # 1:

. 2
. 2
- 4
@ 3
* 4

Test Case # 2

Input # 2:

  /\----
 /\/\*\/
/ /\d\/
------

Output # 2:

- 3
- 2
d 2
- 1    
* 2
- 1

Tes # 3

Input # 3:

----
\/\/
/\/\  /\
---- /::\
     ----

Output # 3:

- 1
- 1
- 2
- 1
- 1
- 2
: 2

Tes # 4

Input # 4:

 /\/\
/ /\$\
-/--/\\
 --/--\
  /xxx/\
 /xxx/##\
 ---/----\
   /      \
   -------- 

Keluaran # 4:

$ 2
x 4
- 3
- 2
- 4
- 1
- 1
# 2

Kasus Uji Tidak Valid # 5

Memasukkan:

/\
\/

Keluaran:

Anda tidak perlu menangani ini.

Bukan itu Charles
sumber
Bagaimana dengan test case di mana hamentaschen tumpang tindih tetapi tidak memiliki garis horizontal yang sama? Seseorang bahkan dapat memblokir garis horizontal orang lain.
haskeller bangga
@proudhaskeller Oke, sudah selesai. Namun, dan saya hanya memasukkan ini ke dalam teks, ini adalah 2 ruang. Kami akan selalu melihat semua /dan \ , dan -akan selalu mengisi truf.
Bukan karena Charles
2
@EasterlyIrk Ada juga potongan-potongan penting lainnya - membaca Book of Esther (dan mengejek orang-orang jahat), memberi kepada orang miskin - dan hal-hal yang kurang mendasar seperti berpakaian dalam kostum.
Bukan berarti Charles
1
dibuat relevan lagi!
downrep_nation
1
Berdasarkan pada kolom awal nol, semua kolom titik Anda, kecuali (1,0), mati oleh +1. Tetap saja, saya tahu apa yang Anda maksud, dan saya tidak setuju. Indikasi apa yang ada (2, 2)di tengah atas - 2dan bukan hanya kanan atas dan kiri atas - 1? Tidak ada yang bisa saya lihat. Dan logika yang sama berlaku untuk (3, 2). Kecuali Anda ingin menambahkan aturan untuk mengasumsikan maksimum hamantaschen ...
Michael Plotke

Jawaban:

4

C #, 496 452 byte

Sunting: menemukan bug dengan batas memeriksa ... tetapi juga menggarisbawahi byte yang dipaksa untuk memahami kode saya sendiri. Membuka gulungan fungsi lokal sedikit membantu, dan menghapus kode khusus C # 7. Pertanyaan ini sangat menyenangkan.

using C=System.Console;class P{static void Main(){string D="",L;int W=0,H=0,z=0,d,q,c,j,b;for(;(L=C.ReadLine())!=null;H+=W=L.Length)D+=L;var B=new int[H];for(d=W;(d=-d)>0||++z<H*H;)for(c=1,q=z%H;c<=z/H&q%W+c<W&q>=d&q<H+d&&D[q]==(d>0?92:47)&D[j=q+c]==(d<0?92:47);q-=d+1,c+=2){for(b=0;j>q;)b+=D[--j-d]==45?2:0;for(char h='-',e;c==z/H&b>c;C.WriteLine(h+" "+c/2))for(b=c++;b>1;j=q+=d+1,b-=2)for(;j<q+b;)B[j]=h=B[j]<1&h==45&(e=D[j++])!=47&e!=92&e>32?e:h;}}}

Cobalah secara Online

Program lengkap, mengharapkan input ruang-empuk ke standar masuk, keluaran standar keluar. Outputnya adalah satu entri per baris, dengan trailing line feed. Cookie dikeluarkan dalam urutan ukuran yang meningkat, paling kiri atas terlebih dahulu. Butuh waktu cukup lama bagi saya untuk memahami aturan, tetapi saya pikir itu melewati semua contoh yang diberikan.

Ini bekerja dengan berulang kali mencari seluruh kotak untuk Hamantaschen yang valid, menambah ukuran 'diizinkan'. Untuk setiap sel, ia memeriksa ke atas dan ke bawah, mengikuti \dan /di kedua sisi sejauh mungkin. Jika pemberitahuan bahwa baris berikutnya memiliki banyak -, dan ukuran saat ini adalah ukuran 'diizinkan', maka itu menentukan pengisian dan mencetak entri.

Isi ditemukan dengan menjelajahi seluruh ruang cookie, mencari sel 'tidak terpakai'. Ketika sel yang tidak digunakan ditemukan, itu ditandai sebagai digunakan (karena kami meningkatkan ukuran yang diizinkan, kami tahu kami adalah cookie terkecil yang mengandungnya), dan kami mencatat isinya.

Kode yang diformat dan dikomentari:

using C=System.Console;

class P
{
    static void Main()
    {
        //   32
        // - 45
        // / 47
        // \ 92
        // range 32..127 (no mod for you)

        string D="", // the whole map
            L; // initally each line of the map, later each line of output

        int W=0, // width
            H=0, // length (width * height)
            z=0, // search tracker
            d, // check direction (this is backwards (1 byte saving!))
            q, // check tracker
            c, // counter (truely, this is the distance from the right to the left)
            //M, // c max (now inlined as z/H)
            j, // horiontal tracker
            b; // - count, and reverse counter

        // read map and width
        for(;(L=C.ReadLine())!=null; // read a line, while we can
                H+=W=L.Length) // record the width, and increment height
            D+=L; // add the line to the map

        var B=new int[H]; // whether this filling has been used already (0 -> false, >0 -> true)

        for(d=W; // init direction
            (d=-d)>0|| // swap direction, else increment z (this allows us to run the check for the same z twice with opposite direction)
            ++z<H*H; // for all M, for all q (z<H -> M=z/H=0 -> no valid cookies, so we can safetly skip them)
            )
            for(//M=z/H, // c allow (now inlined)
                c=1, // reset counter
                q=z%H; // note position
                c<=z/H& // counter check
                // no need for a left check: if we run off the left end, then the right check will necessarily fail
                q%W+c<W& // right check
                q>=d& // high check
                q<H+d&& // low check (short-circuit lookups)
                D[q]==(d>0?92:47)&D[j=q+c]==(d<0?92:47); // /\ or \/ check, and set j=q+c
                    q-=d+1, // move left tracker
                    c+=2) // increase counter (move right tracker)
            {
                // count the number of '-' into b
                for(b=0; // zero b
                    j>q; // for each element in the row below
                        ) // empty
                    b+=D[--j-d]==45?2:0; // add 2 to b if we tap a '-'

                // j = q

                // check valid before looking up cHaracter (so we don't mark unused stuff as taken)
                // if we are at the current max count, and we have enough -, then we are valid and should be commited
                for( // this runs either one or zero times, we only have a for here (rather than an if) so we can ditch a pair of braces
                    char h='-', // default filling
                         e; // filling we are considering
                    c==z/H&b>c;
                        C.WriteLine(h+" "+c/2)) // print filling and count
                    // continuously compute character
                    for(b=c++; // count b backwards, starting from c (add 1 to c so we can /2 in print)
                        b>1;j=q+=d+1,b-=2) // count q backwards toward z%H (where q came from), and b backwards toward 1 (for each row)
                        for(;j<q+b;) // for each cell in row
                            B[j]= // mark cell as taken (h,e > 0)
                            h= // record filling
                                B[j]<1& // check cell not already used
                                h==45& // '-'
                                (e=D[j++])!=47& // '/'
                                e!=92& // '\'
                                e>32 // ' '
                                ?e:h; // take first filling we can
                    // c runs out after this (exists both loops), so no need to action
            }
    }
}

Output untuk 4 kasus uji:

testcase #1
. 2
. 2
@ 3
- 4
* 4

testcase #2
- 1
- 1
- 2
d 2
* 2
- 3

testcase #3
- 1
- 1
- 1
- 1
- 2
- 2
: 2

testcase #4
- 1
- 1
- 2
$ 2
# 2
- 3
x 4
- 4
VisualMelon
sumber
Saya kagum melihat betapa ringkasnya ini di C #! Sudah selesai dilakukan dengan baik!
Bukan berarti Charles
Satu-satunya jawaban yang valid! Saya memiliki sesuatu yang hampir berfungsi, tetapi memiliki beberapa kesalahan (tapi saya tetap tidak akan menetapkan diri sebagai pemenang)
Bukan karena Charles