Pengkodean Panjang Jalan

21

Di Amerika Serikat , dua arah yang berlawanan dari lalu lintas di jalan dipisahkan oleh garis kuning putus-putus jika melewati diperbolehkan dan dua garis kuning solid jika lewat tidak diizinkan.

grafik garis aturan jalan

(Hanya satu sisi yang dapat dilewati untuk memungkinkan melintas di sisi itu, dan garis kuning dapat berarti hal-hal lain seperti pusat atau jalur yang dapat dibalik, tetapi kami tidak memedulikan kasus-kasus tersebut.)

Tulis program yang menggunakan a jangka panjang dikodekan string Puntuk melewati dan Nuntuk tidak lewat , dan mencetak versi ASCII jalan yang sesuai. Kecuali untuk garis tengah, jalan selalu memiliki pola yang sama, yang dapat dengan mudah disimpulkan dari contoh di bawah ini.

Akan ada angka desimal positif sebelum masing P- masing dan Ndalam string input. Angka ini menentukan panjang bagian yang melintas atau tidak ada bagian yang melintas dari bagian jalan saat ini.

Contohnya

Masukan dari 12N akan menghasilkan 12 kolom tanpa jalan yang lewat (garis tengah semua =):

____________


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

____________

Masukan dari 12P akan menghasilkan 12 kolom jalan yang lewat ( - pengulangan garis tengah ):

____________


- - - - - - 

____________

Lewat dan no passing kemudian dapat digabungkan, misalnya 4N4P9N7P1N1P2N2Pakan menghasilkan:

______________________________


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

______________________________

Ini adalah 4 kolom tanpa lewat , lalu 4 lewat , lalu 9 tanpa lewat , dll.

Perhatikan bahwa zona yang lewat selalu dimulai dengan tanda hubung ( -) di sisi paling kiri, bukan spasi ( ). Ini wajib diisi.

Detail

  • Masukan tidak akan pernah memiliki dua N zona atau dua Pzona berturut-turut. misalnya 4P5Ptidak akan pernah terjadi.
  • Anda tidak perlu mendukung surat tanpa angka positif terkemuka. PolosP akan selalu 1P, plain Nakan selalu 1N.
  • Mungkin ada ruang trailing selama mereka tidak melampaui kolom terakhir jalan. Mungkin ada satu trailing newline opsional.
  • Alih-alih sebuah program, Anda dapat menulis fungsi yang mengambil string yang dikodekan run-length dan mencetak atau mengembalikan jalan ASCII.
  • Mengambil input dengan cara standar apa pun (stdin, baris perintah, fungsi arg).

Kode terpendek dalam byte menang. Tiebreaker adalah posting sebelumnya.

Hobi Calvin
sumber
Apakah jalan harus asimetris, atau apakah bisa mencetak 4 ruang jalan di setiap sisi garis?
orlp
@ orlp Jika Anda bertanya apakah jalan bisa lebih lebar dari 5 baris, maka tidak. Jika Anda bertanya apakah karakter ruang dapat dimasukkan ke dalam baris kosong di atas atau di bawah garis tengah, maka ya selama mereka tahan dengan peluru detail 3.
Calvin Hobbies
Izinkan saya bertanya dengan contoh, apakah salah satu dari ini adalah output yang valid? gist.github.com/orlp/0e0eae16d6e1fcda5e9b
orlp
@ Atau juga tidak.
Hobi Calvin

Jawaban:

5

CJam, 38 byte

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

Bagaimana itu bekerja

Kami pertama kali menetapkan kolom jalan yang benar untuk variabel Ndan Pkemudian hanya mengevaluasi input string. Ini menyisakan sepasang panjang dan kolom di tumpukan. Kami mengelompokkannya, menjalankan RLD di atasnya untuk mendapatkan kolom lengkap, transpos untuk bergabung dengan mereka dan akhirnya, mengonversi kontinu --menjadi -.

:_  - _":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 "- "

Cobalah online di sini

Pengoptimal
sumber
6

JavaScript (ES6), 114

Dengan menggunakan string template , 5 baris umpan yang signifikan harus dihitung.

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


${s}

`+b
edc65
sumber
5

rs , 252 karakter

Walaupun ini mungkin tidak masuk hitungan karena saya menambahkan operator konvergensi sebagai penipuan dari Retina Martin Büttner satu jam yang lalu ... Saya toh tidak benar-benar di sini untuk bersaing. Sangat menyenangkan membuat solusi berbasis regex untuk ini.

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

Saya mendapat baris 2 dari jawaban Retina Martin untuk Bahasa Pemrograman Sepanjang Tahun .

Penjelasan

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

Ini melakukan banyak keajaiban. Lihat jawaban yang saya tautkan di atas untuk info lebih lanjut.

Pada dasarnya, dengan input 4N4P9N7P1N1P2N2P, ini akan menjadi hasilnya:

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

Berikutnya:

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

Ini menggantikan angka-angka yang mendahului simbol larangan lewat (N) dengan tanda sama dengan. Hasilnya dengan input sebelumnya:

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

Ini:

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

mengganti angka pertama sebelum simbol yang lewat (P) dengan tanda hubung pertama. Hasil:

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

Dua baris berikutnya melanjutkan pola yang sama:

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

Baris pertama menggantikan sisa garis dengan pola dash-space. Yang kedua menangani nomor ganjil; itu menggantikan dasbor terakhir diikuti oleh integer tunggal (seperti -5) dengan dasbor-ruang ( -). Sekarang, hasilnya adalah:

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

Sekarang semuanya mulai jatuh ke tempatnya. Baris selanjutnya:

#\D/

hanya menghapus #Ndan #P.

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

atur garis bawah di bagian atas dan bawah untuk memberi:

A______________________________


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

A______________________________

Terakhir, kami menghapus A:

A/
kirbyfan64sos
sumber
2

Haskell, 165 byte

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

Contoh dijalankan ( fmengembalikan string, jadi untuk tampilan yang lebih baik cetaklah):

*Main> putStr $ f "4N4P9N7P1N1P2N2P"
______________________________


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

______________________________

Cara kerjanya: pmengembalikan garis tengah dengan secara parsing mengurai string input dan menyatukan jumlah simbol yang ditemukan oleh fungsi pencarian k. Fungsi utama fbergabung dengan daftar lima elemen dengan baris baru, yang terdiri dari baris atas (setiap karakter dari baris tengah diganti dengan _), baris baru, garis tengah, garis kosong, dan garis bawah (sama seperti atas).

nimi
sumber
2

Python 3, 169 168 byte. (167 dengan 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)

Cukup tidak dicemari:

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

Cobalah online di sini .

Tim
sumber
Anda lupa memperbarui jumlah byte Anda.
mbomb007
@ mbomb007 Itu tidak mengubah hitungan: / Saya tidak bisa mendapatkannya di bawah 169 atm
Tim
Menempatkan p+=['='*v,('- '*v)[:v]][_[-1]=='P']di akhir baris sebelumnya dengan titik koma sebelumnya menghemat satu byte.
mbomb007
Juga, menggunakan Python 2 sebagai gantinya menyimpan 1 byte di print.
mbomb007
@ mbomb007 menambahkan mereka di :) Saya punya perasaan python 2 bahkan mungkin lebih pendek ... Tapi saya tidak yakin.
Tim
2

Python 2, 136 byte

Anehnya, mengimpor retampaknya bermanfaat di sini.

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
Uri Granta
sumber
2

PHP, 187 byte

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

Kode dapat tetap dalam satu baris; itu ditampilkan di sini pada banyak baris agar lebih mudah dibaca (spasi putih dan baris baru yang digunakan untuk memformat tidak dihitung).

Dua byte dapat disimpan dengan tidak mencetak baris baru. Lima byte lagi dapat disimpan dengan menggunakan karakter baris baru nyata pada echo():

echo("$a


$o

$a");

Enam byte tambahan dapat disimpan dengan menghilangkan inisialisasi $o ( $o='';) tetapi ini akan memicu pemberitahuan. Pemberitahuan dapat ditekan dengan menjalankan skrip menggunakan baris perintah:

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

Ini membawanya ke 174 byte.

aksioma
sumber
2

Rubi, 137 135 byte

Bukan yang terpendek yang bisa saya lakukan, tetapi dekat dengan yang terbaik. Sebagian meminjam dari jawaban Pengoptimal.

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

Tidak Disatukan:

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(/--/, '- ')
14mRh4X0r
sumber
Anda harus dapat meningkatkan ini dengan 2 byte (dan mengalahkan jawaban python 2) dengan mengubah baris terakhir menjadi (a.shift.zip(*a).map(&:join)*?\n).gsub'--','- '.
blutorange
1

C, 155 byte

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

Lebih mudah dibaca:

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

Loop luar menghitung garis dari 5 hingga 0.

Loop tengah berulang pada bagian-bagian dari string yang disandikan:

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

Loop dalam menerjemahkan bagian, seperti, 7P ,, dan mengulangi jumlah yang diperlukan kali (misalnya 7).

Setiap iterasi mencetak satu char. Nilai dari chardijelaskan oleh kode l%5?l^2?32:c^78?++x&1?45:32:61:95:

  • Jika nomor baris 5 atau 0, cetak 95 (_ )
  • Jika tidak, jika nomor baris tidak sama dengan 2, cetak spasi
  • Jika tidak, jika simbolnya adalah 'N', cetak 61 (= )
  • Jika tidak, tambah x1 (diinisialisasi ke 2 oleh sscanf)
  • Jika aneh, cetak 45 ( -), cetak lain 32 (spasi)
anatolyg
sumber
0

Scala, 163 byte

(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"}

Coba pertama, mungkin golf lagi.

Yakub
sumber
0

Ruby, 94 byte

Pinjam gsub'--','- 'ide dari jawaban 14mRh4X0r . Saya pikir jawaban itu lebih menarik, meskipun ini lebih pendek.

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


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

#{n}"}

Pengujian:

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


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

#{n}"}

puts f['4N4P9N7P1N1P2N2P']

Menghasilkan:

______________________________


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

______________________________
blutorange
sumber
0

biarkan saya memasukkan versi matlab saya

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

memasukkan

String berformat ascii yang diuntai oleh spasi (karena tidak ada ujung rantai '\ 0' di matlab

contoh V = '12N13P'


keluaran

representasi pola jalan

_________________________


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

_________________________

fungsi

fungsi harus dipanggil dari tail-1 (karakter kosong dihapus)

contoh : p (V, numel (V) -1)

Simulasi

coba online di sini

Abr001am
sumber
0

R, 132 byte

Tidak terlalu senang dengan ini, tapi itu sedikit menyenangkan untuk dilakukan :) Sudah mencoba untuk menyingkirkan beberapa gsubs, tetapi usaha saya sia-sia. Saya curiga ada cara yang lebih baik untuk melakukan ini.

cat(rbind(nchar(a<-scan(,'',t=gsub('PN','P N',gsub('NP','N P',chartr('- =','PPN',scan(,'',sep='|')[4]))))),substring(a,1,1)),sep='')
  • scanmendapatkan string dari STDIN dan meraih yang ke-4. Perhatikan bahwa baris kosong memerlukan ruang (atau sesuatu) di dalamnya untuk pemindaian agar terus mendapatkan input.

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

  • Ini menggantikan =s dengan Ns, -dan denganP s.

    "NNNNPPPPNNNNNNNNNPPPPPPPNPNNPP"

  • Kemudian ia menyisipkan ruang antara masing NP- masing danPN

    "NNNN PPPP NNNNNNNNNN PPPPPPP NP NN PP"

  • Pemindaian membagi string pada spasi

    "NNNN" "PPPP" "NNNNNNNNNN" "PPPPPPP" "N" "P" "NN" "PP"

  • Panjang string kemudian diikat ( rbind) dengan karakter pertama dari setiap string

    4 4 9 7 1 1 2 2
    "N" "P" "N" "P" "N" "P" "N" "P"

  • Array kemudian keluaran menggunakan cat.

Uji coba

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
MickyT
sumber