Наглядник для паркування


13

Вступ

Ви наглядач за парковкою, і ваш менеджер готується до скорочення розміру до крайності.

Це спрощена та адаптована версія проблеми в минулорічному топ-рівні PAT .

Виклик

Вас просять підрахувати, скільки автомобілів у партії одночасно, максимум .

Діють стандартні правила. І це код-гольф, тому найкоротший код виграє.

Перший рядок - це кількість записів (не більше ніж 100,000, ваш вхід може не містити цей рядок, якщо вам подобається, оскільки це лише спрощене визначення місця закінчення введення ). Наступний текст містить один запис у рядку. І кожен запис включає три числа:

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

Модифікація 2: Добре використовувати масив трійки як вхід.

Модифікація 3: Ви можете змінити порядок чисел в одному записі. І ви можете вибрати, який використовувати. (див. розділ Зауваження)

Гарантоване введення є дійсним, якщо:

  • Car plate number- ціле число в діапазоні 10000~99999
  • Time- ціле число в діапазоні 0~86400

І

  • Записи необов'язково впорядковані хронологічно.
  • До першої секунди автомобіля немає.
  • Там немає не обов'язково ні один автомобіля після останньої секунди.
  • Автомобіль не виїжджав, перш ніж сісти.
  • Car plate numberє унікальним. (але той самий автомобіль може відвідувати не один раз)
  • Тож неможливо, щоб автомобіль зайшов до партії, коли вона вже знаходиться в ній.
  • Один і той же автомобіль не входив і виходив одночасно time.
  • Вважається, що автомобіль знаходиться на партії під час входу / виходу.

Приклад 1

Вхідні дані

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

Вихідні дані

3

Пояснення

У 16500машині 12345і 75487були на стоянці.

Приклад 2

Я зробив це, тому що виявив, що на ньому багато кодів не вдалося.

Введення (перший рядок залишився)

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

Вихідні дані

2

Пояснення

У 16500машині 12345і 75487були на стоянці.

Зауваження

Насправді, не всі три потрібні для виходу. Принаймні, для отримання результату вам потрібна лише табличка + час або час / вихід + час. Але алгоритм дещо відрізняється за двох обставин, тому вибір скорочення залишається невідомим певної мови. І звичайно, ви можете використовувати всі три числа. Тому я залишаю їх у виклику.


Чи завжди номери автомобільних табличок - 5 цифр?
Тит

1
@Titus Я вважаю, що цифри від 10000 до 99999 завжди мають 5 цифр.
Кейу Ган

3
Гей, я сьогодні сліпий
Тит

Я припускаю, що автомобіль не може в'їхати знову, перш ніж виїхати з першого разу? Це, мабуть, не зазначено прямо.
Джон Дворак

@JanDvorak ах вибачте. Ні, не може. Мається на увазі номер автомобільної таблички унікальний, тому що насправді неможливо зайти в одну партію, коли вона вже знаходиться в ній.
Кейу Ган

Відповіді:


7

Математика, 33 байти

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

Мені довелося краще прочитати постановку проблеми, щоб зрозуміти, що існує набагато простіший алгоритм, який не вимагає інформації номерних знаків.

Безіменна функція, що повертає ціле число; формат введення - це список упорядкованих трійки у формі {time, 0|1, license plate}. Почнемо з Sorting, який робить список хронологічним, а також розбиває часові зв'язки, сортуючи 0s до 1s; потім 2#2-1&@@@зберігає інформацію про прибуття / від'їзд і забуває про відпочинок, а також перетворює 0s в -1s.

Accumulateобчислює поточні підсумки цього списку; результат - перелік негативів кількості машин на парковці після кожного приїзду / виїзду. Потім Minвибирається найменший (найнегативніший) з них і негативний знак знімається.

Математика, 56 байт

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

Оригінальне подання (перші кілька коментарів стосуються цього подання). Безіменна функція, що повертає ціле число; формат введення - це список упорядкованих трійки у формі {time, 0|1, license plate}.

Причина, по якій ми вирішуємо поставити час першим, а вхід / вихід другий, полягає в тому, що Sort@#сортує список хронологічно та записує прибуття перед вилетами, якщо вони одночасні. Після цього #3->#2&@@@повертає список "правил" форми license plate -> 0|1, все ще відсортованих хронологічно.

Потім FoldList[List,{},...]створює список усіх початкових сегментів цього списку правил. Насправді він справді псує ці початкові сегменти; то kй початкові кінці сегментів до того , щоб бути список з одним правилом на глибині 2, одне правило , на глибині 3, ..., і одне правило , на глибині k+1. ( FoldList[Append,{},...]дав би більш природний результат.) Однак <|#|>кожен з цих початкових сегментів перетворюється на "асоціацію", яка має два бажані ефекти: по-перше, вона повністю розгладжує структуру вкладеного списку, яку ми тільки що створили; по-друге, він змушує пізніші правила відміняти більш ранні правила, саме це нам і потрібно - для будь-якого автомобіля, який вийшов із стоянки, запис про його початковий запис повністю зникла (як і для автомобілів, які знову в’їжджають) .

Отже, все, що залишилося зробити - це Countскільки 0с є в кожній з цих асоціацій, і взяти Max.


1
Чи завжди це зробить правильно, якщо машини приїдуть і їдуть одночасно?
Крістіан Сіверс

Ваша відповідь може бути неправильною. Максимум не обов'язково трапляється, коли автомобіль увійшов ще раз, тому видалити записи за допомогою асоціації небезпечно. Дивіться цю картинку: i.imgur.com/D5xUl3z.png Очевидно, що на 16500 є 3 машини.
Keyu Gan

@KeyuGan: Я не стверджував, що максимум трапляється при повторному в'їзді машини. Зауважте, що моє рішення підраховує кількість автомобілів на стоянці під час кожного в'їзду / виїзду і приймає максимум таких.
Грег Мартін

1
Можливо, ви можете спробувати приклад 2.
Кейу Ган

1
Особисто я з вами згоден. :) Що я зробив, це скопіювати визначення з початкової проблеми. Основна відмінність полягає в тому, що оригінал вимагає розпізнавання автомобільних табличок із зображень та надрукування як кінцевого результату.
Кейу Ган

5

Haskell, 76 63 61 байт

2 байти, збережені варіантом пропозиції @ nimi.

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

Очікує аргумент як перелік трійки в порядку, заданому викладом проблеми.

Кожен можливий час (та ще багато інших) ми шукаємо спочатку прибуття, а потім виїзду з автомобільних подій та перетворюємо їх на список плюс-мінус. Ми беремо часткові суми цього списку, а потім максимум цих часткових сум.


Відкиньте importі використовуйте [(-1)^c|i<-[1..86400],(_,b,c)<-l,i==b].
німі

Мені потрібні вхідні машини перед вихідними, тому це трохи складніше, але я все-таки можу зберегти 2 байти зі своєю ідеєю. Спасибі!
Крістіан Сіверс

2

PHP 7.1, 126 117 байт

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;

приймає дані з файлу i, ігнорує перший рядок. Бігайте з -r.
Потрібна нова введення нового рядка. Замініть -2на -3для Windows.

зламатися

# 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

Вибачте, що ви можете використовувати масив трійки як вхід, якщо ви пишете функцію. Мої друзі, і я вважаю, що це хороший спосіб зробити мову, яка не займається гольфом, більш конкурентоспроможною, якщо ми говоримо про проблему без складного введення.
Кейу Ган

@KeyuGan: Дякую за підказку; але з масивом як вхідним запитом мені потрібна функція, і це коштуватиме два байти, як з масивом триплетів, так і з трійкою масивів. функції, картографування масивів та власні сортування є об'ємними в PHP. Єдиний спосіб, коли я міг би зберегти що-небудь, був би моїм підготовленим $dяк введення або відсортований вклад (за часом і в / в). І тест брав би надто багато від виклику. Вирівнювання вводу ttttt i plateдозволить заощадити 17 байт, ще 19 при рахунку, вирівняному за номером пластини.
Тит

2

C, 147 байт

Повна програма, що читає вхід з 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);}

Спробуйте це на ideone .


Я вважаю, що безпечно видаляти пробіли між ними%d
Keyu Gan

На жаль, спасибі Я не використовую scanfдостатньо, я думаю.
owacoder

Я люблю cin. LOL
Keyu Gan


2

Октава, 50 , 64 38 байт

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

Те саме, що відповідь @Greg Martin's Mathematica

Функція отримує масив з 3 стовпцями [time, i/o,plateN]

попередня відповідь:

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

Функція отримує лише два входи t: час і O: введення / виведення з перших двох елементів масиву комірок, Aщо містять потрійні входи!

Розрізна матриця, створена для підрахунку для кожної записаної за часом кількості існуючих автомобілів. Для цього час виїзду + 1 вважається для виходу з машини, а відповідна 1 зміна - -1 та 0 змінена на 1.
Використання розріджених тут дуже важливо, оскільки декілька автомобілів можуть приїхати або виїхати одночасно.
Потім знайдена кумулятивна сума, що представляє кількість поточних автомобілів у партії та макс.


Я пам’ятаю масив клітинок підтримки Octave, а це означає, що ви можете використовувати лише один масив з трійки як вхід. Обмеження згідно з виданням перед M5 і в ньому йдеться про "масив трійки". Я уточнив це в M5
Keyu Gan

@KeyuGan Я думаю, що ваше нове винайдене обмеження непотрібне, збільшивши 14 байт мого коду. тож Ви новачок на цьому веб-сайті, краще мати питання з мінімальною кількістю обмежень, щоб залучити більше учасників.
rahnema1

2

JavaScript (ES6), 63 73 71 байт

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

Це приймає введення як масив упорядкованих записів [time, inout, plate]. На жаль, через те, що однаковий час прийому означає, що обидва автомобілі враховуються в партії в даний момент, алгоритм сортування повинен замовляти 0раніше 1, що коштувало 11 байт.

Кредити

  • Я врятував 1 байт, повністю перемістивши зсув та множення всередині функції карти (дякую Ніл).
  • Я врятував ще два байти, використовуючи деструктурований аргумент у функції сортування (спасибі edc65).

Демо

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


Здається, ваш код не працює добре, d=[[16400,75487,0],[16500,75487,1],[16500,99999,0],[16600,99999,1]];я вважав, що він повинен надрукувати 2?
Кейу Ган

Ну а в тестовому випадку з 4 входами є лише 2 машини. Я відформатував його, щоб відповідати вашому порядку введення.
Кейу Ган

@KeyuGan вибачте за непорозуміння, я не зрозумів, що ви маєте на увазі другий приклад. Це зараз виправлено.
Патрік Робертс

Я знаю, що ваш алгоритм не залежить від номера тарілки. Однак я пропоную його включити до визначення порядку введення, просто залиште його останньою;)
Кейу Ган

1
@ edc65 насправді всього 2 байти, а не 4. Це також 71 байт:d=>Math.max(...d.sort(([a,b],[c,d])=>a-b||c-d).map(e=>s+=1-e[1]*2,s=0))
Патрік Робертс

2

JavaScript (ES6), 8368 70 байт

EDIT: виправлено для підтримки 2-го прикладу

Приймає введення як масив [in_out, time, plate]масивів. Але plateстовпець насправді ігнорується.

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

Тест


Читаючи in_outколонку замість plateколонки повинні зберегти вам шість байт: v=>n+=1-v[2]*2.
Ніл

Для другого прикладу це неправильно, тому якщо ви знову відредагуєте це, вам потрібно буде це врахувати. (Оскільки остання редакція цього питання була перед додаванням другого прикладу, це технічно звільнено від її дотримання, і я зовсім не ревную!)
Патрік Робертс

@PatrickRoberts Спробую це виправити, коли я знову перед комп'ютером ^^
Арнольд

@Neil Хороший улов! Мені довелося переписати це так, щоб підтримати другий приклад, але я в кінцевому підсумку дотримувався вашої поради.
Арнольд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.