编码高尔夫ASCII艺术的简单方法!


18

任务:

在这个网站上,有很多答案都被安排在ascii艺术中,例如这个。通常,这种安排是手动完成的,但是程序对此没有帮助吗?:)

您的程序将接受3个输入:

  • 代码,作为一行
  • 模式中的行数(如有必要,可以省略)
  • 模式本身,如*s或其他字符

规则:

  • 您必须编写一个从stdin读取的程序(而不是函数)
  • 文本每行从左到右放置
  • 如果没有足够的文字填充模式,请.在剩余的空格中输入s
  • 如果文本太多,无法填充图案,请在输出后将其打印出来
  • ,所以最短的代码(以字节为单位)获胜

样品运行:

输入(精确拟合测试)

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

输出

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

输入(额外字符测试)

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

输出

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

输入(字符不足测试)

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

输出

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

2
对于在不更改程序语义的情况下允许在何处插入空格和换行符,应该做出什么假设?
彼得·泰勒

1
@PeterTaylor似乎没有放置/分离代码的余地,所以我想语义被忽略了吗?
马丁·恩德

1
做“可以省略”和“或其它字符”规范平均值的部分,我们是自由的,比方说,指定的行数必须被省略,且星号应,比如,更换XES我们程序工作?
Ilmari Karonen 2014年

1
@Bakuriu我不明白您的评论。如果您使用ASCII编写程序,则每个字符都是一个字节。如果使用UTF-32编写,则每个字符为4个字节。根据当前规范,以字节为单位的最短代码(不是字符)获胜。听起来您想让编码成为一种要求,但是我不明白为什么要这样做。我是否误解了您的评论?
Rainbolt 2014年

1
基于缺少某些规则的一些答案,我添加了两个示例,并将整个示例块移到了规则块下方,以更加清楚。
Veskah,

Answers:


5

GolfScript,30个字符

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

在线运行

例子:

> 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个字符 编辑:38分(请参阅底部)

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

如果您不喜欢我的糟糕艺术技能,那么这里就是高尔夫:

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

这与评估时间无关紧要。

首先,首先要BEGIN强制[get.comb, "." xx *]评估关键字,将组成“代码”的字符列表放入数组中,然后是无限数量的"."s。

接下来,对get最后的进行评估,获得ASCII艺术模板的行数。该xx运营商重复节目的第一部分很多次。当您意识到首先应该code() xx count()code() for 1..count()count()进行评估时,这更有意义。

最后,get在程序的开头,获得了一行ASCII美工模板,并将每个"*"值替换为我们在其他所有内容之前创建的数组的开头({shift BEGIN …})。

编辑:

压缩到37个字符,再加上一个用于命令行开关:

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

这是与原始概念相同的概念,该-p开关遍历每行(在BEGIN读入“代码”之后),并*在打印之前用“代码”中的下一个字母替换所有s。输入格式不应该包含格式的行数。


6

Ruby 2.0, 53 52个字符

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

根据规范,不使用“行数”参数。

示例运行:

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

输出:

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'
并不是查尔斯(Charles)

@Charles在我安装的任何版本的Ruby中似乎都看不到该错误。以下是在IDEONE上运行的代码:ideone.com/3HG3Fb
Paul Prestidge 2014年

奇怪的。IDEONE工作正常。无论如何,你可以通过更换保存字符(空间)puts $><<和改变,在最后一个+
不是查尔斯的是

@Charles好电话。谢谢!
保罗·普雷斯蒂奇

2

PowerShell63 86 83 82字节

+20个字节@Veskah

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

在线尝试!

少打高尔夫球:

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个字节

@h是输入文本

@是模式

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)

在线尝试



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

如果未在模式中使用,则在文本输入中输出额外的字符,并使用填充的“。” 如果还不够。

编辑:修改为接受文本和模式的函数


4
很好...但这使用了硬编码输入。
TheDoctor 2014年

我不确定如何从JS处理stdin,尤其是换行符。有什么建议吗?
马特2014年

@Matt节点?蜘蛛猴?
并不是说查理

也许使其具有功能……
TheDoctor 2014年

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))}
迈克尔·

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

注意:如OP建议,我正在使用一个函数。但是,如果需要使用某个程序,这里提供93个字符的解决方案

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

编辑1:重大更改,我不知道为什么我第一次没有意识到这一点:P保存了40个字符。


用法

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

测试输入:(不需要根据规格的可选编号)

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

输出

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

非高尔夫代码

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

听到用户的任何建议将是非常高兴的:)


1

Perl,70个字符

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

或者,在没有边界检查的情况下为56个字符

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

请注意,此代码未使用规范中的第二行,并且可以缩短三个字符 <>;


1

重击 166156111 106

从标准输入读取,不占用行数。输入的第一行是您要输入到ascii art中的代码,所有后续行都是ascii art,由@字符组成。输入的最大长度为999个字符,并且不允许包含正斜杠。(我选择不使用,*或者#因为它们在Bash中具有特殊含义)。

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

警告:该程序使用名为的文件p。执行该程序后,删除p-它将在您第二次运行该程序时造成混淆。

这里的大部分工作是由

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

第一行用@代码的第一个字符替换了本领域的第一行。第二行删除代码的第一个字符。

如果没有足够的代码来填充形状,则在通过ascii输出的主要图形之后打印换行符echo $i


1

C,98,91个字符

这是一个非常简单的C解决方案,少于100个字符。这不使用行数输入。(否则需要第二个不需要的gets())。

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

松散:

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

您可以使用puts(s)而不是printf("%s",s)保存7个字节。
nyuszika7h 2014年

@ nyuszika7h谢谢!但是我不知道是否还有其他\n问题。
MarcDefiant 2014年

1

Python 2.7, 165 155 150 138 119个字符

好的,差不多,但是我想这是用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))

编辑:新功能1.0.1版本使用更少的字节:

Edit2: map(r,['']*input())代替[r()for _ in[1]*input()]并删除未使用的导入

Edit3: '>'*input()而不是['']*input()保存一个字符并为模式添加提示字符:)

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)

您可以使用(['.']+l).pop(0)而不是(len(l)and l.pop(0)or'.')保存9个字节。而input()不是int(r())节省1个字节。
nyuszika7h 2014年

谢谢input!不幸的是,您的第一个建议不起作用,因为它会输出字符串长度大于0的点。
可用

我明白了为什么我的建议不正确。请尝试尝试(l+['.']).pop(0),但是如果该方法也不起作用,您仍然可以使用l and代替来保存4个字节len(l)and
nyuszika7h 2014年

(l+['.']).pop(0)不会从中删除元素,l因此仅打印第一个字符,但l条件有效:)
avall 2014年


0

05AB1E18 17 15 字节

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

将代码作为第一个输入,将模式作为第二个输入(使用0代替#)。

在线尝试验证所有测试用例

18 15字节替代,以相反的顺序输入:

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

在线尝试

说明:

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.