Otopark süpervizörü


13

Giriş

Bir park yerinin gözetmenisiniz ve müdürünüz büyüklüğün aşırıya çekilmesine hazırlanıyor.

Geçen yılın PAT üst düzeyindeki bir sorunun basitleştirilmiş ve uyarlanmış bir versiyonudur .

Meydan okuma

Sen aynı anda yerinde kaç tane araba ölçüsü sorulabilir en fazla .

Standart kurallar geçerlidir. Ve bu bir kod golf çok kısa kod kazanır.

Birinci satır girişlerinin miktarı (en fazla olduğu 100,000, İsterseniz girişinizi nerede girdi uçlarını belirlemek için yalnızca bir eğreti olduğu için, bu çizgi içeremez ). Aşağıdaki metin satır başına bir girdi içerir. Ve her giriş üç sayı içerir:

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

Değişiklik 2: Giriş olarak üçlü bir dizi kullanmak uygundur.

Değişiklik 3: Bir girişteki sayıların sırasını değiştirebilirsiniz. Ve hangisini kullanacağınızı seçebilirsiniz. (Notlar bölümüne bakın)

Girdinin, aşağıdaki varsayımlarla geçerli olduğu garanti edilir:

  • Car plate number10000~ aralığında bir tamsayıdır99999
  • Time0~ aralığında bir tamsayıdır86400

Ve

  • Girişlerin kronolojik olarak sıralanması gerekmez .
  • İlk saniyeden önce hiç araba yok.
  • Orada mutlaka değil son saniyede sonra hiç araba.
  • Bir araba içeri girmeden çıkmazdı.
  • Car plate numberbenzersiz. (ancak aynı araba birden fazla kez ziyaret edebilir)
  • Bu nedenle, bir arabanın zaten içinde olduğu zaman partiye girmesi imkansızdır.
  • Aynı araba aynı anda içeri ve dışarı çıkmazdı time.
  • Bir arabanın içeri / dışarı zamanında lotta olduğu kabul edilir.

örnek 1

Giriş

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

Çıktı

3

açıklama

At 16500, araba 12345ve 75487park yerinde idi.

ÖRNEK 2

Ben bunu başarısız birçok kod bulundu çünkü yaptım.

Giriş (ilk satır dışarıda iken)

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

Çıktı

2

açıklama

At 16500, araba 12345ve 75487park yerinde idi.

Uyarılar

Aslında, çıktı için her üçüne de gerek yoktur. En azından, sonuç için sadece plaka + zamanına veya giriş / çıkış + zamanına ihtiyacınız var. Ancak algoritma iki koşulda biraz farklıdır, bu nedenle daha kısa olma seçimi belirli bir dilde bilinmemektedir. Ve elbette üç sayıyı da kullanabilirsiniz. Bu yüzden onları zor durumda bırakıyorum.


Araba plakası numaraları her zaman 5 basamak uzunluğunda mıdır?
Titus

1
@Titus 10000 ila 99999 arasındaki sayıların her zaman 5 basamak uzunluğunda olduğuna inanıyorum.
Keyu Gan

3
Gee bugün körüm.
Titus

Bir araba ilk kez ayrılmadan önce tekrar giremez sanırım? Açıkça ifade edilmiyor gibi görünüyor.
John Dvorak

@ JanDvorak üzgünüm. Hayır bu olamaz. Araba plakası numarası benzersizdir, çünkü gerçekte bir arabanın zaten içerideyken partiye girmesi imkansızdır.
Keyu Gan

Yanıtlar:


7

Mathematica, 33 bayt

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

Plaka bilgilerini gerektirmeyen çok daha basit bir algoritma olduğunu anlamak için sorun bildirimini daha iyi okumak zorunda kaldım.

Bir tamsayı döndüren adsız işlev; giriş biçimi, formdaki sıralı üçlülerin listesidir {time, 0|1, license plate}. Biz başlamak Sortliste kronolojik yapar, ing ve ayrıca sıralayarak zaman bağlarını kırar 0önce lar 1s; daha sonra 2#2-1&@@@varış / ayrılış bilgilerini saklar ve gerisini unutur ve ayrıca 0s'yi -1s'ye dönüştürür .

Accumulatebu listenin koşu toplamlarını hesaplar; sonuç, her varıştan / ayrılmadan sonra otoparktaki araç sayısının negatiflerinin bir listesidir . Sonra Minbunların en küçük (en negatif) olanını alır ve negatif işaret çıkarılır.

Mathematica, 56 bayt

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

Orijinal gönderim (ilk birkaç yorum bu gönderimdir). Bir tamsayı döndüren adsız işlev; giriş biçimi, formdaki sıralı üçlülerin listesidir {time, 0|1, license plate}.

Zaman girişini önce ve giriş / çıkış girişini ikinci olarak seçmemizin nedeni Sort@#, listeyi kronolojik olarak sıralamak ve eşzamanlı olmaları durumunda kalkıştan önce varışları kaydetmek. Bundan sonra , hala kronolojik olarak sıralanmış #3->#2&@@@formun "kurallarının" bir listesini döndürür license plate -> 0|1.

Ardından, FoldList[List,{},...]bu kurallar listesinin tüm başlangıç ​​bölümlerinin bir listesini oluşturur. Aslında, bu ilk segmentleri berbat ediyor; kderinliği 2 az bir kural olarak, derinlik 3 az bir kural olarak, ..., ve derinlikte bir kuralı ile bir liste olmak kadar inci ilk parçasının uçları k+ 1. ( FoldList[Append,{},...]daha doğal sonuç verir.) Bununla birlikte, <|#|>bu başlangıç ​​segmentlerinin her birini, istenen iki etkiye sahip bir "ilişkilendirme" ye dönüştürür: ilk olarak, az önce oluşturduğumuz iç içe liste yapısını tamamen düzleştirir; ikincisi, daha sonraki kuralları, tam da burada ihtiyacımız olan şey olan önceki kuralları geçersiz kılmaya zorlar - otoparktan ayrılan herhangi bir araba için, ilk girişinin kaydı artık tamamen kaybolmuştur (ve benzer şekilde yeniden giren arabalar için) .

Yani geriye kalan tek şey, bu çağrışımların her birinde Countkaç tane 0var olduğudur Max.


1
Arabalar aynı anda gelip giderse, bu her zaman doğru olanı yapar mı?
Christian Sievers

Cevabınız yanlış olabilir. Maksimum değer, bir araç bir kez daha girildiğinde gerçekleşmeyebilir, bu nedenle ilişkilendirmeleri kullanarak girişleri silmek güvenli değildir. Bu resme bakın: i.imgur.com/D5xUl3z.png Açıkçası 16500'de 3 araba var.
Keyu Gan

@KeyuGan: Bir araba tekrar girdiğinde maksimumun gerçekleştiğini iddia etmedim. Çözümümün, her bir giriş / ayrılış sırasında otoparktaki araç sayısını sayar ve bunların maksimumunu alır.
Greg Martin

1
Belki örnek 2'yi deneyebilirsiniz.
Keyu Gan

1
Şahsen sana katılıyorum. :) Yaptığım orijinal tanımdan tanımı kopyalamak. En büyük fark, orijinal olanın araba plakalarının görüntülerden tanınmasını ve nihai sonuç olarak basılmasıdır.
Keyu Gan

5

Haskell, 76 63 61 bayt

@ Nimi'nin önerisinin bir varyasyonu ile 2 bayt kaydedildi.

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

Argümanı, problem ifadesi tarafından verilen sıraya göre üçlü bir liste olarak bekler.

Mümkün olan her bir zaman (ve biraz daha fazlası) için önce gelip sonra araba olaylarını terk etmek için arama yaparız ve bunları artı veya eksi olanların listesine dönüştürürüz. Bu listenin kısmi toplamlarını ve daha sonra bu kısmi toplamların maksimumunu alıyoruz.


Bırakın importve kullanın [(-1)^c|i<-[1..86400],(_,b,c)<-l,i==b].
nimi

Giden arabalardan önce gelen arabalara ihtiyacım var, bu yüzden biraz daha karmaşık, ama yine de fikrinizle 2 bayt tasarruf edebilirim. Teşekkürler!
Christian Sievers

2

PHP 7.1, 126 117 bayt

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;

dosyadan girdi alır i, ilk satırı yoksayar. İle çalıştırın -r.
Girdide bir satırsonu satırı gerektirir. Windows -2ile değiştirin -3.

Yıkmak

# 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

Maalesef, bir işlev yazıyorsanız giriş olarak üçlü bir dizi kullanabilirsiniz. Arkadaşlarım ve ben, karmaşık girdisiz bir sorundan bahsediyorsak, golf dilini daha rekabetçi hale getirmenin iyi bir yolu olduğuna inanıyoruz.
Keyu Gan

@KeyuGan: İpucu için teşekkürler; ancak girdi olarak bir dizi ile, bir fonksiyona ihtiyacım var ve bu hem üçüz bir dizi hem de dizilerin üçlüsü ile iki bayta mal olur. işlevleri, dizi eşleme ve özel sıralama PHP'de hantaldır. Herhangi bir şeyi kaydedebilmemin tek yolu $d, girdi veya sıralı girdi olarak (zamana ve içeri / dışarıya göre) hazırladım . Ve bu meydan okumadan çok fazla şey alacaktı. Hizalanmış giriş ttttt i plate, plaka numarası ile hizalanan sayı ile 17 bayt, 19 daha fazla tasarruf sağlayacaktır.
Titus


2

Oktav, 50 , 64 38 bayt

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

@Greg Martin Mathematica yanıtıyla aynı

İşlev 3 sütunlu bir dizi alır [time, i/o,plateN]

önceki cevap:

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

Fonksiyon sadece iki giriş alır t: üçlü giriş içeren Obir hücre dizisinin ilk iki elemanından zaman ve : G / Ç A!

Mevcut araçların kaydedilen her zaman sayısı için hesaplanan seyrek bir matris. Bunun için çıkış süresi + 1 araç çıkışı için kabul edilir ve karşılık gelen 1 -1 ve 0 olarak 1 olarak değiştirilir
.
Daha sonra lottaki mevcut araç sayısını temsil eden kümülatif toplam hesaplanır ve maksimumu bulunur.


Oktav destek hücre dizisini hatırlıyorum, yani giriş olarak yalnızca bir üçlü dizi kullanabilirsiniz. Kısıtlama, M5 öncesi baskıya göre yapılır ve 'üçlü bir dizi' belirtir. M5'te açıkladım
Keyu Gan

@KeyuGan Yeni icat edilen kısıtlamanızın gereksiz bir şekilde kodumun 14 byte arttığını düşünüyorum. bu nedenle bu sitede yenisiniz, daha fazla katılımcı çekmek için asgari sayıda kısıtlamaya sahip sorularınız olması daha iyidir.
rahnema1

2

JavaScript (ES6), 63 73 71 bayt

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

Bu, girişi sipariş edilen bir dizi girdi olarak kabul eder [time, inout, plate]. Maalesef aynı inout kez araçlarının her iki araba sürede anda çok da göz önünde bulundurulması olması nedeniyle, sıralama algoritması sipariş gerekir nedeniyle 0önce 111 bayt mal olan oldu.

Kredi

  • Harita işlevinin içinde kaydırma ve çarpma işlemini tamamen hareket ettirerek 1 bayt kazandım (teşekkürler Neil).
  • Sıralama işlevinde bir yıkılmış bağımsız değişken kullanarak başka iki bayt kurtardım (teşekkürler edc65).

gösteri

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


Kodunuzu iyi çalışmıyor gibi görünüyor d=[[16400,75487,0],[16500,75487,1],[16500,99999,0],[16600,99999,1]];2 yazdırmak gerekiyordu?
Keyu Gan

4 girişli test durumunda, sadece 2 araba var. Girdi siparişinizi karşılayacak şekilde biçimlendirdim.
Keyu Gan

@Anahtar Yanlış anlama için üzgünüm, ikinci örneğe atıfta bulunduğunuzu fark etmedim. Şimdi düzeltildi.
Patrick Roberts

Algoritmanızın plaka numarasına bağlı olmadığını biliyorum. Bununla birlikte, giriş emrinin tanımına dahil edilmesi gerektiğini öneririm, sadece sonuna kadar bırakın;)
Keyu Gan

1
@ edc65 aslında, sadece 2 bayt, 4 değil. Bu da 71 bayt: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 bayt

EDIT: 2. örneği destekleyecek şekilde düzeltildi

Girdileri bir dizi [in_out, time, plate]dizisi olarak alır. Ancak platesütun aslında yok sayılır.

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

Ölçek


Okuma in_outyerine sütun platesütununda size altı bayt kaydetmek gerekir: v=>n+=1-v[2]*2.
Neil

Bu ikinci örnek için yanlıştır, bu yüzden bunu tekrar düzenlerseniz, bunu dikkate almanız gerekir. (Bu konudaki son düzenleme ikinci örnek eklenmeden önce olduğundan, teknik olarak buna uymaktan muaftır ve kıskanç değilim!)
Patrick Roberts

@PatrickRoberts Bir bilgisayarın önünde olduğumda bunu düzeltmeye çalışacağız ^^
Arnauld

@Neil İyi yakala! Yine de ikinci örneği desteklemek için yeniden yazmak zorunda kaldım, ama tavsiyelerinizi takip ettim.
Arnauld
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.