ชามที่เต็มไปด้วยน้ำ


19

คุณควรเขียนโปรแกรมหรือฟังก์ชั่นที่รับปริมาตรของชามและปริมาตรของน้ำในนั้นเป็นอินพุตและเอาต์พุตหรือคืนค่าการแสดง ASCII ของชามด้วยน้ำในปริมาตรที่ต้องการ

ชามมีโครงสร้างดังต่อไปนี้:

 \     /
  \___/

โถอย่างน้อยหนึ่ง_ตัว การนับ\และการ/บวกก็เป็นบวกและเท่ากันเนื่องจากสมมาตร

ปริมาณของชามคือจำนวน_และspaceตัวอักษรระหว่าง\'และ/' s บวกหนึ่งสำหรับคู่ของทุกและ\ /ซึ่งหมายความว่าชามด้านบนมีปริมาณ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ตามลำดับ

อินพุต

  • จำนวนเต็มบวกสองตัวปริมาตรของชามและปริมาตรของน้ำ
  • คุณสามารถเลือกลำดับของตัวเลขทั้งสอง
  • จำนวนเต็มสองตัวสามารถป้อนเข้าในรูปแบบรายการทั่วไป (list, tuple, array ฯลฯ ) หรือเป็นจำนวนเต็มสองตัวที่แยกกัน
  • มีการรับประกันการกำหนดค่าชามน้ำที่ถูกต้องอย่างน้อยหนึ่งรายการสำหรับค่าอินพุต

เอาท์พุต

  • การแทน 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);}}}

Ungolfed:

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
Cole Cameron

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 เป็นความกว้างและ 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

โดยทั่วไปจะคำนวณความสูงและความกว้างของถังและน้ำแล้วพิมพ์ออกมา

พยายามยากที่จะลบน่าเกลียดในขณะที่วนส่วนที่จุดเริ่มต้น (นั้นฉันคำนวณความสูงของถังและความสูงจากที่ที่ควรจะวาดน้ำตอนนี้ทุกบรรทัดในรหัสยกเว้นคนสุดท้ายสำหรับการคำนวณความกว้างและ สูง) ยังคงพยายาม: P

ทดสอบในกรณีที่แตกต่างกัน -

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

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

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

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

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

(102, 42)
\                     /
 \                   /
  \~~~~~~~~~~~~~~~~~/
   \               /
    \             /
     \___________/
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.