道路长度编码


21

在美国,如果允许通过,则道路上两个相反的交通方向用虚线黄线分隔,如果不允许通过,则用两条实线黄线分隔。

道路线规则图形

(只需将一侧划线以允许通过该侧即可,黄线可能表示其他事物,例如中心车道或可逆车道,但我们与这些情况无关。)

编写一个程序,它在游程编码的字符串P进行传递,并N不及格,并打印相应道路的ASCII版本。除中心线外,道路始终具有相同的样式,可以从以下示例中轻松推断出该样式。

输入字符串中的每个P和之前将有一个正的十进制数N。此数字定义的长度通过不通过的道路的当前部分的区域。

例子

输入12N会产生12列没有通过的路(中线all =):

____________


============

____________

输入12P会产生12列通过的路(- 重复中心线):

____________


- - - - - - 

____________

通过没有通过可以合并,例如4N4P9N7P1N1P2N2P将产生:

______________________________


====- - =========- - - -=-==- 

______________________________

这些是4个不通过列,然后是4个通过,然后9个不通过,等等。

请注意,通过区域始终以-最左侧的破折号()开头,而不是以空格()开头。这是必需的。

细节

  • 输入永远不会有两个N区域或P连续两个区域。例如4P5P永远不会发生。
  • 您无需支持没有前导正数的字母。朴素P永远是1P,朴素N永远是1N
  • 只要不超出道路的最后一列,就可以有尾随的空间。可能有一个可选的尾随换行符。
  • 您可以编写一个函数,该函数采用游程长度编码的字符串并打印或返回ASCII路径,而不是程序。
  • 以任何标准方式(stdin,命令行,函数arg)接受输入。

以字节为单位的最短代码获胜。Tiebreaker是较早的帖子。


道路是否必须是非对称的,还是允许在线路的每一侧打印4个道路空间?
orlp 2015年

@orlp如果您要问道路的宽度是否可以超过5行,则否。如果你问如果空格字符可以被放置在空行上方或中线下方,然后是只要他们有详细的子弹3.持有
加尔文的爱好

让我举例说明,这两个都是有效的输出吗? gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp

@orlp都不是。
加尔文的爱好2015年

Answers:


5

CJam,38个字节

"_  - _":N3'=t:P;q~]2/e~z'
*"--"/"- "*

怎么运行的

首先,我们的正确道路列的变量赋值NP,然后简单地评价输入字符串。这样就将一对长度和一列留在堆栈上。我们将它们分组,在其上运行RLD以获得完整的列,转置以加入它们,然后最后将连续转换---

:_  - _":N                    e# This is the no passing column. We assign it to N
          3'=t:P              e# Replace the '-' in N with '=" and assign it to P
                q~]2/         e# Read the input, evaluate it and then group it in pairs
                     e~       e# Run a run-length-decoder on the pairs
                       z'
*                             e# Transpose and join with new lines.
 "--"/                        e# Split on two continuous occurrence of -
      "- "*                   e# Join by an alternate "- "

在这里在线尝试


6

JavaScript(ES6),114

使用 模板字符串,必须对5个重要的换行符进行计数。

f=s=>(b=(s=s.replace(/(\d+)(.)/g,(x,n,b)=>(b<'P'?'=':'- ').repeat(n).slice(0,n))).replace(/./g,'_'))+`


${s}

`+b

5

rs,252个字符

尽管这可能不算什么,但是因为我一小时前将收敛运算符添加为马丁·布特纳(MartinBüttner)的视网膜翻版 ……我真的不是来这里竞争的。为此创建基于正则表达式的解决方案很有趣。

(\d+\D)/#\1
+(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)(?=\d*\D)/\1\1\1\1\1\1\1\1\1\1\2\3\4\5\6\7\8\9\10#
\d(?=\d*#N)/=
(^|(?<=\D))\d(?=\d*#P)/-
+(?<=-)\d\d(?=\d*#P)/ -
(?<=-)\d(?=\d*#P)/ 
#\D/
((?:(=|-| ))+)/A\1\n\n\n\1\n\nA\1\n
+(A_*)(.)/\1_
A/

我从Martin的Retina答案中获得了第2行,即“多年来的编程语言”

说明

(\d+\D)/#\1
+(\d*)#(?:(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0)(?=\d*\D)/\1\1\1\1\1\1\1\1\1\1\2\3\4\5\6\7\8\9\10#

这做很多魔术。有关更多信息,请参见我上面链接的答案。

基本上,使用input 4N4P9N7P1N1P2N2P,将是结果:

4444#N4444#P999999999#N7777777#P1#N1#P22#N22#P

下一个:

\d(?=\d*#N)/=

这将用等号替换不通过符号(N)之前的数字。先前输入的结果:

====#N4444#P=========#N7777777#P=#N1#P==#N22#P

这个:

(^|(?<=\D))\d(?=\d*#P)/-

用第一个破折号替换传递符号(P)之前的第一个数字。结果:

====#N-444#P=========#N-777777#P=#N-#P==#N-2#P

接下来的两行继续相同的模式:

+(?<=-)\d\d(?=\d*#P)/ -
(?<=-)\d(?=\d*#P)/ 

第一行用虚线空间模式替换了其余的行。第二个处理奇数;它将最后一个破折号后跟-5一个破折号(-)替换为单个整数(例如)。现在,输出为:

====#N- - #P=========#N- - - -#P=#N-#P==#N- #P

现在事情开始逐渐成熟。下一行:

#\D/

只是删除#N#P

((?:(=|-| ))+)/A\1\n\n\n\1\n\nA\1\n
+(A_*)(.)/\1_

在顶部和底部设置下划线以给出:

A______________________________


====- - =========- - - -=-==- 

A______________________________

最后,我们删除A

A/

2

Haskell,165个字节

k 'N'="="
k _="- "
d c=c>'/'&&c<':'
p[]=[]
p s=take(read$takeWhile d s)(cycle$k a)++p r where(a:r)=dropWhile d s
f s=unlines[q,"\n",p s,"",q]where q=map(\x->'_')$p s

运行示例(f返回一个字符串,以便更好地显示它):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


====- - =========- - - -=-==- 

______________________________

工作原理:p通过递归解析输入字符串并连接由lookup函数找到的给定数量的符号,返回中线k。main函数f通过换行符将一个五元素列表连接在一起,包括顶行(中间行的每个字符替换为_),换行,中间行,空行和底行(与顶行相同)。


2

Python 3,169 168字节。(Python 2为167)

p,s='',str.split
for _ in s('N '.join(s('P '.join(s(input(),'P')),'N'))):
 v=int(_[:-1]);p+=['='*v,('- '*v)[:v]][_[-1]=='P']
l=len(p)
u='_'*l
print(u+'\n'*3+p+'\n\n'+u)

完全没有高尔夫球感:

p=''
for i in'N '.join('P '.join(input().split('P')).split('N')).split():

  v=int(i[:-1])         # Get the number from the input section

  if i[-1]=='N':        # Check the letter (last char) from the input section
      p+=('='*v)        # Repeat `=` the number from input (v)
  else:
      p+=('- '*v)[:v]   #Repeat `- ` v times, then take first v chars (half)
l=len(p)                #Get the length of the final line markings
print('_'*l+'\n\n\n'+p+'\n\n'+'_'*l)

print('_'*l                          # Print _ repeated the length of p
           +'\n\n\n'                 # 3 new lines
                    +p+              # print out p (the markings)
                       '\n\n'        # 2 new lines
                             +'_'*l) # Print _ repeated the length of p

for i in
        'N '.join(
                  'P '.join(
                            input().split('P'))
                                               .split('N'))
                                                           .split():
                            # Split the input into items of list at P
                  # Join together with P and ' '
                                                # Split at N...
         # Join with N and ' '
                                                           # Split at space
# Loop through produced list

在这里在线尝试。


您忘记更新字节数了。
mbomb007 2015年

@ mbomb007它没有改变计数:/我无法在169 atm以下获得它
Tim

p+=['='*v,('- '*v)[:v]][_[-1]=='P']在与前面的分号前一行的末尾保存一个字节。
mbomb007 2015年

另外,使用Python 2可以在上节省1个字节print
mbomb007 2015年

@ mbomb007在:)中添加了它们:)我觉得python 2可能更短...但是我不确定。
蒂姆(Tim)

2

Python 2,136字节

令人惊讶的是,导入re似乎在这里实际上是值得的。

import re
s=""
for x,y in re.findall("(\d+)(.)",input()):s+=(("- ","==")[y=="N"]*int(x))[:int(x)]
t="_"*len(s);print t+"\n"*3+s+"\n"*2+t

2

PHP,187字节

preg_match_all('/(\d+)(\w)/',$argv[1],$m,2);
$o='';
foreach($m as $p)
    $o.=str_replace('--','- ',str_repeat($p[2]<'P'?'=':'-',$p[1]));
$a=preg_replace('/./','_',$o);
echo("$a\n\n\n$o\n\n$a\n");

代码可以放在一行上;它在此处显示为多行以便于阅读(不计算用于格式化的空格和换行符)。

通过不打印尾随换行符可以节省两个字节。通过在上使用实际的换行符,可以再保存五个字节echo()

echo("$a


$o

$a");

省略$o$o='';)的初始化可以节省六个额外的字节,但这将触发一个通知。可以通过使用命令行运行脚本来抑制该通知:

$ php -d error_reporting=0 <script_name> 4N4P9N7P1N1P2N2P

这些将其增加到174个字节。


2

Ruby,137 135字节

我想出的不是最短的,而是最接近的。部分是从Optimizer的答案中借来的。

require'scanf'
N='_  = _'
P='_  - _'
a=[]
scanf('%d%c'){|l,t|a+=[eval(t).chars]*l}
puts (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '

取消高尔夫:

require 'scanf'

N = '_  = _'
P = '_  - _'
columns = [] # array of columns
# scan stdin for a number followed by a single char
scanf('%d%c') do |length, type|
  columns += [eval(type).chars] * length
done

# Convert to an array of rows, and join into a string
rows = columns.shift.zip(*columns).map(&:join)
str = rows * "\n" # join lines

# Replace '--' by '- ' and print
puts str.gsub(/--/, '- ')

通过将最后一行更改为,您应该能够将其提高2个字节(并击败python 2答案)(a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '
blutorange

1

C,155个字节

main(l,v,k,n,x,s,c)char*s,**v,c;{for(l=6;l--;puts(s))for(s=v[1];*s;s+=k)for(x=sscanf(s,"%d%c%n",&n,&c,&k);n--;)putchar(l%5?l^2?32:c^78?++x&1?45:32:61:95);}

更具可读性:

main(l,v,k,n,x,s,c)
    char*s,**v,c;
{
    for(l=6;l--;puts(s))
        for(s=v[1];*s;s+=k)
            for(x=sscanf(s,"%d%c%n",&n,&c,&k);n--;)
                putchar(l%5?l^2?32:c^78?++x&1?45:32:61:95);
}

外循环计数从5到0的行。

中间循环遍历部分编码字符串:

4N4P9N7P1N1P2N2P
4P9N7P1N1P2N2P
9N7P1N1P2N2P
7P1N1P2N2P
1N1P2N2P
1P2N2P
2N2P
2P
string is empty - exit

内部循环将部分解码为7P,并迭代所需的次数(例如7)。

每次迭代都打印一个char。的值char由以下代码描述l%5?l^2?32:c^78?++x&1?45:32:61:95

  • 如果行号是5或0,则打印95(_
  • 否则,如果行号不等于2,则打印一个空格
  • 否则,如果符号为“ N”,则打印61(=
  • 否则,增加x1(由初始化为2 sscanf
  • 如果为奇数,则打印45(-),否则打印32(空格)

0

Scala,163个字节

(s:String)=>{val r=(("\\d+(P|N)"r) findAllIn(s) map(r=>{val l=r.init.toInt;if(r.last=='N')"="*l else ("- "*l).take(l)})).mkString;val k="_"*r.length;s"$k\n\n\n$r\n\n$k"}

第一次尝试,可能会打更多的高尔夫球。


0

Ruby,94个字节

gsub'--','- '14mRh4X0r的答案中借用这个想法。我认为答案虽然更短,但更有趣。

f=->x{n=?_*x.gsub!(/(\d+)(.)/){($2==?P??-:?=)*$1.to_i}.size
"#{n}


#{x.gsub'--','- '}

#{n}"}

测试:

f=->x{n=?_*x.gsub!(/(\d+)(.)/){($2==?P??-:?=)*$1.to_i}.size
"#{n}


#{x.gsub'--','- '}

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

产生:

______________________________


====- - =========- - - -=-==- 

______________________________

0

让我包括我的Matlab版本

MATLAB(267羽)

function d=p(V,a),j=numel(V)-1;if (a==0),d=0;return; end,d=(V(a)-48+10*p(V,a-1))*(V(a)<64);fprintf('%c%.*s%c%.*s',(a>=j)*10,(a==j|a==1)*eval(strcat(regexprep(V,'[NP]','+'),48)),ones(99)*'_',(a<3)*10,(V(a+1)>64)*d,repmat((V(a+1)==78)*'=='+(V(a+1)==80)*'- ',[1 99]));end

输入

一个带空格的ascii格式的字符串(因为在matlab中没有链“ \ 0”的结尾

示例 V ='12N13P'


输出

道路的模式表示

_________________________


============- - - - - - -

_________________________

功能

该函数必须从其tail-1调用(删除空字符)

例如:p(V,numel(V)-1)

模拟

在这里在线尝试


0

R,132个字节

对此并不太满意,但是这样做有点有趣:)试图摆脱多重数gsub,但是我的努力是徒劳的。我怀疑有更好的方法可以做到这一点。

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scan 从STDIN获得琴弦,并获得第四名。 请注意,空行在其中需要一个空格(或其他内容),以便进行扫描以继续获取输入。

    “ ====--=========----=-==-”

  • 它将=s 替换为Ns,然后将-andP秒。

    “ NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP”

  • 然后在每个之间插入一个空格 NPPN

    “ NNNN PPPP NNNNNNNNN PPPPPPP NP NN PP”

  • 扫描将字符串拆分为空格

    “ NNNN”“ PPPP”“ NNNNNNNNN”“ PPPPPPP”“ N”“ P”“ NN”“ PP”

  • 然后绑定字符串长度(rbind与每个字符串的第一个字符)

    4 4 9 7 1 1 2 2
    “ N”“ P”“ N”“ P”“ N”“ P”“ N”“ P”

  • 然后使用输出数组cat

测试运行

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
1: ____________
2:  
3:  
4: ============
5:  
6: ____________
7: 
Read 6 items
Read 1 item
12N
> 
> cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
1: ____________
2:  
3:  
4: - - - - - - 
5:  
6: ____________
7: 
Read 6 items
Read 1 item
12P
> cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
1: ______________________________
2:  
3:  
4: ====- - =========- - - -=-==- 
5:  
6: ______________________________
7: 
Read 6 items
Read 8 items
4N4P9N7P1N1P2N2P
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.