Richten Sie Funktionsargumente in eigenen Zeilen aus

16

Wenn Sie eine Zeichenfolge eingeben, die eine Funktionsdefinition darstellt, geben Sie die Zeichenfolge mit eingefügten Zeilenumbrüchen und Leerzeichen aus, damit die Argumente der Funktion durch Zeilenumbrüche getrennt und ausgerichtet werden.

Die Eingabezeichenfolge folgt dem folgenden Muster:

  • Zunächst beginnt es mit einem Präfix, das immer mindestens ein Zeichen lang ist und keines der Zeichen enthält ,().

  • Eine offene Klammer ( () markiert dann den Anfang der Argumentliste.

  • Es folgt eine Liste mit null oder mehr Argumenten. Diese werden durch die Zeichenfolge ", "(ein Komma und dann ein Leerzeichen) getrennt. Keines der Argumente enthält eines der Zeichen ,().

  • Eine enge Klammer ( )) markiert das Ende der Argumentliste.

  • Zuletzt kann ein Postfix gefunden werden, der null oder mehr Zeichen lang ist und die Zeichen enthalten kann,() .

Die Eingabezeichenfolge besteht ausschließlich aus druckbarem ASCII (dh, sie enthält niemals eine neue Zeile).

Die Ausgabe muss sein:

  • Das wörtlich kopierte Präfix und die offene Klammer.

  • Die Argumentliste, diesmal nicht durch ", "Komma, Zeilenumbruch und so viele Leerzeichen getrennt, wie erforderlich sind, um das erste Zeichen jedes Arguments vertikal auszurichten.

  • Das nahe Paren und Postfix (falls vorhanden) wörtlich.

Da es sich um , wird der kürzeste Code in Bytes gewinnen.

Testfälle (Format: einzeilige Eingabe, gefolgt von Ausgabe, gefolgt von doppelter Zeilenumbruch):

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)
Türknauf
quelle

Antworten:

7

Haskell, 115 Bytes

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

Anwendungsbeispiel:

*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>) {

Wie es funktioniert:

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
quelle
a>>" "ist wirklich schlau ...
Actorclavilis
4

Japt, 23 Bytes

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

Online testen!

Wie es funktioniert

               // 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
quelle
3

Perl, 62 52 + 2 = 54 Bytes

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

Benötigt die -pFlagge:

$ 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>) {

Wie es funktioniert:

# '-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
undlrc
quelle
3

Retina, 31 Bytes

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

Beachten Sie die Leerzeichen am Ende beider Zeilen.

Wir ersetzen jeden Raum, der den regulären Ausdruck ^([^(])*\([^)]*,vor sich hat. Die ersetzende Zeichenfolge ist eine neue Zeile und die Anzahl der Captures mit ([^(])*plus einem Leerzeichen.

Eine schlüssigere Erklärung folgt später.

Probieren Sie es hier online aus.

randomra
quelle
3

ES6, 68 67 Bytes

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

Dies funktioniert, indem die Argumentliste aus der ursprünglichen Zeichenfolge extrahiert und jedes Argumenttrennzeichen durch einen Einzug ersetzt wird, der aus der Position der Argumentliste in der ursprünglichen Zeichenfolge berechnet wird.

Bearbeiten: 1 Byte dank @ETHproductions gespeichert.

Neil
quelle
Ich habe mich gefragt , warum Sie tat .split`, `.join(...)statt .replace(...). Es stellt sich heraus, dass das andere Byte kürzer ist:s=>s.replace(/\(.*?\)/,(s,n)=>s.replace(/, /g,`,\n `+` `.repeat(n)))
ETHproductions
2

Pyth, 35 30 Bytes

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

Probieren Sie es hier aus!

Erläuterung:

+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
quelle
2

Groovy, 137 89 95 Bytes

Groovy ist nicht das "richtige Werkzeug für den Job" ™. Bearbeiten: Es funktioniert gut, wenn Sie jemanden mit einem Gehirn haben, das es verwendet ...

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)")

Etwas ungolfed:

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

Netzhaut , 47 Bytes

Die Anzahl der Bytes setzt die Kodierung nach ISO 8859-1 voraus.

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

Probieren Sie es online!

Martin Ender
quelle
1

JavaScript (ES6), 85

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

Prüfung

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
quelle
Es tut mir leid, ich habe mich geirrt, habe den Code in meiner Konsole ausgeführt und die Ausgabe war ungefähr so: "x y z(xWie Sie sehen können, "dachte ich deshalb, es sei ein Leerzeichen entfernt. Daher die Löschung
andlrc
@ dev-null das passiert mir die ganze zeit.
Edc65
0

Jelly , 39 Bytes

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

Probieren Sie es online!

Erik der Outgolfer
quelle