字->城市天际线


40

挑战

您的程序或函数将接受来自STDIN或函数参数的单个字符串输入。您可以假定输入将仅包含字母字符(a-zA-Z),空格和句号。输入不区分大小写,因此您应将'a'与对待'A'完全一样。

对于字符串中的每个字符,您将按照以下规范输出建筑物的表示形式。

每个建筑物必须有一个屋顶,在顶行上用下划线指定,然后在第二行上用斜杠,空格和反斜杠指定。

 _
/ \

然后,您将拥有多个楼层,与字母编号(a = 1,b = 2,c = 3等)匹配,字母编号由两侧的墙(|)和中间的空格表示。底层(并且只有底层)应具有基础,该基础是墙之间的下划线。像这样...

|_|

因此,例如,“ b”看起来像这样

 _
/ \
| |
|_|

现在,我们知道非常高,狭窄的建筑物无法站立,必须在底部变宽,因此没有任何其他支撑,任何建筑物都不能站立超过三层高。因此,每三个级别(不少于一个)都应添加一个“扩展层”。加宽层由位于其下面部分的壁正上方的斜杠和反斜杠组成,并且下面的部分应比上面的部分宽两个空格。多余的层不计入建筑物的高度。

建筑物不应重叠,但建筑物之间不应有任何多余的空间,并且地面始终是平坦的,因此所有建筑物的底脚应在同一水平线上。

例如,“ abcdefga”将如下所示。

                           _
                          / \
                     _    | |
                _   / \   | |
           _   / \  | |   | |
          / \  | |  | |  /   \
       _  | |  | |  | |  |   |
    _ / \ | |  | | /   \ |   |
 _ / \| | | | /   \|   | |   |  _
/ \| || |/   \|   ||   |/     \/ \
|_||_||_||___||___||___||_____||_|

字符串输入中的空格应由双精度空格表示。

字符串输入中的句号应该用这样的碎石表示。

/\/\

进一步的例子

输入= Hello world.

输出=

                                                   _                                                  
                                                  / \                                                 
                                                  | |                                                 
                                                  | |                                                 
                                                  | |                                                 
                                                 /   \                                                
                                                 |   |                                                
                                                 |   |                       _                        
                                                 |   |                      / \                       
                                                /     \                     | |                       
                                                |     |                     | |                       
                                   _            |     |          _          | |                       
                                  / \           |     |         / \        /   \                      
                                  | |          /       \        | |        |   |                      
                                  | |          |       |        | |        |   |                      
                _        _        | |          |       |        | |        |   |        _             
               / \      / \      /   \         |       |       /   \      /     \      / \            
               | |      | |      |   |        /         \      |   |      |     |      | |            
               | |      | |      |   |        |         |      |   |      |     |      | |            
               | |      | |      |   |        |         |      |   |      |     |      | |            
   _          /   \    /   \    /     \       |         |     /     \    /       \    /   \           
  / \         |   |    |   |    |     |      /           \    |     |    |       |    |   |           
  | |         |   |    |   |    |     |      |           |    |     |    |       |    |   |           
  | |         |   |    |   |    |     |      |           |    |     |    |       |    |   |           
  | |    _   /     \  /     \  /       \     |           |   /       \  /         \  /     \          
 /   \  / \  |     |  |     |  |       |    /             \  |       |  |         |  |     |   _      
 |   |  | |  |     |  |     |  |       |    |             |  |       |  |         |  |     |  / \     
 |   |  | |  |     |  |     |  |       |    |             |  |       |  |         |  |     |  | |     
 |   |  | | /       \/       \/         \   |             | /         \/           \/       \ | |     
/     \/   \|       ||       ||         |  /               \|         ||           ||       | | |     
|     ||   ||       ||       ||         |  |               ||         ||           ||       |/   \    
|_____||___||_______||_______||_________|  |_______________||_________||___________||_______||___|/\/\

输入= lorem ipsum

                                                                                             _                  
                                                                                            / \                 
                                                                              _             | |                 
                                                                             / \            | |                 
                          _                                                  | |            | |                 
                         / \                                                 | |           /   \                
                         | |                                    _            | |           |   |                
                         | |                                   / \          /   \          |   |                
              _          | |                                   | |          |   |          |   |                
             / \        /   \                                  | |          |   |         /     \               
             | |        |   |              _                   | |          |   |         |     |         _     
             | |        |   |             / \                 /   \        /     \        |     |        / \    
    _        | |        |   |             | |                 |   |        |     |        |     |        | |    
   / \      /   \      /     \            | |                 |   |        |     |       /       \       | |    
   | |      |   |      |     |            | |                 |   |        |     |       |       |       | |    
   | |      |   |      |     |           /   \               /     \      /       \      |       |      /   \   
   | |      |   |      |     |           |   |        _      |     |      |       |      |       |      |   |   
  /   \    /     \    /       \          |   |       / \     |     |      |       |     /         \     |   |   
  |   |    |     |    |       |          |   |       | |     |     |      |       |     |         |     |   |   
  |   |    |     |    |       |         /     \      | |    /       \    /         \    |         |    /     \  
  |   |    |     |    |       |         |     |      | |    |       |    |         |    |         |    |     |  
 /     \  /       \  /         \   _    |     |     /   \   |       |    |         |   /           \   |     |  
 |     |  |       |  |         |  / \   |     |     |   |   |       |    |         |   |           |   |     |  
 |     |  |       |  |         |  | |  /       \    |   |  /         \  /           \  |           |  /       \ 
 |     |  |       |  |         |  | |  |       |    |   |  |         |  |           |  |           |  |       | 
/       \/         \/           \ | |  |       |   /     \ |         |  |           | /             \ |       | 
|       ||         ||           |/   \ |       |   |     | |         |  |           | |             | |       | 
|       ||         ||           ||   |/         \  |     |/           \/             \|             |/         \
|_______||_________||___________||___||_________|  |_____||___________||_____________||_____________||_________|

输入= a.a.a.x.x.x.a.a.a

                             _                    _                    _                             
                            / \                  / \                  / \                            
                            | |                  | |                  | |                            
                            | |                  | |                  | |                            
                            | |                  | |                  | |                            
                           /   \                /   \                /   \                           
                           |   |                |   |                |   |                           
                           |   |                |   |                |   |                           
                           |   |                |   |                |   |                           
                          /     \              /     \              /     \                          
                          |     |              |     |              |     |                          
                          |     |              |     |              |     |                          
                          |     |              |     |              |     |                          
                         /       \            /       \            /       \                         
                         |       |            |       |            |       |                         
                         |       |            |       |            |       |                         
                         |       |            |       |            |       |                         
                        /         \          /         \          /         \                        
                        |         |          |         |          |         |                        
                        |         |          |         |          |         |                        
                        |         |          |         |          |         |                        
                       /           \        /           \        /           \                       
                       |           |        |           |        |           |                       
                       |           |        |           |        |           |                       
                       |           |        |           |        |           |                       
                      /             \      /             \      /             \                      
                      |             |      |             |      |             |                      
                      |             |      |             |      |             |                      
                      |             |      |             |      |             |                      
                     /               \    /               \    /               \                     
 _      _      _     |               |    |               |    |               |     _      _      _ 
/ \    / \    / \    |               |    |               |    |               |    / \    / \    / \
|_|/\/\|_|/\/\|_|/\/\|_______________|/\/\|_______________|/\/\|_______________|/\/\|_|/\/\|_|/\/\|_|

规则

  • 当然这是代码高尔夫,以字节为单位的最低得分获胜
  • 适用标准漏洞规则
  • 在输出之前或之后可以有任意数量的其他空白行
  • 您可以选择将整个结果输出为一个字符串,也可以将输出提供为数组,其中每个元素代表一行输出,或者发送到STDOUT

注意

这是我对PPCG的第一篇文章,所以请放轻松。已经通过了沙箱。任何不利之处或可能的改进,请发表评论,我将尽我所能


7
转换[a,z][A,Z][1,26]似乎是一个毫无意义的要求。最好只使用列表整数作为输入(必须0是碎石的输入)。此外,在您在沙箱中停留21个小时之后就发布您的挑战,而不必等待获得来自多个用户的任何投票或反馈,就不算挑战已经“穿越了沙箱”。建议您将挑战至少在沙箱中保留48-72小时,以使人们有足够的时间进行审查。
Mego

2
让我想起了这一点。尼斯的第一个挑战,但我建议你考虑改变[a,z][1.26]部分迈戈提及。使其具有可选性通常是最好的(除非它是挑战的关键部分(不在此处))
Stewie Griffin

2
我会说,这是一个非常好的第一个挑战。欢迎光临本站!
DJMcMayhem

1
我可以理解关于az映射到整数的要点。在挑战的第一个迭代中这是有道理的,但由于编辑简洁明了(我删除了一个背景故事),所以字母不再相关。我会尽快进行适当的编辑
达伦·H

1
我个人更喜欢z,空间,时期。
isaacg

Answers:


10

JavaScript的(ES6),330 326 ... 315个 309字节

从底层开始,并在每个阶段之间应用几个正则表达式,以递归方式构建ASCII艺术:

(a,l,R=(E,b)=>E.split`:`.map((e,i)=>l=(l||a).replace(RegExp(e,'g'),b?b.split`:`[i]:n=>(x=(n.charCodeAt()-65)%32)<0?x+1?'/y/y':n+n:x%3+'_'.repeat((x/3<<1)+1)+0)))=>(L=l)?(R('/y:_:/xy:1:2:/xx(x+)y:0(x+)0:3','  :x: _ :3:1: 2$10 :/$1y:0'),L==l?(l=a.join`
`,R('\\d:x:y','|: :\\'),l):f([l].concat(a),l)):f(R('.'),l)

这个怎么运作

1)底楼

我们首先将输入字符串转换为底层内容,例如:

"ab cd.df.hcab"  -->  "0_01_0  2_00___0/y/y0___02___0/y/y1_____02_00_01_0"

哪里:

  • y 是反斜杠的较短别名(需要转义)
  • 数字(012只是的序列之前)_是建筑物的左壁。它表示在下一个“加宽层”之前必须在其上方放置的墙的数量。
  • 序列之后的数字_是建筑物的右墙,并且始终设置为0

2)在每个阶段之间应用正则表达式

递归过程包括使用以下正则表达式在前一层应用9个替换项:

  1. /\/y/g=> " "(去除瓦砾)
  2. /_/g=> "x"(用实体块替换基础或建筑物的顶部)
  3. /\/xy/g=> " _ "(用建筑物的顶部替换最后一个加宽层)
  4. /1/g=> "3"(暂时替换13-参见最后一步)
  5. /2/g=> "1"(替换21
  6. /\/xx(x+)y/g=> " 2$10 "(用新的,更窄的壁代替加宽层)
  7. /0(x+)0/g=> "/$1y"(用加宽层替换墙的顶部)
  8. /3/g=> "0"(替换30

例如,以下是2___0(由生成的最低层'f')的连续转换:

"2___0" > "1xxx0" > "0xxx0" > "/xxxy" > " 2x0 " > " 1x0 " > " 0x0 " > " /xy " > "  _  "

                                                                                   _   
                                                                        /xy       /xy  
                                                              0x0       0x0       0x0  
                                                    1x0       1x0       1x0       1x0  
                                          2x0       2x0       2x0       2x0       2x0  
                               /xxxy     /xxxy     /xxxy     /xxxy     /xxxy     /xxxy 
                     0xxx0     0xxx0     0xxx0     0xxx0     0xxx0     0xxx0     0xxx0 
           1xxx0     1xxx0     1xxx0     1xxx0     1xxx0     1xxx0     1xxx0     1xxx0 
 2___0     2___0     2___0     2___0     2___0     2___0     2___0     2___0     2___0 

注意:建筑物的顶部然后被代替x。上图中未显示。

3)将正则表达式应用于最终结果

当没有其他要替换的内容时,递归就会停止,这意味着我们已经超出了最高建筑物的顶部。

现在,我们需要使用另外几个正则表达式来清理所有内容:

  1. /\d/g=> "|"(用管道替换数字)
  2. /x/g=> " "(用空格替换实心块)
  3. /y/g=> "\"y用反斜杠代替)

例如:

  _            _  
 /xy          / \ 
 0x0          | | 
 1x0          | | 
 2x0   -->    | | 
/xxxy        /   \
0xxx0        |   |
1xxx0        |   |
2___0        |___|

演示版

let f =

(a,l,R=(E,b)=>E.split`:`.map((e,i)=>l=(l||a).replace(RegExp(e,'g'),b?b.split`:`[i]:n=>(x=(n.charCodeAt()-65)%32)<0?x+1?'/y/y':n+n:x%3+'_'.repeat((x/3<<1)+1)+0)))=>(L=l)?(R('/y:_:/xy:1:2:/xx(x+)y:0(x+)0:3','  :x: _ :3:1: 2$10 :/$1y:0'),L==l?(l=a.join`
`,R('\\d:x:y','|: :\\'),l):f([l].concat(a),l)):f(R('.'),l)

console.log(f('ab cd.df.hcab'));

贡献者:
Hedi节省了4个
字节,Not Not Charles节省了8个字节


欢迎任何想要将输入作为整数的人使用,但我建议这样的输入应不具有竞争力
mbomb007

@ mbomb007-已修复。不过,我目前的优化无法补偿臭名昭著的成本.charCodeAt()
Arnauld

你不需要new new RegExp(e,'g')
赫迪拉

我非常喜欢这种方法。一些想法可能会有所帮助:1.使用类似char的字符y,不需要转义正斜杠。2.如果_用于一楼,您仍然可以使用正则表达式区分顶部/_ /
不是查尔斯(Charles)

1
@NotthatCharles-实际上我从没注意到“双倍空格”规则。;)这是固定的。
Arnauld

7

PHP,386个 376 367 364 362 358 356字节

第一种方法;可能仍然可以打高尔夫球。

foreach(str_split($argv[1])as$c)for($n=28,$w='.'!=$c?1+2*ceil(1/3*$n=31&ord($c)):4,$p=$y=0;$y<36;){$s=str_pad("",$w,$y||!$n?" ":_);if($n>26&&!$y){$s="/\\/\\";$n=-1;}elseif($n-->0){$s[$p]=$s[$w-$p-1]="|";if($n%3<1){$o[$y++].=$s;$s=str_pad("",$w);$s[$p]="/";$s[$w-++$p]="\\";}}$o[$y++].=$s;if(!$n)$o[$y++].=str_pad(_,$w," ",2);}for($y=36;$y--;)echo"$o[$y]
";

PHP,366个 362 361 360 357字节

具有子功能的类似方法:

function a($p,$r){global$o,$w,$y;$o[$y++].=str_pad(str_pad($r[0],2*$p,$r[1]).$r[2],$w," ",2);}foreach(str_split($argv[1])as$i=>$c)for($n=28,$w='.'!=$c?1+2*$p=ceil(1/3*$n=31&ord($c)):$p=4,$y=0;$y<36;)if($n>26&&!$y)$o[$n=$y++].="/\\/\\";elseif($n-->0){a($p,$y?"| |":"|_|");if($n%3<1)a($p--,"/ \\");if(!$n)a(1," _");}else a(0,"");for($y=36;$y--;)echo"$o[$y]
";

第二种方法细分

function a($p,$r)
{
    global$o,$w,$y;
    $o[$y++].=                  // 3. add result to current line, increase line counter
        str_pad(                // 2. pad ...
        str_pad($r[0],2*$p,$r[1]).$r[2]     // 1. A + inner width(=2*$p-1) times B + C
        ,$w," ",2);             // ... to $w with blanks on both sides # 2==STR_PAD_BOTH
}

foreach(str_split($argv[1])as$i=>$c)
    for(
    $n=28,
    $w='.'!=$c                          // $w=total width
        ?1+2*$p=ceil(1/3*$n=31&ord($c)) // $n=storey count, $p=(inner width+1)/2
        :$p=4                           // $n=28, $p <= $w=4 for rubble
    ,
    $y=0;$y<36;)                        // $y=line counter
        if($n>26&&!$y)
            $o[$n=$y++].="/\\/\\";      // bottom line=rubble, $n=0
        elseif($n-->0)
        {
            a($p,$y?"| |":"|_|");       // add storey
            if($n%3<1)a($p--,"/ \\");   // add widening layer/roof
            if(!$n)a(1," _");           // add roof top
        }
        else
            a(0,"");                    // idk why str_pad doesn´t yield a warning here

for($y=36;$y--;)if($s=rtrim($o[$y]))echo"$s\n"; // output

+16字节(如果不允许前导换行符):
替换echo"$o[$y]\n;if($s=rtrim($o[$y]))echo"$s\n";

-3字节为任何的;<=>?[\]^_{|}~替换1):作为瓦砾($n=31&ord($c))$n,2)$n=28,$w='.'!=$c($n=31&ord($c))<27和3)4($n=28)/7

另一个-8为>^~作为瓦砾:撤消3)


1
if(!$n){$o[$y++].=str_pad(_,$w," ",2);}-2字节的括号
约尔格Hülsermann

和输出可以做到3字节短:for($y=36;$y--;)echo"$o[$y]\n";; 但我有一个新方法,可以节省另外2个字节。
泰特斯(Titus)

1
php.net/manual/en/functions.anonymous.php对于第二种方法`功能的($ P,$ R)使用($ O,$ W,$ Y)”,而不是全球
约尔格Hülsermann

@JörgHülsermann:use仅适用于匿名函数。它将节省2个字节;但我必须将该函数存储在变量中,$a=而不是给它一个名称(+3个字节),然后$在四个调用中的每一个上添加一个。
泰特斯(Titus)2016年

4

Pyth,93 79字节

K"/\\"j_.tsm?hJxGdC_m.[hyNk\ +\_mj*hy/k4?nkJ\ \_?%k4"||"Kh=+J=Nh/J3[F*2|@d;Krz0

在线尝试。 测试套件。

说明

由于时间太长,我默认将其隐藏。


4

Perl,147146字节

包括+1的 -p

使用STDIN上的输入运行,例如

citysky.pl <<< " abcdefgxyz."

citysky.pl

#!/usr/bin/perl -p
s%.%@{[map chr~-ord(lc$&)*4/3-4*(abs||-9),-9..9]}%g;y/M\xa248
A|-\xc6\0-\xff/MA||
A}-\xc6A/d,$a=(lc$a).$_ for($_)x36;*_=a;s/\x9f.*?\K\x9f/\xa3/g;y%A\xc6\x9f-\xa3\x0b-\xff%__/|||\\ %

如图所示工作,但将\xhh转义替换为其字面值以获得要求的分数。您可以使用以下命令行进行操作:

perl -0pi -e 's/\\x(..)/chr hex $1/eg;s/\n$//' citysky.pl

我还没有真正探索其他方法,所以这可能是非常好的...


2

Haskell,289个字节

c?l=c++l++c
c%s=("|"?(drop 2(r s)>>c)):s
g 46=["/\\"?""]
g 32=["  "]
g x="_"%h(mod x 32)
h 1=["/ \\"," _ "]
h x=(" "%h(x-1))!x
v!x|mod x 3/=1=v|z<-'/':r v++"\\"=z:map(" "?)v
r v=v!!0>>" "
f t|l<-map(g.fromEnum)t,m<-maximum(map length l)-1=unlines[l>>= \x->(x++cycle[r x])!!i|i<-[m,m-1..0]]

2

红宝石245

->s{a=['']*36
w=' '
s.chars{|c|a[u=0]+=c<?!?w*2:c<?/?"/\\"*2:(h=c.upcase.ord-64
1.upto(1+h+=(h-1)/3){|t|u=[u,l=1+2*((f=h-t)/4)].max
a[t]+=w*(a[0].size-a[t].size)+(f<-1?w:f<0??_:(f%4<1?[?/,?\\]:[?|]*2)*(w*l)).center(u+2)}
"|#{?_*u}|")}
a.reverse}

您可以根据需要允许任意数量的额外换行符,因此我对此感到自由。除此之外,过程如下:

  1. 初始化输出数组a
  2. 对于每个字符:
    1. 如果是“”,则添加 a[0]
    2. 如果是“。”,则添加/\/\a[0]
    3. 除此以外:
      1. 计算高度(c.upcase.ord + (c.upcase.ord-1)/3
      2. 对于中的每一行a
        1. 用空格填充行。 a[t]+=w*(a[0].size-a[t].size)
        2. 如果我们在上方h,请居中_
        3. 否则,如果我们高于高度,则将a居中 
        4. 否则,如果我们低于高度,中心| |/ \适当的宽度(1+2*((h-t)/4),具体取决于h-t%4==0
        5. 加上"|___|"正确的宽度a[0]
  3. 返回 a.reverse

我敢打赌,如果我算一下算术以避免,可以把它缩小一些 reverse


2

PHP,297字节

foreach(str_split($argv[1])as$c)for($j=0,$h=ord($c)-64,$g=$h+$f=ceil($h/3),$w=$v=$h<0?$h<-18?2:4:2*$f+1;$j<36;$j++,$g--,$v-=$h>0&&$v>1?($g%4||!$j)?0*$n="|$s|":2+0*$n="/$s\\":$v+0*$n=['','_','',0,'/\/\\'][$v],$o[$j].=str_pad($n,$w,' ',2))$s=str_repeat($j?' ':'_',$v-2);krsort($o);echo join($o,'
');

更具可读性的版本:

foreach (str_split($argv[1]) as $character) {
    for (
        $line = 0,
        $buildingHeight = ord($character) - 64,
        $floorsLeft = $buildingHeight + $supportFloors = ceil($buildingHeight / 3),
        $buildingWidth = $widthOnThisFloor = $buildingHeight < 0
            ? $buildingHeight < -18
                ? 2
                : 4
            : 2 * $supportFloors + 1;

        $line < 36;

        // The body of the for-loop is executed between these statements

        $line++,
        $floorsLeft--,
        $widthOnThisFloor -= $buildingHeight > 0 && $widthOnThisFloor > 1
            ? ($floorsLeft % 4 || !$line)
                ? 0 * $floorString = "|$middleSpacing|"
                : 2 + 0 * $floorString = "/$middleSpacing\\"
            : $widthOnThisFloor + 0 * $floorString = ['', '_', '', 0, '/\/\\'][$widthOnThisFloor],
        $outputArray[$line] .= str_pad($floorString, $buildingWidth, ' ', 2)
    ) {
        $middleSpacing = str_repeat($line ? ' ' : '_', $widthOnThisFloor - 2);
    }
}
krsort($outputArray);
echo join($outputArray, '
');
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.