Aligner les arguments de fonction sur leurs propres lignes

16

Étant donné l'entrée d'une chaîne représentant une définition de fonction, sortez la chaîne avec des sauts de ligne et des espaces insérés de sorte que les arguments de la fonction soient séparés par des sauts de ligne et alignés.

La chaîne d'entrée suivra le modèle suivant:

  • Tout d'abord, il commencera par un préfixe, qui est toujours long d'au moins un caractère et ne contient aucun des caractères ,().

  • Une parenthèse ouverte ( () marquera alors le début de la liste d'arguments.

  • Une liste de zéro ou plusieurs arguments suivra ensuite. Celles-ci sont séparées par la chaîne ", "(une virgule puis un espace). Aucun des arguments ne contiendra aucun des caractères ,().

  • Une parenthèse fermée ( )) marquera la fin de la liste des arguments.

  • Enfin, un suffixe peut être trouvé, qui est long de zéro ou plusieurs caractères et peut contenir les caractères ,().

La chaîne d'entrée consistera uniquement en ASCII imprimable (ce qui signifie qu'elle ne contiendra jamais de nouvelle ligne).

La sortie doit être:

  • Le préfixe, copié mot pour mot, et la parenthèse ouverte.

  • La liste d'arguments, cette fois séparée non pas par ", "mais par une virgule, une nouvelle ligne et autant d'espaces que nécessaire pour aligner verticalement le premier caractère de chaque argument.

  • Le paren proche et le suffixe (s'il existe) textuellement.

Puisqu'il s'agit de , le code le plus court en octets gagnera.

Cas de test (format: entrée sur une seule ligne suivie d'une sortie suivie d'un double retour à la ligne):

def foo(bar, baz, quux):
def foo(bar,
        baz,
        quux):

int main() {
int main() {

fn f(a: i32, b: f64, c: String) -> (String, Vec<i32>) {
fn f(a: i32,
     b: f64,
     c: String) -> (String, Vec<i32>) {

function g(h) {
function g(h) {

def abc(def, ghi, jkl, mno)
def abc(def,
        ghi,
        jkl,
        mno)

x y z(x, y, z) x, y, z)
x y z(x,
      y,
      z) x, y, z)
Poignée de porte
la source

Réponses:

7

Haskell, 115 octets

import Data.Lists
f x|(a,b:c)<-span(/='(')x,(d,e)<-span(/=')')c=a++b:intercalate(",\n "++(a>>" "))(splitOn", "d)++e

Exemple d'utilisation:

*Main> putStrLn $ f "fn f(a: i32, b: f64, c: String) -> (String, Vec<i32>) {"
fn f(a: i32,
     b: f64,
     c: String) -> (String, Vec<i32>) {

Comment ça fonctionne:

bind
  a: everything before the first (
  b: the first (
  c: everything after the first (
  d: everything of c before the first )
  e: everything of c from the first ) to the end

construct the output string by concatenating
  a
  b
  splitting d at the argument separator ", " and rejoining it with ",\n " followed by (length a) spaces    
  e
nimi
la source
a>>" "est vraiment intelligent ...
Actorclavilis
4

Japt, 23 octets

¡Y?X:Xr',",
"+SpUb'(}')

Testez-le en ligne!

Comment ça fonctionne

               // Implicit: U = input string
¡        }')   // Map each item X and index Y in U.split(")") to:
Y?X            //  If Y is non-zero, X. This keeps e.g. "(String, Vec<i32>)" from being parsed.
:Xr',",\n"+    //  Otherwise, X with each comma replaced with ",\n" concatenated with
SpUb'(         //  U.indexOf("(") spaces.
               // Implicit: re-join with ")", output
ETHproductions
la source
3

Perl, 62 52 + 2 = 54 octets

s/\(.*?\)/$a=$"x length$`;$&=~s|(?<=,)[^,]+|\n$a$&|gr/e

Nécessite le -pdrapeau:

$ echo "x y z(x, y, z) x, y, z)
fn f(a: i32, b: f64, c: String) -> (String, Vec<i32>) {" | \
perl -pe's/\(.*?\)/$a=$"x length$`;$&=~s|(?<=,)[^,]+|\n$a$&|gr/e'
x y z(x,
      y,
      z) x, y, z)
fn f(a: i32,
     b: f64,
     c: String) -> (String, Vec<i32>) {

Comment ça fonctionne:

# '-p' reads first line into $_ and will also auto print at the end
s/\(.*?\)/             # Match (...) and replace with the below
  $a=$"x length$`;     # $` contains all the content before the matched string
                       # And $" contains a literal space 
  $&=~s|               # Replace in previous match
    (?<=,)[^,]+        # Check for a , before the the string to match
                       # This will match ' b: f64', ' c: String'
  |\n$a$&|gr/e         # Replace with \n, [:spaces:] and all the matched text
andlrc
la source
3

Rétine, 31 octets

(?<=^([^(])*\([^)]*,) 
¶ $#1$* 

Notez les espaces à la fin des deux lignes.

Nous remplaçons chaque espace qui a le regex ^([^(])*\([^)]*,devant lui. La chaîne de remplacement sera une nouvelle ligne et le nombre de captures avec ([^(])*plus un espace.

Une explication plus cohérente vient plus tard.

Essayez-le en ligne ici.

randomra
la source
3

ES6, 68 67 octets

s=>s.replace(/\(.*?\)/,(s,n)=>s.replace/, /g, `,
 `+` `.repeat(n)))

Cela fonctionne en extrayant la liste d'arguments de la chaîne d'origine et en remplaçant chaque séparateur d'arguments par une indentation calculée à partir de la position de la liste d'arguments dans la chaîne d'origine.

Edit: 1 octet enregistré grâce à @ETHproductions.

Neil
la source
Je me demandais pourquoi tu l'as fait à la .split`, `.join(...)place .replace(...). Il s'avère que l'autre est un octet plus court:s=>s.replace(/\(.*?\)/,(s,n)=>s.replace(/, /g,`,\n `+` `.repeat(n)))
ETHproductions
2

Pyth, 35 30 octets

+j++\,b*dhxz\(c<zKhxz\)", ">zK

Essayez-le ici!

Explication:

+j++\,b*dhxz\(c<zKhxz\)", ">zK    # z = input()

                 Khxz\)           # Get index of the first ")"
               <z                 # Take the string until there...
              c        ", "       # ...and split it on the arguments
 j                                # Join the splitted string on...
  ++                              # ...the concatenation of...
    \,b                           # ...a comma followed by a newline...
       *dhxz\(                    # ...followed by the right amount of spaces = index of the first "(" + 1
+                         >zK     # Concat the resulting string with the postfix
Denker
la source
2

Groovy, 137 89 95 octets

Groovy n'est pas le "bon outil pour le travail" ™. Edit: Cela fonctionne très bien lorsque quelqu'un avec un cerveau l'utilise ...

f={s=(it+' ').split(/\0/)
s[0].replace(',',',\n'+(' '*it.indexOf('(')))+')'+s[1..-1].join(')')}

Tests:

println f("def foo(bar, baz, quux):")
println f("int main() {")
println f("fn f(a: i32, b: f64, c: String) -> (String, Vec<i32>) {")
println f("function g(h) {")
println f("def abc(def, ghi, jkl, mno)")
println f("x y z(x, y, z) x, y, z)")

Assez peu golfé:

f = {String it ->
    def str = (it + ' ').split(/\)/)
    return (str[0].replace (',', ',\n'+(' ' * it.indexOf('('))) + ')' + str[1])
}
J Atkin
la source
1

Rétine , 47 octets

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

m+`^(([^(]+.)[^,)]+,) (.+)
$1¶$2$3
T`p` `¶.+?\(

Essayez-le en ligne!

Martin Ender
la source
1

JavaScript (ES6), 85

s=>s.replace(/^.*?\(|[^),]+, |.+/g,(x,p)=>[a+x,a=a||(p?`
`+' '.repeat(p):a)][0],a='')

Tester

f=s=>s.replace(/^.*?\(|[^),]+, |.+/g,(x,p)=>[a+x,a=a||(p?`
`+' '.repeat(p):a)][0],a='')

console.log=x=>O.textContent+=x+'\n'

;['def foo(bar, baz, quux):',
  'int main() {',
  'fn f(a: i32, b: f64, c: String) -> (String, Vec<i32>) {',
  'function g(h) {',
  'def abc(def, ghi, jkl, mno)',
  'x y z(x, y, z) x, y, z)']
.forEach(t=>console.log(t+'\n'+f(t)+'\n'))
<pre id=O></pre>

edc65
la source
Je suis désolé, je me trompais, exécutais le code dans ma console et la sortie était quelque chose comme ceci: "x y z(xcomme vous pouvez le voir, "c'est pourquoi je pensais que c'était un espace de moins. D'où la suppression
andlrc
@ dev-null qui m'arrive tout le temps.
edc65
0

Gelée , 39 octets

ṣ”)Ḣṣ”(Ṫ©œṣ⁾, ji”(⁶ẋƊ⁾,¶;ƊḢ,j®${jʋ@œṣ®$

Essayez-le en ligne!

Erik le Outgolfer
la source