| Bytes | Lang | Time | Link |
|---|---|---|---|
| 169 | Python3 | 250819T190651Z | Ajax1234 |
| 131 | Retina 0.8.2 | 211001T161139Z | Neil |
| 059 | K ngn/k | 210915T093807Z | chrispsn |
| 046 | 05AB1E | 210914T093940Z | Kevin Cr |
| 032 | Stax | 210914T035747Z | Razetime |
| 092 | JavaScript Node.js | 210914T021845Z | tsh |
| 033 | Jelly | 210915T001941Z | Jonathan |
| 183 | Scala | 210914T231435Z | user |
| 126 | Python 3.8 prerelease | 210914T032109Z | gsitcia |
Python3, 169 bytes
import re
def f(s):
a,*b=[i.split(';')for i in re.findall('[\d;]+',s)]
for i in b:a=[j if j.isdigit()else(i.pop(0)if i else'')for j in a]+i
return f"f[{';'.join(a)}]"
Retina 0.8.2, 131 bytes
(f.(\d;)*(;(\d;)*)*)(;[^]]*].(?<-3>;)*(?(3)^))(\d);?
$1$6$5
}`\[\]
}`(f(.(\d|((?=;)))(?=[];]))*);?(].(?<-4>;)*)([^]]+)?
$1$#6$*;$6
Try it online! Explanation: Uses .NET balancing groups to shuffle arguments into slots. The first two lines shuffle arguments from the second application into free slots in the first. The middle two lines delete an empty application resulting from the first two lines. The last two lines append trailing arguments or slots from the second application to the first, however the test assumes that there are no arguments left to shuffle or empty applications, which is why an extra loop is needed.
K (ngn/k), 65 59 bytes
{"f[",|x,|y/{.![a*+\a:~#'x;x],(1+!#y)!y}/y\'-1_'1_z\}."];["
Thanks to ngn for cutting 4 bytes here and here.
K (k9 2021.09.01), 54 bytes
{"f[",|x,|y/{!?(?x*+\x!:~#'x),?+\y!1}/y\'1_z\x_}."];["
05AB1E, 46 bytes
¦¤¡¨ε¦';¡}Å»U0ìD_OXg-(©di®Å0«}0X.;}θ';ý0K"f[ÿ]
05AB1E is not the right language for this challenge.. :/
Try it online or verify all test cases.
Explanation:
Step 1: Transform the input to something more usable: Try it online.
¦ # Remove the leading "f" from the (implicit) input-string
¤ # Get its last character "]" (without popping)
¡ # Split it on this "]"
¨ # Remove the trailing empty item
ε # Map over each inner string
¦ # Remove the leading character (the "[")
';¡ '# Split it on ";"
} # Close the map
We now have a list of lists of digits and empty strings.
Step 2: Reduce this list of lists according to the challenge: Try it online.
Å» # Cumulative left-reduce (which unfortunately keeps track of steps):
U # Pop and store the current list in variable `X`
0ì # Prepend a 0 before each item in the result-string
# (so all empty strings become 0s)
D_O # Get the amount of 0s in this list (duplicate; ==0; sum)
Xg # Push the length of the current list `X`
s- # Subtract the amount of 0s from this length
© # Store it in variable `®` (without popping)
di } # Pop, and if this value is >= 0:
®Å0 # Push a list with `®` amount of 0s
« # And append this to the result-list
0X.; # Then replace each zero ("0","00","000",etc.) in this list one by
# one with the values from list `X`
}θ # And after the cumulative left-reduce, pop and keep the last list
Step 3: Format this resulting list to a format similar as the input:
';ý '# Join the list with ";" delimiter
0K # Remove all 0s from the string
"f[ÿ] "# Push string "f[ÿ]", where `ÿ` is automatically replaced with the
# string
# (after which the result is output implicitly)
Stax, 37 34 32 bytes
Ñgí⌡²☼☺≈AU▀≤L♠╫$U∩─.ù·○╓╥ò±E♦τèZ
-2 reducing splitting code
Explanation
2t1T.][/ {';/m{s{c{c{B}z?}?ms+k';*:}'fs+
2t1T.][/ get all argument bodies
{';/m split all on semicolons
{s{c{c{B}z?}?ms+k reduce by:
s swap with prev
{c{c{B}z?}?m map elements in prev to:
c{ }? if non-empty, leave elem as is
c{B}z? else remove first element of next and push
(pushes [] if empty)
s+ append the rest elements
';* join with semicolons
:} put in square brackets
'fs+ prepend 'f'
Stax, 37 bytes
Ö☺τσj↔₧♂√V{▐9,=☺|╢Δ‼$≥ä₧ÿºÉ/♂y╩▲S╞♫┘{
uses an assign at index builtin, slightly longer.
JavaScript (Node.js), 92 bytes
v=>v.match(/(?<=[[;])\d*|\[/g).map(g=n=>1/n?o[++i]?g(n):o[i]=n:i=-1,o=[])&&`f[${o.join`;`}]`
-1 byte by Arnauld.
Jelly, 33 bytes
ṣ”[Ṗ€ṣ€”;VṆ€k$ḟ0;ɗ"Ẏɗ/j”;ḟ0Ø[j”f;
A monadic Link that accepts a list of characters and yields a list of characters.
How?
ṣ”[Ṗ€ṣ€”;VṆ€k$ḟ0;ɗ"Ẏɗ/j”;ḟ0Ø[j”f; - Link: list of characters, S
ṣ”[ - split (S) at '['
Ṗ€ - pop (i.e. remove ']' from) each
ṣ€”; - split each at ';'
V - evaluate as Jelly code
-> list of projections with zeros at empty slots
/ - reduce by:
ɗ - last three links as a dyad, f(P, Q):
$ - last two links as a monad, f(P):
Ṇ€ - logical NOT each
k - partition (P) after truthy indices (of that)
-> P split after each empty slot
" - zip (across [t in that] and [q in Q]) with:
ɗ - last three links as a dyad, f(t, q):
0 - zero
ḟ - (t) filter discard (zeros)
; - concatenate (q)
Ẏ - tighten (to a flat list)
j”; - join with ';'
ḟ0 - filter discard zeros
Ø[j - "[]" join (that)
”f; - 'f' concatenate (that)
Scala, 183 bytes
_.drop(2).init split "\\]\\["map(_ split ";")reduce{(p,q)=>val(b,a)=((q,q take 0)/:p){case((q,p),x)=>if(q.size<1|x!="")(q,p:+x)else(q drop 1,p++q.take(1))}
a++b}mkString("f[",";","]")
A pretty horrible solution, but I'll work on it later. Explanation coming soon.
_ //The input
.drop(2) //Drop the "f["
.init //Drop the "]" at the very end
split "\\]\\[" //Split the projections up
map(_ split ";") //Split each projection into its parts
reduce{ (p, q) => //Reduce the projections by this function, which does the real work
val(b,a)=((q,q take 0)/:p){case((q,p),x)=>if(q.size<1|x!="")(q,p:+x)else(q drop 1,p++q.take(1))}
a++b}mkString("f[",";","]")
Python 3.8 (pre-release), 126 bytes
lambda s,D=[]:f'f[{";".join([D:=[j or next(i,"")for j in D]+[*i]for k in s[2:-1].split("][")if(i:=iter(k.split(";")))]*0+D)}]'
Ungolfed:
def f(s):
D=[]
for k in s[2:-1].split(']['):
i = iter(k.split(';')) # next projection
D = [j or next(i,'') for j in D] # replace empty slots with arguments from i
D += [*i] # add the rest of i
return 'f['+';'.join(D)+']'