Руководитель парковки

13

Вступление

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

Это упрощенная и адаптированная версия проблемы на прошлогоднем ПАТ верхнего уровня.

Вызов

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

Стандартные правила применяются. И это код-гольф, поэтому выигрывает самый короткий код.

Первая строка - количество записей (не более того 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

Mathematica, 33 байта

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

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

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

Accumulateвычисляет промежуточные итоги этого списка; Результатом является список отрицательных чисел автомобилей на стоянке после каждого прибытия / отъезда. Затем Minвыбирает самый маленький (самый отрицательный) из них и отрицательный знак удаляется.

Mathematica, 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сколько 0s есть в каждой из этих ассоциаций, и взять Max.

Грег Мартин
источник
1
Будет ли это всегда делать правильно, если машины приходят и уходят одновременно?
Кристиан Сиверс
Ваш ответ может быть неправильным. Максимум не обязательно случается, когда автомобиль въехал еще раз, поэтому небезопасно удалять записи, используя ассоциацию. Смотрите это изображение: i.imgur.com/D5xUl3z.png Очевидно, что в 16500 есть 3 машины.
Кейу Ган,
@KeyuGan: я не утверждал, что максимум случается, когда автомобиль снова входит. Обратите внимание, что мое решение подсчитывает количество автомобилей на стоянке на момент каждого отдельного въезда / выезда и принимает максимальное из них.
Грег Мартин
1
Может быть, вы могли бы попробовать пример 2.
Keyu Gan
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
Titus
источник
К сожалению, вы можете использовать массив троек в качестве входных данных, если вы пишете функцию. Мои друзья и я полагаем, что это хороший способ сделать язык, не относящийся к игре в гольф, более конкурентоспособным, если мы говорим о проблеме без сложного ввода.
Кейу Ган
@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 .

owacoder
источник
Я считаю, что безопасно удалять пробелы между%d
Кейу Ган
Ой, спасибо. Я не использую scanfдостаточно, я думаю.
owacoder
Я люблю cin. LOL
Кейу Ган
118 байт
floorcat
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.
Использование разреженных здесь очень важно, так как несколько автомобилей могут прибыть или уехать одновременно.
Затем вычисляется накопленная сумма, представляющая количество текущих автомобилей в лоте и максимальное из них.

rahnema1
источник
Я помню массив ячеек поддержки Octave, что означает, что вы можете использовать только один массив троек в качестве входных данных. Ограничение согласно изданию до M5, в котором говорится «массив троек». Я уточнил это в M5
Кейу Ган
@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 байт

РЕДАКТИРОВАТЬ: исправлено для поддержки второго примера

Принимает входные данные в виде массива [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

Тестовое задание

Arnauld
источник
Читая in_outколонку вместо plateколонки должны сохранить вам шесть байт: v=>n+=1-v[2]*2.
Нил
Это неверно для второго примера, поэтому, если вы отредактируете это снова, вам нужно будет это учесть. (Так как последнее редактирование этого было до того, как был добавлен второй пример, он технически освобожден от его соответствия, и я совсем не ревнив!)
Патрик Робертс
@PatrickRoberts постарается это исправить, когда я снова окажусь перед компьютером ^^
Арно
@Neil Хороший улов! В любом случае мне пришлось переписать его, чтобы поддержать второй пример, но в итоге я последовал вашему совету.
Арно