Ciotola Piena Di Acqua


19

Dovresti scrivere un programma o una funzione che riceva il volume di una ciotola e il volume dell'acqua in esso come input e output o restituisca una rappresentazione ASCII di una ciotola con acqua con i volumi desiderati.

Una ciotola ha la seguente struttura:

 \     /
  \___/

La ciotola ha almeno un _personaggio. Anche il conteggio di \"se /" è positivo e sono uguali a causa della simmetria.

Il volume della ciotola è il numero totale di _e spacecaratteri tra \'e /' più uno per ogni coppia di \e /. Ciò significa che la ciotola sopra ha il volume di 10:

 \     /  =>  xxxxx x (the last one is for the \/ pair)
  \___/        xxx x (the last one is for the \/ pair)

Si noti che due diverse vasche potrebbero avere lo stesso volume. Ad esempio, entrambe le seguenti ciotole hanno un volume di 18:

\       /
 \     /      \         /
  \___/        \_______/

Possiamo versare un po 'd'acqua nella ciotola. L'acqua è rappresentata da una fila di ~personaggi anziché da spazi all'interno della ciotola. La riga in basso non ha spazi, quindi non può contenere quelli ~. Ciò significa che il nostro esempio può essere riempito d'acqua solo in un modo:

 \~~~~~/
  \___/

Altre ciotole possono essere riempite in più modi:

 \~~~~~/   \     /
  \   /     \~~~/
   \_/       \_/

Il volume dell'acqua in una ciotola è il volume delle file della ciotola sotto i ~caratteri. Gli esempi sopra hanno volumi d'acqua 4, 6 and 2rispettivamente.

Ingresso

  • Due numeri interi positivi, il volume della ciotola e il volume dell'acqua.
  • Puoi scegliere l'ordine dei due numeri.
  • I due numeri interi possono essere immessi in qualsiasi formato di elenco comune (elenco, tupla, matrice, ecc.) O come due numeri interi separati.
  • Per i valori di input è garantita almeno una configurazione valida per l'acqua della vasca.

Produzione

  • La rappresentazione ASCII di una ciotola con acqua in cui la vasca e i volumi d'acqua corrispondono all'ingresso.
  • Se si sceglie di restituire il risultato anziché la stampa, è necessario restituirlo come stringa singola (o l'alternativa più vicina alla propria lingua).
  • È consentito qualsiasi spazio bianco finale.
  • Non è consentito alcun spazio bianco iniziale non necessario.
  • Se ci sono più configurazioni corrette, sei libero di scegliere quale output ma puoi solo generare uno di essi.

Esempi

Ogni coppia di numeri interi di input è seguita da una o più uscite possibili.

6 2
\~~~/
 \_/

10 4
\~~~~~/
 \___/

24 8
\        /
 \~~~~~~/
  \    /
   \__/

42 12 //either of the two output is correct
\           /
 \         /
  \~~~~~~~/
   \     /
    \   /
     \_/

\               /
 \~~~~~~~~~~~~~/
  \___________/

90 68
\~~~~~~~~~~~~~~~~~~~~~/
 \                   /
  \                 /
   \               /
    \_____________/

102 42
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/

Questo è il codice golf, quindi vince l'ingresso più breve.

Risposte:


6

CJam, 72 70 69 byte

q~:QW=3m*{:,2ff*),)ff+}%{::)1fbQ=}=~W%ee_,S*W'_t@,~'~t.{S\+.*"\/".+N}

Provalo online nell'interprete CJam .

Il tempo di esecuzione e l'utilizzo della memoria sono O (spaventosi) , quindi gli ultimi tre casi di test devono essere verificati utilizzando l'interprete Java (e lo spazio di memoria aggiuntivo).

Esempio di esecuzione

$ time java -Xmx4G -jar cjam-0.6.5.jar bowl.cjam <<< '[42 102]'
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/

real    0m40.669s
user    3m13.100s
sys     0m11.690s

Come funziona

q~:Q     e# Read from STIDN, evaluate and save the result in Q.
W=       e# Select the last element of Q (bowl volume B).
3m*      e# Push all vectors of {0,...,B-1} × {0,...,B-1} x {0,...,B-1}.

{        e# For each vector [X Y Z]:
  :,     e#   Push [[0 1 ... X-1] [0 1 ... Y-1] [0 1 ... Z-1]].
  2ff*   e#   Multiply each coordinate by 2.
  ),)    e#   Pop the last vector, compute its length and increment.
  ff+    e#   Add the result to each component of each vector.
}%       e# Result: [[Z Z+2 ... Z+2(X-1)] [Z Z+2 ... Z+2(Y-1)]]

{        e# Find:
  ::)    e#   Increment each coordinate (to account for the volume in "\/").
  1fb    e#   Sum the coordinate of both vectors.
  Q=     e#   Compare the result to Q (desired volumes).
}=       e# If they match, push the array and break.

~        e# Dump both vectors on the stack.
W%       e# Reverse the rightmost one (corresponds to the bowl volume).
ee       e# Enumerate its coordinates.
         e# [Z+2(Y-1) ... Z+2 Z] -> [[0 Z+2(Y-1)] ... [Y-2 Z+2] [Y-1 Z]].
_,S*     e# Compute the length (Y) and push a string of Y spaces.
W'_t     e# Replace the last space with an underscore.
@        e# Rotate the leftmost vector (corresponds to the water volume) on top.
,        e# Compute its length (X).
~'~t     e# Replace the space at index X from the right with a tilde.

.{       e# For each enumerates coordinate and the corresponding character:
  S\+    e#   Append the character to the string " ".
  .*     e#   Vectorized repetition: [1 2] " ~" -> [" " "~~"]
  "\/".+ e#   Append the first (second) solidus to the first (second) string.
  N      e#   Push a linefeed.
}

2

C, 231 229 byte

Presentazione anticipata :) Qui c'è molto altro da giocare a golf.

v,V,w,h,H,i,j;main(c,a)char**a;{V=atoi(a[1]);v=atoi(a[2]);for(;++H;)for(h=0;h++<H;){for(w=1;h*h+w*h-h<v;++w);if(H*H+w*H-H==V){for(;H--;){printf("%*s",++i,"\\");for(j=0;j++<w-1+2*H;)putchar(H?H==h?'~':32:95);puts("/");}exit(0);}}}

Ungolfed:

int v,V,w,h,H,i,j;
int main(int c, char **a)
{
    V=atoi(a[1]); /* Volume of bowl */
    v=atoi(a[2]); /* Volume of water */

    for(;++H;) /* Make the bowl taller */
    {
        for(h=0;h++<H;) /* Make the water taller */
        {
            for(w=1;h*h+w*h-h<v;++w); /* Make the bowl wider until the water volume matches */
            if(H*H+w*H-H==V) /* if the bowl volume matches, then we're good */
            {
                for(;H--;) /* Print out the bowl, one line at a time */
                {
                    printf("%*s",++i,"\\"); /* Print the left edge */
                    /* Print the inside (either with air/water, the top of the water, or the bottom of the bowl */
                    for(j=0;j++<w-1+2*H;)
                        putchar(H?H==h?'~':32:95);
                    /* Print the right edge of the bowl */
                    puts("/");
                }
                exit(0); /* die, we're done */
            }
        }
    }
}

È possibile incontrare una ciotola che corrisponde al volume della ciotola ma non riesce a raggiungere un volume d'acqua?
Vartan,

At least one valid bowl-water configuration is guaranteed for the input values.- OP
Cole Cameron,

2

Javascript ES5, 364 byte

Questo è quello che ho potuto inventare rapidamente durante il mio pranzo, aiutami a golf fuori mentre il mio turno termina!

fonte

function V(x,v) { // calculate volume of bowl/water
    for(i=v,j=x;i--;j+=2) {
      v+=j; 
    }
    return v
}
function B(x,y,l) { // draw bowl/water
    for(s="",h=y,w = x+2*y;y--;s+="\n")
        for(i=w;i--;) {
            f= i>h-y-1 && w-i > h-y;
            s+=i==h-y-1?"/": 
                w-i == h-y? "\\":
                y==l-1 && f? "~" :
                !y && f?"_":" "
        }
    return s;
}
n=prompt().split(" ");
b=+n[0]; // bowl volume
w=+n[1]; // water volume
for(x=b;x;x--)  // loop through possible widths
  for(y=b;y;y--)  // loop through possible heights
    if(V(x,y)==b) // check if we found bowl volume
       for(y2=y;y2;y2--) { // check possible water heights
         v = V(x,y2-1);
         if(v==w){ // see if volume matches
          alert(B(x,y,y2));
          x=1;break;
         }
       }

golfed:

(attraversò il minificatore per comprimere, il turno di pranzo terminò)

function V(f,r){for(i=r,j=f;i--;j+=2)r+=j;return r}function B(r,y,n){for(s="",h=y,w=r+2*y;y--;s+="\n")for(i=w;i--;)f=i>h-y-1&&w-i>h-y,s+=i==h-y-1?"/":w-i==h-y?"\\":y==n-1&&f?"~":!y&&f?"_":" ";return s}for(n=prompt().split(" "),b=+n[0],w=+n[1],x=b;x;x--)for(y=b;y;y--)if(V(x,y)==b)for(y2=y;y2;y2--)if(v=V(x,y2-1),v==w){alert(B(x,y,y2)),x=1;break}

2

Perl, 227 172 byte

Esegui con l'opzione -n:

/ /;for$h(1..$`){for$w(1..$`){for$l(1..($h*($w+$h)==$`)*$h){if($l*($w+$l)==$'){for(0..$h-1){print$"x$_."\\".($_<$h-1?$_==$h-$l-1?"~":$":"_")x($w+($h-$_-1)*2)."/
"}exit}}}}

Grazie a Dennis per l'aiuto nel golf.

Calcola il volume della ciotola come altezza * (larghezza + altezza), dove larghezza è il numero di _caratteri e altezza è il numero di \caratteri.

Ogni combinazione di altezza e larghezza viene testata in una coppia di anelli nidificati fino a quando non viene trovato il volume corretto della vasca, quindi viene eseguito un altro ciclo su possibili livelli di altezza dell'acqua per scoprire se è possibile un volume d'acqua corretto con quella larghezza.

È possibile rimuovere il terzo ciclo semplicemente calcolando il livello dell'acqua usando la formula quadratica con a come 1, b come larghezza ec come negativo del volume d'acqua desiderato e verificando se si tratta di un numero intero, ma che richiede più byte che fare semplicemente un ciclo. Eccolo comunque (183 byte):

/ /;for$h(1..$`){for$w(1..$`){if($h*($w+$h)==$`){$l=(sqrt($w*$w+4*$')-$w)/2;if(int$l==$l){for(0..$h-1){print$"x$_."\\".($_<$h-1?$_==$h-$l-1?"~":$":"_")x($w+($h-$_-1)*2)."/
"}exit}}}}

2

Python 2, 162 byte

V,W=input()
r=1
while r*r<V:a=V/r-r;k=1;exec"if(a+k)*k==W*(V%r<1):i=1;exec\"print' '*~-i+'\%s/'%(' _~'[(i==r)-(i==r-k)]*(a+2*(r-i)));i+=1;\"*r;r=V\nk+=1\n"*r;r+=1

Un po 'disordinato, ma ecco il mio primo tentativo. Prova tutti i possibili numeri di righe r, impostando il numero di caratteri di sottolineatura di base a = V/r-r. Quindi prova tutte le possibili altezze del livello dell'acqua ke verifica se la vasca è valida, stampandola in tal caso.


1

Python 2.7, 284 270 260 byte

def f(b,w,i=1,e='while s<%s:j+=2;s+=j'):
 while 1:
    i+=1;j=s=i;exec e%w
    if s==w:p=j;exec e%b
    if s==b:break
 h=(j-i)/2+1;t=w=i+(h-1)*2+1
 for j in range(h):r,s,t=((' '*(t-2),'_'*(i-1))[j==h-1],'~'*(t-2))[j==h-(p-i)/2-2],(w-t)/2,t-2;print" "*s+"\\"+r+"/"+" "*s

Questo in sostanza calcola l'altezza e la larghezza del secchio e dell'acqua e li stampa.

Ho cercato di rimuovere la parte brutta del ciclo while all'inizio (in cui calcolo l'altezza del secchio e l'altezza da cui dovrebbe essere disegnata l'acqua. In questo momento, tutte le linee nel codice tranne l'ultima sono per il calcolo della larghezza e altezza). Sto ancora provando: P

Test per diversi casi -

>>> execfile("buckets.py")
(6, 2)
\~~~/
 \_/

(10, 4)
\~~~~~/
 \___/

(24, 8)
\        /
 \~~~~~~/
  \    /
   \__/

(42, 12)
\           /
 \         /
  \~~~~~~~/
   \     /
    \   /
     \_/

(90, 68)
\~~~~~~~~~~~~~~~~~~~~~/
 \                   /
  \                 /
   \               /
    \_____________/

(102, 42)
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/
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.