Crea un semplice strumento per commentare


14

Sfida:

Alcuni ascii-art sono una seccatura da fare, ma facilitano la lettura dei commenti sul codice, specialmente quando il codice è denso. La sfida è quella di creare un semplice strumento che converta i commenti in semplici arte ascii con le frecce. I commenti da modificare sono delimitati da commenti vuoti.

Ad esempio, supponendo che la sintassi dei commenti di Haskell, converta questo:

--
-- Here's a thing
-- Here's another thing
-- The most important thing
-- *    *     *
--
f x=x+1*x*1*1*0

A questo:

-- /------------< Here's a thing
-- |    /-------< Here's another thing
-- |    |     /-< The most important thing
-- |    |     |
-- v    v     v
f x=x+1*x*1*1*0

Regole:

  • La tua risposta può essere una funzione o un programma completo
  • Puoi scegliere la lingua con cui è fatto funzionare, sostituendo il "-" con due o più caratteri che delimitano un commento in una lingua
  • Se si utilizza un altro formato di commento che richiede delimitatori di inizio e fine, ogni riga delle sezioni riformattate deve essere un commento appropriato
  • Le sezioni da riformattare sono delimitate dal commento vuoto "\ n - \ n"
  • Oltre ad aggiungere nuove righe, il programma non deve modificare alcun input tranne le sezioni delimitate
  • Un commento riempito con un numero arbitrario di spazi può venire immediatamente prima di una sezione di output correttamente formattata
  • Le scappatoie standard non sono ammesse

Esempi aggiuntivi:

(input)
--
--
(output)
nothing


(input)
[Code Here]
--
-- important
--    *
--
(output)
[Code Here]
--    /-< important
--    |
--    v


(input)
--
-- Do
-- Re
-- Mi
-- Fa
-- So
-- *****
--
(output)
-- /-----< Do
-- |/----< Re
-- ||/---< Mi
-- |||/--< Fa
-- ||||/-< So
-- |||||
-- vvvvv

punteggio:

  • Vince il minor numero di byte
  • Non verranno presi in considerazione invii senza spiegazioni o esempi non banali di input / output (anche se lascerò un periodo di tolleranza per consentire il tempo di aggiungerli)

2
Cosa succede se è necessario un solo carattere per delimitare un commento?
Adám,

Finché è un commento valido nella lingua, va bene
Michael Klein,

Possiamo presumere che ogni sezione di commento soggetta a riformattazione conterrà esattamente una linea di asterischi di indicatore di posizione, giusto? Quella linea sarà sempre l'ultima?
arte

Sì, esattamente uno e sempre l'ultimo (commento prima del delimitatore di fine)
Michael Klein,

E la quantità di asterischi sarà uguale al numero di righe precedenti in quella sezione, giusto?
arte

Risposte:


4

Rubino, 160 caratteri

->c{c.gsub(/^--$(.+?)^--$/m){*t,a=$&.lines[1..-2]
a&&a.chop!&&(t.map{|l|a[?*]=?/
l[0,2]=a.gsub(/(?<=\/).*/){?-*$&.size}+'-<'
a[?/]=?|
l}<<a+$/+a.tr(?|,?v))*''}}

Esecuzione di esempio:

2.1.5 :001 > puts ->c{c.gsub(/^--$(.+?)^--$/m){*t,a=$&.lines[1..-2];a&&a.chop!&&(t.map{|l|a[?*]=?/;l[0,2]=a.gsub(/(?<=\/).*/){?-*$&.size}+'-<';a[?/]=?|;l}<<a+$/+a.tr(?|,?v))*''}}["
2.1.5 :002"> --
2.1.5 :003"> -- Here's a thing
2.1.5 :004"> -- Here's another thing
2.1.5 :005"> -- The most important thing
2.1.5 :006"> -- *    *     *
2.1.5 :007"> --
2.1.5 :008"> f x=x+1*x*1*1*0
2.1.5 :009"> "]

-- /------------< Here's a thing
-- |    /-------< Here's another thing
-- |    |     /-< The most important thing
-- |    |     |
-- v    v     v
f x=x+1*x*1*1*0
 => nil 

Breve descrizione:

.lines splits the section to array items ─────────╮
                                                  ▽

.gsub extracts ⎧   --                             0         
these sections ⎪   -- Here's a thing              1   t[0]   
for processing ⎨   -- Here's another thing        2   t[1]   
and replaces   ⎪   -- The most important thing    ⋮   t[2]   
them with the  ⎪   -- *    *     *               -2   a      
pretty version ⎩   --                            -1          
rest untouched —   f x=x+1*x*1*1*0
                                                      △
only the needed lines get into variables ─────────────╯



a = "-- *    *     *" + "-<"           inside .gsub's block
        ↓↓                             the first 2 characters
t[0] = "-- Here's a thing"             of t's each item are
t[1] = "-- Here's another thing"       replaced with a's value
t[2] = "-- The most important thing"   and the the separator



not only t's items are transformed inside .gsub's block,
but a's value also gets changed in multiple small steps

                       change a's value    change the value    change a's value
   a's initial value   before insertion   being inserted now   after insertion
   ╭───────────────╮   ╭───────────────╮   ╭───────────────╮   ╭───────────────╮

0  "-- *    *     *" → "-- /    *     *" → "-- /-----------" → "-- |    *     *"
1  "-- |    *     *" → "-- |    /     *" → "-- |    /------" → "-- |    |     *"
2  "-- |    |     *" → "-- |    |     /" → "-- |    |     /" → "-- |    |     |"

                       ╰───────────────╯   ╰───────────────╯   ╰───────────────╯
                      change first * to /  change everything  change first / to |
                                          after / with string
                                          of - of same length

5

JavaScript (ES6), 418 , 237 , 233 , 236 byte

f=(s)=>(d='\n//',s.split(d+'\n').map((x,y)=>y%2?'//'+(l=x.slice(2).split(d),t=l.pop().split('*'),l.map((i,j)=>t.map((k,m)=>m==j?k+'/':m<j?k+'|':k.replace(/ /g,'-')+'-').join('')+'<'+i).join(d)+d+t.join('|')+d+t.join('v')):x).join('\n'))

Accidenti, questa è la mia prima presentazione su CG. Ho preso, credo, una virata totalmente diversa da Washington Guedes. Finito 54 byte in meno rispetto al suo primo passaggio. Minimizzare tutto questo a mano era estenuante. Il mio unico rimpianto è di non essere ancora riuscito a eliminare il ciclo while, il che mi permetterebbe anche di tagliare il ritorno.

Riscrittura totale, prendendo parzialmente ispirazione da un paio di altre risposte. Devo chiudere tutto nelle mappe, rendendo il ritorno molto migliore. Lo snippet di codice contiene la versione commentata.

Si tolse qualche altro byte e fece funzionare l'esempio su se stesso. (Avrai bisogno di un monitor più grande.) :)

Hai dimenticato un'intera lettera nelle specifiche! Fortunatamente, l'aggiunta del principale "<" è stata una piccola, banale soluzione.


3

Python 2, 299 byte

Si aspetta una nuova riga finale nell'input

i=input().split('--\n')
a=0
for j in i:
 a+=1
 if a%2:print j,;continue
 if''==j:continue
 l=j.split('\n');n=l[-2];r=l[:-2];R=[n.replace('*','v'),n.replace('*','|')];L=R[1]
 for x in range(len(l)-2)[::-1]:L=L[:L.rfind('|')]+'/';R+=[L.ljust(n.rfind('*')+2,'-')+'< '+r[x][3:]]
 print'\n'.join(R[::-1])

Spiegazione / Esempio

Ingresso:

[Code Here]
--
-- important
--    *
--

Divide l'input per --\n. Ogni seconda stringa è un blocco di commenti delimitato.

['[Code Here]\n',
'-- important\n-- stuff\n--    *  *\n',
'']

Esegue ogni stringa. Se la stringa non è un commento, stampa semplicemente la stringa. Altrimenti:

Divide ogni riga nel blocco dei commenti.

['-- important', '-- stuff', '--    *  *', '']

Crea le due righe inferiori sostituendo le linee di *s con ve |.

['--    v  v', '--    |  |']

Per ogni riga di commenti (all'indietro) rimuovere la colonna più a destra, aggiungere /, riempire -e aggiungere commenti.

'--    |  /'
'--    /'
'--    /----< important'

Stampa tutto

--    /----< important
--    |  /-< stuff
--    |  |
--    v  v

Meno golf:

i=input().split('--\n')
a=0
for j in i:
 a+=1
 if a%2:print j,;continue # Not commment
 if''==j:continue # Empty comment
 l=j.split('\n') # Split comment into lines
 r=l[:-2]
 # Replace line of *s with v and | respectively
 R=[l[-2].replace('*','v'),l[-2].replace('*','|')]
 L=R[1][3:] # line of |
 for x in range(len(l)-2)[::-1]: # For each comment line
  L=L[:L.rfind('|')]+'/' #Remove rightmost column
  # Add a line with '-- ',columns, and comment
  R+=['-- '+L.ljust(n.rfind('*')-1,'-')+'< '+r[x][3:]]
 print'\n'.join(R[::-1]) #Print all comment lines

1

JavaScript (ES6), 253

Come funzione anonima, con il codice da formattare come parametro stringa e restituire il codice formattato.

Appunti

  1. La coppia di commenti marker deve racchiudere il testo giusto (righe di commento, quindi stelle)
  2. ... o la coppia non deve racchiudere nulla (esempio aggiuntivo 1)
t=>(t=t.split`
`,t.map((r,i)=>r=='--'?(c++&&l.map((r,j)=>(p+=q[j],z+=~q[j].length,t[i-n+j]=p+`/${'-'.repeat(z+1)}<`+r.slice(3),p+=`|`),q=l.pop(c=p=``)||p,z=q.length,q=q.split`*`,t[i]=p+q.join`v`,t[i-1]=p+q.join`|`),l=[]):n=l.push(r),c=0,l=[]),t.join`
`)

Meno golf

f=t=>{
  t = t.split`\n`; // string to array of lines
  l = []; // special coment text
  c = 0; // counter of marker comment '--'
  t.forEach((r,i)=>{ // for each line of t - r: current line, i: index
    if (r == '--') // if marker comment
    {
       ++ c; // increment marker counter
       if (c > 1) // this is a closing marker
       {
          c = 0; // reset marker counter
          if (n > 0) // n is the length of array l
             q = l.pop(); // get last line from l, have to be the star line
          else
             q = ''; // no text comment, no star line 
          p = '';  // prefix for drawing the tree
          z = q.length; // length of star line, used to draw the tree horiz lines
          q = q.split('*'); // split to get star count and position
          // each element in q is the spaces between stars
          // modifiy the current and previous text line 
          t[i] = p + q.join`v`; // current row was '--', becomes the V line
          t[i-1] = p + q.join`|`; // previous row was the star line, becomes the last tree line
          l.forEach((r,j)=>{ // for each line in l, r: current line, j: index
             // each line in tree is: prefix("-- |  |"...) + ... "---< " + text
             p = p + q[j]; // adjust prefix
             z = z - q[j].length - 1 // adjust length of '---'
             // modify text in t
             t[i-n+j] = p // prefix
                + '/' + '-'.repeat(z+1) + '<'  // horiz line and <
                + r.slice(3); // text, removed '-- '
             p = p + '|'; // add vertical bar to prefix
          });
       } // end if closing comment
       l = []; // reset l
    }  
    else // not a special comment marker
       n = l.push(r) // add current line to l, set n to array size
  });
  return t.join`\n` // join to a single string
}

Test


Mi manca il secondo blocco di commenti su Chrome 47 senza errori. Inoltre, merda, non avevo visto prima che potresti usare qualsiasi sintassi di commento con qualsiasi lingua .
Emmett R.

Sì, hai ragione. @EmmettR. Grazie. Proverò a risolverlo
edc65,
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.