เพิ่มประสิทธิภาพหลอดทดสอบ ASCII


13

คุณได้รับหลอดทดสอบ ASCII จำนวนมากงานของคุณคือลดจำนวนหลอดทดสอบที่ใช้

หลอดทดลองแต่ละอันมีลักษณะดังนี้:

|  |
|  |
|  |
|~~|
|  |
|  |
|  |
|  |
|__|

เห็นได้ชัดว่า~~เป็นระดับน้ำ หลอดทดลองอาจว่างเปล่าซึ่งในกรณีนี้จะไม่มี~~ตัวอักษรอยู่ภายใน หลอดเดียวสามารถบรรจุได้ถึง 8 ระดับหน่วยน้ำ

คุณจะได้รับจำนวน จำกัด ของหลอดทดลองที่มีระดับน้ำต่างกัน คุณต้องเทน้ำในหลอดทดลองให้น้อยที่สุดเท่าที่จะเป็นไปได้และส่งออกผลลัพธ์

|  | |  | |  | |  |         |~~| |  |
|  | |  | |  | |  |         |  | |  |
|  | |~~| |  | |  |         |  | |  |
|~~| |  | |  | |  |         |  | |~~|
|  | |  | |  | |  | ------> |  | |  |
|  | |  | |  | |  |         |  | |  |
|  | |  | |~~| |  |         |  | |  |
|  | |  | |  | |  |         |  | |  |
|__| |__| |__| |__|         |__| |__|

 05 + 06 + 02 + 00  ------>  08 + 05

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

กรณีทดสอบ: http://pastebin.com/BC0C0uii

มีความสุขในการเล่นกอล์ฟ!


เราสามารถแจกจ่ายน้ำได้หรือไม่ เช่นจะ 7 + 6 เป็นผลลัพธ์ที่ถูกต้องสำหรับตัวอย่างของคุณ?
Martin Ender

@MartinEnder คุณควรใช้หลอดให้น้อยที่สุดเท่าที่จะทำได้ ฉันคิดว่ามันเป็นที่ยอมรับในกรณีนี้
Jacajack

@StewieGriffin ฉันไม่ได้เห็นอะไรที่คล้ายกันที่นี่ยังดังนั้นหากที่เป็นนะซ้ำกันฉันขอโทษ
Jacajack

อนุญาตให้ใช้ช่องว่างต่อท้ายได้หรือไม่
PurkkaKoodari

ชื่อที่ดีขึ้น - "ทารกหลอดทดลอง ASCII ของเครื่องมือเพิ่มประสิทธิภาพ"
เครื่องมือเพิ่มประสิทธิภาพ

คำตอบ:



4

JavaScript (ES6), 159 148 ไบต์

s=>s.replace(/~~|\n/g,c=>1/c?i++:n+=7-i,n=i=-1)&&`012345678`.replace(/./g,i=>`|${g(+i)}| `.repeat(n>>3)+`|${g(~n&7^i)}|
`,g=i=>i?i>7?`__`:`  `:`~~`)

เอาต์พุตตัวป้อนบรรทัดที่ต่อท้าย แก้ไข: บันทึก 11 ไบต์ด้วยความช่วยเหลือจาก @Arnauld


s.replace(/~~/g,(_,i)=>n+=9-i/s.indexOf`\n`|0,n=0)ควรบันทึก 4 ไบต์ คุณอาจต้องการเริ่มต้น n ถึง -1 แทนและใช้n>>3และ~n&7^iบันทึกอีกหนึ่งไบต์
Arnauld

@ Arnauld ขอบคุณสำหรับ-1ความคิด แต่ฉันสามารถปรับปรุงreplaceความคิด
Neil

1
ดี! ฉันไม่เคยรู้เลยว่า1/"\n"เป็นความจริง
Arnauld

@Arnauld เอาละมันเป็นแค่ไอเท็มพิเศษบนเค้ก ...
Neil

3

Perl, 150 ไบต์

149 ไบต์ของรหัสเมือง + -nธง

$l+=9-$.for/~~/g}if($l){$%=($v=$l/8)+($r=$l!=8);say"|~~| "x$v.($@="|  | ")x$r;say$:=$@x$%for$l%8..6;say$@x$v."|~~|"x$r;say$:for 2..$l%8;say"|__| "x$%

ฉันจะไม่อธิบายรหัสทั้งหมดเพียงเล็กน้อย:
$l+=9-$.for/~~/gนับจำนวนน้ำที่อยู่ในอินพุต
ส่วนที่สองของรหัสจะพิมพ์เอาท์พุท แนวความคิดคือการใส่หลอดที่เต็มแล้วให้ได้มากที่สุดและหลอดสุดท้ายที่บรรจุน้ำที่เหลือ (ถ้ามี) ดังนั้นขั้นตอนวิธีการที่อยู่ใน 4 ส่วน: พิมพ์บรรทัดแรกของน้ำ say"|~~| "x$v.($@="| | ")x$r(ด้านบนของท่อ): say$:=$@x$%for$l%8..6จากนั้นพิมพ์ชิ้นส่วนที่ว่างเปล่าของหลอดจนกว่าจะถึงระดับของน้ำในท่อที่ผ่านมา: จากนั้นพิมพ์ระดับที่ระดับน้ำสุดท้ายของหลอด: say$@x$v."|~~|"x$r. จากนั้นพิมพ์ทั้งหมดที่เหลืออยู่ในระดับ say$:for 2..$l%8;"ว่างเปล่า": say"|__| "x$%และในที่สุดก็พิมพ์บรรทัดด้านล่าง:
ชื่อตัวแปรทำให้มันยากที่จะอ่าน ( $%, $@, $:) แต่ช่วยให้คำหลักเช่นxและfor ที่จะเขียนหลังจากตัวแปรโดยไม่มีช่องว่าง

วิธีเรียกใช้:

perl -nE '$l+=9-$.for/~~/g}if($l){$%=($v=$l/8)+($r=$l!=8);say"|~~| "x$v.($@="|  | ")x$r;say$:=$@x$%for$l%8..6;say$@x$v."|~~|"x$r;say$:for 2..$l%8;say"|__| "x$%' <<< "|  | |  | |  | |  |
|  | |  | |  | |  |
|  | |~~| |  | |  |
|~~| |  | |  | |  |
|  | |  | |  | |  |
|  | |  | |  | |  |
|  | |  | |~~| |  |
|  | |  | |  | |  |
|__| |__| |__| |__| "

ฉันไม่ค่อยพอใจกับคำตอบนี้นานแค่ไหน ฉันพยายามทำให้ดีที่สุดจากอัลกอริทึมของฉัน แต่วิธีการอื่นอาจสั้นกว่านี้ได้ ฉันจะพยายามทำงานกับมันในไม่ช้า


@ JamesHolderness ฉันลองทุกกรณีทดสอบ (และลองใหม่ตอนนี้เพราะคุณสงสัยฉัน) และดูเหมือนจะดีสำหรับฉัน "อันสุดท้าย" คืออันที่มี 3 หลอด: 2 ที่ระดับน้ำ 4 และ 1 ที่ระดับน้ำ 2 ใช่ไหม? ถ้าเป็นเช่นนั้นฉันลองแล้วมันจะให้ผลลัพธ์เช่นเดียวกับ pastbin
Dada

@ JamesHolderness โอ้ถูกต้องอธิบายได้มากมาย! ขอบคุณ :)
Dada

3

Befunge, 144 138 ไบต์

9>1-00p>~$~2/2%00gv
 |:g00_^#%4~$~$~+*<
$< v01!-g01+*8!!\*!\g00::-1</8+7:<p01-1<9p00+1%8-1:_@#:
_ ~>g!-1+3g:"|",,," |",,:>#^_$55+,10g:#^_@

ลองออนไลน์!

สองบรรทัดแรกประมวลผลอินพุตโดยทั่วไปจะละเว้นทุกอย่างยกเว้นอักขระตัวแรกในแต่ละหลอดที่อาจเป็นเครื่องหมายระดับ เราใช้ค่า ASCII ของตัวละครนั้นหารด้วย 2 และ mod 2 (ให้เรา 1 หรือ 0 ขึ้นอยู่กับว่าเราอยู่ในเครื่องหมายระดับหรือไม่) คูณด้วยจำนวนแถว (นับถอยหลังจาก 8 ดังนั้นให้เรา ค่าระดับสำหรับหลอดนั้น) และเพิ่มลงในผลรวมสะสม

เอาต์พุตถูกจัดการในสองบรรทัดที่สองโดยเริ่มต้นที่ด้านขวาสุดของบรรทัดที่สาม อันดับแรกเราคำนวณจำนวนหลอดโดยจดระดับน้ำทั้งหมดบวก 7 หารด้วย 8 จากนั้นเมื่อวนซ้ำแถวของหลอดทั้งหมดเราจะคำนวณอักขระที่จะแสดงภายในหลอดเฉพาะ ( tนับเป็น 0) แถวที่กำหนด ( r , นับถอยหลังจาก 8 ถึง 0) ดังนี้:

last_level = (total_water - 1)%8 + 1
level      = last_level*!t + 8*!!t
char_type  = !(level - r) - !r

char_type ที่คำนวณได้คือ -1 สำหรับแถวที่อยู่ด้านล่างสุด (ฐานของหลอด), 0 สำหรับพื้นที่อื่น ๆ ที่ไม่ใช่ระดับน้ำและ 1 สำหรับระดับน้ำ มันสามารถใช้เป็นการค้นหาตารางอย่างง่าย ๆ สำหรับอักขระที่เหมาะสมในการแสดงผล (คุณสามารถดูตารางนี้ที่จุดเริ่มต้นของบรรทัดที่ 4)


2

Haskell, 186 ไบต์

import Data.Lists
z=[8,7..0]
f x|s<-sum[i*length j-i|(i,j)<-zip z$splitOn"~~"<$>lines x],s>0=unlines$(\i->(#i)=<<(min 8<$>[s,s-8..1]))<$>z|1<2=""
l#i|i==l="|~~| "|i<1="|__| "|1<2="|  | "

ตัวอย่างการใช้งาน:

*Main> putStr $ f "|  | |  | |  | |  |\n|  | |  | |  | |  |\n|  | |~~| |  | |  |\n|~~| |  | |  | |  |\n|  | |  | |  | |  |\n|  | |  | |  | |  |\n|  | |  | |~~| |  |\n|  | |  | |  | |  |\n|__| |__| |__| |__|"
|~~| |  | 
|  | |  | 
|  | |  | 
|  | |~~| 
|  | |  | 
|  | |  | 
|  | |  | 
|  | |  | 
|__| |__| 

วางพื้นที่ต่อท้ายในทุกบรรทัด มันทำงานอย่างไร:

              lines x      -- split the input string at newlines             
      splitOn"~~"<$>       -- split every line on "~~"
    zip z                  -- pair every line with its water level, i.e.
                           -- first line = 8, 2nd = 7 etc.
   [i*length j-i|(i,j)   ] -- for each such pair take the number of "~~" found
                           -- times the level
 s<-sum                    -- and let s be the sum, i.e. the total amount of water

  s>0                      -- if there's any water at all

          [s,s-8..1]       -- make a list water levels starting with s
                           -- down to 1 in steps of 8
       min 8<$>            -- and set each level to 8 if its greater than 8
                           -- now we have the list of water levels for the output
  \i->(#i)=<<(  )<$>z      -- for each number i from 8,7..0 map (#i) to the
                           -- list of output water levels and join the results
unlines                    -- join output lines into a single string (with newlines)

l#i                        -- pick a piece of tube:
                           --  |__|  if l==0
                           --  |~~|  if l==i
                           --  |  |  else



  |1<2=""                  -- if there's no water in the input, return the
                           -- empty string

ความเจ็บปวดหลักคือการขาดฟังก์ชั่นที่นับความถี่ที่สตริงย่อยเกิดขึ้นในสตริง มีcountอยู่ในData.Textแต่การนำเข้ามันนำไปสู่ความขัดแย้งของชื่อที่แพงเกินไปที่จะแก้ไข


1

Python ขนาด 261 ไบต์

i=input().split('\n')
t=0
R=range(9)[::-1]
for n in R:t+=i[n].count('~')/2*(8-n)
m=t%8
e=t/8
o=t/8+1
T='|~~| '
b='|  | '
B='|__| '
n='\n'
if m:
 print T*e+b
 for n in R:
    if n==m:print b*e+T
    else:print b*o
 print B*o
elif t<1:1
else:print T*e+(n+b*e)*7+(n+B)*e

ฉันรู้สึกเหมือนมีบางสิ่งที่ฉันขาดหายไป นอกจากนี้หากมีการขึ้นบรรทัดใหม่จำนวนหนึ่งสำหรับเอาต์พุตว่างฉันอาจสูญเสียบางไบต์ '| | | | | |\n| | | | | |\n| | | | | |\n| | | | | |\n| | | | | |\n| | | | | |\n| | | | | |\n| | | | | |\n|__| |__| |__|'จะเข้าเช่น


1

ทับทิม 139 ไบต์

(รหัส 138 ไบต์บวกหนึ่งไบต์สำหรับ-n)

n||=0;b=gsub(/~~/){n=n+9-$.}[0,5];END{8.times{|i|puts (b*(n/8)).tr(?_,i>0??\ :?~)+(n%8>0?b.tr(?_,(8-i==n%8)??~:?\ ):"")};puts b*((n+7)/8)}

ลองออนไลน์!

คำอธิบายเล็กน้อย:

โปรแกรมนี้ต้องการ-nสวิตช์

n - เคาน์เตอร์น้ำ

b- แม่แบบสำหรับการสร้างหลอด; เท่ากับ"|__| "

i - ดัชนีเส้นปัจจุบันระหว่างการก่อสร้างท่อ

gsub(/~~/){... }- การละเมิดนี้gsubนับเพียงระดับน้ำ gsubจริงขยายซึ่งเทียบเท่ากับKernel.gsub $_.gsub!นี้ไม่จำเป็นปรุงแต่งบรรทัดปัจจุบัน ( $_); แต่มันช่วยให้การกำหนดรัดกุมมากขึ้นของb=... แทน[0,5]b=$_[0,5]

n=n+9-$.- การวัดระดับน้ำ, การแสดงออกใช้ตัวแปรที่กำหนดไว้ล่วงหน้า$.ซึ่งถือหมายเลขบรรทัดป้อนข้อมูลปัจจุบัน สิ่งนี้ทำให้ฉันสูญเสียตัวแปรลูปที่ชัดเจน

b=gsub(/~~/){... }[0,5]- แคชด้านล่างของหลอดด้านซ้ายสุดเป็นเทมเพลต (ให้ความรู้สึกเหมือนกับลาย“ Elephant in Cairo” สำหรับฉันเพราะบรรทัดล่างชนะ)
เนื่องจากด้านล่างของหลอดไม่แสดงน้ำดังนั้นgsubจะไม่แทนที่อะไรเมื่อเราอยู่ที่นั่น ดังนั้นในท้ายที่สุดแล้วเท่ากับเสมอb"|__| "

END{}- ได้รับการเรียกหลังจากประมวลผลสตรีมทั้งหมดแล้ว ฉันใช้เฟสนี้เพื่อสร้างหลอดเป้าหมาย

i>0??\ :?~- i > 0 ? " " : "~"เป็นเพียงระยะสั้นมือ

อัปเดต 1:เพิ่มรายละเอียดเกี่ยวกับตัวแปรgsubกลอุบายและเฟสEND{}

อัปเดต 2: (± 0 ไบต์โดยรวม)

  • ใช้n||=0แทนn=n||0 (-1 ไบต์)
  • ใช้ Malus เป็นเวลา-n (+1 ไบต์)

0

Python 3, 404 ไบต์

โปรแกรมนี้สร้างเอาต์พุตเต็มตามความต้องการพร้อมระดับน้ำทั้งในรูปแบบ ASCII และตัวเลข

w,x,y=[],[],[];a,b,s=" ------> ","~","";y=input().split("\n")
for i in [i for i in zip(*y) if "_" in i][::2]:w+=[8-i.index(b)] if b in i else [0]
u=sum(w)
while u:x+=[[8],[u]][u<8];u-=x[-1]
for i,k in enumerate(y):
    s+=k+"%s"%[a," "*9][i!=4]
    for j,l in enumerate(x):
        c=["  ","__"][i==8];s+="|%s| "%(c,b*2)[l==8-i]
    s+="\n"
s+="\n"
for i in w:s+=" %02d  "%i
s+="\b"+a
for i in x:s+=" %02d  "%i
print(s)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.