Il modo semplice per codificare golf ascii art!


18

Compito:

Ci sono molte risposte su questo sito che sono disposte in arte ascii, come questa . Di solito la disposizione è fatta manualmente, ma un programma non sarebbe d'aiuto? :)

Il tuo programma avrà 3 input:

  • Il codice, come un'unica riga
  • Il numero di linee nel modello (può essere omesso se non necessario)
  • Il modello stesso, come *se un altro personaggio

Regole:

  • Devi scrivere un programma (non una funzione) che legge dallo stdin
  • Il testo viene posizionato da sinistra a destra per riga
  • Se il testo non è sufficiente per riempire il motivo, inserire .s negli spazi rimanenti
  • Se è presente troppo testo per riempire il motivo, stamparlo dopo l'output
  • vince il , quindi il codice più breve, in byte

Esecuzioni campione:

Input (test di adattamento esatto) :

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

Uscita :

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

Input (Test caratteri extra) :

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

Uscita :

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

Input (test caratteri insufficienti) :

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

Uscita :

qwert y uio
p   a s d
f   g . .
..... . ...

2
Quali ipotesi dovrebbero essere fatte su dove è consentito inserire spazi e newline senza cambiare la semantica del programma?
Peter Taylor,

1
@PeterTaylor sembra che non ci sia margine per posizionare / separare il codice, quindi suppongo che la semantica venga ignorata?
Martin Ender,

1
Se le parti "possono essere omesse" e "o un altro carattere" della specifica significano che siamo liberi di, diciamo, specificare che il numero di linee deve essere omesso e che gli asterischi dovrebbero essere sostituiti, diciamo, Xper il nostro programma per lavorare?
Ilmari Karonen,

1
@Bakuriu Non capisco il tuo commento. Se scrivi un programma in ASCII, ogni carattere è un byte. Se scrivi in ​​UTF-32, ogni carattere è di 4 byte. Il codice più breve in byte , non in caratteri, vince in base alle specifiche correnti. Sembra che tu voglia che la codifica diventi un requisito, ma non vedo perché sia ​​necessario. Ho frainteso il tuo commento?
Rainbolt,

1
Sulla base di alcune risposte mancanti di alcune regole, ho aggiunto due esempi e ho spostato l'intero blocco di esempio sotto il blocco di regole per maggiore chiarezza.
Veskah,

Risposte:


5

GolfScript, 30 caratteri

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

Corri online .

Esempi:

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

10

Perl 6: 60 caratteri MODIFICA : 38 punti (vedi sotto)

  #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#       #!#

Se non apprezzi le mie terribili abilità artistiche, ecco il golf:

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

Questo fa cose strane con i tempi di valutazione.

Innanzitutto, la BEGINparola chiave forza[get.comb, "." xx *] di essere valutata per prima, inserendo in una matrice l'elenco di caratteri che compongono "il codice", seguito da una quantità infinita di "."s.

Successivamente, getviene valutata la fine, ottenendo il numero di linee del modello di arte ASCII. L' xxoperatore ripete la prima parte del programma molte volte. Questo ha più senso quando ti rendi conto che code() xx count()è fondamentalmente zucchero per code() for 1..count():count() dovrebbe essere valutato prima.

Infine, getall'inizio del programma ottiene una linea del modello di arte ASCII e sostituisce ognuna "*"con un valore spostato rispetto all'inizio dell'array che abbiamo creato prima di ogni altra cosa ({shift BEGIN …} ).

MODIFICARE:

Giocato a golf fino a 37 caratteri, più uno per l'interruttore della riga di comando:

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

Questo è lo stesso concetto dell'originale, l' -pinterruttore passa da una riga all'altra (dopo che BEGINha letto "il codice") e sostituisce tutti *i messaggi con la lettera successiva da "il codice" prima di stamparlo. Il formato di input per questo non dovrebbe includere il numero di righe del formato.


6

Ruby 2.0, 53 52 caratteri

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

Secondo le specifiche, non utilizza il parametro "numero di righe".

Esempio di esecuzione:

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

Produzione:

qwert y uio
p   a s d
.   . . .
..... . ...

1
./ascii.rb: line 2: syntax error near unexpected token `(' ./ascii.rb: line 2: `puts gets($n).gsub(?*){c.slice!(0)||?.},c'
Non che Charles

@Charles Non riesco a ottenere quell'errore in nessuna versione di Ruby che ho installato. Ecco il codice in esecuzione su IDEONE: ideone.com/3HG3Fb
Paul Prestidge

strano. IDEONE ha funzionato bene. Ad ogni modo, puoi salvare un carattere (lo spazio) sostituendolo puts con $><<e cambiando il ,alla fine in un+
Non che Charles

@Charles Buona chiamata. Grazie!
Paul Prestidge,

2

PowerShell , 63 86 83 82 byte

+20 byte grazie @Veskah

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

Provalo online!

Meno golf:

param($string,$pattern)

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


2

T-SQL, 142 byte

@h è il testo di input

@ è lo schema

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)

Provalo online



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);

Emette caratteri extra nell'input di testo se non viene utilizzato nel modello, usa "". se non c'è abbastanza.

EDIT: modificato per essere una funzione che accetta testo e pattern


4
Bello ... ma questo utilizza input hardcoded.
TheDoctor

Non ero sicuro di come gestire lo stdin di JS, specialmente con le nuove linee. Suggerimenti?
Matt,

@Matt Node? Ragno scimmia?
Non che Charles

Forse rendendolo una funzione ...
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))}

Nota: come suggerito dall'OP , sto usando una funzione. Ma se è richiesto un programma, ecco una soluzione di 93 caratteri .

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

EDIT1: grande cambiamento, non so perché non me ne sono reso conto per la prima volta: P ha salvato 40 caratteri.


Utilizzo :

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

Test Input : (senza numero opzionale non necessario come da specifica)

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

Uscita :

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

Codice Ungolfed :

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
             );
}

Sarebbe molto bello conoscere eventuali suggerimenti degli utenti :)


1

Perl, 70 caratteri

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

Oppure, senza controllo dei confini, 56 caratteri

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

Nota, questo codice non utilizza la seconda riga come nelle specifiche e può essere abbreviato di tre caratteri <>;


1

bash, 166 156 111 106

Legge da input standard, non prende un conteggio di riga. La prima riga di input è il codice che si desidera inserire nell'arte ascii, tutte le righe successive sono l'arte ascii, costituita dal @carattere. L'input ha una lunghezza massima di 999 caratteri e non può contenere barre . (Ho scelto di non usare *o #perché hanno significati speciali in Bash).

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

ATTENZIONE: questo programma utilizza un file chiamato p. Dopo aver eseguito il programma, eliminarep : confonderà il programma la seconda volta che lo avvii.

La maggior parte del lavoro qui è svolto da

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

La prima riga sostituisce la prima @ nell'arte con il primo carattere del codice. La seconda riga rimuove il primo carattere del codice.

Se non c'è abbastanza codice per riempire la forma, viene stampata una nuova riga dopo l'output principale di arte ASCII echo $i.


1

C, 98 , 91 caratteri

Ecco una soluzione C piuttosto semplice in meno di 100 caratteri. Questo non utilizza l'input del conteggio di riga. (Altrimenti sarebbe necessario un secondo non necessario ()).

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

ungolfed:

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

È possibile utilizzare puts(s)invece di printf("%s",s)salvare 7 byte.
nyuszika7h,

@nyuszika7h Grazie! Ma non so se l'ulteriore \nsia un problema.
MarcDefiant,

1

Python 2.7, 165 155 150 138 119 caratteri

Okay, praticamente ma immagino sia il modo più piccolo per farlo con Python.

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

Modifica: nuova versione funzionale 1.0.1 con ancora meno byte utilizzati:

Modifica2: map(r,['']*input()) anziché [r()for _ in[1]*input()]e rimosso importazione inutilizzata

Edit3: '>'*input() invece di ['']*input()salvare un carattere e aggiungere un carattere di prompt per il modello :)

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)

È possibile utilizzare (['.']+l).pop(0)invece di (len(l)and l.pop(0)or'.')salvare 9 byte. E input()invece di int(r())salvare 1 byte.
nyuszika7h,

Grazie per input! Sfortunatamente il tuo primo consiglio non funziona perché genera punti lunghi quanto la lunghezza della stringa> 0.
Avall

Vedo perché il mio suggerimento non è corretto. Prova (l+['.']).pop(0)invece, ma se neanche questo funziona, puoi comunque salvare 4 byte usando l andinvece di len(l)and.
nyuszika7h

(l+['.']).pop(0)non rimuove gli elementi da lcosì viene stampato solo il primo carattere mal condizione funziona :)
avall


0

05AB1E , 18 17 15 byte

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

Prende il codice come primo input, modello come secondo (con 0invece di# ).

Provalo online o verifica tutti i casi di test .

18 15 byte alternativi prendendo gli input in ordine inverso:

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

Provalo online .

Spiegazione:

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)
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.