Trasformare una montagna in una Molehill


12

Ti viene data una serie di terreni, con talpe e montagne:

                        /\
                       /  \
              _/\__   /    \
          ___/     \_/      \_
____/\___/                    \___

Il tuo compito è quello di sostituire ogni molehill nella stringa con una montagna equivalente centrata nella stessa colonna. Il resto della stringa non deve essere interessato. Ciò potrebbe richiedere righe aggiuntive all'inizio della stringa.

Un molehill è costituito da colonne adiacenti in cui il terreno sale, immediatamente seguito da colonne adiacenti in cui il terreno scende. Il lato più corto deve essere esattamente largo una colonna.

Questi sono tutti molehills:

_____/\______

   /\________
__/

________/\
          \__

\           /
 \         /
  \       /
   \     /
    \/\_/

Questi non sono talpa:

    /\
___/  \______

      ___
_____/   \___

____  _______
    \/

Una montagna è come una molehill, ma il lato più corto è alto quattro righe anziché uno.

Esempi

                  /\
                 /  \
           ->   /    \
____/\____    _/      \_

                       /\
                      /  \
                     /    \
           __ ->    /      \__
_     /\__/      __/
 \___/

                         /\
                        /  \
               ->      /    \
  /\                /\/      \
_/  \__/\_____    _/          \_

_                _    _                _
 \              /      \      /\      /
  \            /        \    /  \    /
   \          /          \  /    \  /
    \        /     ->     \/      \/
     \      /
      \    /
       \/\/

                             /\      /\
                            /  \    /  \
                           /    \  /    \
_                     -> _/      \/      \
 \                                        \
  \                                        \
   \/\______/\_______                       \_

                        /\                           /\       /\
                       /  \               /\        /  \     /  \
              _/\__   /    \       ->    /  \      /    \   /    \
          ___/     \_/      \_          /    \  __/      \_/      \_
____/\___/                    \___    _/      \/                    \___

Regole aggiuntive

  • Sono vietate le scappatoie standard .
  • L'input e l'output possono essere in qualsiasi formato ragionevole.
  • È possibile assumere la presenza o l'assenza di spazi vuoti finali nella stringa di input.
  • Ci sarà sempre abbastanza spazio ai lati della corda e tra le talpe per qualsiasi montagna di cui potresti aver bisogno.
  • Se la sostituzione dei Molehills con le montagne crea ulteriori Molehills, non è necessario trasformare tali Molehills in montagne.
  • Il terreno non può andare su e giù nella stessa colonna. In questo caso, il terreno non si muove.
  • Se una determinata colonna non diventa parte di una montagna, la sua altezza deve rimanere invariata.

Questo è , quindi vince la risposta più breve in byte.


Questa è una bella sfida!
Galen Ivanov,

Penso che il penultimo esempio dovrebbe finire con quattro \ e quattro _ e non sette \ e uno _.
ngm,

1
La tua intenzione è che il primo e l'ultimo carattere non debbano cambiare la posizione verticale e che anche il minor numero di caratteri possibile debba essere cambiato ? Questo sembra essere ciò che gli esempi suggeriscono, soprattutto se la seconda ultima è l'unica risposta corretta.
ngm,

1
Sarebbe una buona idea modificare le specifiche della sfida per chiarire questi punti.
ngm,

1
Inoltre, l'ultima regola "il terreno non può andare su e giù nella stessa colonna" - cosa significa? Sicuramente "il terreno" è solo uno dei tre personaggi /, \, _, quindi come potrebbe eventualmente andare su e giù allo stesso tempo?
Chas Brown,

Risposte:


2

Python 2 , 509 495 480 byte

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

Provalo online!

Non è ancora chiaro quali siano le regole effettive; ma qui ci sono i vincoli aggiuntivi che vengono applicati al di sopra e al di là della regola secondo cui le talpe devono essere trasformate in montagne:

  • I caratteri del primo e dell'ultimo terreno dell'output devono essere _, così come devono essere per input validi.
  • La differenza verticale tra il primo _e l'ultimo _deve essere mantenuta tra l'ingresso e l'uscita.
  • Dopo che le sostituzioni hanno trasformato le talpe in montagne, alcuni altri personaggi potrebbero dover essere cambiati per mantenere detta differenza verticale; ma i personaggi cambiati non devono essere nessuno dei personaggi che fanno parte delle montagne che sono state create da talpe.
  • E quando si effettuano queste modifiche, il numero di caratteri aggiuntivi modificati deve essere minimo.

Algoritmo Ungolf:

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

1

Rosso , 855, 845 833 byte

func[s][r: split s"^/"c: charset"\_/"m: copy #()repeat n l: length? r[parse r/:n[any[i:
c(put m 1 + offset? r/:n i reduce[first i n])| skip]]]m: extract next sort/skip to-block m
2 2 e: copy[]parse b: rejoin collect[foreach c m[keep c/1]][any[c:["/\_"|"/\/"](alter
e 1 + offset? b c)| c:["_/\"|"\/\"](alter e 2 + offset? b c)| skip]]y: 0 foreach a e[q: p:
d: -3 + min m/(a - 4)/2 m/(a + 5)/2 if d < y[y: d]j: i: a until[m/:i/1: #"/"m/:i/2: p k: i
- 2 if all[k > 0 #"_"= m/:k/1 p = m/:k/2][m/(k + 1)/1: #"_"m/(k + 1)/2: p break]i: i - 1
m/:i/2 < p: p + 1]j: j + 1 until[m/:j/1: #"\"m/:j/2: q k: i + 2 if all[#"_"= m/:k/1
p = m/:k/2][m/(k - 1)/1: #"_"m/(k - 1)/2: p break]j: j + 1 m/:j/2 < q: q + 1]]y: y - 1 q:
collect[loop l - y[k: copy""keep pad k p: length? m]]repeat n p[w: m/1/2 - y
q/:w/:n: m/1/1 m: next m]foreach d q[print d]]

Provalo online!

Lontano, molto lontano da una soluzione da golf ... Passa i casi di test ma molto probabilmente fallirebbe su qualche altro schema più strano.

Più leggibile:

f: func [ s ] [
    r: split s "^/"
    c: charset "\_/"
    m: copy #()
    repeat n l: length? r[
        parse r/:n[ any [ i: c(put m 1 + offset? r/:n i reduce[ first i n ])
        | skip]]
    ]
    m: sort/skip to-block m 2
    m: extract next m 2
    b: rejoin collect [ foreach c m [ keep c/1 ] ]
    e: copy []
    parse b [ any [ c: [ "/\_" | "/\/" ]
                (alter e 1 + offset? b c)
            | c: [ "_/\" | "\/\" ]
                (alter e 2 + offset? b c)
            | skip
        ]
    ]
    y: 0
    foreach a e [
        q: p: d: -3 + min m/(a - 4)/2 m/(a + 5)/2
        if d < y [ y: d ]
        j: i: a
        until [
            m/:i/1: #"/"
            m/:i/2: p
            k: i - 2
            if all [ k > 0
                     #"_" = m/:k/1
                     p = m/:k/2
            ] [ 
                m/(k + 1)/1: #"_"
                m/(k + 1)/2: p
                break
            ]
            i: i - 1
            p: p + 1 
            m/:i/2 < p
        ]
        j: j + 1
        until[
            m/:j/1: #"\"
            m/:j/2: q
            k: i + 2
            if all [ #"_" = m/:k/1 
                     p = m/:k/2
            ] [
                m/(k - 1)/1: #"_"
                m/(k - 1)/2: p
                break
            ]
            j: j + 1
            q: q + 1 
            m/:j/2 < q
        ]
    ]
    y: y - 1
    q: collect [
        loop l - y [
            k: copy ""
            keep pad k p: length? m
        ]
    ]
    repeat n p [ w: m/1/2 - y
                 q/:w/:n: m/1/1
                 m: next m ]
    foreach d q [ print d ]
]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.