Sejajarkan argumen fungsi pada baris mereka sendiri


16

Diberikan input dari string yang mewakili definisi fungsi, output string dengan baris baru dan spasi dimasukkan sehingga argumen fungsi dipisahkan oleh baris baru dan disejajarkan.

String input akan mengikuti pola berikut:

  • Pertama, itu akan dimulai dengan awalan, yang selalu setidaknya satu karakter dan tidak mengandung karakter apa pun ,().

  • Tanda kurung terbuka ( () kemudian akan menandai awal daftar argumen.

  • Daftar nol atau lebih argumen akan mengikuti. Ini dipisahkan oleh string ", "(koma dan kemudian spasi). Tak satu pun dari argumen akan berisi karakter apa pun ,().

  • Tanda kurung dekat ( )) akan menandai akhir daftar argumen.

  • Terakhir, postfix dapat ditemukan, yang panjangnya nol atau lebih karakter dan mungkin berisi karakter ,().

String input hanya akan terdiri dari ASCII yang dapat dicetak (yang berarti tidak akan mengandung baris baru).

Outputnya harus:

  • Awalan, disalin ke bawah kata demi kata, dan tanda kurung terbuka.

  • Daftar argumen, kali ini tidak dipisahkan oleh ", "tetapi oleh koma, baris baru, dan ruang sebanyak yang diperlukan untuk meluruskan karakter pertama dari setiap argumen.

  • Tutup paren dan postfix (jika ada) kata demi kata.

Karena ini adalah , kode terpendek dalam byte akan menang.

Kasus uji (format: input baris tunggal diikuti oleh output diikuti oleh baris ganda ganda):

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)

Jawaban:


7

Haskell, 115 byte

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

Contoh penggunaan:

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

Bagaimana itu bekerja:

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>>" "benar-benar pintar ...
Actorclavilis

4

Japt, 23 byte

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

Uji secara online!

Bagaimana itu bekerja

               // 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 byte

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

Membutuhkan -pbendera:

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

Bagaimana itu bekerja:

# '-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 byte

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

Perhatikan spasi di akhir kedua garis.

Kami mengganti setiap ruang yang memiliki regex ^([^(])*\([^)]*,sebelumnya. String pengganti akan menjadi baris baru, dan jumlah tangkapan dengan ([^(])*ditambah satu spasi.

Penjelasan yang lebih masuk akal muncul kemudian.

Cobalah online di sini.


3

ES6, 68 67 byte

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

Ini bekerja dengan mengekstraksi daftar argumen dari string asli, dan mengganti setiap pemisah argumen dengan lekukan yang dihitung dari posisi daftar argumen dalam string asli.

Sunting: Disimpan 1 byte berkat produk @ETH.


Aku bertanya-tanya mengapa Anda melakukan .split`, `.join(...)bukan .replace(...). Ternyata yang lain adalah byte lebih pendek:s=>s.replace(/\(.*?\)/,(s,n)=>s.replace(/, /g,`,\n `+` `.repeat(n)))
ETHproduk

2

Pyth, 35 30 byte

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

Coba di sini!

Penjelasan:

+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 byte

Groovy bukanlah "Alat yang Tepat untuk Pekerjaan" ™. Sunting: Ini berfungsi dengan baik ketika Anda memiliki seseorang dengan otak menggunakannya ...

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

Tes:

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

Agak tidak terserang:

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='')

Uji

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>


Maaf, saya keliru, menjalankan kode di konsol saya dan hasilnya kira-kira seperti ini: "x y z(xseperti yang Anda lihat, "itulah sebabnya saya berpikir itu hanya berjarak satu spasi. Oleh karena itu penghapusan
andlrc

@ dev-null itu terjadi pada saya sepanjang waktu.
edc65

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.