การเข้ารหัสความยาวถนน


21

ในสหรัฐอเมริกาทั้งสองทิศทางที่ตรงข้ามของการจราจรบนถนนจะถูกคั่นด้วยเส้นสีเหลืองประถ้าอนุญาตให้ผ่านและเส้นสีเหลืองทึบสองเส้นถ้าผ่านไม่ได้รับอนุญาต

กราฟิกกฎของถนน

(เพียงด้านเดียวสามารถประเพื่อให้ผ่านด้านนั้นและเส้นสีเหลืองอาจหมายถึงสิ่งอื่น ๆ เช่นกึ่งกลางหรือเลนย้อนกลับ แต่เราไม่ได้เกี่ยวข้องกับกรณีเหล่านี้)

จงเขียนโปรแกรมที่ใช้ในที่ทำงานระยะเวลาในการเข้ารหัสสตริงของPสำหรับการส่งผ่านและNสำหรับไม่ผ่านและพิมพ์รุ่น ASCII ของถนนที่สอดคล้องกัน ยกเว้นเส้นกลางถนนมีรูปแบบเดียวกันเสมอซึ่งสามารถอนุมานได้ง่ายจากตัวอย่างด้านล่าง

จะมีตัวเลขทศนิยมเป็นบวกก่อนละPและNในสตริงที่ป้อน หมายเลขนี้กำหนดความยาวของพื้นที่ผ่านหรือไม่ผ่านของส่วนปัจจุบันของถนน

ตัวอย่าง

อินพุตของ12Nจะผลิต 12 คอลัมน์ของถนนที่ไม่ผ่าน (เส้นกลางทั้งหมด=):

____________


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

____________

อินพุตของ12Pจะผลิต 12 คอลัมน์ของถนนที่ผ่าน (เส้นกลาง- ซ้ำ):

____________


- - - - - - 

____________

การผ่านและไม่ผ่านสามารถรวมกันได้เช่น4N4P9N7P1N1P2N2Pจะสร้าง:

______________________________


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

______________________________

เหล่านี้คือ 4 ไม่มีคอลัมน์ผ่านแล้ว 4 ผ่านแล้ว 9 ไม่ผ่านฯลฯ

โปรดทราบว่าเขตผ่านจะเริ่มต้นด้วยเส้นประ ( -) ทางด้านซ้ายสุดไม่ใช่ช่องว่าง ( ) สิ่งนี้จำเป็น

รายละเอียด

  • อินพุตจะไม่มีสองNโซนหรือสองPโซนในหนึ่งแถว เช่น4P5Pจะไม่เกิดขึ้น
  • คุณไม่จำเป็นต้องสนับสนุนจดหมายโดยไม่มีหมายเลขบวกนำหน้า ธรรมดาPจะเป็น1Pธรรมดาจะเป็นN1N
  • อาจมีช่องว่างต่อท้ายตราบใดที่ไม่ขยายเกินคอลัมน์สุดท้ายของถนน อาจมีบรรทัดใหม่ต่อท้ายที่เป็นตัวเลือกหนึ่งบรรทัด
  • แทนที่จะเป็นโปรแกรมคุณสามารถเขียนฟังก์ชั่นที่ใช้ในสตริงที่เข้ารหัสแบบรันไทม์แล้วพิมพ์หรือส่งคืนถนน ASCII
  • รับอินพุตในวิธีมาตรฐานใด ๆ (stdin, บรรทัดคำสั่ง, ฟังก์ชัน arg)

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ Tiebreaker เป็นโพสต์ก่อนหน้า


ถนนต้องมีความไม่สมดุลหรืออนุญาตให้พิมพ์ถนน 4 เส้นในแต่ละด้านของเส้นได้หรือไม่?
orlp

@ หรือไม่ถ้าคุณถามว่าถนนสามารถกว้างกว่า 5 แถวได้หรือไม่ หากคุณถามว่าอักขระช่องว่างสามารถใส่ในบรรทัดว่างด้านบนหรือด้านล่างบรรทัดกลางใช่แล้วตราบใดที่พวกเขามี bullet รายละเอียด 3
งานอดิเรกของ Calvin

ให้ฉันถามโดยตัวอย่างเป็นหนึ่งในผลลัพธ์ที่ถูกต้องหรือไม่ gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp

@ หรือไม่ก็คือ
งานอดิเรกของ Calvin

คำตอบ:


5

CJam, 38 ไบต์

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

มันทำงานอย่างไร

ครั้งแรกที่เรากำหนดคอลัมน์ถนนที่ถูกต้องกับตัวแปรNและPแล้วก็ประเมินสายป้อน ทำให้มีความยาวหนึ่งคู่และคอลัมน์อยู่บนสแต็ก เรากลุ่มพวกเขาขึ้นเรียกใช้ 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

อาร์เอส , 252 ตัวอักษร

แม้ว่าสิ่งนี้อาจไม่นับเพราะฉันเพิ่มผู้ประกอบการคอนเวอร์เจนซ์เป็น ripoff ของ Martin Büttnerของ Retinaหนึ่งชั่วโมงที่ผ่านมา ... ฉันไม่ได้มาที่นี่เพื่อแข่งขัน มันสนุกมากที่ได้ทำ regex-based solution

(\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/

ผมได้รับสาย 2 จากคำตอบ Retina มาร์ตินสำหรับการเขียนโปรแกรมภาษาปีที่ผ่านมา

คำอธิบาย

(\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#

มันมีเวทย์มนตร์มากมาย ดูคำตอบที่ฉันเชื่อมโยงข้างต้นสำหรับข้อมูลเพิ่มเติม

โดยพื้นฐานด้วยอินพุต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 kฟังก์ชั่นหลักfเข้าร่วมรายการองค์ประกอบห้ารายการด้วยการขึ้นบรรทัดใหม่ประกอบด้วยบรรทัดบนสุด (อักขระทุกตัวของบรรทัดกลางแทนที่ด้วย_), บรรทัดใหม่, บรรทัดกลาง, บรรทัดว่างเปล่าและบรรทัดล่าง (เหมือนกับด้านบน)


2

Python 3, 169 168 ไบต์ (167 กับ Python 2)

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)

ungolfed ค่อนข้างเป็นธรรม:

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

@ mbomb007 มันไม่เปลี่ยนการนับ: / ฉันไม่สามารถรับต่ำกว่า 169 atm
ทิม

การวางp+=['='*v,('- '*v)[:v]][_[-1]=='P']ที่ส่วนท้ายของบรรทัดก่อนหน้าด้วยเครื่องหมายอัฒภาคก่อนหน้าจะบันทึกหนึ่งไบต์
mbomb007

นอกจากนี้การใช้งูหลาม 2 แทนที่จะช่วยประหยัด 1 printไบต์บน
mbomb007

@ mbomb007 เพิ่มพวกเขาใน :) ฉันมีความรู้สึกหลาม 2 มันอาจจะสั้นกว่านี้ ... แต่ฉันไม่แน่ใจ
ทิม

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

ทับทิม, 137 135 ไบต์

ไม่ใช่สั้นที่สุดที่ฉันสามารถทำได้ แต่ใกล้กับที่อร่อยที่สุด ยืมมาบางส่วนจากคำตอบของเครื่องมือเพิ่มประสิทธิภาพ

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

Ungolfed:

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 ไบต์ (และชนะหลาม 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

สกาลา, 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 b)

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 ซึ่งมีช่องว่าง (เนื่องจากไม่มีจุดสิ้นสุดของเชน '\ 0' ใน matlab

ตัวอย่าง 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 และคว้าสตริงที่ 4 โปรดทราบว่าบรรทัดว่างต้องมีช่องว่าง (หรือบางอย่าง) ในการสแกนเพื่อดำเนินการรับอินพุต

    "==== - - ========= - - - - = - == -"

  • มันแทนที่=s ด้วยNs, -และด้วยPs

    "NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP"

  • จากนั้นจะแทรกช่องว่างระหว่างแต่ละNPและPN

    "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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.