Чаша, наповнена водою


19

Ви повинні написати програму або функцію, яка отримує об’єм чаші і об’єм води в ній як вхід і вихід або повертає ASCII подання чаші з водою в ній з потрібними обсягами.

Миска має таку структуру:

 \     /
  \___/

Чаша має принаймні один _символ. Кількість \/' s також позитивні і вони рівні через симетрію.

Об'єм чаші - це загальна кількість _та spaceсимволів між \/" плюс один для кожної пари \та /. Це означає, що зазначена вище чаша має об'єм 10:

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

Зверніть увагу, що дві різні миски можуть мати однаковий об'єм. Наприклад, обидві наступні миски мають об'єм 18:

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

Ми можемо налити трохи води в миску. Вода представлена ​​у вигляді рядів ~символів замість пробілів всередині миски. У нижньому рядку немає пробілів, тому він не може містити ~s. Це означає, що наш приклад можна наповнити водою лише одним способом:

 \~~~~~/
  \___/

Інші миски можна заповнити кількома способами:

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

Обсяг води в чаші є об'єм чаші рядків нижче в ~символи. Наведені вище приклади мають 4, 6 and 2відповідно обсяги води .

Вхідні дані

  • Два натуральних числа, об’єм миски та об’єм води.
  • Ви можете вибрати порядок двох чисел.
  • Два цілих числа можуть бути введені у будь-якому загальному форматі списку (список, кортеж, масив тощо) або у вигляді двох окремих цілих чисел.
  • Принаймні одна допустима конфігурація чаші-вода гарантована для вхідних значень.

Вихідні дані

  • Представлення ASCII чаші з водою, де чаша та об'єм води співпадають із вхідними.
  • Якщо ви вирішите повернути результат замість друку, він повинен бути повернутий як один рядок (або найближча альтернатива вашої мови).
  • Дозволяється будь-який пробіл пробілу.
  • Не допускається зайвих провідних пробілів.
  • Якщо є кілька правильних конфігурацій, ви можете вибрати, яку саме вивести, але ви можете вивести лише одну.

Приклади

Кожна ціла пара вводу супроводжується одним або кількома можливими виходами.

6 2
\~~~/
 \_/

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

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

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

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

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

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

Це кодовий гольф, тому найкоротший запис виграє.

Відповіді:


6

CJam, 72 70 69 байт

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

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Час виконання та використання пам’яті є O (страшно) , тому три останні тестові випадки слід перевірити за допомогою інтерпретатора Java (та додаткового простору купи).

Приклад виконання

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

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

Як це працює

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 байт

Раннє представлення :) Тут є ще багато гольфу.

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

Безголівки:

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 */
            }
        }
    }
}

Чи можна зустріти миску, яка відповідає об'єму чаші, але не може відповідати об'єму води?
Вартан

At least one valid bowl-water configuration is guaranteed for the input values.- ОП
Коул Камерон

2

Javascript ES5, 364 байти

Це те, що я міг швидко придумати під час обіду, допоможіть мені гольфу, поки моя зміна закінчується!

Джерело

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

Гольф:

(пробіг через мініфікатор для компресії, обід закінчився)

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 байт

Запустити з опцією -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}}}}

Дякуємо Деннісу за допомогу в цьому.

Обчислює об'єм миски як висоту * (ширина + висота), де ширина - кількість _символів, а висота - кількість \символів.

Кожна комбінація висоти та ширини тестується в парі вкладених петель, поки не буде знайдено правильний об'єм чаші, потім робиться ще одна петля над можливими рівнями води, щоб виявити, чи можливий правильний об'єм води з цією шириною.

Вилучити третю петлю можна просто обчисливши рівень води за допомогою квадратичної формули з а 1, b як ширина і с як від’ємник від потрібного об'єму води, і перевіривши, чи є ціле число, але це займає більше байтів ніж просто робити цикл. Ось це все одно (183 байти):

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

Пітон 2, 162 байти

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

Трохи безладно, але ось моя перша спроба. Він намагається rвиконати всі можливі числа рядків , встановивши кількість підкреслень основи a = V/r-r. Потім він випробовує всі можливі висоти рівня води kі перевіряє чи справжній посудину, друкуючи її, якщо так.


1

Python 2.7, 284 270 260 байт

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

Це в основному обчислює висоту і ширину відра і води і друкує їх.

Намагався видалити некрасиву частину петлі під час старту (де я обчислюю висоту відра і висоту, з якої слід черпати воду. Зараз усі рядки в коді, крім останнього, призначені для обчислення ширини і висота). Ще намагаюся: P

Тестуючи його для різних випадків -

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

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

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

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

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

(102, 42)
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.