ปอกเปลือกมันฝรั่ง


20

นี่คือมันฝรั่ง:

  @@
 @@@@
@@@@@@
@@@@@@
 @@@@
  @@

โดยทั่วไปมันฝรั่งขนาด N ถูกกำหนดให้เป็นรูปร่างดังต่อไปนี้:

ถ้า N เป็นเลขคู่จะมี@สัญลักษณ์อยู่ตรงกลาง 2 สัญลักษณ์ตามด้วย@สัญลักษณ์ศูนย์กลาง 4 อันตามด้วย@สัญลักษณ์ศูนย์กลาง 6 อันจนถึง@สัญลักษณ์ที่อยู่กึ่งกลาง N ทั้งหมด จากนั้น@สัญลักษณ์กึ่งกลาง N ตามด้วยสัญลักษณ์กึ่งกลางN-2 @ไปจนถึง 2
หาก N เป็นเลขคี่มันฝรั่งขนาด N จะถูกสร้างขึ้นในลักษณะเดียวกับที่อธิบายข้างต้น แต่เราเริ่มต้นด้วย 1 @สัญลักษณ์แทนที่จะเป็น 2 .

มันฝรั่งถูกปอกเปลือกโดยเริ่มต้นที่มุมขวาบนและลบหนึ่ง@ป้ายในแต่ละขั้นตอนไปในรูปแบบทวนเข็มนาฬิกา ตัวอย่างเช่นการปอกมันฝรั่งขนาด 3 ออกมาเป็นแบบนี้:

 @
@@@
@@@
 @

​
@@@
@@@
 @

 ​
 @@
@@@
 @

  ​
 @@
 @@
 @

 ​
 @@
 @@
 ​

 ​
 @@
 @
 ​

​
 @
 @
 ​

 ​
​
 @
 ​


ท้าทาย

เขียนโปรแกรมที่ให้อินพุตเป็นจำนวนเต็มแสดงขั้นตอนทั้งหมดของการปอกมันฝรั่งที่มีขนาดนั้น
อนุญาตให้เว้นวรรคช่องว่าง / บรรทัดใหม่

เกณฑ์การให้คะแนน

นี่คือ ; รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


กรณีทดสอบตัวอย่าง

N = 2

@@
@@

@
@@


@@


 @



N = 7

   @   
  @@@  
 @@@@@ 
@@@@@@@
@@@@@@@
 @@@@@ 
  @@@  
   @   


  @@@  
 @@@@@ 
@@@@@@@
@@@@@@@
 @@@@@ 
  @@@  
   @   


   @@  
 @@@@@ 
@@@@@@@
@@@@@@@
 @@@@@ 
  @@@  
   @   


   @@  
  @@@@ 
@@@@@@@
@@@@@@@
 @@@@@ 
  @@@  
   @   


   @@  
  @@@@ 
 @@@@@@
@@@@@@@
 @@@@@ 
  @@@  
   @   


   @@  
  @@@@ 
 @@@@@@
 @@@@@@
 @@@@@ 
  @@@  
   @   


   @@  
  @@@@ 
 @@@@@@
 @@@@@@
  @@@@ 
  @@@  
   @   


   @@  
  @@@@ 
 @@@@@@
 @@@@@@
  @@@@ 
   @@  
   @   


   @@  
  @@@@ 
 @@@@@@
 @@@@@@
  @@@@ 
   @@  



   @@  
  @@@@ 
 @@@@@@
 @@@@@@
  @@@@ 
   @   



   @@  
  @@@@ 
 @@@@@@
 @@@@@@
  @@@  
   @   



   @@  
  @@@@ 
 @@@@@@
 @@@@@ 
  @@@  
   @   



   @@  
  @@@@ 
 @@@@@ 
 @@@@@ 
  @@@  
   @   



   @@  
  @@@  
 @@@@@ 
 @@@@@ 
  @@@  
   @   



   @   
  @@@  
 @@@@@ 
 @@@@@ 
  @@@  
   @   




  @@@  
 @@@@@ 
 @@@@@ 
  @@@  
   @   




   @@  
 @@@@@ 
 @@@@@ 
  @@@  
   @   




   @@  
  @@@@ 
 @@@@@ 
  @@@  
   @   




   @@  
  @@@@ 
  @@@@ 
  @@@  
   @   




   @@  
  @@@@ 
  @@@@ 
   @@  
   @   




   @@  
  @@@@ 
  @@@@ 
   @@  





   @@  
  @@@@ 
  @@@@ 
   @   





   @@  
  @@@@ 
  @@@  
   @   





   @@  
  @@@  
  @@@  
   @   





   @   
  @@@  
  @@@  
   @   






  @@@  
  @@@  
   @   






   @@  
  @@@  
   @   






   @@  
   @@  
   @   






   @@  
   @@  







   @@  
   @   







   @   
   @   








   @   
 ​
 ​
 ​
 ​  


แค็ตตาล็อก

ขึ้นอยู่กับจำนวนนี้เป็นนายกรัฐมนตรีหรือไม่?


5
ยินดีต้อนรับสู่ PPCG! คำถามแรกที่ดีโดยวิธีการ
clismique

1
การเว้นวรรคช่องว่าง / บรรทัดใหม่ต่อท้ายอนุญาตหรือไม่
Loovjo

1
ฉันไม่มีทักษะจอประสาทตา แต่ฉันสนใจที่จะเห็นว่า - ถ้าเป็นไปได้
Jerry Jeremiah

@ JamesHolderness ขอบคุณ! ฉันได้แก้ไขแล้ว
VarmirGadkin

คำตอบ:


5

Perl, 129 ไบต์

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

$p=($r=$"x$n++."@"x$_.$/).$p.$r,$_-=2while$_>0;say$_=$p;say y/A/ /r while s/(^| )A(.*
? *)@/$1 $2A/m||s/@( *
?.*)A/A$1 /||s/@/A/

คุณจะต้องใช้-nEธงเพื่อเรียกใช้:

perl -nE '$p=($r=$"x$n++."@"x$_.$/).$p.$r,$_-=2while$_>0;say$_=$p;say y/A/ /r while s/(^| )A(.*
? *)@/$1 $2A/m||s/@( *
?.*)A/A$1 /||s/@/A/' <<< 7

คำอธิบาย: (ฉันจะให้รายละเอียดเพิ่มเติมเมื่อฉันมีเวลา)
ส่วนแรก$p=($r=$"x$n++."@"x$_.$/).$p.$r,$_-=2while$_>0;สร้างมันฝรั่งเริ่มต้น: มันเริ่มต้นจากบรรทัดกลางของมันฝรั่งและเพิ่มสองบรรทัดในแต่ละการวนซ้ำ: หนึ่งก่อนที่สตริงก่อนหน้าหนึ่ง หลังจาก. โปรดทราบว่า$"เป็นช่องว่างและเนื่องจาก$nไม่ได้กำหนดค่าเริ่มต้นจึงเริ่มต้นที่ 0 และ$/เป็นบรรทัดใหม่

โปรดสังเกตว่าจะพูดเกี่ยวกับสิ่งsay$_=$p;ที่พิมพ์มันฝรั่งเริ่มต้นในขณะที่เก็บไว้ใน$_(ซึ่งจะง่ายต่อการจัดการในภายหลัง)

ในที่สุดก็say y/A/ /r while s/(^| )A(.*\n? *)@/$1 $2A/m||s/@( *\n?.*)A/A$1 /||s/@/A/ปอกเปลือกมันฝรั่ง ตำแหน่งสุดท้ายที่@ถูกลบออกมีA(โดยพลการมันอาจมีสัญลักษณ์ใด ๆ ) ดังนั้นแต่ละซ้ำประกอบด้วยในการหาAแทนที่มันด้วยช่องว่างและในขณะเดียวกันการเปลี่ยนถัดไปด้วย@ Aมันทำด้วยสอง regex: s/(^| )A(.*\n? *)@/$1 $2A/mเมื่อAอยู่ทางด้านซ้ายของมันฝรั่ง ( A(.*\n? *)@อนุญาตให้ไปทางขวาหรือลง) และs/@( *\n?.*)A/A$1 /เมื่อAอยู่ทางด้านขวา ( @( *\n?.*)Aอนุญาตให้ขึ้นหรือไปทางซ้าย) s/@/A/แทนที่แรก@ด้วยA(นั่นคือการเริ่มต้น) เนื่องจากเรามีAสตริงในเสมอเราจึงต้องแทนที่ด้วยช่องว่างเมื่อพิมพ์มันนั่นคือสิ่งที่y/A/ /rทำ


แค่อนิเมชั่นเวอร์ชั่นแอนิเมชั่นก็ดูค่อนข้างดี: (ในการรันในเทอร์มินัลมันเป็นรหัสเดียวกันโดยประมาณclearและด้วยsleep)

perl -nE 'system(clear);$p=($r=$"x$n++."@"x$_.$/).$p.$r,$_-=2while$_>0;say$_=$p;select($,,$,,$,,0.1),system(clear),say y/A/ /r while(s/(^| )A(.*\n? *)@/$1 $2A/m||s/@( *\n?.*)A/A$1 /||s/@/A/)&&/@/' <<< 10

1
มันเยี่ยมมาก! ฉันไม่เคยสนุกกับการดูรายการการ์ตูน :)
VarmirGadkin

3

Befunge, 319 254 ไบต์

&:00p1+:40p2/10p>:40g%20p:40g/30p\:10g30g`:!00g:2%!-30g-*\30g*+:20g1+v
+10g-::40g\-*2*30g+\-1+00g2%!+\00g2/1++20g-:::40g\-*2*+30g-\4*00g2*-v>
v+1\,-**2+92!-g02g00**84+1`\+*`g02g01\*!`g02g01+**!-g02\`g03:/2g00-4<
>:40g00g:2%+*`!#v_$1+:55+,00g::*1-2/+`#@_0

แรงจูงใจสำหรับอัลกอริทึมนี้คือพยายามและหลีกเลี่ยงการแยกให้มากที่สุดเท่าที่จะทำได้เนื่องจากเส้นทางการประหารชีวิตเพียงเส้นทางเดียวนั้นง่ายกว่าในการตีกอล์ฟ รหัสนี้ประกอบไปด้วยสองลูปเท่านั้น: ลูปด้านนอกวนซ้ำไปตามเฟรมของกระบวนการปอกเปลือกและลูปด้านในจะแสดงมันฝรั่งสำหรับแต่ละเฟรม

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

ลองออนไลน์!


1
ว้าวนี่สวยงาม
416E64726577

2

Python 3.5.1, 520 ไบต์

n=int(input())L=lenR=rangeP=printdefg(a,b):f=list(a)ifb:foriinR(L(f)):iff[i]=="@":f[i]=""breakelse:foriinR(L(f)-1,-1,-1):iff[i]=="@":f[i]=""breakreturn"".join(f)l=[]s=(2-n%2n)*(((n-2n%2)/2)1)i=2-n%2whilei<=n:l.append("@"*i)i=2j=L(l)-1whilej>=0:l.append(l[j])j-=1y=[rforrinR(int((L(l)/2)-1),-1,-1)]forhinR(L(y)-1,-1,-1):y.append(y[h])defH(q):foreinR(L(l)):P((""*y[e])q[e])P("")H(l)k=0m=0whilek<s:fortinR(L(l)):if'@'inl[t]andm%2==0:l[t]=g(l[t],True)k=1H(l)if'@'inl[t]andm%2==1:l[t]=g(l[t],False)k=1p=l[:]p.reverse()H(p)m=1

คำอธิบาย

แนวคิดพื้นฐาน: สลับระหว่างการวนซ้ำแต่ละบรรทัดและลบอักขระซ้ายสุดและวนซ้ำแต่ละบรรทัดลบอักขระขวาสุดขณะที่ยัง@เหลือ

n=int(input())
L=len
R=range
P=print
# g() returns a line in the potato with leftmost or rightmoxt '@' removed
def g(a,b):
    f=list(a)
    if b:
        for i in R(L(f)):
            if f[i]=="@":
                f[i]=" "
                break
    else:
        for i in R(L(f)-1,-1,-1):
            if f[i]=="@":
                f[i]=" "
                break
    return "".join(f)

l=[]
# s is the total number of '@'s for size n
s=(2-n%2+n)*(((n-2+n%2)/2)+1)
i=2-n%2

# store each line of potato in l
while i<=n:
    l.append("@"*i)
    i+=2
j=L(l)-1
while j>=0:
    l.append(l[j])
    j-=1

# this is used for spacing
y=[r for r in R(int((L(l)/2)-1),-1,-1)]
for h in R(L(y)-1,-1,-1):
    y.append(y[h])

# print the potato
def H(q):
    for e in R(L(l)):
        P((" "*y[e])+q[e])
    P("\n")

H(l)
k=0
m=0

# while there are still '@'s either
# go down the potato removing leftmost '@' 
# go up the potato removing rightmost '@'
while k<s:
    for t in R(L(l)):
        if '@' in l[t] and m%2==0:
            l[t]=g(l[t],True)
            k+=1
            H(l)               
        if '@' in l[t] and m%2==1:
            l[t]=g(l[t],False)
            k+=1
            p=l[:]
            p.reverse()
            H(p)
    m+=1

โดยรวมแล้วเป็นเรื่องน่าเศร้าในขั้นตอนที่ตรงไปตรงมา

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