Patatesi soyun


20

Bu bir patates:

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

Daha genel olarak, bir boyut N patates aşağıdaki şekil olarak tanımlanır:

N eşitse, 2 ortalanmış @sembol, ardından 4 ortalanmış @sembol ve ardından 6 ortalanmış @sembol, N ortalanmış @sembollere kadar; daha sonra N merkezli @semboller, ardından N-2 merkezli @semboller, 2'ye kadar iner.
N garip ise, N boyutunda bir patates yukarıda açıklandığı şekilde üretilir, ancak @2 yerine 1 sembolle başlarız .

Bir patates, sağ üst köşeden başlayıp @her adımda bir işareti kaldırarak saat yönünün tersine doğru soyulur . Örneğin, 3 boy patatesleri soymak şöyle görünür:

 @
@@@
@@@
 @

​
@@@
@@@
 @

 ​
 @@
@@@
 @

  ​
 @@
 @@
 @

 ​
 @@
 @@
 ​

 ​
 @@
 @
 ​

​
 @
 @
 ​

 ​
​
 @
 ​


Meydan okuma

Bir tamsayı girişi verildiğinde, bu boyutta bir patates soyma adımlarının tümünü görüntüleyen bir program yazın.
Sondaki boşluk / satırsonlarına izin verilir.

puanlama

Bu ; bayt cinsinden en kısa kod kazanır.


Örnek Test Durumları

N = 2

@@
@@

@
@@


@@


 @



N = 7

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


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


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


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


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


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


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


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


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



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



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



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



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



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



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




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




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




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




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




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




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





   @@  
  @@@@ 
  @@@@ 
   @   





   @@  
  @@@@ 
  @@@  
   @   





   @@  
  @@@  
  @@@  
   @   





   @   
  @@@  
  @@@  
   @   






  @@@  
  @@@  
   @   






   @@  
  @@@  
   @   






   @@  
   @@  
   @   






   @@  
   @@  







   @@  
   @   







   @   
   @   








   @   
 ​
 ​
 ​
 ​  


Katalog

Dayanarak bu sayı asal mı?


5
PPCG'ye Hoşgeldiniz! Güzel ilk soru, bu arada.
clismique

1
Sondaki boşluk / satırsonlarına izin verilir mi?
Loovjo

1
Retina becerilerim yok, ancak bunu görmek isterim - eğer mümkünse.
Jerry Jeremiah

@JamesHolderness Teşekkürler! Bunu düzelttim.
VarmirGadkin

Yanıtlar:


5

Perl, 129 bayt

128 bayt kod + -nbayrak.

$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Çalıştırmak için bayraklara ihtiyacınız olacak:

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

Açıklamalar: (Bir dakikam olduğunda onları daha ayrıntılı olarak açıklayacağım)
İlk kısım, $p=($r=$"x$n++."@"x$_.$/).$p.$r,$_-=2while$_>0;ilk patatesi üretir: patatesin orta çizgisinden başlar ve her bir yinelemeye iki satır ekler: bir önceki dizeden önce, bir sonra. Bunun $"bir boşluk olduğunu ve $nbaşlatılmadığından 0 ile başladığını ve $/yeni bir satır olduğunu unutmayın.

Hakkında söylenecek çok dikkat say$_=$p;olarak saklama sırasında ilk patates yazdırır $_(daha sonra işlemek için daha kolay olacaktır).

Son olarak, say y/A/ /r while s/(^| )A(.*\n? *)@/$1 $2A/m||s/@( *\n?.*)A/A$1 /||s/@/A/patatesleri soyun. @A'nın kaldırıldığı son konum bir içerir A(isteğe bağlı, herhangi bir sembol olabilir). Yani her yineleme A, onu bulmak, onu bir boşlukla değiştirmek ve bu arada @bir sonrakini a ile değiştirmek A. : Bu iki regex için bitti borçluyum s/(^| )A(.*\n? *)@/$1 $2A/mzaman Apatatesin sol tarafında ( A(.*\n? *)@sağ veya aşağı gitmek için izin verir) ve s/@( *\n?.*)A/A$1 /zaman Asağ tarafta ( @( *\n?.*)Ayukarı çıkmak veya solda sağlar). s/@/A/ilkini a @ile değiştirir A(bu başlatmadır). Dizede her zaman bir tane Abulunduğundan, yazdırırken bir boşlukla değiştirmemiz gerekir, işte budur y/A/ /r.


Sadece gözler için , animasyonlu sürüm oldukça güzel görünüyor: (bir terminalde çalıştırmak için, kabaca aynı kod ancak clearve ile 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
Bu harika! Animasyonlu bir programı izlerken hiç bu kadar eğlendim :)
VarmirGadkin

3

Befunge, 319 254 bayt

&: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

Bu algoritmanın motivasyonu, mümkün olduğunca dallanmayı önlemek ve kaçınmaktı, çünkü tek bir uygulama yolu genellikle golf oynamak daha kolaydır. Kod böylece sadece iki döngüden oluşur: soyma işleminin çerçeveleri üzerinde yinelenen dış döngü ve her çerçeve için patatesi oluşturan iç döngü.

Oluşturma döngüsü esasen sadece bir karakter dizisi çıkarır, her yineleme için karakter, soyma işleminin kare numarasını ve çıkış dizisinin dizinini alan ve an @, boşluk veya a döndüren oldukça karmaşık bir formülle belirlenir. gerektiği gibi yeni satır.

Çevrimiçi deneyin!


1
Vay canına, bu çok güzel.
416E64726577

2

Python 3.5.1, 520 bayt

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

açıklama

Temel fikir: Her satırı aşağı yineleme ile en soldaki karakteri kaldırma ve hala soldayken en sağdaki karakteri kaldırarak her satırı yukarı yineleme arasında geçiş yapın @.

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

Genel olarak basit bir prosedür için üzücü bir girişim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.