A maneira mais fácil de codificar arte ascii de golfe!


18

Tarefa:

Existem muitas respostas neste site que são organizadas em arte ascii, como esta . Normalmente, o arranjo é feito manualmente, mas um programa não ajudaria nisso? :)

Seu programa terá três entradas:

  • O código, como uma única linha
  • O número de linhas no padrão (pode ser omitido se não for necessário)
  • O próprio padrão, como *s ou outro caractere

Regras:

  • Você precisa escrever um programa (não uma função) que leia stdin
  • O texto é colocado da esquerda para a direita por linha
  • Se não houver texto suficiente para preencher o padrão, coloque .s nos espaços restantes
  • Se houver muito texto para preencher o padrão, imprima-o após a saída
  • , então o código mais curto, em bytes, vence

Execuções de amostra:

Entrada (teste de ajuste exato) :

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

Saída :

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

Entrada (teste de caracteres extras) :

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

Saída :

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

Entrada (teste de caracteres insuficientes) :

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

Saída :

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

2
Que suposições devem ser feitas sobre onde é permitido inserir espaços e novas linhas sem alterar a semântica do programa?
Peter Taylor

1
@ PeterTaylor, parece que não há margem para colocar / separar o código, então suponho que a semântica seja ignorada?
Martin Ender

1
As partes "pode ​​ser omitida" e "ou outro caractere" da especificação significam que somos livres para, por exemplo, especificar que o número de linhas deve ser omitido e que os asteriscos devem ser substituídos por, digamos, Xes para programa para trabalhar?
Ilmari Karonen

1
@ Bakuriu Não entendo o seu comentário. Se você escrever um programa em ASCII, cada caractere será um byte. Se você escrever em UTF-32, cada caractere terá 4 bytes. O código mais curto em bytes , não em caracteres, vence de acordo com a especificação atual. Parece que você deseja que a codificação se torne um requisito, mas não vejo por que é necessário. Eu entendi mal o seu comentário?
Rainbolt

1
Com base em algumas respostas que faltam em algumas regras, adicionei dois exemplos e movi o bloco de exemplo inteiro abaixo do bloco de regras para maior clareza.
Veskah

Respostas:


5

GolfScript, 30 caracteres

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

Execute online .

Exemplos:

> 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

Edição 6: 60 caracteres Perl : 38 pontos (veja abaixo)

  #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 você não aprecia minhas terríveis habilidades artísticas, aqui está o golfe:

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

Este faz coisas estranhas com os tempos de avaliação.

Primeiro, o BEGIN palavra chave força [get.comb, "." xx *]a ser avaliada primeiro, colocando em uma matriz a lista de caracteres que compõem "o código", seguida por uma quantidade infinita de "."s.

Em seguida, o getfinal é avaliado, obtendo o número de linhas do modelo de arte ASCII. O xxoperador repete a primeira parte do programa várias vezes. Isso faz mais sentido quando você percebe que code() xx count()é basicamente açúcar paracode() for 1..count() : count()deve ser avaliado primeiro.

Finalmente, getno início do programa, obtém uma linha do modelo de arte ASCII e substitui todos os"*" um com um valor deslocado do início da matriz que criamos antes de todo o resto ( {shift BEGIN …}).

EDITAR:

Jogou até 37 caracteres, mais um para a opção de linha de comando:

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

Esse é o mesmo conceito que o original, o -pcomutador iterando sobre cada linha (após a BEGINleitura do "código") e substituindo todos os *s pela letra seguinte do "código" antes de imprimi-lo. O formato de entrada para isso não deve incluir o número de linhas do formato.


6

Ruby 2.0, 53 52 caracteres

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

De acordo com a especificação, não usa o paramater 'número de linhas'.

Exemplo de execução:

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

Resultado:

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'
Não que Charles seja

@ Charles Não consigo obter esse erro em nenhuma versão do Ruby que eu instalei. Aqui está o código em execução no IDEONE: ideone.com/3HG3Fb
Paul Prestidge

esquisito. IDEONE funcionou bem. De qualquer forma, você pode salvar um char (o espaço), substituindo puts com $><<e mudando o ,no final para um+
Não que Charles

@ Charles Boa chamada. Obrigado!
Paul Prestidge

2

PowerShell , 63 86 83 82 bytes

+20 bytes obrigado @Veskah

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

Experimente online!

Menos golfe:

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 bytes

@h é o texto de entrada

@ é o padrão

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)

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

Gera caracteres extras na entrada de texto, se não for usado no padrão, usa "." se não houver o suficiente.

EDIT: modificado para ser uma função que aceita texto e padrão


4
Bom ... mas isso usa entrada codificada.
TheDoctor

Eu não tinha certeza de como lidar com o stdin do JS, especialmente com as novas linhas. Sugestões?
Matt

@Matt Node? Macaco aranha?
Não que Charles seja

Talvez tornando uma função ...
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: Conforme sugerido pelo OP , estou usando uma função. Mas se for necessário ter um programa, aqui está uma solução de 93 caracteres .

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

EDIT1: Grande mudança, não sei por que não percebi isso pela primeira vez: P Salvei 40 caracteres.


Uso :

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

Entrada de teste : (sem número opcional desnecessário conforme a especificação)

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

Saída :

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

Código 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
             );
}

Seria muito bom ouvir sugestões de usuários :)


1

Perl, 70 caracteres

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

Ou, sem verificação de limite, 56 caracteres

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

Observe que este código não está usando a segunda linha como na especificação e pode ser reduzido por três caracteres <>;


1

Bater, 166 156 111 106

Lê da entrada padrão, não leva uma contagem de linhas. A primeira linha de entrada é o código que você deseja inserir na arte ascii, todas as linhas subseqüentes são a arte ascii, consistindo no @caractere. A entrada tem um comprimento máximo de 999 caracteres e não tem permissão para conter barras . (Optei por não usar *ou #porque eles têm significados especiais no Bash).

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

AVISO: Este programa usa um arquivo chamado p. Depois de executar o programa, exclua p- ele confundirá o programa na segunda vez em que você o executar.

A maior parte do trabalho aqui é feita por

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

A primeira linha substitui a primeira @na técnica pelo primeiro caractere do código. A segunda linha remove o primeiro caractere do código.

Se não houver código suficiente para preencher a forma, uma nova linha será impressa após a saída principal da arte ASCII echo $i.


1

C, 98 , 91 caracteres

Aqui está uma solução C bastante direta, com menos de 100 caracteres. Isso não usa a entrada de contagem de linhas. (Caso contrário, seria necessário um segundo get desnecessário ()).

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

Você pode usar em puts(s)vez de printf("%s",s)salvar 7 bytes.
Nyuszika7h

@ nyuszika7h Obrigado! Mas não sei se o adicional \né um problema.
MarcDefiant

1

Python 2.7, 165 155 150 138 119 caracteres

Ok, praticamente, mas acho que é a menor maneira de fazer isso com o 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))

Edit: nova versão 1.0.1 funcional com menos bytes usados:

Edit2: em map(r,['']*input()) vez de [r()for _ in[1]*input()]e removida importação não utilizada

Edit3: em '>'*input() vez de ['']*input()salvar um caractere e adicionar um caractere de prompt para o padrão :)

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)

Você pode usar em (['.']+l).pop(0)vez de (len(l)and l.pop(0)or'.')salvar 9 bytes. E em input()vez de int(r())salvar 1 byte.
Nyuszika7h

Obrigado por input! Infelizmente, seu primeiro conselho não funciona porque gera pontos contanto que o comprimento da string seja> 0.
Avall

Vejo por que minha sugestão não está correta. Tente em (l+['.']).pop(0)vez disso, mas se isso também não funcionar, você ainda poderá salvar 4 bytes usando em l andvez de len(l)and.
precisa saber é o seguinte

(l+['.']).pop(0)não remove elementos de ltão somente primeiro caractere é impresso, mas lcondição funciona :)
avall


0

05AB1E , 18 17 15 bytes

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

Pega o código como primeira entrada, padrão como segundo (com em 0vez de #).

Experimente online ou verifique todos os casos de teste .

Alternativa de 18 bytes usando as entradas na ordem inversa:

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

Experimente online .

Explicação:

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)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.