Formowanie ASCII art

18

Otrzymujesz pojedynczy ciąg ASCII do wydrukowania, który nie zawiera żadnych znaków nowego wiersza, oraz wielowierszową „formę”, zawierającą spacje ( ) i krzyżyk ( #).

Musisz ciągnąć znak po znaku w ciągu i zamieniać skróty za pomocą znaków z ciągu w kolejności od lewej do prawej i od góry do dołu. Jeśli sznurek jest zbyt krótki, aby wypełnić formę, przestajesz wysyłać, jeśli sznur jest zbyt długi, przycinasz sznur, aby dokładnie wypełnić formę.


Przykładowy ciąg / forma (ciąg zbyt długi, obcięty):

Loremipsumdolorsitamet,consecteturadipiscingelit.Namsuscipitmagnanoneratgravidacondimentum.Vestibulumnecnisllorem.Fuscemolestieviverranibh,eueleifendnislplaceratnon.Namblanditturpislacus,vitaemolestielacusimperdietquis.Nullapulvinar,exquissollicitudinfacilisis,eratnullavolutpatlectus,etluctusenimvelitegetex.Inhachabitasseplateadictumst.Donecinterdumnullalacinia,sodalesloremin,eleifendturpis.Pellentesqueanisimi.Aeneannonlobortisdiam,quisaliquetquam.Aeneanaugueipsum,imperdietsedaliquetnon,volutpategetsapien.Nullampharetranullaquispretiumornare.Aliquamfermentumvestibulummassavitaevehicula.
###########################################################
##### ##############   ###### ###### ######################
#####  ##   ######   #  ##### ###### ########        ######
###### #  #  ####  #### ##### ###### #######  ######  #####
######   ###  ###       ##### ###### ####### #######  #####
######  ##### ### ########### ###### #######   ###   ######
###### ###### ###  ########## ######      #####   #########
##################       ####    ##########################
###########################################################

Przykładowe dane wyjściowe:

Loremipsumdolorsitamet,consecteturadipiscingelit.Namsuscipi
tmagn anoneratgravid   acondi mentum .Vestibulumnecnisllore
m.Fus  ce   molest   i  evive rranib h,euelei        fendni
slplac e  r  atno  n.Na mblan dittur pislacu  s,vita  emole
stiela   cus  imp       erdie tquis. Nullapu lvinar,  exqui
ssolli  citud inf acilisis,er atnull avolutp   atl   ectus,
etluct usenim vel  itegetex.I nhacha      bitas   seplatead
ictumst.Donecinter       dumn    ullalacinia,sodalesloremin
,eleifendturpis.Pellentesqueanisimi.Aeneannonlobortisdiam,q

Przykładowy ciąg / forma (ciąg zbyt krótki, wyjście zatrzymane):

This probably won't look good.
### ### ### ###
# # # # #   #
### ### #   # #
#   #   #   # #
#   #   ### ###

Odpowiednia wydajność:

Thi s p rob abl
y   w o n   '
t l ook     g o
o   d   .   

Najkrótszy kod w bajtach wygrywa.

Podziękowania dla pomysłu na tej stronie .

orlp
źródło
Czy wiersz wejściowy może zawierać skróty? (Jeśli tak, to można użyć przypadku testowego.)
Martin Ender
Czy wiersz wejściowy może zawierać spacje?
manatwork
Czy dane wejściowe mogą zawierać początkowe / końcowe spacje / nowe linie?
Sp3000,
@manatwork W drugim przypadku testowym tak jest.
Martin Ender
@ MartinBüttner Tak, skrzynka wejściowa może zawierać skróty.
orlp

Odpowiedzi:

5

CJam, 16 14 bajtów

Dzięki Sp3000 za oszczędność 2 bajtów.

lq{s'#-\+(\}/;

Kończy się z błędem, jeśli ciąg jest zbyt krótki, ale błąd jest drukowany do STDERR.

Wypróbuj online!

Alternatywnie (ta sama liczba bajtów):

lq{SN+&\+(\}/;

Wyjaśnienie

l       e# Read the input line.
q       e# Read the grid.
{       e# For each character in the grid...
  s     e#   Convert to string.
  '#-   e#   Remove "#" from it.
  \+    e#   Prepend it to the input line (this is a no-op for "#"s in the grid).
  (     e#   Pull off the first character from the input line. This will terminate the
        e#   program with an error once the input line is empty.
  \     e#   Swap the character with the input line.
}/
;       e# Discard the remainder of the input line if there is any.
Martin Ender
źródło
7

LabVIEW, 37 Prymitywy LabVIEW

dzieli ciąg na tekst i pleśń, a następnie przekształca je w tablicę. Sprawdza pleśń, jeśli jest tam # i umieszcza znak z tekstu, w przeciwnym razie nic nie robi. Jeśli tekst lub forma są puste, wyjdź z pętli

Eumel
źródło
Fakt, że zrobiłeś to z ciosami LabView
Brain Guider
I fajnie jest na to patrzeć!
Draco18s nie ufa już
6

Haskell, 48 bajtów

nazywany jak „(zamień na ciąg) # (ciąg hashmark)”:

[]#_=[]
(r:t)#('#':s)=r:t#s
r#(c:s)=c:r#s
_#_=[]

Mniej golfa:

combine replacements slots | null replacements = []
                           | null slots        = []
                           | head slots == '#' = head replacements : combine (tail replacements) (tail slots)
                           | otherwise         = head slots        : combine       replacements  (tail slots)
Michael Klein
źródło
Fajnie, ale czy to nie jest nieprawidłowe, chyba że dodasz I / O? Np.import Control.Applicative;main=liftA2(#)getLine getContents>>=putStrLn
Cubic
@Cubic Stwierdzenie problemu nie wymaga IO (ani nawet pełnego programu), a inne rozwiązania, w tym jedno w Python 3, nie obejmują IO.
Michael Klein,
5

Siatkówka , 42 40 bajtów

Liczba bajtów zakłada kodowanie ISO 8859-1.

T`#`×`¶.+
+`^(.)([^×]+)×
$2$1
^.*¶|×\D*

Końcowe podawanie linii jest znaczące.

Wypróbuj online!

Wyjaśnienie

T`#`×`¶.+

Najpierw zastępujemy, #które są częścią siatki, znakiem innym niż ASCII (ale rozszerzony ASCII), ×więc nie mylimy ich z żadnym, #który może pojawić się w pierwszym wierszu.

+`^(.)([^×]+)×
$2$1

Teraz wypełniamy jak najwięcej ×z pierwszego wiersza, kilkakrotnie zastępując pierwszy, ×jaki możemy znaleźć, pierwszym znakiem w pierwszym wierszu (który jest usuwany w trakcie).

^.*¶|×\D*

Wreszcie pozbywamy się wszystkiego, co pozostało w pierwszym wierszu, a także wszystkiego, co pierwsze, ×aby skrócić dane wejściowe w obu kierunkach.

Martin Ender
źródło
4

JavaScript (ES6), 57 56 55 bajtów

(s,m)=>m.replace(x=/[^]/g,c=>c-1?x&&c:x=s[i++]||"",i=0)

Zapisano 1 bajt dzięki @Neil !

Wyjaśnienie

Działa z skrótami w ciągu wejściowym i zachowuje końcowe białe znaki po zakończeniu ciągu wejściowego.

var solution =

(s,m)=>
  m.replace(x=/[^]/g,c=> // for each character c of the mold, initialise x to true
    c-1?                 // if c is a space or newline:
      x&&c               // if x is truthy, return c
                         // else if the string has ended, x will equal "" (false), return x
    :                    // else if c is a hash:
      x=                 // set x to the character of the input string
        s[i++]||"",      // return the input string character (or "" if finished)
    i=0                  // initialise i to 0
  )
<input type="text" id="input" value="This probably won't look good." /><br>
<textarea id="mold" rows="6" cols="40">### ### ### ###
# # # # #   #
### ### #   # #
#   #   #   # #
#   #   ### ###</textarea><br>
<button onclick="result.textContent=solution(input.value,mold.value)">Go</button>
<pre id="result"></pre>

użytkownik 81655
źródło
1
Niezły algorytm, ale m.replace(/./g,c=>...)krótszy.
Neil
@Neil Masz rację. Próbowałem zbyt mocno, aby było inaczej od twojej odpowiedzi haha!
user81655
1
Już nie, ponieważ możesz użyć /[^]/zamiast /.|\n/. (Również przeprosiny za niewłaściwe sugestie /./.)
Neil
3

Python 3, 69 68 67 bajtów

def f(s,m):s=iter(s);return''.join(n<'#'and n or next(s)for n in m)

Ideone

Dzięki FryAmTheEggman, Chiel ten Brinke za bajt off. Alternatywnie mogłem użyć Pythona 2 jako dodatkowego ( printbez ()).

409_Konflikt
źródło
Można zapisać jeden bajt zastępując printz return.
Chiel ten Brinke
2

sb , 359 bajtów

^w[B!0]{w[B=10]{t[T+1]b[0]}>}<w[T!0]{w[B!0]{<}>^b[T]vw[B!0]{t[B]b[0]^v[B]v<[X]w[B!0]{>}b[T]<[X]^[Y+2]w[B=0]{>}t[B]b[0]>b[T]v}^t[B-1]vw[B=0]{<}}>b[10]t[X]w[X!-2]{w[B!0]{v}<}w[X!T]{b[35]>}^[Y]^<[X]w[B!10]{t[B]b[0]w[T=35]{t[10]}v<[X]w[B!35]{w[B=0]{v<[X]<b[1]}>}b[T]^[Y]^<[X]w[B=0]{>}}<[X+2]w[B=0]{v}w[B!0]{b[0]>}w[Y!-1]{<[X]^w[B!0]{w[B=35]{b[0]}w[B=10]{b[35]}>}}

W pb dane wejściowe są ściśle jednowymiarowe. Nie rozumie, że rysujesz kształt za pomocą danych wejściowych, po prostu widzi jedną długą linię z kilkoma bajtami o wartości 10. Pierwszą rzeczą, którą robi ten program, jest skopiowanie wszystkich oprócz pierwszej „linii” danych wejściowych na Y = 0, Y = 1 itd., Aby utworzyć kształt formy.

Coś, co zauważyłem w golfie kodowym, ale szczególnie podczas golfa w językach ezoterycznych, że często nie chcesz mieć do czynienia z dwiema gałęziami; po prostu ustaw się tak, że robisz to samo w obu przypadkach. Naiwny sposób rozwiązania tego problemu prawdopodobnie sprawdzi długość łańcucha w porównaniu z liczbą skrótów w pozostałej części danych wejściowych i zrobi coś w zależności od wyniku, ponieważ musi zachowywać się inaczej w zależności od tego, co zostanie odcięte. Ale to dużo bajtów.

Zamiast tego po zakończeniu formy na dole dodawana jest dodatkowa linia. To po prostu nskróty w rzędzie, gdzie njest długość łańcucha. Teraz gwarantowane jest dopasowanie sznurka! Po wstawieniu wszystkich znaków ciągu dodatkowa linia, która została dodana, zostaje bezwarunkowo zniszczona. Usuwane są również wszelkie hasze pozostające w odpowiedniej formie, a to jest niezbędny wynik!

Oczywiście złamanie specyfikacji po prostu zniszczyłoby wszystkie hasze. W końcu w łańcuchu wejściowym może znajdować się skrót! Aby poradzić sobie z tym, odsyłam do innej części specyfikacji:

Otrzymujesz pojedynczy ciąg ASCII do wydruku, który nie zawiera żadnych znaków nowej linii

(Podkreśl moje.) Kiedy mamy do czynienia ze sznurkiem, tak naprawdę nie obchodzi nas, czy są w nim nowe linie, ale wiemy, że nie ma żadnych. Tak więc wszystkie skróty są zastępowane nowymi wierszami, zanim zostaną wprowadzone do formy! Po zniszczeniu wszystkich skrótów wszystkie wiersze ponownie są zastępowane skrótami. Nie zamienia to całego wyjścia w pojedynczą linię rozdzielaną hashem, ponieważ natura wyniku 2D pb oznacza, że ​​tak naprawdę nigdy nie umieszcza nowej linii na końcu każdej linii, po prostu przechodzi do następnej linii.

Nie golfowany:

# Start by copying down the mold
^
# (B means "the character under the cursor")
w[B!0]{       # While B isn't a null byte:
    w[B=10]{    # While B IS a newline:
            t[T+1]    # Increase T by 1
                      # (`T` is the only variable that can be modified directly)
            b[0]      # Overwrite with 0 to break out of inner loop
    }
    >           # Move to the right
                # (dodge the 0 we wrote and progress towards the end of input)
}

# Brush is now at the end of the input, T contains number of lines

<             # Make sure the brush is actually /on/ the input
w[T!0]{       # While T isn't 0:
    w[B!0]{<}>  # Go to the first character of the last line
    ^b[T]       # Place a flag above current character
                # Also a convenient way to get the value of T back later
    vw[B!0]{    # While the character under the flag isn't 0:
            t[B]b[0]  # Put it in T, overwrite with 0
            ^v[B]v    # Go down by the amount written in the space above
            <[X]      # Go left by the amount right the brush is (i.e. go to X=0)
            w[B!0]{>} # Find first empty space
            b[T]      # Write the value of T
            <[X]      # Go left by the amount right the brush is
            ^[Y+2]    # Go up by the amount down the brush is plus 2 (above input)
            w[B=0]{>} # Find flag
            t[B]b[0]  # Pick it up, overwrite with 0
            >b[T]     # Place it to the right
    v}
    ^t[B-1]v    # Collect flag - 1
    w[B=0]{<}   # Go to end of previous line
}

# Mold is placed, all that's left is placing the string
>b[10]        # Put a newline at the end, guaranteed to not be in the string
t[X]          # Save current X value in T

# Add more hashes, guaranteed to fit the input and findable later
w[X!-2]{       # While X!=-2:
    w[B!0]{v}    # Move down until hitting a null byte
    <            # Move left
}
w[X!T]{        # While not at the X value we saved earlier:
    b[35]>       # Travel right, leaving hashes
}

^[Y]^<[X]     # Go to (0, -1)

w[B!10]{      # Until hitting the newline at the end:
    t[B]b[0]    # Pick up character, overwrite with 0
    w[T=35]{    # If it's a hash...
            t[10]     # Make it a newline so we remember, deal with it later
    }
    v<[X]       # Go to (0, 0)
    w[B!35]{    # While B is not a hash:
            w[B=0]{   # While B IS null:
                    v       # Go down
                    <[X]<   # Go to X=-1
                    b[1]    # Print a 1 to break loop (it won't be rendered anyway)
            }
            >           # Go right, either ignore a non hash or go to X=0
    }
    b[T]        # Overwrite hash with picked up character
    ^[Y]^<[X]   # Go to (0, -1)
    w[B=0]{>}   # Go to first character of it to restart loop
}

<[X+2]        # Go to (-2, -1)
w[B=0]{v}     # Go down until finding the row of added hashes
w[B!0]{b[0]>} # Wipe it out unconditionally
w[Y!-1]{      # For every remaining line on the screen:
    <[X]^       # Go to the beginning
    w[B!0]{     # For each character in it:
            w[B=35]{  # If it's a hash:
                    b[0]    # Destroy it
            }
            w[B=10]{  # If it's a newline:
                    b[35]   # Write a hash (after the check to destroy hashes!)
            }
    >}
}
podziemny monorail
źródło
Fajnie, to wygląda na dużo pracy.
Rɪᴋᴇʀ
1

ES6, 59 bajtów

(t,m)=>m.replace(/#/g,h=>t[i++]||h,i=0).replace(/#[^]*/,'')

70 bajtów, jeśli tekst może zawierać hasze:

(t,m)=>m.replace(/#/g,(_,n)=>t[i]&&(j=++n)&&t[i++],i=0,j=0).slice(0,j)
Neil
źródło
Nie usuwaj końcowych białych znaków, dokładnie skopiuj formę, przy czym dokładnie łańcuch wejściowy zastępuje znaki skrótu.
orlp
@orlp Dzięki. Ponownie edytuję tę wersję.
Neil
1

Perl, 53 51 42 + 2 = 44 bajty

@a=/./g;$/="";$_=<>;s/#/shift@a/ge;s/\s+$//

Wymaga -puruchomienia. Wyjaśnienie:

@a=/./g; # Split first line into an array of characters
$/=""; # Enable slurp mode (read the rest of lines in one go)
$_=<>;
s/#/shift@a/ge;
s/\s+$//
# With '-p' auto print is enabled
andlrc
źródło
Dostaję trochę brzydkich „1” na początku linii wyjściowych. Wypróbuj to, aby uzyskać czysty wynik:$a=<>;$/="";say<>=~s/#/substr$a,$i++,1/ger
manatwork
@manatwork Zdałem sobie również z tego sprawę, sprytne dzięki użyciu $/zamiast dołączyć
andlrc
1

Galaretka, 10 8 bajtów

¹ƈ<”#$?€

Wypróbuj tutaj!

Lynn
źródło
2
Wydaje się, że drukuje za dużo końcowych białych znaków, gdy linia wejściowa jest krótsza niż liczba #na wejściu.
Martin Ender
1

Perl 6 , 72 bajtów

my@a=get.comb;say(S:g/\#/{@a.shift//''}/~~{S/\s+$//}),@a||last for lines
Brad Gilbert b2gills
źródło
1

ES6, 47 bajtów

Prawdopodobnie najprostsze rozwiązanie.

(S,R)=>(i=-1,S.replace(/#/g,_=>R[++i]||R[i=0]))

Ten kod tworzy anonimową funkcję, która otrzymuje 2 parametry i zwraca wynik końcowy.

Pierwszy parametr Sto ciąg „map” z twoim "#", natomiast drugi parametr Rto „zamiennik” dla nich "#".

Ismael Miguel
źródło
0

Python 3

152 127 bajtów

Pełny program.

from sys import stdin as S
s=list(S.readline())
print(''.join([''if not s else(s.pop(0)if m=='#'else m)for m in S.read()]))

106 bajtów

Funkcja, która pobiera strumień jako dane wejściowe.

def f(S):s=list(S.readline());return''.join([''if not s else(s.pop(0)if m=='#'else m)for m in S.read()])
Chiel ten Brinke
źródło
Mamy już odpowiedź w języku Python, która jest znacznie krótsza i używa tej samej metody do utworzenia wyniku.
Mego
Widzę. Napisałem to jednak wczoraj, kiedy tej odpowiedzi jeszcze nie było. Przepraszam, że opublikowałem tak późno
Chiel ten Brinke
Nie piszesz późno, wiele osób prawdopodobnie jeszcze nie widziało tego pytania (z pewnością nie widziałem, dopóki nie zobaczyłem tego postu)
Blue