Aus einem Maulwurfshügel einen Berg machen

12

Sie erhalten eine Reihe von Gelände mit Maulwurfshügeln und Bergen:

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

Ihre Aufgabe ist es, jeden Maulwurfshügel in der Schnur durch einen gleichwertigen Berg zu ersetzen, der in der gleichen Spalte zentriert ist. Der Rest der Zeichenfolge darf nicht betroffen sein. Dies erfordert möglicherweise zusätzliche Zeilen am Anfang der Zeichenfolge.

EIN Maulwurfshügel besteht aus benachbarten Säulen, an denen das Gelände ansteigt, unmittelbar gefolgt von benachbarten Säulen, an denen das Gelände abfällt. Die kürzeste Seite muss genau eine Spalte breit sein.

Dies sind alles Maulwurfshügel:

_____/\______

   /\________
__/

________/\
          \__

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

Dies sind keine Maulwurfshügel:

    /\
___/  \______

      ___
_____/   \___

____  _______
    \/

EIN Berg ist wie ein Maulwurfshügel, aber die kürzeste Seite ist vier statt einer Linie hoch.

Beispiele

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

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

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

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

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

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

Zusätzliche Regeln

  • Standard-Schlupflöcher sind verboten.
  • Eingabe und Ausgabe können in jedem vernünftigen Format erfolgen.
  • Sie können das Vorhandensein oder Fehlen von nachgestellten Leerzeichen in der Eingabezeichenfolge annehmen.
  • An den Seiten der Schnur sowie zwischen den Maulwurfshügeln ist immer genügend Platz für die Berge, die Sie möglicherweise benötigen.
  • Wenn durch das Ersetzen der Maulwurfshügel durch Berge zusätzliche Maulwurfshügel entstehen, müssen Sie diese nicht in Berge verwandeln.
  • Das Gelände kann nicht in derselben Spalte sowohl nach oben als auch nach unten verlaufen. In diesem Fall bewegt sich das Gelände nicht.
  • Wenn eine bestimmte Säule nicht Teil eines Berges wird, muss ihre Höhe unverändert bleiben.

Das ist , also gewinnt die kürzeste Antwort in Bytes.

RamenChef
quelle
Das ist eine schöne Herausforderung!
Galen Ivanov
Ich denke, das vorletzte Beispiel sollte mit vier und vier enden und nicht mit sieben und eins.
ngm
1
Ist Ihre Absicht, dass das erste und das letzte Zeichen die vertikale Position nicht ändern dürfen und dass auch so wenig Zeichen wie möglich geändert werden sollen ? Dies scheint das zu sein, was die Beispiele andeuten, besonders wenn die vorletzte die einzig richtige Antwort ist.
ngm
1
Es wäre eine gute Idee, die Herausforderungsspezifikation zu bearbeiten, um diese Punkte zu verdeutlichen.
ngm
1
Darüber hinaus gilt die letzte Regel "Das Gelände kann nicht in derselben Spalte sowohl nach oben als auch nach unten verlaufen" - was bedeutet das? "The terrain" ist sicherlich nur eine von drei Figuren /, \, _, wie kann es also gleichzeitig auf und ab gehen?
Chas Brown

Antworten:

2

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

Probieren Sie es online!

Es ist immer noch nicht klar, welche Regeln es gibt. Aber hier sind die zusätzlichen Einschränkungen, die über die Regel hinaus gelten, dass aus Maulwurfshügeln Berge werden sollen:

  • Das erste und das letzte Terrain-Zeichen der Ausgabe müssen so sein _, wie sie für gültige Eingaben sein müssen.
  • Der vertikale Unterschied zwischen dem ersten _und dem letzten _muss zwischen dem Eingang und dem Ausgang eingehalten werden.
  • Nach dem Auswechseln von Maulwurfshügeln in Berge müssen möglicherweise einige andere Zeichen geändert werden, um den vertikalen Unterschied aufrechtzuerhalten. Die veränderten Charaktere dürfen jedoch keine der Charaktere sein, die Teil von Bergen sind, die aus Maulwurfshügeln entstanden sind.
  • Bei diesen Änderungen muss die Anzahl der zusätzlichen Zeichen minimal sein.

Ungolfed-Algorithmus:

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
Chas Brown
quelle
1

Red , 855, 845 833 Bytes

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

Probieren Sie es online!

Weit weg von einer golferischen Lösung ... Sie besteht die Testfälle, würde aber höchstwahrscheinlich nach einem anderen, seltsameren Muster scheitern.

Besser lesbar:

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 ]
]
Galen Ivanov
quelle