Peler la pomme de terre

20

Ceci est une pomme de terre:

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

Plus généralement, une pomme de terre de taille N est définie comme la forme suivante:

Si N est pair, ce sont 2 @symboles centrés , suivis de 4 @symboles centrés , suivis de 6 @symboles centrés , jusqu'à N @symboles centrés ; puis, N @symboles centrés , suivis de N-2 @symboles centrés , jusqu'à 2.
Si N est impair, une pomme de terre de taille N est générée de la même manière que décrite ci-dessus, mais nous commençons par 1 @symbole, plutôt que 2 .

Une pomme de terre est pelée en commençant dans le coin supérieur droit et en supprimant un @signe à chaque étape, dans le sens antihoraire. Par exemple, éplucher une pomme de terre de taille 3 ressemble à ceci:

 @
@@@
@@@
 @

​
@@@
@@@
 @

 ​
 @@
@@@
 @

  ​
 @@
 @@
 @

 ​
 @@
 @@
 ​

 ​
 @@
 @
 ​

​
 @
 @
 ​

 ​
​
 @
 ​


Défi

Écrivez un programme qui, étant donné une entrée entière, affiche toutes les étapes de pelage d'une pomme de terre de cette taille.
Les espaces de fin / les nouvelles lignes sont autorisés.

Notation

C'est ; le code le plus court en octets gagne.


Exemples de cas de test

N = 2

@@
@@

@
@@


@@


 @



N = 7

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


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


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


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


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


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


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


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


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



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



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



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



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



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



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




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




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




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




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




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




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





   @@  
  @@@@ 
  @@@@ 
   @   





   @@  
  @@@@ 
  @@@  
   @   





   @@  
  @@@  
  @@@  
   @   





   @   
  @@@  
  @@@  
   @   






  @@@  
  @@@  
   @   






   @@  
  @@@  
   @   






   @@  
   @@  
   @   






   @@  
   @@  







   @@  
   @   







   @   
   @   








   @   
 ​
 ​
 ​
 ​  


Catalogue

Basé sur Est-ce que ce nombre est un nombre premier?

VarmirGadkin
la source
5
Bienvenue chez PPCG! Belle première question, au fait.
clismique
1
Les espaces de fin / sauts de ligne sont-ils autorisés?
Loovjo
1
Je n'ai pas les compétences de la rétine mais je serais intéressé à voir cela - si c'est possible.
Jerry Jeremiah
@JamesHolderness Merci! J'ai corrigé ça.
VarmirGadkin

Réponses:

5

Perl, 129 octets

128 octets de code + -nindicateur.

$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/

Vous aurez besoin de -nEdrapeaux pour l'exécuter:

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

Explications: (je les détaillerai plus quand j'aurai un moment)
La première partie $p=($r=$"x$n++."@"x$_.$/).$p.$r,$_-=2while$_>0;,, génère la pomme de terre initiale: elle part de la ligne médiane de la pomme de terre, et ajoute deux lignes à chaque itération: une avant la chaîne précédente, une après. Notez qu'il $"s'agit d'un espace, et puisqu'il $nn'est pas initialisé, il commence à 0 et $/est une nouvelle ligne.

Notez beaucoup de choses à dire sur le say$_=$p;qui imprime la pomme de terre initiale tout en la stockant $_(ce qui sera plus tard plus facile à manipuler).

Enfin, say y/A/ /r while s/(^| )A(.*\n? *)@/$1 $2A/m||s/@( *\n?.*)A/A$1 /||s/@/A/épluche la pomme de terre. La dernière position où a @été supprimé contient un A(c'est arbitraire, ça pourrait être n'importe quel symbole). Ainsi, chaque itération consiste à trouver le A, à le remplacer par un espace, et en attendant à remplacer le suivant @par un A. Cela se fait grâce à deux regex: s/(^| )A(.*\n? *)@/$1 $2A/mlorsque le Aest sur le côté gauche de la pomme de terre ( A(.*\n? *)@permet d'aller à droite ou en bas), et s/@( *\n?.*)A/A$1 /lorsque le Aest sur le côté droit ( @( *\n?.*)Apermet de monter ou de gauche). s/@/A/remplace le premier @par un A(c'est l'initialisation). Puisque nous avons toujours un Adans la chaîne, nous devons le remplacer par un espace lors de l'impression, c'est ce qui y/A/ /rfait.


Juste pour les yeux , la version animée est plutôt sympa: (pour fonctionner dans un terminal, c'est à peu près le même code mais avec clearet 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
Dada
la source
1
C'est bien! Je n'ai jamais eu autant de plaisir à regarder un programme animé :)
VarmirGadkin
3

Befunge, 319 254 octets

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

La motivation de cet algorithme était d'essayer d'éviter autant que possible les branchements, car un seul chemin d'exécution est généralement plus facile à jouer au golf. Le code est donc composé de seulement deux boucles: la boucle externe itérant sur les images du processus de pelage et la boucle interne rendant la pomme de terre pour chaque image.

La boucle de rendu est essentiellement juste la sortie d'une séquence de caractères, le caractère pour chaque itération étant déterminé par une formule assez compliquée qui prend le numéro de trame du processus de décorticage et l'index de la séquence de sortie et renvoie soit un @, un espace ou un nouvelle ligne, au besoin.

Essayez-le en ligne!

James Holderness
la source
1
Wow, c'est magnifique.
416E64726577
2

Python 3.5.1, 520 octets

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

Explication

Idée de base: alterner entre itérer sur chaque ligne et supprimer le caractère le plus à gauche et itérer sur chaque ligne en supprimant le caractère le plus à droite tant qu'il reste encore @.

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

Dans l'ensemble, c'est une triste tentative de procédure simple.

Bobas_Pett
la source