Bát đầy nước


19

Bạn nên viết một chương trình hoặc chức năng nhận thể tích của một cái bát và thể tích nước trong đó làm đầu vào và đầu ra hoặc trả về một đại diện ASCII của một cái bát có nước trong đó với các thể tích mong muốn.

Một cái bát có cấu trúc như sau:

 \     /
  \___/

Cái bát có ít nhất một _ký tự. Số lượng của \/cũng là dương và chúng bằng nhau do tính đối xứng.

Âm lượng của bát là tổng số _spaceký tự giữa \'s và /' cộng với một cho mỗi cặp \/. Điều này có nghĩa là bát trên có khối lượng 10:

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

Lưu ý rằng hai bát khác nhau có thể có cùng một thể tích. Ví dụ: cả hai bát sau có thể tích 18:

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

Chúng ta có thể đổ một ít nước vào bát. Nước được thể hiện dưới dạng một hàng ~ký tự thay vì khoảng trắng bên trong bát. Hàng dưới cùng không có khoảng trắng nên không thể chứa ~'s. Điều này có nghĩa là ví dụ của chúng ta có thể được đổ đầy nước chỉ bằng một cách:

 \~~~~~/
  \___/

Các bát khác có thể được điền theo nhiều cách:

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

Thể tích của nước trong một cái bát là thể tích của các hàng bát bên dưới các ~ký tự. Các ví dụ trên có lượng nước 4, 6 and 2tương ứng.

Đầu vào

  • Hai số nguyên dương, thể tích của bát và thể tích của nước.
  • Bạn có thể chọn thứ tự của hai số.
  • Hai số nguyên có thể được nhập vào trong bất kỳ định dạng danh sách chung nào (danh sách, bộ dữ liệu, mảng, v.v.) hoặc dưới dạng hai số nguyên riêng biệt.
  • Ít nhất một cấu hình bát nước hợp lệ được đảm bảo cho các giá trị đầu vào.

Đầu ra

  • Biểu diễn ASCII của một bát có nước trong đó bát và thể tích nước khớp với đầu vào.
  • Nếu bạn chọn trả về kết quả thay vì in, nó sẽ được trả về dưới dạng một chuỗi (hoặc thay thế gần nhất với ngôn ngữ của bạn).
  • Bất kỳ khoảng trắng dấu vết được cho phép.
  • Không có khoảng trắng hàng đầu không cần thiết được cho phép.
  • Nếu có nhiều cấu hình chính xác, bạn có thể tự do chọn cái nào bạn xuất nhưng bạn chỉ có thể xuất một trong số chúng.

Ví dụ

Mỗi cặp số nguyên đầu vào được theo sau bởi một hoặc nhiều đầu ra có thể.

6 2
\~~~/
 \_/

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

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

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

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

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

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

Đây là mã golf nên mục ngắn nhất sẽ thắng.

Câu trả lời:


6

CJam, 72 70 69 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Thời gian chạy và sử dụng bộ nhớ là O (đáng sợ) , do đó, ba trường hợp thử nghiệm cuối cùng phải được xác minh bằng trình thông dịch Java (và không gian heap thêm).

Chạy ví dụ

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

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

Làm thế nào nó hoạt động

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

Nộp sớm :) Có rất nhiều golf để làm ở đây.

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

Ung dung:

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

Có thể bắt gặp một cái bát phù hợp với thể tích bát nhưng không thể gặp một thể tích nước?
Vartan

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

2

Javascript ES5, 364 byte

Đây là những gì tôi có thể đến nhanh chóng trong bữa trưa của mình, hãy giúp tôi chơi golf trong khi ca làm việc của tôi kết thúc!

Nguồn

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

Chơi gôn

(chạy qua công cụ khai thác để nén, kết thúc ca ăn trưa)

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

Chạy với tùy chọn -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}}}}

Cảm ơn Dennis vì đã giúp chơi golf này.

Tính khối lượng bát là chiều cao * (chiều rộng + chiều cao), trong đó chiều rộng là số lượng _ký tự và chiều cao là số lượng \ký tự.

Mỗi sự kết hợp giữa chiều cao và chiều rộng được kiểm tra trong một cặp vòng lồng nhau cho đến khi tìm thấy thể tích bát chính xác, sau đó một vòng lặp khác trên các mức độ cao có thể được thực hiện để tìm xem liệu có thể có thể tích nước chính xác với chiều rộng đó không.

Có thể loại bỏ vòng lặp thứ ba bằng cách tính mực nước bằng công thức bậc hai với 1, b là chiều rộng và c là âm của thể tích nước mong muốn và kiểm tra xem đó có phải là số nguyên không, nhưng cần nhiều byte hơn hơn là chỉ làm một vòng lặp. Đây là dù sao (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

Một chút lộn xộn, nhưng đây là nỗ lực đầu tiên của tôi. Nó thử tất cả các số hàng có thể r, đặt số lượng dấu gạch dưới cơ sở là a = V/r-r. Sau đó, nó thử tất cả các độ cao mực nước có thể kvà kiểm tra xem bát có hợp lệ không, in nó nếu có.


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

Điều này về cơ bản tính toán chiều cao và chiều rộng của xô và nước và in chúng.

Đã cố gắng hết sức để loại bỏ phần vòng lặp xấu xí khi bắt đầu (trong đó tôi tính chiều cao của xô và chiều cao từ đó nên rút nước. Ngay bây giờ, tất cả các dòng trong mã ngoại trừ phần cuối cùng là để tính chiều rộng và Chiều cao). Vẫn đang thử: P

Kiểm tra nó cho các trường hợp khác nhau -

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

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

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

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

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

(102, 42)
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.