Bol rempli d'eau

19

Vous devez écrire un programme ou une fonction qui reçoit le volume d'un bol et le volume d'eau qu'il contient en entrée et en sortie ou renvoie une représentation ASCII d'un bol contenant de l'eau avec les volumes souhaités.

Un bol a la structure suivante:

 \     /
  \___/

Le bol a au moins un _caractère. Les nombres de \'et /' sont également positifs et ils sont égaux en raison de la symétrie.

Le volume du bol est le nombre total de caractères _et spaceentre les \s et /les plus un pour chaque paire de \et /. Cela signifie que le bol ci-dessus a le volume de 10:

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

Notez que deux bols différents peuvent avoir le même volume. Par exemple, les deux bols suivants ont un volume de 18:

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

Nous pouvons verser un peu d'eau dans le bol. L'eau est représentée comme une rangée de ~caractères au lieu d'espaces à l'intérieur du bol. La rangée du bas n'a pas d'espaces et ne peut donc pas contenir les ~. Cela signifie que notre exemple peut être rempli d'eau d'une seule manière:

 \~~~~~/
  \___/

D'autres bols peuvent être remplis de plusieurs manières:

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

Le volume d'eau dans un bol est le volume des rangées de bol sous les ~caractères. Les exemples ci-dessus ont 4, 6 and 2respectivement des volumes d'eau .

Contribution

  • Deux entiers positifs, le volume du bol et le volume de l'eau.
  • Vous pouvez choisir l'ordre des deux nombres.
  • Les deux entiers peuvent être entrés dans n'importe quel format de liste commun (liste, tuple, tableau, etc.) ou sous forme de deux entiers distincts.
  • Au moins une configuration d'eau de bol valide est garantie pour les valeurs d'entrée.

Production

  • Représentation ASCII d'un bol avec de l'eau où les volumes du bol et de l'eau correspondent à l'entrée.
  • Si vous choisissez de renvoyer le résultat au lieu d'imprimer, il doit être renvoyé sous forme de chaîne unique (ou l'alternative la plus proche de votre langue).
  • Tout espace de fin est autorisé.
  • Aucun espace blanc non nécessaire n'est autorisé.
  • S'il existe plusieurs configurations correctes, vous êtes libre de choisir celle que vous produisez, mais vous ne pouvez en sortir qu'une.

Exemples

Chaque paire d'entiers en entrée est suivie de ses une ou plusieurs sorties possibles.

6 2
\~~~/
 \_/

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

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

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

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

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

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

C'est le golf de code, donc l'entrée la plus courte gagne.

randomra
la source

Réponses:

6

CJam, 72 70 69 octets

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

Essayez-le en ligne dans l' interpréteur CJam .

Le temps d'exécution et l'utilisation de la mémoire sont O (effrayants) , donc les trois derniers cas de test doivent être vérifiés à l'aide de l'interpréteur Java (et de l'espace de tas supplémentaire).

Exemple d'exécution

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

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

Comment ça fonctionne

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.
}
Dennis
la source
2

C, 231 229 octets

Soumission anticipée :) Il y a beaucoup plus de golf à faire ici.

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

Non golfé:

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 */
            }
        }
    }
}
Cole Cameron
la source
Est-il possible de rencontrer un bol qui correspond au volume du bol mais ne peut pas atteindre un volume d'eau?
Vartan
At least one valid bowl-water configuration is guaranteed for the input values.- OP
Cole Cameron
2

Javascript ES5, 364 octets

C'est ce que j'ai pu trouver rapidement pendant mon déjeuner, aidez-moi à jouer au golf pendant la fin de mon quart de travail!

La source

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

Golfé:

(parcouru la minifiante pour compresser, fin de quart de midi)

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}
Vartan
la source
2

Perl, 227 172 octets

Exécuter avec l'option -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}}}}

Merci à Dennis pour son aide à jouer au golf.

Calcule le volume du bol en hauteur * (largeur + hauteur), où largeur est le nombre de _caractères et hauteur est le nombre de \caractères.

Chaque combinaison de hauteur et de largeur est testée dans une paire de boucles imbriquées jusqu'à ce que le volume de bol correct soit trouvé, puis une autre boucle sur les niveaux de hauteur d'eau possibles est effectuée pour déterminer si un volume d'eau correct est possible avec cette largeur.

Il est possible de supprimer la troisième boucle en calculant simplement le niveau d'eau en utilisant la formule quadratique avec a comme 1, b comme largeur et c comme négatif du volume d'eau souhaité, et en vérifiant s'il s'agit d'un entier, mais cela prend plus d'octets que de faire une boucle. Le voici quand même (183 octets):

/ /;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}}}}
samgak
la source
2

Python 2, 162 octets

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 peu désordonné, mais voici ma première tentative. Il essaie tous les nombres de lignes possibles r, définissant le nombre de soulignements de base à être a = V/r-r. Ensuite, il essaie toutes les hauteurs de niveau d'eau possibles ket vérifie si le bol est valide, l'imprimant si c'est le cas.

Sp3000
la source
1

Python 2.7, 284 270 260 octets

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

Cela calcule essentiellement la hauteur et la largeur du seau et de l'eau et les imprime.

J'ai essayé dur de retirer la partie laide tout en boucle au début (dans laquelle je calcule la hauteur du seau et la hauteur d'où l'eau devrait être tirée. À l'heure actuelle, toutes les lignes du code, à l'exception de la dernière, servent à calculer la largeur et la taille). Toujours en train d'essayer: P Le

tester pour différents cas -

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

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

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

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

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

(102, 42)
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/
Kamehameha
la source