Prosty sposób na kodowanie sztuki ascii w golfa!

18

Zadanie:

Istnieje wiele odpowiedzi na tej stronie, które są ułożone w sztukę ascii, taką jak ta . Zazwyczaj aranżacja odbywa się ręcznie, ale czy program nie pomógłby w tym? :)

Twój program pobierze 3 dane wejściowe:

  • Kod jako jedna linia
  • Liczba linii we wzorze (można pominąć, jeśli nie jest to konieczne)
  • Sam wzór, jako *s lub inny znak

Zasady:

  • Musisz napisać program (nie funkcję), który czyta ze standardowego wejścia
  • Tekst jest umieszczany od lewej do prawej w wierszu
  • Jeśli nie ma wystarczającej ilości tekstu do wypełnienia wzoru, wstaw .s w pozostałych spacjach
  • Jeśli jest zbyt dużo tekstu, aby wypełnić wzór, wydrukuj go po wydruku
  • , czyli wygrywa najkrótszy kod w bajtach

Przykładowe przebiegi:

Dane wejściowe (test dokładnego dopasowania) :

qwertyuiopasdfghjklzxcvbnm
4
***** * ***
*   * * *
*   * * *
***** * ***

Wyjście :

qwert y uio
p   a s d
f   g h j
klzxc v bnm

Dane wejściowe (test dodatkowych znaków) :

qwertyuiopasdfghjklzxcvbnm12345
4
***** * ***
*   * * *
*   * * *
***** * ***

Wyjście :

qwert y uio
p   a s d
f   g h j
klzxc v bnm
12345

Dane wejściowe (test niewystarczających znaków) :

qwertyuiopasdfg
4
***** * ***
*   * * *
*   * * *
***** * ***

Wyjście :

qwert y uio
p   a s d
f   g . .
..... . ...
Doktor
źródło
2
Jakie założenia należy przyjąć odnośnie tego, gdzie dozwolone jest wstawianie spacji i znaków nowej linii bez zmiany semantyki programu?
Peter Taylor
1
@PeterTaylor wydaje się, że nie ma swobody w umieszczaniu / rozdzielaniu kodu, więc przypuszczam, że semantyka jest ignorowana?
Martin Ender
1
Czy fragmenty „można pominąć” i „lub inny znak” w specyfikacji oznaczają, że możemy, powiedzmy, określić, że liczba wierszy musi zostać pominięta i że gwiazdki należy zastąpić, powiedzmy, Xes dla naszego program do pracy?
Ilmari Karonen
1
@ Bakuriu Nie rozumiem twojego komentarza. Jeśli piszesz program w ASCII, każdy znak jest bajtem. Jeśli piszesz w UTF-32, każdy znak ma 4 bajty. Najkrótszy kod w bajtach , a nie znakach, wygrywa zgodnie z bieżącą specyfikacją. Wygląda na to, że chcesz, aby kodowanie stało się wymaganiem, ale nie rozumiem, dlaczego jest konieczne. Czy źle zrozumiałem twój komentarz?
Rainbolt
1
W oparciu o niektóre odpowiedzi, w których brakuje niektórych zasad, dodałem dwa przykłady i przesunąłem cały blok przykładów poniżej bloku reguł dla dodatkowej przejrzystości.
Veskah

Odpowiedzi:

5

GolfScript, 30 znaków

n/(\(;n*'*'/{@.!'.'*+([]+@+}*\

Uruchom online .

Przykłady:

> qwertyuiopasdfghjklzxcvbnm
> 4
> ***** * ***
> *   * * *
> *   * * *
> ***** * ***

qwert y uio
p   a s d
f   g h j
klzxc v bnm

> qwertyuiopasdfghjklzxcvbnm
> 1
> ***** * ***

qwert y uio
pasdfghjklzxcvbnm

> qwerty
> 2
> ***** * ***
> *   * * *

qwert y ...
.   . . .
Howard
źródło
10

Perl 6: 60 znaków EDYCJA : 38 punktów (patrz poniżej)

  #C#O     D#E#G#O       #L#
#F    #.#S#       T#A#C#K
  get\     .subst(       "*"
,{    shift       BEGIN [
  get\     .comb,\       "."
xx    * ]},       :g)\ .\
  say\     xx get\       ()\
#E    #X#C#       H#A#N#G
  #E#.     #C#O#M#       #!#

Jeśli nie doceniasz moich okropnych umiejętności plastycznych, oto golf:

get.subst("*",{shift BEGIN [get.comb,"."xx*]},:g).say xx get

Ten robi dziwne rzeczy z czasami oceny.

Po pierwsze, BEGINsłowo kluczowe wymusza [get.comb, "." xx *]ocenę w pierwszej kolejności, umieszczając w tablicy listę znaków tworzących „kod”, a następnie nieskończoną liczbę "."s.

Następnie getocenia się koniec na podstawie liczby wierszy szablonu sztuki ASCII. xxOperator powtarza pierwszej części programu to wiele razy. Ma to większy sens, gdy uświadomisz sobie, że code() xx count()jest to w zasadzie cukier code() for 1..count(): count()należy go najpierw ocenić.

Wreszcie getna początku programu pobierana jest linia szablonu sztuki ASCII i podstawia każdy "*"wartością przesuniętą od początku tablicy, którą utworzyliśmy przed wszystkim innym ( {shift BEGIN …}).

EDYTOWAĆ:

Grał w golfa do 37 znaków plus jeden dla przełącznika wiersza poleceń:

perl6 -pe's:g[\*]=shift BEGIN [get.comb,"."xx*]'

Jest to ta sama koncepcja, co oryginał, -pprzełącznik iteruje po każdej linii (po BEGINprzeczytaniu „kodu”) i zastępuje wszystkie *s kolejną literą z „kodu” przed wydrukowaniem. Format wejściowy tego nie powinien zawierać liczby wierszy formatu.

Mouq
źródło
6

Ruby 2.0, 53 52 znaki

c=gets.chop
$><<gets($n).gsub(?*){c.slice!(0)||?.}+c

Zgodnie ze specyfikacją nie używa parametru „liczba linii”.

Przykładowy przebieg:

qwertyuiopasd
***** * ***
*   * * *
*   * * *
***** * ***

Wynik:

qwert y uio
p   a s d
.   . . .
..... . ...
Paul Prestidge
źródło
1
./ascii.rb: line 2: syntax error near unexpected token `(' ./ascii.rb: line 2: `puts gets($n).gsub(?*){c.slice!(0)||?.},c'
Nie, że Charles
@Charles Nie mogę uzyskać tego błędu w żadnej zainstalowanej wersji Ruby. Oto kod działający na IDEONE: ideone.com/3HG3Fb
Paul Prestidge
dziwne. IDEONE działało dobrze. W każdym razie, można zaoszczędzić char (odstęp), zastępując puts z $><<i zmieniając ,na koniec do+
Nie dlatego, że Charles
@Charles Dobra rozmowa. Dzięki!
Paul Prestidge
2

PowerShell , 63 86 83 82 bajtów

+20 bajtów dzięki @Weskah

param($s,$p)-join($p|% *ht($s|% Le*)'*'|% t*y|%{if($_-eq42){$_=$s[$i++]}"$_."[0]})

Wypróbuj online!

Mniej golfa:

param($string,$pattern)

$chars = $pattern |
    % PadRight ($string|% Length) '*' |
    % toCharArray |
    % {
        if($_-eq42){$_=$string[$i++]}    # $_ can become $null
        "$_."[0]                         # $_ or '.' if $_ is $null
    }
-join($chars)
mazzy
źródło
2

Japt , 18 bajtów

sVè-)iVr-@t°J1 ª'.

Spróbuj

Kudłaty
źródło
sVl)iVr-@t°J1 ª'.pracuje dla 17
Embodiment of Ignorance
1
@EmbodimentofIgnorance, które zawiodłyby na 4 zasadzie. A
Kudłaty
2

T-SQL, 142 bajty

@h to tekst wejściowy

@ jest wzorem

DECLARE @h varchar(max)='qwertyuiopasdfg'
DECLARE @ varchar(max)='
***** * ***
*   * * *
*   * * *
***** * ***'

WHILE @ like'%*'SELECT @=left(@,charindex('*',@)-1)+left(@h+'.',1)+stuff(@,1,charindex('*',@),''),@h=substring(@h,2,999)PRINT
concat(@,'
'+@h)

Wypróbuj online

t-clausen.dk
źródło
2

Perl 5 -plF , 51 bajtów

$_=join'',<>;s/\*/@F?shift@F:'.'/ge;$\=$/.join'',@F

Wypróbuj online!

Xcali
źródło
1
Masz rację; Przegapiłem ten wymóg. Teraz jest naprawione.
Xcali,
1

JavaScript - 199

text="qwertyuiopasdfghjklzxcvbnm";
pattern="***** * ***\n*   * * *\n*   * * *\n***** * ***";

function p(a,c){z=c.length,y=a.length,x=0;for(i=z;i-->0;)if(c[i]=="*")x+=1;if(x-y>0)for(i=x-y;i-->0;)a+=".";for(;i++<x;)c=c.replace(new RegExp("[*]"),a[i]);console.log(c);console.log(a.substring(x))}

p(text,pattern);

Wypisuje dodatkowe znaki podczas wprowadzania tekstu, jeśli nie są używane we wzorcu, używa dopełnienia „.” jeśli nie ma wystarczającej ilości.

EDYCJA: zmodyfikowana, aby była funkcją akceptującą tekst i wzór

Matt
źródło
4
Fajnie ... ale wykorzystuje to zakodowane wejście.
TheDoctor
Nie byłem pewien, jak poradzić sobie ze standardem z JS, szczególnie w przypadku nowych linii. Propozycje?
Matt
@Matt Node? Pająk Małpa?
Nie, że Charles
Być może uczynienie go funkcją ...
TheDoctor
4
136:function p(a,c){x=c.split(s='*').length-1;for(i=x-a.length;i--;)a+='.';for(;i++<x;)c=c.replace(s,a[i]);console.log(c+'\n'+a.substring(x))}
Michael M.
1

JavaScript (ES6) - 96 87

r=(c,p)=>{c=0+c;console.log(p.replace(/\*/g,t=>(c=c.substr(1),c[0]||'.'))+c.substr(1))}

Uwaga: Jak sugeruje OP , używam funkcji. Ale jeśli wymagane jest posiadanie programu, oto rozwiązanie 93 znaków .

c=0+(x=prompt)();p=x();console.log(p.replace(/\*/g,t=>(c=c.substr(1),c[0]||'.'))+c.substr(1))

EDYCJA 1: Poważna zmiana, nie wiem, dlaczego nie zdałem sobie z tego sprawy po raz pierwszy: P Zapisałem 40 znaków.


Zastosowanie :

// r(code, pattern)
r("qwertyuiopasdfghjklzxcvbnm", "***** * ***\n*   * * *\n*   * * *\n***** * ***\n** ** **)

Wejście testowe : (bez zbędnego opcjonalnego numeru zgodnie ze specyfikacją)

qwertyuiopasdfghjklzxcvbnm
***** * ***
*   * * *
*   * * *
***** * ***
** ** **

Wyjście :

qwert y uio
p   a s d
f   g h j
klzxc v bnm
.. .. ..      // not much text was there to fill *s - replaced with dots as per spec

Nieskluczony kod :

function run(code, pattern){
  code = "0" + code;  // prepend a zero; useful for the substring operation ahead

  pattern = pattern.replace(/\*/g, function(){  // replace the dots
    // by removing the first letter of code
    // and replacing dot with the first-letter of leftover code 
    // and if it isn't there (code finished)
    // return a dot

    code = code.substr(1); 
    return c[0] || '.';
  });
  }

  // after this operation; code contains the last letter of the org. code

  console.log(  p +  // the pattern has now code
                "\n" +   // and a newline
                c.substr(1) // if there is more than one letter of code left; display it
             );
}

Byłoby bardzo miło usłyszeć o sugestiach użytkowników :)

Gaurang Tandon
źródło
1

Perl, 70 znaków

@_=split'',<>=~s/\n//r;<>;print/\*/?shift@_||'.':$_ for map{split''}<>

Lub bez kontroli granicy 56 znaków

@_=split'',<>;<>;print/\*/?shift@_:$_ for map{split''}<>

Uwaga: ten kod nie używa drugiej linii jak w specyfikacji i może zostać skrócony o trzy znaki <>;

m1el
źródło
1

Grzmotnąć, 166 156 111 106

Odczytuje ze standardowego wejścia, nie pobiera liczby wierszy. Pierwszy wiersz wprowadzania to kod, który chcesz umieścić w sztuce ascii, wszystkie kolejne wiersze to sztuka ascii, składająca się ze @znaku. Dane wejściowe mają maksymalną długość 999 znaków i nie mogą zawierać ukośników . (Nie zdecydowałem się używać *lub #ponieważ mają one specjalne znaczenie w Bash).

read -n999 -d/ i p
while [[ $p =~ @ && -n $i ]];do
p="${p/@/${i:0:1}}"
i=${i:1}
done
tr @ .<<<"$p"
echo $i

OSTRZEŻENIE: Ten program używa pliku o nazwie p. Po uruchomieniu programu, usuń p- pomyli program przy drugim uruchomieniu.

Większość pracy tutaj wykonuje

p="${p/@/${i:0:1}}"
i=${i:1}

Pierwszy wiersz zastępuje pierwszy @w tej dziedzinie pierwszym znakiem kodu. Drugi wiersz usuwa pierwszy znak kodu.

Jeśli nie ma wystarczającej ilości kodu, aby wypełnić kształt, nowa linia jest drukowana po głównym wydruku ascii art echo $i.


źródło
1

C, 98 , 91 znaków

Tutaj całkiem proste rozwiązanie C w mniej niż 100 znaków. Nie korzysta z danych wejściowych licznika linii. (W przeciwnym razie potrzebna byłaby druga niepotrzebna metoda get ()).

char b[999],*s;c;main(){gets(s=b);while(~(c=getchar()))putchar(c^42?c:*s?*s++:46);puts(s);}

bez golfa:

char b[999],*s;c;
main(){
    gets(s=b);
    while(~(c=getchar()))
        putchar(c^42?c:*s?*s++:46);
    puts(s);
}
MarcDefiant
źródło
Możesz użyć puts(s)zamiast printf("%s",s)zapisać 7 bajtów.
nyuszika7h
@ nyuszika7h Thanks! Ale nie wiem, czy \nproblem stanowi problem.
MarcDefiant
1

Python 2.7, 165 155 150 138 119 znaków

Dobra, właściwie, ale myślę, że to najmniejszy sposób na zrobienie tego z Pythonem.

import sys
r=raw_input
l=list(r())
w=sys.stdout.write
for c in"\n".join([r()for _ in[1]*input()]):w(c=='*'and(l and l.pop(0)or'.')or c)
w("".join(l))

Edycja: nowa funkcjonalna wersja 1.0.1 z jeszcze mniejszą liczbą używanych bajtów:

Edycja2: map(r,['']*input()) zamiast [r()for _ in[1]*input()]i usunięto nieużywany import

Edycja3: '>'*input() zamiast ['']*input()zapisywać jeden znak i dodawać znak zachęty do wzorca :)

r=raw_input
l=list(r())
print''.join(map(lambda c:c=='*'and(l and l.pop(0)or'.')or c,"\n".join(map(r,'>'*input())))+l)
avall
źródło
Możesz użyć (['.']+l).pop(0)zamiast (len(l)and l.pop(0)or'.')zapisać 9 bajtów. I input()zamiast int(r())zaoszczędzić 1 bajt.
nyuszika7h
Dzięki za input! Niestety twoja pierwsza rada nie działa, ponieważ wyświetla kropki o długości łańcucha> 0.
avall
Rozumiem, dlaczego moja sugestia jest nieprawidłowa. Spróbuj (l+['.']).pop(0)zamiast tego, ale jeśli to nie zadziała, nadal możesz zapisać 4 bajty, używając l andzamiast len(l)and.
nyuszika7h
(l+['.']).pop(0)nie usuwa elementów z, lwięc drukowany jest tylko pierwszy znak, ale lwarunek działa :)
avall
1

C # (interaktywny kompilator Visual C #) , 122 bajty

var n=ReadLine();int k=0;foreach(var z in In.ReadToEnd())Write(z>33?(n+new string('.',999))[k++]:z);Write(n.Substring(k));

Wypróbuj online!

Wcielenie ignorancji
źródło
Ze względu na brak szczegółowych informacji i innych odpowiedzi, które możesz to zrobić, prawdopodobnie możesz "\n"+
porzucić
0

05AB1E , 18 17 15 bajtów

s0¢.$«0¹S.;0'.:

Pobiera kod jako pierwsze wejście, wzorzec jako drugie ( 0zamiast zamiast# ).

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

18 15 bajtów alternatywnych, przyjmując dane wejściowe w odwrotnej kolejności:

0¢.$¹ì0IS.;0'.:

Wypróbuj online .

Wyjaśnienie:

s                # Swap with implicit inputs, so the stack order is now: [code, pattern]
 0¢              # Count the amount of "0" in the pattern
   .$            # Remove that many leading characters from the code
     «           # Append it to the (implicit) pattern input
      0¹S.;      # Replace every "0" one by one with the characters of the first code input
           0'.: '# Then replace any remaining "0" with "."
                 # (after which the result is output implicitly as result)
Kevin Cruijssen
źródło