Acquedotto ASCII


19

Intro

Considera una griglia di personaggi f A\/come

f  f  f  
      A  
   A / \ 
\ /     A
    A \/ 
   /     
 \/         

dove:

  • f rappresenta un rubinetto che versa un flusso di acqua verso il basso
  • A biforcò il flusso d'acqua sopra così esattamente la metà va a sinistra e esattamente la metà va a destra
  • \ sposta il flusso di acqua in alto a destra di un'unità
  • / sposta il flusso di acqua in alto a sinistra di un'unità
  • le combinazioni \/creano un trogolo con capacità infinita che raccoglie i corsi d'acqua sopra di esso
  • [space] è uno spazio vuoto che l'acqua può attraversare

Da questo possiamo immaginare il percorso che l'acqua ( *) prenderebbe quando esce dai rubinetti e cade nelle vasche o fuori dall'area della griglia:

f  f  f    <-- first second and third faucets
*  * *A* 
* *A*/ \*
\*/ *  *A  <-- a '*' is not drawn to the right of this A because it would be out of the 9×7 bounds
 * *A*\/   <-- upper trough
 **/ *   
 \/  *     <-- lower trough

Supponendo che i 3 rubinetti emettano la stessa quantità di acqua uno alla volta, possiamo vederlo

  • Tutta l'acqua del primo rubinetto va nella vasca inferiore.
  • La metà dell'acqua del secondo rubinetto va nella vasca inferiore e l'altra metà viene divisa tra la vasca inferiore e cade dalla griglia.
  • Un quarto dell'acqua del terzo rubinetto va nella vasca inferiore, un quarto cade dal fondo della griglia, un quarto va nella vasca superiore e un quarto cade dalla griglia a destra.

Da questo possiamo dire che (1 + 3/4 + 1/4 + 1/4) / 3 = 75%l'acqua viene catturata dai trogoli e (1/4 + 1/4 + 1/4) / 3 = 25%cade dalla griglia.

Le sfide

È possibile completare una o tutte queste sfide relative a questa configurazione del flusso d'acqua ASCII. Sono tutti code-golf, la risposta più breve per ogni sfida è il vincitore. La risposta accettata sarà la persona che completa il maggior numero di sfide, con la lunghezza totale del codice come pareggio.

Sfida 1
Scrivi un programma che genera la frazione di acqua che scorre in canali per una data griglia. L'output dell'esempio sopra sarebbe semplicemente 0.75.

Sfida 2
Scrivi un programma che, data una griglia, disegna *i punti nei punti in cui scorre l'acqua come ho fatto sopra. Non devi sovrascrivere nulla oltre ai caratteri dello spazio e la griglia non dovrebbe cambiare dimensione. Quindi per qualcosa del genere

 f
/A

nulla deve essere fatto poiché, sebbene l'acqua scorra su entrambi i lati della A, non può essere trascinata a sinistra senza rimuovere la / e non può essere disegnata a destra senza allargare la griglia 2 × 2.

Sfida 3 (aggiornato)
Scrivi un programma che accetta due numeri interi non negativi, il totale T e l'importo per mantenere K (T> = K). Genera e disegna una griglia con esattamente unaf tale in modo che quando quel rubinetto fuoriesca T unità di acqua, esattamente K fluirà nelle vasche. Se è impossibile farlo in una griglia finita per una particolare coppia (T, K), quindi produrre "Impossibile".

Chiarimenti (si applicano a tutte le sfide)

  • L'input può essere tramite stdin, o un file, o anche una chiamata di funzione sulla rappresentazione di stringa della griglia. Rendi ovvio come eseguire input diversi.
  • L'output deve andare su stdout.
  • \Aed A/e AAsono depressioni anche come ci si aspetterebbe.
  • Una griglia w by h sarà sempre un rettangolo ben formattato di caratteri w * h senza contare le nuove righe. Non ci saranno spazi finali mancanti e nessuna occorrenza di* .
  • Le dimensioni della griglia possono essere piccole quanto 1 × 1 e arbitrariamente grandi. (Arbitrariamente entro limiti ragionevoli, int.maxValue o simili è un limite accettabile. Lo stesso vale per T e K.)
  • Un flusso sopra un fflusso scorre attraverso di esso.
  • I rubinetti possono essere ovunque, non solo nella riga superiore.
  • A divide sempre la quantità di acqua versata su di essa esattamente a metà.

Nota: cose come /Ae //sono perfettamente valide. L'acqua fa liberamente fluire tra i personaggi (anche se per sfida 2 non c'è spazio sufficiente per disegnarlo).

Quindi, nel setup

ff

/A

Il fflusso sinistro scorre verso il basso, colpisce /e si sposta a sinistra. Il fflusso destro scorre verso il basso, colpisce il A, metà va a destra e metà va a sinistra tra iA e il /.

per esempio

 ff
 **
*/A*
** *
** *

3
+1 Bella sfida. Per quanto riguarda la sfida 3, la griglia in alto non sarebbe una risposta valida perché ha 3 fsecondi
— edc65

@ edc65 Ah, buona cattura!
— Calvin's Hobbies,


2
Per la seconda sfida, è necessario specificare come gestire l'input come /Ase l'acqua cade sul A. Per tutte le sfide, sarebbe bene chiarire se si \Atratta di una depressione. Per la terza sfida, Asi suppone che 3 unità che cadono su si dividano 1.5 / 1.5(quindi l'input è davvero un singolo numero razionale) oppure 2 / 1, in quale caso da quale parte riceve il 2?
— Peter Taylor,

1
@PeterTaylor Grazie. Ho chiarito questi punti. Immagino che T e K possano essere float ma li tengo interi per semplicità. (Ma se T = 3 colpisce un, Aallora entrambe le parti ottengono 1.5. Spetta al programmatore assicurarsi che la precisione del galleggiante non sia un problema.)
— Calvin's Hobbies

Risposte:


3

Tutte le sfide C # 690bytes (416bytes + 274bytes)

Sfide 1 e 2 C # 579 446 416 byte

Questo è un programma completo che dovrebbe affrontare le Sfide 1 e 2, quasi. Legge le righe di input dallo stdin fino a quando non riceve una riga vuota. Stampa il risultato per Challenge 2 e quindi il risultato per Challenge 1. Utilizza la classe decimale .NET per evitare eventuali errori di arrotondamento.

using C=System.Console;class P{static void Main(){decimal u,t=0,f=0;string c,z="";for(decimal[]n=null,o;(c=C.ReadLine())!="";z+='\n'){int s=c.Length,i=s,e;o=n;n=new decimal[s];for(o=o??n;i-->0;n[i]+=(e&2)*u/2){e=c[i]%13;u=o[i]/(e<1?2:1);if(e%8<1)if(i>0)if(c[i-1]%7<3)t+=u;else n[i-1]+=u;if(e<2)if(i<s-1)if(c[i+1]%2>0)t+=u;else n[i+1]+=u;if(e>9){u++;f++;}}for(;++i<s;)z+=c[i]<33&n[i]>0?'*':c[i];}C.WriteLine(z+t/f);}}

Meno golf:

using C=System.Console;
class P
{
    static void Main()
    {
        decimal u,t=0,f=0;
        string c,z="";

        for(decimal[]n=null,o;(c=C.ReadLine())!="";z+='\n')
        {
            int s=c.Length,i=s,e;
            o=n;
            n=new decimal[s];
            for(o=o??n;i-->0;n[i]+=(e&2)*u/2)
            {
                e=c[i]%13;
                u=o[i]/(e<1?2:1);

                if(e%8<1)
                    if(i>0)
                        if(c[i-1]%7<3)t+=u;
                        else n[i-1]+=u;
                if(e<2)
                    if(i<s-1)
                        if(c[i+1]%2>0)t+=u;
                        else n[i+1]+=u;
                if(e>9)
                {
                    u++;
                    f++;
                }
            }
            for(;++i<s;)
                z+=c[i]<33&n[i]>0?'*':c[i];
        }

        C.WriteLine(z+t/f);
    }
}

Esecuzione del test (con una mancanza di spazi finali che prometto ci sono):

f  f  f
      A
   A / \
\ /     A
    A \/
   /
 \/

f  f  f
*  * *A*
* *A*/ \*
\*/ *  *A
 * *A*\/
 **/ *
 \/  *
0.75

Sfida 3 C # 274 byte

Questo è un programma completo che dovrebbe completare la Sfida 3. Sono riuscito a salvare 6 byte scrivendo il mio parser intero per leggere l'input anziché Spliting ReadLinee usando long.Parse;

using C=System.Console;class P{static void Main(){long t=-1,f=t,k;for(;f<0;)for(f=t,t=0;(k=C.Read())>47;)t=t*10+k-48;var r="Impossible\n";for(k=t;k<t*f;)k*=2;if(f<1||(k/f)*f==k)for(r=" f \n";t>0&t<f;t-=(t/f)*f)r+=((t*=2)<f?" ":"A")+"A \n/ /\n";C.Write(r+(t<f?"":"AAA\n"));}}

Meno golf:

using C=System.Console;
class P
{
    static void Main()
    {
        long t=-1,f=t,k;
        for(;f<0;)
            for(f=t,t=0;(k=C.Read())>47;)
                t=t*10+k-48;

        var r="Impossible\n";
        for(k=t;k<t*f;)
            k*=2;
        if(f<1||(k/f)*f==k)
            for(r=" f \n";t>0&t<f;t-=(t/f)*f)
                r+=((t*=2)<f?" ":"A")+"A \n/ /\n";
        C.Write(r+(t<f?"":"AAA\n"));
    }
}

Esecuzione del test (di nuovo con una mancanza di spazi finali che prometto ci sono):

32 17
 f
AA
/ /
 A
/ /
 A
/ /
 A
/ /
AA
/ /

3

Prima di tutto, ho una domanda sulla sfida. Dal momento che non ho abbastanza reputazione per commentare la domanda, la scrivo qui:

  • Qual è il comportamento di /A(acqua che scorre su A), //(acqua che scorre sul lato destro) e variazioni di questo principio? L'acqua fluisce verso il primo "punto libero" sul lato o scorre "sotto" il suo vicino?

Solo un semplice tentativo, può essere waaaaay semplificato (cosa che farò in seguito modificando questo post).

Modificare: seconda versione, un po 'più piccola. Ho optato per un approccio diverso: invece di cercare ogni cella per verificare cosa proviene dall'alto e dai lati, parto dai rubinetti e "scorro" verso il basso con la ricorsione.

Javascript, 226 byte (Sfida 1)

function f(c){function h(b,a,d,e){b<c.length&&0<=a&&a<c[0].length&&("\\"==c[b][a]?"/"==e||"A"==e?g+=d:h(b,a+1,d,"\\"):"/"==c[b][a]?"\\"==e||"A"==e?g+=d:h(b,a-1,d,"/"):"A"==c[b][a]?"A"==e||"\\"==e||"/"==e?g+=d:(h(b,a-1,d/2,"A"),h(b,a+1,d/2,"A")):h(b+1,a,d,c[b][a]))}for(var g=0,m=0,k=0;k<c.length;k++)for(var l=0;l<c[k].length;l++)"f"==c[k][l]&&(h(k+1,l,1),m++);alert(g/m)};

Javascript, 204 byte (Challenge 2)

function f(c){function e(b,a,d){b<c.length&&0<=a&&a<c[0].length&&("\\"==c[b][a]?"/"!=d&&"A"!=d&&e(b,a+1,"\\"):"/"==c[b][a]?"\\"!=d&&"A"!=d&&e(b,a-1,"/"):"A"==c[b][a]?"A"!=d&&"\\"!=d&&"/"!=d&&(e(b,a-1,"A"),e(b,a+1,"A")):(" "==c[b][a]&&(c[b][a]="*"),e(b+1,a,c[b][a])))}for(var g=0;g<c.length;g++)for(var h=0;h<c[g].length;h++)"f"==c[g][h]&&e(g+1,h)};

Javascript, 238 byte (Challenge 1 + 2)

function f(c){function h(b,a,d,e){b<c.length&&0<=a&&a<c[0].length&&("\\"==c[b][a]?"/"==e||"A"==e?g+=d:h(b,a+1,d,"\\"):"/"==c[b][a]?"\\"==e||"A"==e?g+=d:h(b,a-1,d,"/"):"A"==c[b][a]?"A"==e||"\\"==e||"/"==e?g+=d:(h(b,a-1,d/2,"A"),h(b,a+1,d/2,"A")):(" "==c[b][a]&&(c[b][a]="*"),h(b+1,a,d,c[b][a])))}for(var g=0,m=0,k=0;k<c.length;k++)for(var l=0;l<c[k].length;l++)"f"==c[k][l]&&(h(k+1,l,1),m++);alert(g/m)};

Come usare

Fornire una rappresentazione bidimensionale della mappa. Ecco l'esempio fornito nella domanda:

var input = [["f"," "," ","f"," "," ","f"," "," "],[" "," "," "," "," "," ","A"," "," "],[" "," "," ","A"," ","/"," ","\\"," "],["\\"," ","/"," "," "," "," "," ","A"],[" "," "," "," ","A"," ","\\","/"," "],[" "," "," ","/"," "," "," "," "," "],[" ","\\","/"," "," "," "," "," "," "]];
f(input);

Produzione

Sfida 1: creerà semplicemente una finestra di dialogo (avviso) con il risultato (0,75 per l'esempio sopra).

Sfida 2: modificherà direttamente la mappa. Dovrei stamparlo? In tal caso, console.log è accettato? come output valido?

Sfida 1 + 2: entrambi sopra combinati, ovviamente ...


L'acqua continua a scorrere tra i personaggi come se stesse abbracciando le linee delle Ao delle barre. L'ho chiarito nella domanda.
— Calvin's Hobbies,

La domanda affermaOutput must go to stdout.
— user80551

Come formato di input hai specificato che hai una matrice di stringhe di un carattere per riga, ma tieni presente che puoi indicizzare str[0]in stringhe. Sarebbe una matrice di stringhe anziché una matrice di array di caratteri.
— tomsmeding

1
user80551 Grazie, non so perché mi sia sfuggito di mente. Aggiornerò il mio codice il prima possibile. @tomsmeding Sì, funziona per la mia risposta alla sfida 1. Ma per la sfida 2 Sto modificando direttamente l'input e non è possibile modificare un carattere in una stringa usando str [i], quindi l'uso di una matrice di array.
— aggiornamento del

2

Python 3, 186 byte (Challenge 3)

Ho preso l'idea per la griglia dalla risposta di VisualMelon . La funzione dovrebbe stampare una griglia valida su stdout per T e K arbitrariamente grandi, purché sia ​​possibile (griglia di dimensioni finite) ovviamente.

from fractions import*
def c(T,K):
 p=print;g=gcd(T,K);K//=g;T//=g
 if T&(T-1):p('Impossible')
 else:
  p(' f ')
  while T-1:
   T//=2;p('A/'[K<T]+'A \n///')
   if K>=T:K-=T
  p('AAA'*K)

Come usare

Chiamare la cfunzione con l'importo totale e l'importo da mantenere come argomenti.

>>> c(24, 9)
 f 
/A 
///
AA 
///
AA 
///

>>> c(6, 2)
Impossible
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.