高尔夫代码:点点滴滴 [英] Code Golf: Connecting the dots

查看:66
本文介绍了高尔夫代码:点点滴滴的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可能还记得小时候的这些绘图,但是现在是时候让计算机绘制它们了(以全幅的ascii效果).玩得开心!

You may remember these drawings from when you were a child, but now it's time to let the computer draw them (in full ascii splendour). Have fun!

说明:

输入是描述字段"的多行(由换行符终止).在此字段中散布着数字"(由空格分隔).所有行的长度都可以视为相同(您可以在末尾填充空格).

The input are multiple lines (terminated by a newline) which describe a 'field'. There are 'numbers' scattered across this field (seperated by whitespace). All lines can be considered to be the same length (you can pad spaces to the end).

  • 数字总是从1开始
  • 它们遵循自然数的顺序:每个下一个数"都以1递增
  • 每个数字的左右两侧都被(至少)一个空格包围

任务:

绘制线 (1 -> 2 -> 3 -> ...N)(假设N< = 99)具有以下特征:

Draw lines between these numbers in their natural order (1 -> 2 -> 3 -> ...N) (assume N <= 99) with the following characteristics:

  1. 用'+'字符替换数字
  2. 对于水平线:使用'-'
  3. 垂直线:使用'|'
  4. 左右移动或上下移动:/
  5. 左右移动或上下移动:\
  1. replace a number with a '+' character
  2. for horizontal lines: use '-'
  3. for vertical lines: use '|'
  4. going left and down or right and up: /
  5. going left and up or right and down: \

重要说明:

  1. 在绘制类型4和5的线时,可以假定(给定与坐标x1,y1和x2,y2连接的点)distance(x1,x2) == distance(y1,y2).或者换句话说(如用户jball所说):未水平或垂直对齐的连续元素始终与斜杠或反斜杠的坡度对齐".

  1. When drawing lines of type 4 and 5 you can assume (given the points to connect with coordinates x1, y1 and x2, y2) that distance(x1,x2) == distance(y1,y2). Or in other words (as user jball commented): "consecutive elements that are not horizontally or vertically aligned always align to the slope of the slash or backslash".

重要的是要遵循点的连接顺序(较新的线条会击破较旧的线条).

It is important to follow the order in which the dots are connected (newer lines can strike out older lines).

-样本输入1-


                                  8 

                                  7  6 
                      10       9       

                                        5            

                                     3  4        
                 11 

                   12                       13    
          1                          2                     

-样本输出1-


                                 +                                
                                /|                                
                               / +--+                             
                     +--------+      \                            
                    /                 \                           
                   /                   +                          
                  /                    |                          
                 /                  +--+                          
                +                   |                             
                 \                  |                             
                  +------------------------+                      
         +--------------------------+        

-样本输入2-


                        64          
                        63              



                    62 61                             
               1  65                                   
                 66    57 58                               
               2      56  59               45                
                   67  55                  46              
             3                               44           
                         54  60            47              
                          53 52   49      48              
             4                51 50       43            

           5                                42              
                                            41               
           6              23                                 
                          22 25  26       40              
                      20 21 24            34                 
              7 13 12                    33                    
                    19              27  32                     
                14                        35               
           8   15                                           
                16                                         
                                   39                        
                17  18         28  31 36                  
               9                     38                       
                10 11          29  30 37                       

-示例输出2-( unicorn参考)


                       +        
                      /+      
                     //          
                    //        
                   //           
                  /+--+        
              +  +     \         
              | +     +-\+          
              +  \   +   \                +         
             /    +   +   \               +\    
            +          \   \              | +       
            |           +   +             +/           
            |            +--+    +-------+/               
            +                +--+        +              
           /                              \              
          +                                +               
          |                                +                 
          +              +                /             
           \             +\ +---+        +           
            \        +--+  +     \      /+              
             + +--+ /             \    /+|             
            /  |  |+               +  /+ |                 
           /   +  ||              /  //  +            
          +   +   ||             /  //  /                
           \   +  ||            /  //  /              
            \  |  ||           /  +/  /                  
             \ +---+          +   +\ +                  
              +   |           |   | +|                 
               +--+           +---+  +               

优胜者:

最短的解决方案(按代码字符计数).输入可以通过标准输入读取.

Shortest solution (by code character count). Input can be read via standard input.

推荐答案

Perl,222个字符(211)

Perl, 384 365 276 273 253 225 222 218 211个字符(比赛结束时为222个字符).换行符仅用于可读性",不包括在字符计数中.

Perl, 222 char (211)

Perl, 384 365 276 273 253 225 222 218 211 chars (222 when contest ended). Newlines are for "readability" only and are not included in the character count.

最后不再覆盖$",而直接打印@S

Last edit: no longer overwriting $", and printing @S directly

    $_=join'',@S=map{$n=s/$/$"x97/e;(/./g)[0..95],$/}<>;
    while(/\b$n /){$S[$q=$-[0]]='+';($P,$Q)=sort{$a-$b}$q,$p||$q;
    for(qw'\98 |97 /96 -1'){/\D/;$S[$P]=$&until($Q-$P)%$'||$Q<=($P+=$')}
    $n++;$p=$q}s/\d/ /,print for@S

说明:

$_=join'',@S=map{$n=s/$/$"x97/e;(/./g)[0..95],$/}<>;

如果所有行的长度都相同(例如97个字符),则此任务将更加容易. 该语句接受输入的每一行,将行尾字符替换为 96个空格,然后将前96个字符和换行符压入数组@S中. 请注意,我们也在设置$n=1,因为1是我们要查找的第一个数字 输入. join语句从数组@S创建单个字符串. 使用标量变量$_进行模式匹配更加方便,而使用数组@S进行图片更新更方便.

This task will be easier if all the lines are the same length (say, 97 characters). This statement takes each line of input, replaces the end-of-line character with 96 spaces, then pushes the first 96 characters plus a newline into the array @S. Note we are also setting $n=1, as 1 is the first number we'll look for in the input. The join statement creates a single string from the array @S. It is more convenient to use the scalar variable $_ for pattern matching, and more convenient to use the array @S for making updates to the picture.

while(/\b$n /){

在变量$_中搜索数字$n.评估Perl中的正则表达式 有几个副作用.一种是使用匹配的字符串在匹配字符串中的开始位置设置特殊变量$-[0].这样,我们就可以在字符串$_和数组@S中找到数字$n的位置.

Search for the number $n in the variable $_. Evaluating regular expressions in Perl has several side-effects. One is to set the special variable $-[0] with the position of the start of the matched pattern within the matched string. This gives us the position of the number $n in the string $_ and also the array @S.

当然,当$n足够高以至于我们无法在输入中找到它时,循环将结束.

Of course, the loop will end when $n is high enough that we can't find it in the input.

    $S[$q=$-[0]]='+';

$q为数字$n在字符串$_和数组@S中的位置, 并在该位置分配字符"+".

Let $q be the position of the number $n in the string $_ and the array @S, and assign the character '+' at that position.

        $P=($p||=$q)+$q-($Q=$q>$p?$q:$p)
        ($P,$Q)=sort{$a-$b}$p||$q,$q;

第一次通过循环,将$p设置为$q.之后 第一次,$p将保留$q previous 值(其中 将参考前一个数字在输入中的位置). 分配$P$Q以使$P = min($p$q), $Q = max($p$q)

The first time through the loop, set $p to $q. After the first time, $p will hold the previous value of $q (which will refer to the position in the input of the previous number). Assign $P and $Q such that $P=min($p,$q), $Q=max($p,$q)

    for(qw'\98 |97 /96 -1'){

通过构造,连续数字可以是

By construction, consecutive numbers are either

  • 通过垂直线连接.由于输入是构造的 每行有97个字符,这种情况意味着 $p-$q可被97整除.

  • connected by a vertical line. Since the input is constructed to have 97 characters on each line, this case means that $p-$q is divisible by 97.

与反斜线的斜率对齐",这将使 $p-$q可被98整除

"aligned to the slope of a backslash", which would make $p-$q divisible by 98

与正斜线的斜率对齐",这将使 $p-$q可被96整除

"aligned to the slope of a forward slash", which would make $p-$q divisible by 96

在同一水平线上

此列表的元素编码可能的位置数量 线段之间以及要对该线段进行编码的字符之间.

The elements of this list encode the possible number of positions between line segments, and the character to encode that segment.

        /\D/;

另一个琐碎的正则表达式评估.作为副作用,它设置了 线段的特殊变量$&( MATCH 变量) 字符(\ | /-)和$'( POSTMATCH 变量) 到 列表元素中编码的数字(98 97 96或1).

Another trivial regex evaluation. As a side-effect, it sets the special variable $& (the MATCH variable) to the line segment character (\ | / or -) and $' (the POSTMATCH variable) to the number (98 97 96 or 1) encoded in the list element.

        $S[$P]=$&until($Q-$P)%$'||$Q<=($P+=$')

此语句在两个数字之间绘制线段. 如果$Q-$P可被$'整除,则继续将$P递增$' 并将字符$&分配给$S[$P],直到$P到达$Q. 更具体地说,例如,如果$Q-$P可被97整除,则 将$P增加97,然后设置$S[$P]='|'.重复直到$P>=$Q.

This statement draws the line segment between two numbers. If $Q-$P is divisible by $', then keep incrementing $P by $' and assigning the character $& to $S[$P] until $P reaches $Q. More concretely, for example if $Q-$P is divisible by 97, then increment $P by 97 and set $S[$P]='|'. Repeat until $P>=$Q.

    $n++;$p=$q

为循环的下一次迭代做准备.将$n递增到 输入中要搜索的下一个数字,并按住$p 前一个号码的位置.

Prepare for the next iteration of the loop. Increment $n to the next number to search for in the input, and let $p hold the position of the previous number.

s/\d/ /,print for@S

输出数组,转换所有剩余的数字(从double 输入中的数字标识符,我们只覆盖第一个 带有'+'的数字),然后按空格键.

Output the array, converting any leftover digits (from double digit identifiers in the input where we only overwrote the first digit with a '+') to spaces as we go.

这篇关于高尔夫代码:点点滴滴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆