Making a Mountain out of a Molehill
Python 2, 509 495 480 bytes
def f(S):
B='\\';F='/';s=''.join(map(max,*S.split('\n')));t=list(re.sub(r'..((./\\[^\\])|([^/]/\\.))..',r'////\\\\\\\\',s));C=s.count;D=t.count;d=C(F)-D(F)+D(B)-C(B);m=[{'_':F,B:'_'},{'_':B,F:'_'}][d<0];d=abs(d);i=1
while d:
if s[i]!=t[i]:i+=7
elif t[i]in m:d-=1;t[i]=m[t[i]]
i+=1
return'\n'.join(u for u in map(''.join,zip(*[u.ljust(2*len(S))for u in reduce(lambda (a,p),c:(a+[' '*[p,p-1][c==B]+c],p+[[0,-1][c==B],1][c==F]),t,([],len(t)))[0]]))[::-1]if u.strip())
import re
Try it online!
Still not clear what the actual rules are; but here are the additional constraints that are enforced above and beyond the rule that molehills shall be turned into mountains:
- The first and last terrain characters of the output must be
_
, just as they must be for valid inputs. - The vertical difference between the first
_
and the last_
must be maintained between the input and output. - After substitutions from turning molehills into mountains, some other characters might need to be changed in order to maintain said vertical difference; but the characters changed must not be any of the characters that are part of mountains that were created from molehills.
- And when accomplishing these changes, the number of additional characters changed must be minimal.
Ungolfed Algorithm:
def f(s):
s = ''.join(map(max,*s.split('\n'))) # flatten into a single line
t = re.sub(r'..((./\\[^\\])|([^/]/\\.))..',r'////\\\\\\\\',s) # replace molehills with mountains
d = s.count('/')-t.count('/')+t.count('\\')-s.count('\\') # are the two strings equally balanced?
m=[{'_':'/','\\':'_'},{'_':'\\','/':'_'}][d<0] # make an appropriate mapping...
d=abs(d);i=1 # skip over leading '_'...
while d: # while still unbalanced...
if s[i]!=t[i]:i+=7 # skip over any created mountains (7+1==8)
elif t[i] in m:d-=1;t = t[:i]+m[t[i]]+t[i+1:] # if can replace, do replace
i += 1 # next char
t = reduce(lambda (a,p),c:(a+[' '*[p,p-1][c=='\\']+c],p+[[0,-1][c=='\\'],1][c=='/']),t,([],len(t)))[0] # pad spaces at left side
t = map(''.join,zip(*[u.ljust(max(map(len,t))) for u in t])) # rotate
return '\n'.join(u for u in t[::-1] if u.strip()) # reverse and join into lines.
import re