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)

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

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

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

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.


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.


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

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])
}


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>


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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.