¡La manera fácil de codificar el arte ascii del golf!

18

Tarea:

Hay muchas respuestas en este sitio que están organizadas en arte ascii, como esta . Por lo general, el arreglo se realiza manualmente, pero ¿no ayudaría un programa con eso? :)

Su programa tomará 3 entradas:

  • El código, como una sola línea.
  • El número de líneas en el patrón (puede omitirse si no es necesario)
  • El patrón en sí, como *s u otro carácter

Reglas:

  • Tienes que escribir un programa (no una función) que lea desde stdin
  • El texto se coloca de izquierda a derecha por línea.
  • Si no hay suficiente texto para llenar el patrón, coloque .s en los espacios restantes
  • Si hay demasiado texto para llenar el patrón, imprímalo después de la salida
  • , entonces el código más corto, en bytes, gana

Ejecuciones de muestra:

Entrada (prueba de ajuste exacto) :

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

Salida :

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

Entrada (prueba de caracteres adicionales) :

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

Salida :

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

Entrada (prueba de caracteres insuficientes) :

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

Salida :

qwert y uio
p   a s d
f   g . .
..... . ...
TheDoctor
fuente
2
¿Qué suposiciones deben hacerse sobre dónde está permitido insertar espacios y líneas nuevas sin cambiar la semántica del programa?
Peter Taylor
1
@PeterTaylor parece que no hay margen para colocar / separar el código, ¿así que supongo que se ignora la semántica?
Martin Ender
1
Si las partes "puede omitirse" y "u otro carácter" de la especificación significan que somos libres de, por ejemplo, especificar que se debe omitir el número de líneas y que los asteriscos se deben reemplazar por, digamos, Xes programa para trabajar?
Ilmari Karonen
1
@Bakuriu No entiendo tu comentario. Si escribe un programa en ASCII, cada carácter es un byte. Si escribe en UTF-32, cada carácter tiene 4 bytes. El código más corto en bytes , no caracteres, gana según la especificación actual. Parece que desea que la codificación se convierta en un requisito, pero no veo por qué es necesario. ¿Entendí mal tu comentario?
Rainbolt
1
Basado en algunas respuestas que faltan algunas de las reglas, agregué dos ejemplos y moví todo el bloque de ejemplos debajo del bloque de reglas para mayor claridad.
Veskah

Respuestas:

5

GolfScript, 30 caracteres

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

Corre en línea .

Ejemplos:

> 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
fuente
10

Perl 6: 60 caracteres EDITAR : 38 puntos (ver abajo)

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

Si no aprecia mis terribles habilidades artísticas, aquí está el golf:

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

Este hace cosas raras con los tiempos de evaluación.

Primero el BEGIN palabra clave obliga [get.comb, "." xx *]a ser evaluada primero, colocando en una matriz la lista de caracteres que componen "el código", seguido de una cantidad infinita de "."s.

A continuación, getse evalúa al final, obteniendo el número de líneas de la plantilla de arte ASCII. El xxoperador repite la primera parte del programa tantas veces. Esto tiene más sentido cuando te das cuenta de quecode() xx count() básicamente es azúcar para code() for 1..count(): count()debe evaluarse primero.

Finalmente, el get comienzo del programa se obtiene una línea de la plantilla de arte ASCII y se sustituye cada "*"una con un valor desplazado del comienzo de la matriz que hicimos antes que todo lo demás ( {shift BEGIN …}).

EDITAR:

Bajó a 37 caracteres, más uno para el cambio de línea de comando:

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

Este es el mismo concepto que el original, el -pinterruptor itera sobre cada línea (después de BEGINhaber leído "el código") y sustituye todas las *s con la siguiente letra de "el código" antes de imprimirlo. El formato de entrada para esto no debe incluir el número de líneas del formato.

Mouq
fuente
6

Ruby 2.0 53 52 caracteres

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

Según la especificación, no utiliza el parámetro 'número de líneas'.

Ejemplo de ejecución:

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

Salida:

qwert y uio
p   a s d
.   . . .
..... . ...
Paul Prestidge
fuente
1
./ascii.rb: line 2: syntax error near unexpected token `(' ./ascii.rb: line 2: `puts gets($n).gsub(?*){c.slice!(0)||?.},c'
No es que Charles
@Charles Parece que no puedo obtener ese error en ninguna versión de Ruby que haya instalado. Aquí está el código que se ejecuta en IDEONE: ideone.com/3HG3Fb
Paul Prestidge
extraño. IDEONE funcionó bien. De todos modos, puede guardar un char (el espacio) reemplazando puts con $><<y cambiando el ,al final a un+
No es que Charles
@Charles Buena llamada. ¡Gracias!
Paul Prestidge
2

PowerShell , 63 86 83 82 bytes

+20 bytes gracias @Veskah

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

Pruébalo en línea!

Menos golfizado:

param($string,$pattern)

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

Japt , 18 bytes

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

Intentalo

Lanudo
fuente
sVl)iVr-@t°J1 ª'.funciona para 17
Encarnación de la ignorancia
1
@EmbodimentofIgnorance, eso fallaría en la 4ta regla. A
Shaggy
2

T-SQL, 142 bytes

@h es el texto de entrada

@ es el patrón

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)

Pruébalo en línea

t-clausen.dk
fuente
2

Perl 5 -plF , 51 bytes

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

Pruébalo en línea!

Xcali
fuente
1
Tienes razón; Perdí ese requisito. Ya está arreglado.
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);

Emite caracteres adicionales en la entrada de texto si no se usa en el patrón, usa ". si no hay suficiente

EDITAR: modificado para ser una función que acepta texto y patrón

Mate
fuente
44
Agradable ... pero esto usa una entrada codificada.
TheDoctor
No estaba seguro de cómo manejar stdin de JS, especialmente con las nuevas líneas. Sugerencias?
Matt
@ Nodo Matt? ¿Mono araña?
No es que Charles
Quizás haciéndolo una función ...
TheDoctor
44
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: Según lo sugerido por el OP , estoy usando una función. Pero si se requiere tener un programa, aquí hay una solución de 93 caracteres .

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

EDITAR1: Cambio importante, no sé por qué no me di cuenta de esto por primera vez: P Guardado 40 caracteres.


Uso :

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

Entrada de prueba : (sin número opcional innecesario según la especificación)

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

Salida :

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 sin golf :

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

Sería muy bueno escuchar cualquier sugerencia de los usuarios :)

Gaurang Tandon
fuente
1

Perl, 70 caracteres.

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

O, sin verificación de límites, 56 caracteres

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

Tenga en cuenta que este código no usa la segunda línea como se especifica y puede acortarse en tres caracteres <>;

m1el
fuente
1

Golpetazo, 166 156 111 106

Lee desde la entrada estándar, no toma un recuento de líneas. La primera línea de entrada es el código que desea poner en el arte ascii, todas las líneas siguientes son el arte ascii, que consiste en el @carácter. La entrada tiene una longitud máxima de 999 caracteres y no puede contener barras diagonales . (Elegí no usar *o #porque tienen significados especiales en Bash).

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

ADVERTENCIA: Este programa usa un archivo llamado p. Después de ejecutar el programa, elimine p; confundirá el programa la segunda vez que lo ejecute.

La mayor parte del trabajo aquí es realizado por

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

La primera línea sustituye la primera @en la técnica con el primer carácter del código. La segunda línea elimina el primer carácter del código.

Si no hay suficiente código para llenar la forma, se imprime una nueva línea después de la salida principal de arte ascii por echo $i.


fuente
1

C, 98 , 91 caracteres

Aquí una solución C bastante sencilla en menos de 100 caracteres. Esto no usa la entrada de conteo de línea. (De lo contrario, se necesitaría un segundo gets () innecesario).

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

sin golf:

char b[999],*s;c;
main(){
    gets(s=b);
    while(~(c=getchar()))
        putchar(c^42?c:*s?*s++:46);
    puts(s);
}
MarcDefiant
fuente
Puede usar en puts(s)lugar de printf("%s",s)guardar 7 bytes.
nyuszika7h
@ nyuszika7h ¡Gracias! Pero no sé si el adicional \nes un problema.
MarcDefiant
1

Python 2.7, 165 155 150 138 119 caracteres

De acuerdo, más o menos, pero supongo que es la forma más pequeña de hacerlo 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))

Editar: nueva versión funcional 1.0.1 con incluso menos bytes utilizados:

Edit2: en map(r,['']*input()) lugar de [r()for _ in[1]*input()]y eliminado la importación no utilizada

Edit3: en '>'*input() lugar de ['']*input()guardar un carácter y agregar un carácter de solicitud para el patrón :)

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
fuente
Puede usar en (['.']+l).pop(0)lugar de (len(l)and l.pop(0)or'.')guardar 9 bytes. Y en input()lugar de int(r())guardar 1 byte.
nyuszika7h
Gracias por input! Lamentablemente, su primer consejo no funciona porque genera puntos siempre que la longitud de la cadena> 0.
avall
Veo por qué mi sugerencia no es correcta. Intente en su (l+['.']).pop(0)lugar, pero si eso tampoco funciona, aún puede guardar 4 bytes utilizando en l andlugar de len(l)and.
nyuszika7h
(l+['.']).pop(0)no elimina elementos de lmodo que sólo primer carácter se imprime, pero lla condición funciona :)
Avall
1

C # (compilador interactivo de Visual C #) , 122 bytes

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

Pruébalo en línea!

Encarnación de la ignorancia
fuente
Debido a la falta de detalles y otras respuestas para hacerlo, probablemente puedas "\n"+
deshacerte de ellos
0

05AB1E , 18 17 15 bytes

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

Toma el código como primera entrada, el patrón como segundo (con en 0lugar de #).

Pruébalo en línea o verifique todos los casos de prueba .

18 años Alternativa 15 bytes tomando las entradas en orden inverso:

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

Pruébalo en línea .

Explicación:

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
fuente