Conta l'AMCII hamantaschen!


18

Oggi è Purim su cui un'usanza è quella di distribuire biscotti a forma di triangolo con ripieno chiamato hamantaschen (singolare: hamantasch ). Un'altra usanza è quella di bere molto.

Non sono il fornaio più perfetto .... Ho così tanti hamantaschen di dimensioni irregolari da dare e così tanti amici a cui dare! Se ti ho inviato una foto dei miei biscotti, puoi dirmi quanti ne ho di quali dimensioni e riempimento? Ma poiché è Purim e sono troppo ubriaco per leggere molto codice, deve essere il più piccolo possibile.

definizioni

Taglia

Un hamantasch può essere di qualsiasi dimensione . Il più piccolo hamantasch è di taglia 1 e assomiglia a questi:

/\  --
--  \/

A volte, più hamantaschen possono sovrapporsi . La forma in basso conta come due hamantaschen (una taglia 1, una taglia 2):

 /\
/\ \
----

Alcuni hamantaschen hanno ripieno . Questo sarà indicato riempiendo tutti gli spazi bianchi all'interno con un carattere. Si noti che hamantaschen taglia 1 non può essere riempito.

Saremo nome hamantaschen sulla base di riempimento e dimensione. Usiamo il formato <filling> <size>e, se non compilato, - <size>(puoi usare uno spazio invece di un -, ma il markdown non piace quello).

Ecco a . 2, a . 4e a - 3:

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

Questi sono a @ 3, a . 2e a - 4:

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

Ecco qualcosa di più difficile. Vedi come & 2ha meno riempimento di quanto ti aspetti a causa dell'inclinazione della sovrapposizione - 3? Ha a - 1, a & 2a - 3e a & 4:

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

Ingresso

Ti verrà dato un file di testo o una singola stringa di hamantaschen (spazio di trascinamento facoltativo e spazio di trascinamento eventualmente imbottito per essere pari).

limiti

  • Puoi aspettarti che la stringa sia valida , vale a dire che ogni carattere non bianco contribuisce a creare un hamantasch deliziosamente dolce (perché sprecare l'impasto?).
  • Puoi anche aspettarti che sia riempito correttamente o meno - cioè, ogni hamantasch sarà interamente riempito con un carattere ASCII coerente - ASCII 32 per non riempito, o qualsiasi cosa 32..127 per riempito (esclusi /, \e -).
  • Questi hamantaschen non sono impilati in 3 spazi. Tutto /e \sarà visibile. Tutto -ciò che non è bloccato da /e \sarà visibile. Il riempimento arriva per ultimo.
  • Tutti gli hamantaschen avranno almeno la metà della loro linea orizzontale (arrotondamento per eccesso) visibile.
  • Qualsiasi blocco contiguo di riempimento riempie solo il più piccolo hamantasch che lo circonda.

Produzione

Restituisce un elenco di "nomi" di tutti gli hamantaschen che possono essere trovati rispettando i criteri di cui sopra. L'output può essere in qualsiasi forma tu voglia (una stringa, un hash, uno stdout, ecc.).

Casi test

Caso di test n. 1

Ingresso n. 1:

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

Uscita n. 1:

. 2
. 2
- 4
@ 3
* 4

Caso di prova n. 2

Ingresso n. 2:

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

Uscita n. 2:

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

Test n. 3

Ingresso n. 3:

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

Uscita n. 3:

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

Test n. 4

Ingresso n. 4:

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

Uscita n. 4:

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

Caso di test n. 5 non valido

Ingresso:

/\
\/

Produzione:

Non è necessario gestirlo.


Che ne dite di un caso di prova in cui hamentaschen si sovrappongono ma non hanno la stessa linea orizzontale? Uno può persino bloccare la linea orizzontale di un altro.
orgoglioso haskeller il

@proudhaskeller Ok, fatto. Tuttavia, e ho appena inserito questo nel testo, questo è 2-spazio. Vedremo sempre tutto /e \ , e -vinceremo sempre il riempimento.
Non che Charles

2
@EasterlyIrk Ci sono anche altre parti importanti: leggere il Libro di Ester (e fischiare i cattivi), dare ai poveri - e cose meno fondamentali come vestirsi in costume.
Non che Charles

1
reso rilevante di nuovo!
downrep_nation

1
Sulla base di una colonna iniziale pari a zero, tutte le colonne del vertice, tranne (1,0), sono disattivate da +1. Tuttavia, so cosa intendi e non sono d'accordo. Quale indicazione c'è che (2, 2)è il centro in alto di a - 2e non solo in alto a destra e a sinistra delle due - 1s in alto ? Nessuno che io possa vedere. E la stessa logica si applica a (3, 2). A meno che tu non voglia aggiungere una regola per assumere il massimo possibile hamantaschen ...
Michael Plotke,

Risposte:


4

C #, 496 452 byte

Modifica: trovato un bug con controllo dei limiti ... ma anche rimosso un sacco di byte costretti a capire il mio codice. Srotolare la funzione locale ha aiutato un po 'e rimosso il codice specifico C # 7. Questa domanda è stata molto divertente.

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

Provalo online

Programma completo, prevede input con riempimento di spazio su ingresso standard, uscite su uscita standard. L'output è una voce per riga, con avanzamento riga finale. I cookie vengono emessi in ordine crescente, prima in alto a sinistra. Mi ci è voluto molto tempo per capire le regole, ma penso che passi tutti gli esempi forniti.

Funziona cercando ripetutamente l'intera griglia per Hamantaschen valido, aumentando la dimensione "consentita". Per ogni cella, controlla su e giù, seguendo \e /su entrambi i lati il ​​più lontano possibile. Se nota che la riga successiva ne contiene molte -e la dimensione corrente è la dimensione "consentita", determina il riempimento e stampa la voce.

Il riempimento si trova esplorando l'intero spazio del cookie, cercando una cella "non utilizzata". Quando viene trovata una cella inutilizzata, viene contrassegnata come utilizzata (poiché aumentiamo le dimensioni consentite, sappiamo di essere il cookie più piccolo che la contiene) e registriamo il riempimento.

Codice formattato e commentato:

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

Uscite per i 4 casi di test:

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

Sono stupito di quanto sia compatto in C #! Molto bene!
Non che Charles

L'unica risposta valida! Ho qualcosa che è quasi funzionale, ma presenta alcuni errori (ma non mi definirei comunque vincitore)
Non che Charles
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.