Sbucciare la patata


20

Questa è una patata:

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

Più in generale, una patata di taglia N è definita come la seguente forma:

Se N è pari, sono 2 @simboli centrati , seguiti da 4 @simboli centrati , seguiti da 6 @simboli centrati , fino a N @simboli centrati ; quindi, N @simboli centrati , seguiti da N-2 @simboli centrati , fino a 2.
Se N è dispari, una patata di dimensione N viene generata nello stesso modo descritto sopra, ma iniziamo con 1 @simbolo, anziché 2 .

Una patata viene sbucciata iniziando nell'angolo in alto a destra e rimuovendo un @segno ogni passo, andando in senso antiorario. Ad esempio, sbucciare una patata di taglia 3 si presenta così:

 @
@@@
@@@
 @

​
@@@
@@@
 @

 ​
 @@
@@@
 @

  ​
 @@
 @@
 @

 ​
 @@
 @@
 ​

 ​
 @@
 @
 ​

​
 @
 @
 ​

 ​
​
 @
 ​


Sfida

Scrivi un programma che, dato un input intero, mostri tutti i passaggi per sbucciare una patata di quella dimensione.
Sono consentiti spazi vuoti / newline finali.

punteggio

Questo è ; vince il codice più breve in byte.


Esempi di casi di test

N = 2

@@
@@

@
@@


@@


 @



N = 7

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


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


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


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


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


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


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


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


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



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



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



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



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



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



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




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




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




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




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




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




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





   @@  
  @@@@ 
  @@@@ 
   @   





   @@  
  @@@@ 
  @@@  
   @   





   @@  
  @@@  
  @@@  
   @   





   @   
  @@@  
  @@@  
   @   






  @@@  
  @@@  
   @   






   @@  
  @@@  
   @   






   @@  
   @@  
   @   






   @@  
   @@  







   @@  
   @   







   @   
   @   








   @   
 ​
 ​
 ​
 ​  


Catalogare

Basato su Questo numero è un numero primo?


5
Benvenuti in PPCG! Bella prima domanda, comunque.
clismique,

1
Sono ammessi spazi vuoti / newline finali?
Loovjo,

1
Non ho le capacità di Retina ma sarei interessato a vederlo - se è possibile.
Jerry Jeremiah,

@JamesHolderness Grazie! L'ho risolto.
VarmirGadkin,

Risposte:


5

Perl, 129 byte

128 byte di codice + -nflag.

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

Avrai bisogno di -nEflag per eseguirlo:

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

Spiegazioni: (Li descriverò più dettagliatamente quando avrò un momento)
La prima parte, $p=($r=$"x$n++."@"x$_.$/).$p.$r,$_-=2while$_>0;genera la patata iniziale: inizia dalla linea mediana della patata e aggiunge due righe ad ogni iterazione: una prima della stringa precedente, una dopo. Si noti che $"è uno spazio e, poiché $nnon è inizializzato, inizia da 0 ed $/è una nuova riga.

Nota molto su say$_=$p;ciò che stampa la patata iniziale mentre la riponi $_(che sarà più facile da manipolare in seguito).

Infine, say y/A/ /r while s/(^| )A(.*\n? *)@/$1 $2A/m||s/@( *\n?.*)A/A$1 /||s/@/A/sbuccia la patata. L'ultima posizione in cui una è @stata rimossa contiene una A(è arbitraria, potrebbe essere qualsiasi simbolo). Quindi ogni iterazione consiste nel trovare il A, sostituendolo con uno spazio e nel frattempo sostituire il successivo @con un A. Questo è fatto grazie a due regex: s/(^| )A(.*\n? *)@/$1 $2A/mquando si Atrova sul lato sinistro della patata ( A(.*\n? *)@consente di andare a destra o in basso) e s/@( *\n?.*)A/A$1 /quando Aè sul lato destro ( @( *\n?.*)Aconsente di salire o a sinistra). s/@/A/sostituisce il primo @con un A(questa è l'inizializzazione). Dato che abbiamo sempre un Anella stringa, dobbiamo sostituirlo con uno spazio quando lo stampiamo, ecco cosa y/A/ /rfa.


Solo per gli occhi , la versione animata sembra abbastanza carina: (per funzionare in un terminale, è approssimativamente lo stesso codice ma con cleare 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
Questo è fantastico! Non mi sono mai divertito così tanto a guardare un programma animato :)
VarmirGadkin l'

3

Befunge, 319 254 byte

&: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 motivazione di questo algoritmo è stata quella di cercare di evitare il più possibile la ramificazione, poiché un singolo percorso di esecuzione è generalmente più facile da giocare a golf. Il codice è quindi composto da solo due loop: il loop esterno che scorre sui frame del processo di peeling e il loop interno che rende la patata per ciascun frame.

Il ciclo di rendering essenzialmente sta semplicemente emettendo una sequenza di caratteri, il carattere per ogni iterazione è determinato da una formula piuttosto complicata che prende il numero di frame del processo di peeling e l'indice della sequenza di output e restituisce un @, uno spazio o un newline, come richiesto.

Provalo online!


1
Caspita, è bellissimo.
416E64726577,

2

Python 3.5.1, 520 byte

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

Spiegazione

Idea di base: alternare tra l'iterazione in basso di ogni riga e la rimozione del carattere più a sinistra e l'iterazione di ogni riga in ordine di rimozione del carattere più a destra mentre sono ancora @rimasti.

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

Nel complesso, un triste tentativo di una procedura semplice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.