Miska wypełniona wodą

19

Powinieneś napisać program lub funkcję, która odbiera objętość misy i objętość wody w niej jako dane wejściowe i wyjściowe lub zwraca reprezentację ASCII misy z wodą w niej o pożądanych objętościach.

Miska ma następującą strukturę:

 \     /
  \___/

Miska ma co najmniej jedną _postać. Liczba \'i /' są również dodatnie i są równe ze względu na symetrię.

Objętość misy jest łączna liczba _i spaceznaków między \„s i /” s plus jeden dla każdej pary \i /. Oznacza to, że powyższa misa ma objętość 10:

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

Pamiętaj, że dwie różne miski mogą mieć tę samą objętość. Np. Obie następujące miski mają objętość 18:

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

Możemy wlać trochę wody do miski. Woda jest reprezentowana jako rząd ~znaków zamiast spacji w misce. W dolnym rzędzie nie ma spacji, więc nie może zawierać ~znaków. Oznacza to, że nasz przykład można napełnić wodą tylko w jeden sposób:

 \~~~~~/
  \___/

Inne miski można napełniać na wiele sposobów:

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

Objętość wody w misce jest ilość rzędów miski poniżej tych ~znaków. Powyższe przykłady mają 4, 6 and 2odpowiednio objętości wody .

Wejście

  • Dwie dodatnie liczby całkowite, objętość miski i objętość wody.
  • Możesz wybrać kolejność dwóch liczb.
  • Dwie liczby całkowite można wprowadzić w dowolnym typowym formacie listy (lista, krotka, tablica itp.) Lub jako dwie oddzielne liczby całkowite.
  • Dla wartości wejściowych gwarantowana jest co najmniej jedna poprawna konfiguracja woda w misce.

Wynik

  • Reprezentacja ASCII misy z wodą, gdzie objętość misy i wody są zgodne z danymi wejściowymi.
  • Jeśli zdecydujesz się zwrócić wynik zamiast drukowania, powinien on zostać zwrócony jako pojedynczy ciąg (lub najbliższa alternatywa dla twojego języka).
  • Dowolne końcowe białe znaki są dozwolone.
  • Niedozwolone jest wprowadzanie niepotrzebnych początkowych białych znaków.
  • Jeśli istnieje wiele poprawnych konfiguracji, możesz wybrać, którą z nich wyprowadzasz, ale możesz wyprowadzić tylko jedną z nich.

Przykłady

Po każdej parze liczb całkowitych wejściowych następuje jedno lub więcej możliwych wyjść.

6 2
\~~~/
 \_/

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

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

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

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

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

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

To jest golf golfowy, więc wygrywa najkrótszy wpis.

randomra
źródło

Odpowiedzi:

6

CJam, 72 70 69 bajtów

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

Wypróbuj online w interpretatorze CJam .

Czas działania i użycie pamięci to O (przerażające) , więc ostatnie trzy przypadki testowe należy zweryfikować za pomocą interpretera Java (i dodatkowej przestrzeni sterty).

Przykładowy przebieg

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

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

Jak to działa

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
źródło
2

C, 231 229 bajtów

Wczesne przesłanie :) Jest tu o wiele więcej golfa.

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

Nie golfowany:

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
źródło
Czy można napotkać miskę, która pasuje do objętości miski, ale nie może osiągnąć objętości wody?
Vartan
At least one valid bowl-water configuration is guaranteed for the input values.- OP
Cole Cameron
2

JavaScript ES5, 364 bajty

To jest coś, co mogę szybko wymyślić podczas lunchu, pomóż mi zagrać w golfa do końca mojej zmiany!

Źródło

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

Gra w golfa:

(przebiegał przez kompresor, aby skompresować, przerwa na lunch dobiegła końca)

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
źródło
2

Perl, 227 172 bajtów

Uruchom z opcją -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}}}}

Dzięki Dennisowi za pomoc w grze w golfa.

Oblicza objętość misy jako wysokość * (szerokość + wysokość), gdzie szerokość to liczba _znaków, a wysokość to liczba \znaków.

Każda kombinacja wysokości i szerokości jest testowana w parze zagnieżdżonych pętli, aż do znalezienia właściwej objętości miski, a następnie wykonywana jest kolejna pętla nad możliwymi poziomami wysokości wody, aby sprawdzić, czy przy tej szerokości możliwa jest prawidłowa objętość wody.

Trzecią pętlę można usunąć, po prostu obliczając poziom wody za pomocą wzoru kwadratowego o wartości 1, b jako szerokości ic jako ujemnej pożądanej objętości wody i sprawdzając, czy jest to liczba całkowita, ale to zajmuje więcej bajtów niż tylko wykonywanie pętli. Oto i tak (183 bajtów):

/ /;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
źródło
2

Python 2, 162 bajty

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

Trochę bałagan, ale oto moja pierwsza próba. Sprawdza wszystkie możliwe liczby wierszy r, ustawiając liczbę bazowych znaków podkreślenia a = V/r-r. Następnie ksprawdza wszystkie możliwe wysokości poziomu wody i sprawdza, czy miska jest ważna, a jeśli tak, to drukuje.

Sp3000
źródło
1

Python 2.7, 284 270 260 bajtów

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

To w zasadzie oblicza wysokość i szerokość wiadra i wody i drukuje je.

Próbowałem ciężko usunąć brzydką część pętli while na początku (w której obliczam wysokość wiadra i wysokość, z której należy narysować wodę. W tej chwili wszystkie linie w kodzie, z wyjątkiem ostatniego, służą do obliczania szerokości i wysokość). Wciąż próbuję: P

Testowanie w różnych przypadkach -

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

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

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

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

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

(102, 42)
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/
Kamehameha
źródło