Pelar la papa


20

Esta es una papa:

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

Más generalmente, una papa de tamaño N se define como la siguiente forma:

Si N es par, son 2 @símbolos centrados , seguidos de 4 @símbolos centrados , seguidos de 6 @símbolos centrados , hasta N @símbolos centrados ; luego, @símbolos centrados en N , seguidos por símbolos centrados en N-2 @, hasta 2.
Si N es impar, se genera una papa N de tamaño de la misma manera que se describe anteriormente, pero comenzamos con 1 @símbolo, en lugar de 2 .

Una papa se pela comenzando en la esquina superior derecha y quitando un @signo en cada paso, en sentido contrario a las agujas del reloj. Por ejemplo, pelar una papa tamaño 3 se ve así:

 @
@@@
@@@
 @

​
@@@
@@@
 @

 ​
 @@
@@@
 @

  ​
 @@
 @@
 @

 ​
 @@
 @@
 ​

 ​
 @@
 @
 ​

​
 @
 @
 ​

 ​
​
 @
 ​


Desafío

Escriba un programa que, dada una entrada entera, muestre todos los pasos para pelar una papa de ese tamaño.
Se permiten espacios en blanco al final / líneas nuevas.

Puntuación

Este es el ; gana el código más corto en bytes.


Ejemplos de casos de prueba

N = 2

@@
@@

@
@@


@@


 @



N = 7

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


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


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


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


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


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


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


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


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



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



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



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



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



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



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




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




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




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




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




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




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





   @@  
  @@@@ 
  @@@@ 
   @   





   @@  
  @@@@ 
  @@@  
   @   





   @@  
  @@@  
  @@@  
   @   





   @   
  @@@  
  @@@  
   @   






  @@@  
  @@@  
   @   






   @@  
  @@@  
   @   






   @@  
   @@  
   @   






   @@  
   @@  







   @@  
   @   







   @   
   @   








   @   
 ​
 ​
 ​
 ​  


Catalogar

Basado en ¿Es este número un primo?


55
Bienvenido a PPCG! Buena primera pregunta, por cierto.
clismique

1
¿Se permiten espacios en blanco al final / líneas nuevas?
Loovjo

1
No tengo las habilidades de Retina, pero me interesaría ver eso, si es posible.
Jerry Jeremiah

@JamesHolderness ¡Gracias! He arreglado eso.
VarmirGadkin

Respuestas:


5

Perl, 129 bytes

128 bytes de código + -nbandera.

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

Necesitarás -nEbanderas para ejecutarlo:

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

Explicaciones: (los detallaré más cuando tenga un momento)
La primera parte, $p=($r=$"x$n++."@"x$_.$/).$p.$r,$_-=2while$_>0;genera la papa inicial: comienza desde la línea media de la papa y agrega dos líneas en cada iteración: una antes de la cadena anterior, otra después. Tenga en cuenta que $"es un espacio, y como $nno está inicializado, comienza en 0 y $/es una nueva línea.

Tenga en cuenta mucho que decir sobre el say$_=$p;que imprime la patata inicial mientras la almacena $_(que luego será más fácil de manipular).

Finalmente, say y/A/ /r while s/(^| )A(.*\n? *)@/$1 $2A/m||s/@( *\n?.*)A/A$1 /||s/@/A/pela la papa. La última posición donde @se eliminó un contiene un A(es arbitrario, podría ser cualquier símbolo). Por lo tanto, cada iteración consiste en encontrar el A, reemplazarlo con un espacio y, mientras tanto, reemplazar el siguiente @con un A. Eso se hace gracias a dos expresiones regulares: s/(^| )A(.*\n? *)@/$1 $2A/mcuando Aestá en el lado izquierdo de la papa ( A(.*\n? *)@permite ir hacia la derecha o hacia abajo), y s/@( *\n?.*)A/A$1 /cuando Aestá en el lado derecho ( @( *\n?.*)Apermite subir o hacia la izquierda). s/@/A/reemplaza el primero @con a A(esa es la inicialización). Como siempre tenemos un Aen la cadena, debemos reemplazarlo con un espacio al imprimirlo, eso es lo que y/A/ /rhace.


Solo para los ojos , la versión animada se ve bastante bien: (para ejecutarse en una terminal, es aproximadamente el mismo código pero con cleary 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
¡Esto es genial! Nunca me he divertido tanto viendo un programa animado :)
VarmirGadkin

3

Befunge, 319254 bytes

&: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 motivación para este algoritmo fue tratar de evitar la ramificación tanto como sea posible, ya que una sola ruta de ejecución es generalmente más fácil de jugar al golf. Por lo tanto, el código se compone de solo dos bucles: el bucle externo que itera sobre los fotogramas del proceso de pelado y el bucle interno que representa la patata para cada fotograma.

El bucle de representación esencialmente solo genera una secuencia de caracteres, el carácter para cada iteración está determinado por una fórmula bastante complicada que toma el número de fotograma del proceso de pelado y el índice de la secuencia de salida y devuelve un @, un espacio o un nueva línea, según se requiera.

Pruébalo en línea!


1
Wow, esto es hermoso
416E64726577

2

Python 3.5.1, 520 bytes

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

Explicación

Idea básica: alternar entre iterar hacia abajo en cada línea y eliminar el carácter más a la izquierda e iterar hacia arriba cada línea eliminando el carácter más a la derecha mientras todavía @ s.

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

En general, un intento triste de un procedimiento sencillo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.