Pengawas tempat parkir

13

pengantar

Anda adalah pengawas tempat parkir dan manajer Anda sedang mempersiapkan untuk mengecilkan ukurannya menjadi ekstrem.

Ini adalah versi masalah yang disederhanakan dan diadaptasi di tingkat atas PAT tahun lalu .

Tantangan

Anda diminta menghitung berapa banyak mobil yang ada di tempat parkir pada saat yang bersamaan, paling banyak .

Aturan standar berlaku. Dan ini adalah kode-golf sehingga kode terpendek menang.

Baris pertama adalah jumlah entri (tidak lebih dari 100,000, input Anda mungkin tidak mengandung baris ini jika Anda suka, karena itu hanya pengganti sementara untuk menentukan di mana input berakhir ). Teks berikut ini berisi satu entri per baris. Dan setiap entri mencakup tiga angka:

<Car plate number> <Time (seconds) since open> <0(In) | 1(Out)>

Modifikasi 2: Tidak apa-apa menggunakan array tiga kali lipat sebagai input.

Modifikasi 3: Anda dapat mengubah urutan angka dalam satu entri. Dan Anda dapat memilih mana yang akan digunakan. (lihat bagian Keterangan)

Input dijamin valid, dengan asumsi bahwa:

  • Car plate numberadalah bilangan bulat dalam kisaran 10000~99999
  • Timeadalah bilangan bulat dalam kisaran 0~86400

Dan

  • Entri tidak harus dipesan secara kronologis.
  • Tidak ada mobil sebelum detik pertama.
  • Tidak perlu ada mobil setelah detik terakhir.
  • Mobil tidak akan pergi sebelum masuk.
  • Car plate numberunik. (tetapi mobil yang sama dapat mengunjungi lebih dari satu kali)
  • Jadi tidak mungkin bagi mobil untuk memasuki tempat parkir ketika sudah ada di dalamnya.
  • Mobil yang sama tidak akan masuk dan keluar pada saat yang sama time.
  • Mobil dianggap berada di tempat parkir pada saat keluar / masuk.

Contoh 1

Memasukkan

11
97845 36000 1
75487 16500 1
12345 16 0
75486 3300 0
12345 6500 1
97845 32800 0
12345 16400 0
97846 16501 1
97846 16500 0
75486 8800 1
75487 3300 0

Keluaran

3

Penjelasan

Di 16500, mobil 12345dan 75487berada di tempat parkir.

Contoh 2

Saya membuat ini karena saya menemukan banyak kode gagal di dalamnya.

Input (dengan baris pertama ditinggalkan)

12345 16400 0
12345 16500 1
75487 16500 0
75487 16600 1

Keluaran

2

Penjelasan

Di 16500, mobil 12345dan 75487berada di tempat parkir.

Catatan

Sebenarnya, tidak ketiganya diperlukan untuk output. Paling tidak, Anda hanya perlu piring + waktu atau waktu + keluar / masuk untuk hasilnya. Tetapi algoritma ini sedikit berbeda dalam dua keadaan, sehingga pilihan menjadi lebih pendek tetap tidak diketahui dalam bahasa tertentu. Dan tentu saja Anda dapat menggunakan ketiga angka tersebut. Jadi saya meninggalkan mereka dalam tantangan.

Keyu Gan
sumber
Apakah angka plat mobil selalu panjang 5 digit?
Titus
1
@Itus saya percaya angka dari 10.000 hingga 99999 selalu 5 digit.
Keyu Gan
3
Astaga, aku buta hari ini.
Titus
Saya berasumsi mobil tidak bisa masuk lagi sebelum pergi meninggalkan pertama kali? Tampaknya tidak dinyatakan secara eksplisit.
John Dvorak
@ JanDvorak eh maaf. Tidak, tidak bisa. Hal ini tersirat oleh nomor plat mobil yang unik karena pada kenyataannya tidak mungkin satu mobil yang sama untuk masuk lot ketika sudah ada di dalamnya.
Keyu Gan

Jawaban:

7

Mathematica, 33 byte

-Min@Accumulate[2#2-1&@@@Sort@#]&

Saya harus membaca pernyataan masalah dengan lebih baik untuk menyadari bahwa ada algoritma yang jauh lebih sederhana yang tidak memerlukan informasi plat nomor.

Fungsi yang tidak disebutkan namanya mengembalikan integer; format input adalah daftar tiga kali lipat yang dipesan dalam formulir {time, 0|1, license plate}. Kita mulai dengan Sorting, yang membuat daftar kronologis dan juga memutus ikatan waktu dengan menyortir 0sebelum 1; kemudian 2#2-1&@@@menyimpan informasi kedatangan / keberangkatan dan melupakan sisanya, dan juga mengonversi 0s ke -1s.

Accumulatemenghitung total berjalan dari daftar itu; hasilnya adalah daftar negatif dari jumlah mobil di tempat parkir setelah setiap kedatangan / keberangkatan. Kemudian Minpilih yang terkecil (paling negatif) dari ini dan tanda negatif dilucuti.

Mathematica, 56 byte

Max[<|#|>~Count~0&/@FoldList[List,{},#3->#2&@@@Sort@#]]&

Kiriman asli (beberapa komentar pertama merujuk pada kiriman ini). Fungsi yang tidak disebutkan namanya mengembalikan integer; format input adalah daftar tiga kali lipat yang dipesan dalam formulir {time, 0|1, license plate}.

Alasan kami memilih untuk menempatkan entri waktu lebih dulu dan entri masuk / keluar kedua adalah untuk itu Sort@# mengurutkan daftar secara kronologis, dan mencatat kedatangan sebelum keberangkatan jika mereka simultan. Setelah itu, #3->#2&@@@mengembalikan daftar "aturan" formulir license plate -> 0|1, masih diurutkan secara kronologis.

Kemudian, FoldList[List,{},...]buat daftar semua segmen awal dari daftar aturan itu. Sebenarnya, itu benar-benar mengacaukan segmen-segmen awal itu; ituk th awal segmen ujung sampai menjadi daftar dengan satu aturan di kedalaman 2, satu aturan di kedalaman 3, ..., dan satu aturan di kedalaman k1. ( FoldList[Append,{},...]akan menghasilkan hasil yang lebih alami.) Namun, <|#|>mengubah masing-masing segmen awal ini menjadi "asosiasi", yang memiliki dua efek yang diinginkan: pertama, itu benar-benar meratakan struktur daftar bersarang yang baru saja kita buat; dan kedua, ini kemudian memaksa aturan untuk mengesampingkan aturan sebelumnya, yang persis seperti yang kita butuhkan di sini — untuk mobil apa pun yang telah meninggalkan tempat parkir, catatan entri awalnya sekarang benar-benar hilang (dan juga untuk mobil yang masuk kembali) .

Jadi yang tersisa untuk dilakukan adalah Countberapa banyak 0yang ada di masing-masing asosiasi ini, dan ambil Max.

Greg Martin
sumber
1
Apakah ini akan selalu melakukan hal yang benar jika mobil datang dan pergi pada saat yang sama?
Christian Sievers
Jawaban Anda mungkin salah. Maksimum tidak selalu terjadi ketika mobil masuk sekali lagi sehingga tidak aman untuk menghapus entri menggunakan asosiasi. Lihat gambar ini: i.imgur.com/D5xUl3z.png Jelas ada 3 mobil di 16500.
Keyu Gan
@KeyuGan: Saya tidak mengklaim bahwa maksimum terjadi ketika mobil masuk kembali. Perhatikan bahwa solusi saya menghitung jumlah mobil di tempat parkir pada saat setiap entri / keberangkatan, dan mengambil maksimum dari mereka.
Greg Martin
1
Mungkin Anda bisa mencoba contoh 2.
Keyu Gan
1
Secara pribadi saya setuju dengan Anda. :) Apa yang telah saya lakukan adalah menyalin definisi dari masalah aslinya. Perbedaan utama adalah bahwa yang asli membutuhkan pelat mobil yang dikenali dari gambar dan dicetak sebagai hasil akhir.
Keyu Gan
5

Haskell, 76 63 61 byte

2 byte disimpan oleh variasi saran @ nimi.

f l=maximum$scanl1(+)[(-1)^c|i<-[0..8^6],(_,b,c)<-l,i==2*b+c]

Mengharapkan argumen sebagai daftar tiga kali lipat dalam urutan yang diberikan oleh pernyataan masalah.

Untuk setiap waktu yang memungkinkan (dan lebih banyak lagi), kami mencari terlebih dahulu untuk datang dan kemudian meninggalkan acara mobil dan mengubahnya ke daftar plus atau minus. Kami mengambil jumlah parsial dari daftar ini dan kemudian pepatah dari jumlah parsial ini.

Sievers Kristen
sumber
Jatuhkan importdan gunakan [(-1)^c|i<-[1..86400],(_,b,c)<-l,i==b].
nimi
Saya perlu mobil yang masuk sebelum yang keluar, jadi ini sedikit lebih rumit, tapi saya masih bisa menghemat 2 byte dengan ide Anda. Terima kasih!
Christian Sievers
2

PHP 7.1, 126 117 byte

for(;$s=file(i)[++$i];)$d[+substr($s,6)][$s[-2]]++;ksort($d);foreach($d as$a){$r=max($r,$n+=$a[0]);$n-=$a[1];}echo$r;

mengambil input dari file i, abaikan baris pertama. Jalankan dengan -r.
Membutuhkan baris tambahan di input. Ganti -2dengan-3 untuk Windows.

kerusakan

# generate 2-dim array; first index=time, second index=0/1 (in/out);
# values=number of cars arriving/leaging; ignore plate number
for(;$s=file(i)[++$i];) # read file line by line (includes trailing newline)
    $d[+substr($s,6)][$s[-2]]++;    # substring to int=>time, last but one character=>1/0
ksort($d);                      # sort array by 1st index (time)
foreach($d as$a)    # loop through array; ignore time
{
    $r=max($r,                      # 2. update maximum count
        $n+=$a[0]                   # 1. add arriving cars to `$n` (current no. of cars)
    );
    $n-=$a[1];                      # 3. remove leaving cars from `$n`
}
echo$r;                         # print result
Titus
sumber
Maaf Anda dapat menggunakan array tiga kali lipat sebagai input jika Anda sedang menulis suatu fungsi. Teman-teman saya dan saya percaya itu adalah cara yang baik untuk membuat bahasa non-golf lebih kompetitif jika kita berbicara tentang masalah tanpa input yang rumit.
Keyu Gan
@KeyuGan: Terima kasih atas petunjuknya; tetapi dengan sebuah array sebagai input, saya membutuhkan sebuah fungsi, dan itu akan memakan biaya dua byte, baik dengan array triplet dan dengan triplet array. fungsi, pemetaan larik, dan sortir khusus berukuran besar di PHP. Hanya cara saya bisa menyimpan apa pun yang akan saya siapkan $dsebagai input atau input yang diurutkan (berdasarkan waktu dan masuk / keluar). Dan hal itu akan mengambil terlalu banyak dari tantangan. Input yang ttttt i plateselaras akan menghemat 17 byte, 19 lebih banyak dengan jumlah yang selaras dengan nomor pelat.
Titus
2

C, 147 byte

Program lengkap, membaca input dari stdin.

int r[86402]={},u,i,n,t;g(s,o){for(;s<86401;n<r[s]?n=r[s]:0,++s)r[s+o]+=o?-1:1;}main(){for(n=0;scanf("%d%d%d",&u,&t,&i)==3;g(t,i));printf("%d",n);}

Cobalah di ideone .

owacoder
sumber
Saya percaya aman untuk menghapus spasi di antara%d
Keyu Gan
Ups, terima kasih. Saya tidak menggunakan scanfcukup, saya kira.
owacoder
Saya suka cin. LOL
Keyu Gan
118 byte
ceilingcat
2

Oktaf, 50 , 64 38 byte

@(A)-min(cumsum(sortrows(A)(:,2)*2-1))

Sama dengan jawaban Matematika @Greg Martin

Fungsi mendapat array dengan 3 kolom [time, i/o,plateN]

jawaban sebelumnya:

@(A){[t,O]=A{:};max(cumsum(sparse({++t(!O),t}{2},1,!O*2-1)))}{2}

Fungsi ini hanya mendapat dua input t: waktu dan O: I / O dari dua elemen pertama array sel Ayang berisi tiga input!

Matriks tipis dibuat untuk menghitung setiap catatan waktu jumlah mobil yang ada. Untuk itu waktu keluar + 1 dipertimbangkan untuk keluar mobil dan sesuai 1 perubahan ke -1 dan 0 diubah menjadi 1.
Penggunaan jarang di sini sangat penting karena beberapa mobil dapat tiba atau pergi pada saat yang sama.
Kemudian jumlah kumulatif dihitung mewakili jumlah mobil saat ini di tempat parkir dan maks ditemukan.

rahnema1
sumber
Saya ingat array sel dukungan Octave, yang berarti Anda hanya dapat menggunakan satu array tiga kali lipat sebagai input. Pembatasan ini sesuai dengan edisi sebelum M5 dan menyatakan 'array of triples'. Saya telah mengklarifikasi di M5
Keyu Gan
@ Kaneyan Saya pikir pembatasan baru yang Anda buat tidak perlu meningkat 14 byte dari kode saya. jadi Anda baru di situs ini, lebih baik memiliki pertanyaan dengan jumlah pembatasan minimal untuk menarik lebih banyak kontributor.
rahnema1
2

JavaScript (ES6), 63 73 71 byte

d=>Math.max(...d.sort((a,[b,c])=>a[s=0]-b||a[1]-c).map(e=>s+=1-e[1]*2))

Ini menerima input sebagai array dari entri yang dipesan [time, inout, plate]. Sayangnya karena fakta bahwa waktu keluar yang sama berarti kedua mobil dipertimbangkan dalam lot saat ini, algoritma pengurutan harus dipesan 0sebelum1 , yang biayanya 11 byte.

Kredit

  • Saya menyimpan 1 byte dengan memindahkan shift dan multiplikasi di dalam fungsi peta sepenuhnya (terima kasih Neil).
  • Saya menyimpan dua byte lagi dengan menggunakan argumen yang dirusak dalam fungsi sort (terima kasih edc65).

Demo

// test the two examples
console.log([[[36000,1],[16500,1],[16,0],[3300,0],[6500,1],[32800,0],[16400,0],[16501,1],[16500,0],[8800,1],[3300,0]],[[16400,0],[16500,1],[16500,0],[16600,1]]].map(
// answer submission
d=>Math.max(...d.sort((a,[b,c])=>a[s=0]-b||a[1]-c).map(e=>s+=1-e[1]*2))
));

Patrick Roberts
sumber
Tampaknya kode Anda tidak berfungsi dengan baik pada d=[[16400,75487,0],[16500,75487,1],[16500,99999,0],[16600,99999,1]];saya seharusnya mencetak 2?
Keyu Gan
Nah pada test case 4 entri, hanya ada 2 mobil. Saya telah memformatnya untuk memenuhi pesanan input Anda.
Keyu Gan
@ Kaney Maaf atas kesalahpahaman ini, saya tidak sadar Anda merujuk pada contoh kedua. Sudah diperbaiki sekarang.
Patrick Roberts
Saya tahu algoritma Anda tidak tergantung pada nomor pelat. Namun saya sarankan itu harus dimasukkan dalam definisi urutan input, biarkan saja sampai yang terakhir;)
Keyu Gan
1
@ edc65 sebenarnya, hanya 2 byte, bukan 4. Ini juga 71 byte:d=>Math.max(...d.sort(([a,b],[c,d])=>a-b||c-d).map(e=>s+=1-e[1]*2,s=0))
Patrick Roberts
2

JavaScript (ES6), 8368 70 byte

EDIT: diperbaiki untuk mendukung contoh ke-2

Mengambil input sebagai array [in_out, time, plate]array. Namun platekolom tersebut sebenarnya diabaikan.

a=>a.sort(([a,b],[c,d])=>b-d||a-c).map(v=>a=(n+=1-v[0]*2)<a?a:n,n=0)|a

Uji

Arnauld
sumber
Membaca in_outkolom bukan platekolom harus menghemat enam byte: v=>n+=1-v[2]*2.
Neil
Ini tidak benar untuk contoh kedua, jadi jika Anda mengedit ini lagi, Anda harus mempertimbangkannya. (Karena suntingan terakhir tentang ini adalah sebelum contoh kedua ditambahkan, secara teknis dikecualikan dari mematuhinya, dan saya sama sekali tidak cemburu!)
Patrick Roberts
@ PatrickRoberts Akan mencoba memperbaikinya ketika saya kembali di depan komputer ^^
Arnauld
@Neil Tangkapan bagus! Saya tetap harus menulis ulang untuk mendukung contoh ke-2, tetapi akhirnya saya mengikuti saran Anda.
Arnauld