Analyser les commentaires de mon code ésotérique

30

Plus tôt cette semaine, nous avons appris comment formater des langues ésotériques pour commenter. Aujourd'hui, nous allons faire l'inverse de cela. J'ai besoin que vous écriviez un programme ou une fonction qui analyse un code ésotérique bien commenté et analyse les commentaires, en ne renvoyant que le code. En utilisant quelques exemples du défi précédent, voici à quoi ressemble un code bien commenté:

a                #Explanation of what 'a' does
 bc              #Bc
   d             #d
    e            #Explanation of e
     fgh         #foobar
        ij       #hello world
          k      #etc.
           l     #so on
            mn   #and
              op #so forth

Voici ce que vous devez faire pour extraire le code. Tout d'abord, supprimez le caractère de commentaire ( #), l'espace avant celui-ci et tout ce qui se trouve après le caractère de commentaire.

a               
 bc             
   d            
    e           
     fgh        
        ij      
          k     
           l    
            mn  
              op

Ensuite, réduisez chaque ligne vers le haut en une seule ligne. Par exemple, comme il se btrouve dans la deuxième colonne de la ligne deux, une fois que nous l'avons réduit, il se trouvera dans la deuxième colonne de la ligne un . De même, csera placé dans la troisième colonne de la première ligne, et dsera placé sur la quatrième. Répétez cela pour chaque personnage et vous obtenez ceci:

abcdefghijklmnop

Remarque importante: il semble que la solution triviale consiste simplement à supprimer les commentaires, à supprimer tous les espaces et à joindre chaque ligne. Ce n'est pas une approche valable! Étant donné que le code d'origine peut contenir des espaces, ceux-ci seront supprimés avec cette approche. Par exemple, ceci est une entrée parfaitement valide:

hello         #Line one
              #Line two
       world! #Line three

Et la sortie correspondante devrait être:

hello  world!

Le défi:

Écrivez un programme ou une fonction qui prend le code commenté en entrée et génère ou renvoie le code avec tous les commentaires analysés. Vous devez sortir le code sans aucun espace de fin, bien qu'une nouvelle ligne de fin soit autorisée. Le caractère de commentaire sera toujours #, et il y aura toujours un espace supplémentaire avant le début des commentaires. #ne pas apparaître dans la section des commentaires de l'entrée. Afin de simplifier le défi, voici quelques entrées que vous n'avez pas à gérer:

  • Vous pouvez supposer que le code n'aura pas deux caractères dans la même colonne. Par exemple, il s'agit d'une entrée qui viole cette règle:

    a  #A character in column one
    bc #Characters in columns one and two
    
  • Vous pouvez également supposer que tous les caractères de commentaire apparaissent dans la même colonne. Par exemple, cette entrée:

    short       #this is a short line
          long        #This is a long line
    

    viole cette règle. Cela signifie également que #ne sera pas dans la section de code.

  • Et enfin, vous n'avez pas à gérer les sections de code avec des espaces de début ou de fin. Par exemple,

      Hello,          #
             World!   #
    

Vous pouvez également supposer que l'entrée ne contient que des caractères ASCII imprimables.

Exemples:

Input:
hello         #Line one
              #Line two
       world! #Line three

Output:
hello  world!

Input:
E                                                   #This comment intentionally left blank
 ac                                                 #
   h s                                              #
      ecti                                          #
          on is                                     #
                one c                               #
                     haracte                        #
                            r longer                #
                                     than the       #
                                              last! #

Output:
Each section is one character longer than the last!

Input:
4          #This number is 7
 8         #
  15       #That last comment is wrong.
    16     #
      23   #
        42 #

Output:
4815162342

Input:
Hello                     #Comment 1
      world               #Comment 2
           ,              #Comment 3
             how          #Comment 4
                 are      #Comment 5
                     you? #Comment 6

Output:
Hello world, how are you?

Input:
Prepare                               #
        for...                        #
                        extra spaces! #

Output:
Prepare for...          extra spaces!

Vous pouvez prendre des entrées dans le format raisonnable que vous aimez, par exemple, une liste de chaînes, une seule chaîne avec des retours à la ligne, une liste de caractères 2D, etc. La réponse la plus courte en octets gagne!

DJMcMayhem
la source
Aurons-nous besoin d'accepter du code avec des caractères inférieurs au suivant?
wizzwizz4
Pourriez-vous ajouter le cas de test avec la ligne vide avec seulement deux espaces (comme celui que hello world!vous avez montré)? En outre, vous déclarez: " #n'apparaîtra pas dans la section commentaire de l'entrée. ", Mais peut-il se produire dans l'extrait de code lui-même?
Kevin Cruijssen
@KevinCruijssen Voir mes modifications
DJMcMayhem
@ wizzwizz4 Je ne sais pas si je comprends votre question
DJMcMayhem
@DJMcMayhem Exemple: do {stuff} while (condition);avec l'explication dans l'ordre do while (condition); #Explainythingalors {stuff} #Explainything.
wizzwizz4

Réponses:

18

Gelée , 8 7 octets

»/ṣ”#ḢṖ

Essayez-le en ligne!

Comment ça marche

»/ṣ”#ḢṖ  Main link. Argument: A (array of strings)

»/       Reduce the columns of A by maximum.
         Since the space is the lowest printable ASCII characters, this returns the
         non-space character (if any) of each column.
  ṣ”#    Split the result at occurrences of '#'.
     Ḣ   Head; extract the first chunk, i.e., everything before the (first) '#'.
      Ṗ  Pop; remove the trailing space.
Dennis
la source
2
C'est juste ... wow.
Jonathan Allan
3
Je suis tellement gelée en ce moment.
MonkeyZeus
Comment pouvez-vous même pirater cela sur votre téléphone?
simbabque
2
@simbabque Patience et beaucoup de copier-coller.
Dennis
Je mets toujours à l'aide d'un fer à repasser 9, il est peut-être temps que j'apprenne à utiliser un putter sur le green ...
Urne Magic Octopus
13

Python 2, 48 43 octets

lambda x:`map(max,*x)`[2::5].split(' #')[0]

Merci à @xnor d'avoir joué 5 octets au golf!

Testez-le sur Ideone .

Dennis
la source
1
Je pense que vous pouvez le faire map(max,*x)parce que maxprend un certain nombre d'arguments et Noneest petit.
xnor
Bon, j'oublie toujours que ça mappeut être utilisé comme ça ... Merci!
Dennis
1
Comment fonctionne l' `...`[2::5]astuce?
smls
1
@smls `...`est équivalent à repr(...), donc pour la liste des chaînes singleton ['a', 'b', 'c'], vous obtenez la chaîne "['a', 'b', 'c']". Enfin, [2::5]coupe les deux premiers caractères ( "['") et prend chaque cinquième caractère de la chaîne restante.
Dennis
5

JavaScript (ES6), 97 75 60 octets

Merci à @Neil d' avoir aidé le golf sur 22 octets

a=>a.reduce((p,c)=>p.replace(/ /g,(m,o)=>c[o])).split` #`[0]

L'entrée est un tableau de lignes.

  • a est une entrée de tableau
  • p est l'élément précédent
  • c est l'élément actuel
  • m est une chaîne de correspondance
  • o est décalé
ASCII uniquement
la source
Je compte 96 octets? En outre, l' mindicateur regexp n'est pas nécessaire (en aviez-vous un $à un moment donné), tout comme l'espace (p, c). Enfin, je pense que replacecela fonctionnera plus court que [...p].map().join.
Neil
97 pour moi, à la fois du manuel lengthet du script utilisateur, peut-être que vous n'avez pas compté la nouvelle ligne, mais uniquement parce que j'ai accidentellement inclus le point
ASCII uniquement
Je vois maintenant - je n'avais pas copié ce ;qui n'est pas requis (JavaScript a ASI).
Neil
Oui, désolé, je l'ai eu pour m'assurer que la console Chromium place l'appel de fonction en dehors du corps de la fonction (l'a eu une fois sur un lambda mal écrit)
ASCII uniquement le
Oh wow, je ne savais pas que replaceça aiderait tellement, c'est vraiment bien!
Neil
4

Perl, 35 34 32 octets

Comprend +1 pour -p

Donnez votre avis sur STDIN

eso.pl

#!/usr/bin/perl -p
y/ /\0/;/.#/;$\|=$`}{$\=~y;\0; 

Notez qu'il y a un espace après la finale ;. Le code fonctionne comme indiqué, mais remplacez-le \0par le caractère littéral pour obtenir le score revendiqué.

Ton Hospel
la source
Très beau code. C'est $a|=...plutôt bien fait, il m'a fallu un certain temps pour comprendre ce que vous faisiez! Une question cependant: *_=asemble être à peu près équivalente à $_=$a, pourquoi est-ce?
Dada
*_=aest une affectation de glob très obscure qui alias les _globaux et les aglobaux. Ce n'est donc pas tellement une copie de $aà $_mais à partir de là (global) $aet ce $_sont en fait la même variable. Tout pour économiser 1 octet ...
Ton Hospel
Ok, merci pour l'explication! (et belle amélioration grâce à `$ \`)
Dada
3

Python 2, 187 octets

def f(x,o=""):
 l=[i[:i.index("#")-1]for i in x]
 for n in range(len(l[0])):
  c=[x[n]for x in l]
  if sum([1for x in c if x!=" "])<1:o+=" "
  else:o+=[x for x in c if x!=" "][0]
 print o

Je vais jouer au golf plus demain, j'ai l'école;)

Daniel
la source
1 forpeut être réduit à 1for. De plus, si la somme de la liste (à la ligne 5) ne peut pas être négative, vous pouvez simplement vérifier au <1lieu de ==0. Bonne journée d'école! : D +1.
Yytsi
2

Rubis, 63 octets

Fondamentalement, un port de la réponse de Dennis 'Jelly . Prend l'entrée comme un tableau de chaînes.

->a{l,=a
l.gsub(/./){a.map{|m|m[$`.size]||$/}.max}[/(.+) #/,1]}

Voir sur eval.in: https://eval.in/640757

Jordan
la source
2

CJam , 12 octets

Merci à Sp3000 pour avoir économisé 2 octets.

{:.e>_'##(<}

Un bloc sans nom qui prend une liste de chaînes (une pour chaque ligne) et la remplace par une seule chaîne.

Essayez-le en ligne!

Explication

:.e>  e# Reduce the list of strings by elementwise maximum. This keeps non-spaces in
      e# favour of spaces. It'll also wreak havoc with the comments, but we'll discard
      e# those anyway.
_'##  e# Duplicate and find the index of '#'.
(<    e# Decrement that index and truncate the string to this length.
Martin Ender
la source
2

J, 30 octets

(#~[:<./\'#'~:])@(>./&.(3&u:))

Prend une liste de chaînes en entrée. Utilise essentiellement la même approche que Dennis dans sa réponse Jelly.

Commenté et expliqué

ord =: 3 & u:
under =: &.
max =: >./
over =: @
maxes =: max under ord
neq =: ~:
arg =: ]
runningMin =: <./\
magic =: #~ [: runningMin ('#' neq arg)

f =: magic over maxes

Étapes intermédiaires:

   p
Hello                     #Comment 1
      world               #Comment 2
           ,              #Comment 3
             how          #Comment 4
                 are      #Comment 5
                     you? #Comment 6
   maxes p
Hello world, how are you? #Comment 6
   magic
#~ ([: runningMin '#' neq arg)
   3 neq 4
1
   '#' neq '~'
1
   '#' neq '#'
0
   '#' neq maxes p
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1
   runningMin 5 4 2 5 9 0 _3 4 _10
5 4 2 2 2 0 _3 _3 _10
   runningMin '#' neq maxes p
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
   0 1 0 1 1 0 # 'abcdef'
bde
   'abcdef' #~ 0 1 0 1 1 0
bde
   (maxes p) #~ runningMin '#' neq maxes p
Hello world, how are you? 
   (#~ [: runningMin '#' neq arg) maxes p
Hello world, how are you? 
   ((#~ [: runningMin '#' neq arg) over maxes) p
Hello world, how are you? 
   (magic over maxes) p
Hello world, how are you? 

Cas de test

   f =: (#~[:<./\'#'~:])@(>./&.(3&u:))
   a
Hello                     #Comment 1
      world               #Comment 2
           ,              #Comment 3
             how          #Comment 4
                 are      #Comment 5
                     you? #Comment 6
   $a
6 36
   f a
Hello world, how are you?
Conor O'Brien
la source
2

Javascript (ES6), 63 octets

a=>a.reduce((p,c)=>p+/(.+?)\s+#/.exec(c)[1].slice(p.length),'')

Prend l'entrée comme un tableau de chaînes.

F=a=>a.reduce((p,c)=>p+/(.+?)\s+#/.exec(c)[1].slice(p.length),'')

input.oninput = update;
update();

function update() {
  try {
    output.innerHTML = F(input.value.trim().split`
`);
  } catch(e) {
    output.innerHTML = 'ERROR: INVALID INPUT';
  }
}
textarea {
  width: 100%;
  box-sizing: border-box;
  font-family: monospace;
}
<h2>Input:</h2>
<textarea id="input" rows="8">
a                #Explanation of what 'a' does
 bc              #Bc
   d             #d
    e            #Explanation of e
     fgh         #foobar
        ij       #hello world
          k      #etc.
           l     #so on
            mn   #and
              op #so forth
</textarea>
<hr />
<h2>Output:</h2>
<pre id="output">
</pre>

George Reith
la source
1

Rétine , 32 octets

Le nombre d'octets suppose un codage ISO 8859-1.

Rmr` #.+|(?<=^(?<-1>.)+).+?¶( )+

Essayez-le en ligne!

Martin Ender
la source
1

Pyke, 15 10 octets

,FSe)s\#ch

Essayez-le ici!

Réponse de Port of the Jelly

,          -     transpose()
 FSe)      -    map(min, ^)
     s     -   sum(^)
      \#c  -  ^.split("#")
         h - ^[0]
Bleu
la source
1

C # 157 122 octets

Golfé 35 octets grâce à @milk - même si je le jure, j'ai essayé ça plus tôt.

Prend l'entrée comme un tableau 2D de caractères.

string f(char[][]s){int i=0;foreach(var x in s)for(i=0;x[i]!=35;i++)if(x[i]!=32)s[0][i]=x[i];return new string(s[0],0,i);}

157 octets:

string g(char[][]s){var o=new char[s[0].Length];foreach(var x in s)for(int i=0;x[i]!=35;i++)if(x[i]!=32|o[i]<1)o[i]=x[i];return new string(o).TrimEnd('\0');}
pinkfloydx33
la source
Ne devrait pas Trim()fonctionner à la place de TrimEnd()? Encore mieux, je pense que vous pouvez économiser beaucoup d'octets en utilisant s [0] comme var de sortie et en utilisant return new string(s[0],0,i)iest l'index du dernier caractère de code. Cette idée peut nécessiter deux forboucles au lieu de la foreach, j'y penserai davantage et j'essaierai d'écrire du code réel plus tard dans la journée.
lait
Trim()sera également coupé dès le début, ce qui, je crois, ne serait pas valable. Je faisais également à l'origine le chargement dans s [0] et j'avais un int en i;dehors de la boucle (pour le réutiliser dans le retour) qui, je crois, a finalement ajouté des octets
pinkfloydx33
1

Pyth, 11 octets

PhceCSMCQ\#

Un programme qui prend l'entrée d'une liste de chaînes sur STDIN et imprime une chaîne.

Essayez-le en ligne

Comment ça marche

PhceCSMCQ\#  Program. Input: Q
       CQ    Transpose Q
     SM      Sort each element of that lexicographically
    C        Transpose that
   e         Yield the last element of that, giving the program ending with ' #' and some
             parts of the comments
  c      \#  Split that on the character '#'
 h           Yield the first element of that, giving the program with a trailing space
P            All but the last element of that, removing the trailing space
             Implicitly print
TheBikingViking
la source
1

sed, 126 octets

:a;N;$!ba;s,#[^\n]*\n,#,g;s,^,#,;:;/#[^ ]/{/^# /s,^# *,,;t;H;s,#.,#,g}
t;/#[^ ]/!{H;s,#.,#,g};t;g;s,\n#(.)[^\n]*,\1,g;s,...$,,

Nécessite une nouvelle ligne à la fin de l'entrée.
Je suis sûr que je peux jouer au golf un peu plus, mais je suis juste heureux que cela fonctionne pour l'instant.

Riley
la source
0

Gelée , 27 octets

żḟ€” ;€” Ḣ€
i€”#’©ḣ@"ç/ḣ®ṪṖ

Testez-le sur TryItOnline

Utilise la spécification la plus stricte - l'espace supplémentaire avant que le caractère de commentaire ne soit supprimé au prix d'un octet.

L'entrée est une liste de chaînes.

Jonathan Allan
la source
@Erik le golfeur - peut-être bien, mais avez-vous vu l'écrasement qu'il m'a donné ici ?
Jonathan Allan
0

Rubis, 77 octets

puts File.readlines("stack.txt").join('').gsub(/\s{1}#.*\n/,'').gsub(/\s/,'')
Expéditeur
la source
Le codage en dur d'un nom de fichier d'entrée n'est pas une méthode d'entrée acceptable.
Mego
@Mego, où puis-je trouver les règles de ce qui est "acceptable"?
Renvoi le
0

TSQL, 216 175 octets

Golfé:

DECLARE @ varchar(max)=
'hello         #Line one
              #Line two
       world! #Line three'

DECLARE @i INT=1,@j INT=0WHILE @i<LEN(@)SELECT @=stuff(@,@j+1,len(x),x),@j=iif(x=char(10),0,@j+1),@i+=1FROM(SELECT ltrim(substring(@,@i,1))x)x PRINT LEFT(@,patindex('%_#%',@))

Non golfé:

DECLARE @ varchar(max)=
'hello         #Line one
              #Line two
       world! #Line three'

DECLARE @i INT=1,@j INT=0
WHILE @i<LEN(@)
  SELECT @=stuff(@,@j+1,len(x),x),@j=iif(x=char(10),0,@j+1),@i+=1
  FROM(SELECT ltrim(substring(@,@i,1))x)x
PRINT LEFT(@,patindex('%_#%',@))

Violon

t-clausen.dk
la source
0

Javascript, 56 34 octets, non concurrent

q=>q.split(/\n/).map(x=>/ (.?) #./.exec(x)[1]).join()

q=>q.replace(/^ *| *#.*$\n?/gm,'')

Comme l'a souligné @ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳, je ne suis pas prêt pour les espaces supplémentaires

BlackCap
la source
Ne passe pas le cas "Préparez-vous pour des espaces supplémentaires"
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
0

Dyalog APL , 22 octets

L'inspiration .

(⎕UCS¯2↓⍳∘35↑⊢)⌈⌿∘⎕UCS

(

⎕UCS représentation des caractères de

¯2↓ tous sauf les deux derniers

⍳∘35↑ jusqu'à la position des 35 premiers ("#"), dans ce qui est en dehors de la parenthèse, prise de

ce qui est en dehors de la parenthèse

) à savoir...

⌈⌿ les maximums en colonnes

de

⎕UCS les valeurs Unicode

TryAPL en ligne!

Adam
la source
Combien d'octets?
acrolith