碗里装满水


19

您应该编写一个程序或函数,该程序或函数接收一个碗的容积和其中的水作为输入,然后输出或返回一个带有所需容积的碗的ASCII表示形式。

碗具有以下结构:

 \     /
  \___/

碗至少有一个_字符。的计数\的和/的,也正和他们是平等的对称因。

碗的容积的总数量_space所述字符之间\的和/的加一,每对\/。这表示上述碗的容量为10

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

请注意,两个不同的碗可能具有相同的体积。例如,以下两个碗的容积均为18:

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

我们可以往碗里倒些水。水被表示为一行~字符,而不是碗中的空格。最下面一行没有空格,因此不能包含~。这意味着我们的示例只能以一种方式充满水:

 \~~~~~/
  \___/

其他碗可以通过多种方式填充:

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

碗中的水量是字符下方的碗行的量~。上面的例子4, 6 and 2分别有水量。

输入项

  • 两个正整数,碗的体积和水的体积。
  • 您可以选择两个数字的顺序。
  • 可以以任何常见列表格式(列表,元组,数组等)或两个单独的整数输入两个整数。
  • 对于输入值,至少要保证一种有效的碗水配置。

输出量

  • 装有水的碗的ASCII表示,其中碗和水的体积与输入相匹配。
  • 如果您选择返回结果而不是打印结果,则应将其作为单个字符串(或您的语言最接近的替代品)返回。
  • 允许任何尾随空格。
  • 不允许使用不必要的前导空格。
  • 如果有多个正确的配置,则可以自由选择要输出的配置,但是只能输出其中之一。

例子

每个输入整数对后跟一个或多个可能的输出。

6 2
\~~~/
 \_/

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

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

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

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

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

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

这是代码高尔夫球,因此最短的入场券获胜。

Answers:


6

CJam,72 70 69字节

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

CJam解释器中在线尝试。

运行时间和内存使用情况均为O(scary),因此应使用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 */
            }
        }
    }
}

是否有可能遇到一个与碗容量匹配但不能满足水容量的碗?
Vartan

At least one valid bowl-water configuration is guaranteed for the input values.-OP-
科尔·卡梅隆

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,227172字节

使用-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}}}}

多亏丹尼斯(Dennis)为高尔夫运动提供帮助。

以高度*(宽度+高度)计算碗的体积,其中width是_字符数,height是\字符数。

在成对的嵌套循环中测试高度和宽度的每种组合,直到找到正确的便池容积为止,然后在可能的水高度水平上进行另一个循环,以查找在该宽度下是否可以正确的水容积。

可以通过仅使用二次公式计算水位来删除第三个循环,其中a为1,b为宽度,c为所需水量的负数,然后检查它是否为整数,但是需要更多字节而不是做一个循环。无论如何,这里是(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

Python 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

基本上,这将计算出水桶和水的高度和宽度并进行打印。

尝试从一开始就删除丑陋的while循环部分(其中,我计算了桶的高度和应该从中抽水的高度。现在,代码中除最后一行之外的所有行都用于计算宽度和高度)。仍在尝试:P

针对不同情况进行测试-

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

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

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

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

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

(102, 42)
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.