Le moyen facile de coder le golf ascii art!

18

Tâche:

Il y a beaucoup de réponses sur ce site qui sont organisées en art ascii, comme celle-ci . Habituellement, l'arrangement est fait manuellement, mais un programme ne vous aiderait-il pas? :)

Votre programme prendra 3 entrées:

  • Le code, en une seule ligne
  • Le nombre de lignes dans le motif (peut être omis si ce n'est pas nécessaire)
  • Le motif lui-même, comme *s ou un autre caractère

Règles:

  • Vous devez écrire un programme (pas une fonction) qui lit depuis stdin
  • Le texte est placé de gauche à droite par ligne
  • S'il n'y a pas assez de texte pour remplir le motif, mettez .s dans les espaces restants
  • S'il y a trop de texte pour remplir le motif, imprimez-le après la sortie
  • , donc le code le plus court, en octets, gagne

Exemples de cycles:

Entrée (test d'ajustement exact) :

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

Sortie :

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

Saisie (test de caractères supplémentaires) :

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

Sortie :

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

Entrée (test de caractères insuffisants) :

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

Sortie :

qwert y uio
p   a s d
f   g . .
..... . ...
Le docteur
la source
2
Quelles hypothèses faut-il faire sur les endroits où il est permis d'insérer des espaces et des nouvelles lignes sans changer la sémantique du programme?
Peter Taylor
1
@PeterTaylor, il semble qu'il n'y ait pas de latitude pour placer / séparer le code, donc je suppose que la sémantique est ignorée?
Martin Ender
1
Est-ce que les parties "peut être omis" et "ou un autre caractère" de la spécification signifient que nous sommes libres, par exemple, de spécifier que le nombre de lignes doit être omis et que les astérisques doivent être remplacés par, disons, Xes pour notre programme pour travailler?
Ilmari Karonen
1
@Bakuriu Je ne comprends pas votre commentaire. Si vous écrivez un programme en ASCII, chaque caractère est un octet. Si vous écrivez en UTF-32, alors chaque caractère fait 4 octets. Le code le plus court en octets , pas en caractères, gagne selon la spécification actuelle. Il semble que vous souhaitiez que l'encodage devienne une exigence, mais je ne vois pas pourquoi il est nécessaire. Ai-je mal compris votre commentaire?
Rainbolt
1
Sur la base de certaines réponses manquant certaines des règles, j'ai ajouté deux exemples et déplacé l'ensemble du bloc d'exemple sous le bloc de règles pour plus de clarté.
Veskah

Réponses:

5

GolfScript, 30 caractères

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

Exécutez en ligne .

Exemples:

> 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
la source
10

Perl 6: 60 caractères EDIT : 38 points (voir en bas)

  #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 vous n'appréciez pas mes terribles compétences artistiques, voici le golf:

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

Celui-ci fait des choses étranges avec les temps d'évaluation.

Premièrement, le BEGINmot - clé force [get.comb, "." xx *]à être évalué en premier, en mettant dans un tableau la liste des caractères qui composent "le code", suivi d'une quantité infinie de "."s.

Ensuite, le getà la fin est évalué, obtenant le nombre de lignes du modèle d'art ASCII. L' xxopérateur répète la première partie du programme autant de fois. Cela a plus de sens lorsque vous réalisez que code() xx count()c'est essentiellement du sucre pour code() for 1..count(): count()doit être évalué en premier.

Enfin, le getdébut du programme obtient une ligne du modèle d'art ASCII et remplace chacun "*"par une valeur décalée par rapport au début du tableau que nous avons créé avant tout le reste ( {shift BEGIN …}).

ÉDITER:

Golfé jusqu'à 37 caractères, plus un pour le commutateur de ligne de commande:

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

Il s'agit du même concept que l'original, le -pcommutateur itérant sur chaque ligne (après que le BEGINa lu dans "le code"), et en remplaçant tous les *s par la lettre suivante du "code" avant de l'imprimer. Le format d'entrée pour cela ne doit pas inclure le nombre de lignes du format.

Mouq
la source
6

Ruby 2.0, 53 52 caractères

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

Selon la spécification, n'utilise pas le paramètre "nombre de lignes".

Exemple d'exécution:

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

Production:

qwert y uio
p   a s d
.   . . .
..... . ...
Paul Prestidge
la source
1
./ascii.rb: line 2: syntax error near unexpected token `(' ./ascii.rb: line 2: `puts gets($n).gsub(?*){c.slice!(0)||?.},c'
Pas que Charles
@Charles Je n'arrive pas à obtenir cette erreur dans n'importe quelle version de Ruby que j'ai installée. Voici le code en cours d'exécution sur IDEONE: ideone.com/3HG3Fb
Paul Prestidge
bizarre. IDEONE a bien fonctionné. Quoi qu'il en soit, vous pouvez enregistrer un caractère (l'espace) en remplaçant puts par $><<et en changeant le ,à la fin en un+
Pas que Charles
@Charles Bon appel. Merci!
Paul Prestidge
2

PowerShell , 63 86 83 82 octets

+20 octets merci @Veskah

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

Essayez-le en ligne!

Moins golfé:

param($string,$pattern)

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

Japt , 18 octets

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

Essayez-le

Hirsute
la source
sVl)iVr-@t°J1 ª'.fonctionne pour 17
Incarnation de l'ignorance
1
@EmbodimentofIgnorance, cela échouerait sur la 4ème règle.a
Shaggy
2

T-SQL, 142 octets

@h est le texte saisi

@ est le motif

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)

Essayez-le en ligne

t-clausen.dk
la source
2

Perl 5 -plF , 51 octets

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

Essayez-le en ligne!

Xcali
la source
1
Tu as raison; J'ai raté cette exigence. C'est réparé maintenant.
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);

Produit des caractères supplémentaires dans la saisie de texte s'ils ne sont pas utilisés dans le modèle, utilise un "." s'il n'y en a pas assez.

EDIT: modifié pour être une fonction acceptant du texte et un motif

Mat
la source
4
Bien ... mais cela utilise une entrée codée en dur.
TheDoctor
Je ne savais pas comment gérer stdin de JS, en particulier avec les nouvelles lignes. Suggestions?
Matt
@Matt Node? Spidermonkey?
Pas que Charles
Peut-être en faire une fonction ...
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))}

Remarque: Comme suggéré par l'OP , j'utilise une fonction. Mais s'il est nécessaire d'avoir un programme, voici une solution à 93 caractères .

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

EDIT1: Changement majeur, je ne sais pas pourquoi je ne l'ai pas réalisé pour la première fois: P Enregistré 40 caractères.


Utilisation :

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

Entrée de test : (sans numéro optionnel inutile selon les spécifications)

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

Sortie :

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

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

Ce serait très agréable d'entendre des suggestions des utilisateurs :)

Gaurang Tandon
la source
1

Perl, 70 caractères

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

Ou, sans vérification des limites, 56 caractères

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

Remarque, ce code n'utilise pas la deuxième ligne comme dans la spécification et peut être raccourci de trois caractères <>;

m1el
la source
1

Frapper, 166 156 111 106

Lit à partir de l'entrée standard, ne prend pas de nombre de lignes. La première ligne d'entrée est le code que vous voulez mettre dans l'art ascii, toutes les lignes suivantes sont l'art ascii, composé du @caractère. L'entrée a une longueur maximale de 999 caractères et n'est pas autorisée à contenir des barres obliques . (J'ai choisi de ne pas utiliser *ou #parce qu'ils ont des significations spéciales dans Bash).

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

AVERTISSEMENT: ce programme utilise un fichier appelé p. Après avoir exécuté le programme, supprimez p- cela confondra le programme la deuxième fois que vous l'exécuterez.

La plupart du travail ici est effectué par

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

La première ligne remplace la première @ de la technique par le premier caractère du code. La deuxième ligne supprime le premier caractère du code.

S'il n'y a pas assez de code pour remplir la forme, une nouvelle ligne est imprimée après la sortie de l'art ascii principal par echo $i.


la source
1

C, 98 , 91 caractères

Voici une solution C assez simple en moins de 100 caractères. Cela n'utilise pas l'entrée de comptage de lignes. (Sinon, un second get () inutile serait nécessaire).

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

non golfé:

char b[999],*s;c;
main(){
    gets(s=b);
    while(~(c=getchar()))
        putchar(c^42?c:*s?*s++:46);
    puts(s);
}
MarcDefiant
la source
Vous pouvez utiliser puts(s)au lieu de printf("%s",s)pour enregistrer 7 octets.
nyuszika7h
@ nyuszika7h Merci! Mais je ne sais pas si le supplément \nest un problème.
MarcDefiant
1

Python 2.7, 165 155 150 138 119 caractères

D'accord, à peu près, mais je suppose que c'est la plus petite façon de le faire avec 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: nouvelle version fonctionnelle 1.0.1 avec encore moins d'octets utilisés:

Edit2: map(r,['']*input()) au lieu de [r()for _ in[1]*input()]et a supprimé l'importation inutilisée

Edit3: '>'*input() au lieu d' ['']*input()enregistrer un caractère et d'ajouter un caractère d'invite pour le modèle :)

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
la source
Vous pouvez utiliser (['.']+l).pop(0)au lieu de (len(l)and l.pop(0)or'.')pour enregistrer 9 octets. Et input()au lieu d' int(r())enregistrer 1 octet.
nyuszika7h
Merci pour input! Malheureusement, votre premier conseil ne fonctionne pas car il génère des points tant que la longueur de la chaîne est> 0.
avall
Je vois pourquoi ma suggestion n'est pas correcte. Essayez à la (l+['.']).pop(0)place, mais si cela ne fonctionne pas non plus, vous pouvez toujours enregistrer 4 octets en utilisant l andau lieu de len(l)and.
nyuszika7h
(l+['.']).pop(0)ne supprime pas les éléments ldonc seul le premier caractère est imprimé mais la lcondition fonctionne :)
avall
1

C # (Visual C # Interactive Compiler) , 122 octets

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

Essayez-le en ligne!

Incarnation de l'ignorance
la source
En raison du manque de détails et d'autres réponses, vous pouvez probablement abandonner le "\n"+pour ajouter les caractères supplémentaires à la même ligne
Veskah
0

05AB1E , 18 17 15 octets

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

Prend le code comme première entrée, le motif comme deuxième (avec 0au lieu de# ).

Essayez-le en ligne ou vérifiez tous les cas de test .

18 15 octets alternatifs en prenant les entrées dans l'ordre inverse:

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

Essayez-le en ligne .

Explication:

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
la source