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.