Analizar los comentarios de mi código esotérico

30

A principios de esta semana, aprendimos sobre cómo formatear idiomas esotéricos para comentar. Hoy vamos a hacer lo contrario de eso. Necesito que escriba un programa o función que analice un código esotérico bien comentado y analice los comentarios, devolviendo solo el código. Usando algunos ejemplos del desafío anterior, así es como se ve el código bien comentado:

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

Esto es lo que debe hacer para extraer el código. Primero, elimine el carácter de comentario ( #), el espacio antes y todo después del carácter de comentario.

a               
 bc             
   d            
    e           
     fgh        
        ij      
          k     
           l    
            mn  
              op

Luego, contraiga cada línea hacia arriba en una sola línea. Por ejemplo, dado que bestá en la segunda columna de la línea dos, una vez que la colapsamos, estará en la segunda columna de la línea uno . Del mismo modo, cse colocará en la tercera columna de la línea uno, y dse colocará en la cuarta. Repita esto para cada personaje, y obtendrá esto:

abcdefghijklmnop

Nota importante: Parece que la solución trivial es simplemente eliminar los comentarios, eliminar todos los espacios y unir cada línea. ¡Este no es un enfoque válido! Debido a que el código original puede tener espacios, estos se eliminarán con este enfoque. Por ejemplo, esta es una entrada perfectamente válida:

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

Y la salida correspondiente debe ser:

hello  world!

El reto:

Escriba un programa o función que tome el código comentado como entrada, y envíe o devuelva el código con todos los comentarios analizados. Debe generar el código sin espacios finales, aunque se permite una nueva línea final. El carácter del comentario siempre será #, y siempre habrá un espacio adicional antes de que comiencen los comentarios. #será no aparecerá en la sección de comentarios de la entrada. Para simplificar el desafío, aquí hay algunas entradas que no tiene que manejar:

  • Puede suponer que el código no tendrá dos caracteres en la misma columna. Por ejemplo, esta es una entrada que viola esta regla:

    a  #A character in column one
    bc #Characters in columns one and two
    
  • También puede suponer que todos los caracteres de comentario aparecen en la misma columna. Por ejemplo, esta entrada:

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

    viola esta regla Esto también significa que #no estará en la sección de código.

  • Y, por último, no tiene que manejar secciones de código con espacios iniciales o finales. Por ejemplo,

      Hello,          #
             World!   #
    

También puede suponer que la entrada solo contiene caracteres ASCII imprimibles.

Ejemplos:

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!

Puede ingresar datos en el formato razonable que desee, por ejemplo, una lista de cadenas, una sola cadena con líneas nuevas, una lista 2d de caracteres, etc. ¡La respuesta más corta en bytes gana!

DJMcMayhem
fuente
¿Tendremos que aceptar código con caracteres más bajos que el siguiente?
wizzwizz4
¿Podría agregar el caso de prueba con la línea vacía con solo dos espacios (como el hello world!que ha mostrado)? Además, dice : " #no aparecerá en la sección de comentarios de la entrada ", pero ¿puede ocurrir en el fragmento de código?
Kevin Cruijssen
@KevinCruijssen Ver mis ediciones
DJMcMayhem
@ wizzwizz4 No estoy seguro si entiendo tu pregunta
DJMcMayhem
@DJMcMayhem Ejemplo: do {stuff} while (condition);con la explicación en orden do while (condition); #Explainythingentonces {stuff} #Explainything.
wizzwizz4

Respuestas:

18

Jalea , 8 7 bytes

»/ṣ”#ḢṖ

Pruébalo en línea!

Cómo funciona

»/ṣ”#ḢṖ  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
fuente
2
Eso es solo ... wow.
Jonathan Allan
3
Estoy tan gelatina en este momento.
MonkeyZeus
¿Cómo puedes hackear eso en tu teléfono?
simbabque
2
@simbabque Paciencia y mucho pegado de copias.
Dennis
Siempre pongo usando un hierro 9, tal vez es hora de que aprenda a usar un putter cuando está en el green ...
Magic Octopus Urn
13

Python 2, 48 43 bytes

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

¡Gracias a @xnor por jugar golf 5 bytes!

Pruébalo en Ideone .

Dennis
fuente
1
Creo que puedes hacerlo map(max,*x)porque maxtoma cualquier número de argumentos y Nonees pequeño.
xnor
Claro, siempre olvido que mapse puede usar así ... ¡Gracias!
Dennis
1
¿Cómo funciona el `...`[2::5]truco?
sonríe el
1
@smls `...`es equivalente a repr(...), por lo que para la lista de cadenas singleton ['a', 'b', 'c'], obtienes la cadena "['a', 'b', 'c']". Finalmente, [2::5]corta los primeros dos caracteres ( "['") y toma cada quinto carácter de la cadena restante.
Dennis
5

JavaScript (ES6), 97 75 60 bytes

Gracias a @Neil por ayudar al golf con 22 bytes

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

La entrada es una matriz de líneas.

  • a es entrada de matriz
  • p es el artículo anterior
  • c es el artículo actual
  • m es una cadena de coincidencias
  • o está compensado
Solo ASCII
fuente
Cuento 96 bytes? Además, el mindicador regexp es innecesario (¿tenía un $en algún momento?) Como es el espacio en (p, c). Finalmente, creo replaceque funcionará más corto que [...p].map().join.
Neil
97 para mí, tanto del manual length script de usuario, tal vez no contó la nueva línea, pero solo porque accidentalmente incluí el punto
solo ASCII
Ahora veo: no había copiado lo ;que no es necesario (JavaScript tiene ASI).
Neil
Sí, lo siento, tuve que asegurarme de que la consola de Chromium coloca la llamada de función fuera del cuerpo de la función (lo tenía una vez en un lambda mal escrito)
solo ASCII
Oh wow, no me di cuenta de replaceque ayudaría mucho, ¡eso es genial!
Neil
4

Perl, 35 34 32 bytes

Incluye +1 para -p

Dar entrada sobre STDIN

eso.pl

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

Tenga en cuenta que hay un espacio después de la final ;. El código funciona como se muestra, pero se reemplaza \0por el carácter literal para obtener la puntuación reclamada.

Ton Hospel
fuente
Muy buen código. Eso $a|=...está bastante bien hecho, ¡me llevó un tiempo descubrir qué estabas haciendo! Sin embargo, una pregunta: *_=aparece ser más o menos equivalente a $_=$a¿por qué?
Dada
*_=aes una asignación glob muy oscura que alias los _globales y los aglobales. Así que no es tanto una copia de $aa $_, pero a partir de ese momento (global) $ay $_son en realidad la misma variable. Todo para ahorrar 1 byte ...
Ton Hospel
Ok, gracias por la explicación! (y buena mejora gracias a `$ \`)
Dada
3

Python 2, 187 bytes

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

Voy a jugar al golf más mañana tengo la escuela;)

Daniel
fuente
1 forse puede reducir a 1for. Además, si la suma de la lista (en la línea 5) no puede ser negativa, puede verificar en <1lugar de ==0. Feliz dia de escuela! : D +1.
Yytsi
2

CJam , 12 bytes

Gracias a Sp3000 por guardar 2 bytes.

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

Un bloque sin nombre que toma una lista de cadenas (una para cada línea) y la reemplaza con una sola cadena.

Pruébalo en línea!

Explicación

:.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
fuente
2

J, 30 bytes

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

Toma una lista de cadenas como entrada. Básicamente usa el mismo enfoque que Dennis en su respuesta de Jelly.

Comentó y explicó

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

f =: magic over maxes

Pasos intermedios:

   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? 

Caso de prueba

   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
fuente
2

Javascript (ES6), 63 bytes

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

Toma la entrada como una matriz de cadenas.

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
fuente
1

Pyke, 15 10 bytes

,FSe)s\#ch

Pruébalo aquí!

Puerto de la jalea respuesta

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

C # 157 122 Bytes

Golfé 35 bytes gracias a @milk, aunque juro que lo intenté antes.

Toma la entrada como una matriz de caracteres en 2-d.

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

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
fuente
¿No debería Trim()funcionar en lugar de TrimEnd()? Aún mejor, creo que puede guardar muchos bytes usando s [0] como var de salida y usando return new string(s[0],0,i)where ies el índice del último carácter de código. Esa idea puede requerir dos forbucles en lugar del foreach, lo pensaré más y trataré de escribir el código real más tarde hoy.
leche
Trim()también se recortará desde el principio, lo que creo que no sería válido. Originalmente también estaba cargando en s [0] y tenía int i;fuera del ciclo (para reutilizarlo en el retorno) que creo que finalmente agregó bytes
pinkfloydx33
1

Pyth, 11 bytes

PhceCSMCQ\#

Un programa que toma la entrada de una lista de cadenas en STDIN e imprime una cadena.

Pruébalo en línea

Cómo funciona

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
fuente
1

sed, 126 bytes

: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,...$,,

Requiere una nueva línea al final de la entrada.
Estoy seguro de que puedo jugar al golf un poco más, pero estoy feliz de que funcione por ahora.

Riley
fuente
0

Jalea , 27 bytes

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

Pruébelo en TryItOnline

Utiliza la especificación más estricta: el espacio adicional antes de que el carácter de comentario se elimine a costa de un byte.

La entrada es una lista de cadenas.

Jonathan Allan
fuente
@Erik el golfista, tal vez sí, pero ¿viste el aplastamiento que me dio aquí ?
Jonathan Allan
0

Ruby, 77 bytes

puts File.readlines("stack.txt").join('').gsub(/\s{1}#.*\n/,'').gsub(/\s/,'')
Reenvío
fuente
Codificar un nombre de archivo de entrada no es un método de entrada aceptable.
Mego
@Mego, ¿dónde puedo encontrar las reglas de lo que es "aceptable"?
Reenvío
0

TSQL, 216 175 bytes

Golfizado:

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('%_#%',@))

Sin 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('%_#%',@))

Violín

t-clausen.dk
fuente
0

Javascript, 56 34 bytes, no competidor

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

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

Como @ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ señaló, no estoy preparado para espacios adicionales

Alondra
fuente
No pasa el caso "Prepárese para espacios adicionales"
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
0

Dyalog APL , 22 bytes

La inspiración .

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

(

⎕UCS representación de personajes de

¯2↓ todos menos los dos últimos

⍳∘35↑ hasta la posición de los primeros 35 ("#"), en lo que está fuera del paréntesis, tomado de

lo que está fuera del paréntesis

) a saber...

⌈⌿ los máximos columnares

de

⎕UCS los valores Unicode

TryAPL en línea!

Adán
fuente
Cuantos bytes
Acrolith