Supervisor de estacionamento

13

Introdução

Você é supervisor de um estacionamento e seu gerente está se preparando para reduzir o tamanho ao extremo.

É uma versão simplificada e adaptada de um problema no nível superior do PAT do ano passado .

Desafio

Você é solicitado a calcular quantos carros existem no lote ao mesmo tempo, no máximo .

Aplicam-se regras padrão. E este é um código-golfe, para que o código mais curto ganhe.

A primeira linha é a quantidade de entradas (não mais do que 100,000, sua entrada pode não conter essa linha, se você preferir, pois é apenas improvisado determinar onde a entrada termina ). O texto a seguir contém uma entrada por linha. E cada entrada inclui três números:

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

Modificação 2: Não há problema em usar uma matriz de triplos como entrada.

Modificação 3: você pode alterar a ordem dos números em uma entrada. E você pode escolher qual usar. (consulte a seção Observações)

A entrada é garantida como válida, assumindo que:

  • Car plate numberé um número inteiro no intervalo de 10000~99999
  • Timeé um número inteiro no intervalo de 0~86400

E

  • As inscrições não são necessariamente ordenadas cronologicamente.
  • Não há carro antes do primeiro segundo.
  • Não há necessariamente carro após o último segundo.
  • Um carro não sairia antes de entrar.
  • Car plate numberé único. (mas um mesmo carro pode visitar mais de uma vez)
  • Portanto, é impossível um carro entrar no estacionamento quando já está nele.
  • Um mesmo carro não entra e sai ao mesmo tempo time.
  • Um carro é considerado no estacionamento no momento da entrada / saída.

Exemplo 1

Entrada

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

Resultado

3

Explicação

No 16500carro, 12345e 75487estávamos no estacionamento.

Exemplo 2

Eu fiz isso porque achei que muitos códigos falharam nele.

Entrada (com a primeira linha deixada de fora)

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

Resultado

2

Explicação

No 16500carro, 12345e 75487estávamos no estacionamento.

Observações

Na verdade, nem todos os três são necessários para a saída. Pelo menos, você só precisa de placa + hora ou entrada / saída + hora para o resultado. Mas o algoritmo é ligeiramente diferente em duas circunstâncias, portanto a escolha de ser mais curta permanece desconhecida em um determinado idioma. E é claro que você pode usar todos os três números. Então eu os deixo no desafio.

Keyu Gan
fonte
Os números das placas dos carros sempre têm 5 dígitos?
Titus
1
@Titus Eu acredito que números de 10000 a 99999 sempre têm 5 dígitos.
Keyu Gan
3
Hoje estou cego.
Titus
Presumo que um carro não pode entrar novamente antes de sair da primeira vez? Não parece ser afirmado explicitamente.
John Dvorak
@JanDvorak eh sorry. Não, eu não posso. Está implícito que o número da placa do carro é único porque, na realidade, é impossível que um mesmo carro entre no lote quando já está nele.
Keyu Gan

Respostas:

7

Mathematica, 33 bytes

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

Eu tive que ler melhor a declaração do problema para perceber que existe um algoritmo muito mais simples que não requer as informações da placa.

Função sem nome retornando um número inteiro; o formato de entrada é uma lista de triplos ordenados no formulário {time, 0|1, license plate}. Começamos por Sorting, que torna a lista cronológica e também quebra os intervalos de tempo, classificando 0s antes de 1s; depois 2#2-1&@@@mantém as informações de chegada / partida e esquece o resto, além de converter 0s em -1s.

Accumulatecalcula os totais em execução dessa lista; o resultado é uma lista dos negativos do número de carros no estacionamento após cada chegada / partida. Em seguida, Minescolhe o menor (mais negativo) deles e o sinal negativo é removido.

Mathematica, 56 bytes

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

A submissão original (os primeiros vários comentários se referem a essa submissão). Função sem nome retornando um número inteiro; o formato de entrada é uma lista de triplos ordenados no formato{time, 0|1, license plate} .

O motivo pelo qual escolhemos colocar a entrada de tempo em primeiro lugar e a entrada / saída em segundo é para que Sort@#classifique a lista cronologicamente e registre as chegadas antes das partidas, se forem simultâneas. Depois disso, #3->#2&@@@retorna uma lista de "regras" do formuláriolicense plate -> 0|1 , ainda classificadas cronologicamente.

Em seguida, FoldList[List,{},...]cria uma lista de todos os segmentos iniciais dessa lista de regras. Na verdade, ele realmente atrapalha esses segmentos iniciais; o kth segmento inicial acaba sendo uma lista com uma regra na profundidade 2, uma regra na profundidade 3, ... e uma regra na profundidade k+1. ( FoldList[Append,{},...]produziria o resultado mais natural.) No entanto,<|#|> transforma cada um desses segmentos iniciais em uma "associação", que tem dois efeitos desejáveis: primeiro, aplana completamente a estrutura de lista aninhada que acabamos de criar; e segundo, força as regras posteriores a anular as regras anteriores, que é exatamente o que precisamos aqui - para qualquer carro que saiu do estacionamento, o registro de sua entrada inicial agora está completamente esgotado (e da mesma forma para carros que entram novamente) .

Então, tudo o que resta a fazer é Countquantos 0s existem em cada uma dessas associações e pegar o Max.

Greg Martin
fonte
1
Isso sempre fará a coisa certa se os carros entrarem e saírem ao mesmo tempo?
Christian Sievers
Sua resposta pode estar errada. O máximo não acontece necessariamente quando um carro entra mais uma vez; portanto, não é seguro apagar as entradas usando associação. Veja esta foto: i.imgur.com/D5xUl3z.png Obviamente, existem 3 carros em 16500.
Keyu Gan
@KeyuGan: Eu não afirmei que o máximo acontece quando um carro entra novamente. Observe que minha solução conta o número de carros no estacionamento no momento de cada entrada / partida e leva o máximo deles.
Greg Martin
1
Talvez você possa tentar o exemplo 2.
Keyu Gan
1
Pessoalmente, eu concordo com você. :) O que fiz foi copiar a definição do problema original. A principal diferença é que a original exige que as placas dos carros sejam reconhecidas a partir de imagens e impressas como resultado final.
precisa saber é o seguinte
5

Haskell, 76 63 61 bytes

2 bytes salvos por uma variação da sugestão de @ nimi.

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

Espera o argumento como uma lista de triplos na ordem dada pela declaração do problema.

Para cada tempo possível (e mais alguns), procuramos primeiro a vinda e depois a saída dos eventos do carro e os transformamos em uma lista dos mais ou menos. Tomamos as somas parciais desta lista e depois o máximo dessas somas parciais.

Peneiradores cristãos
fonte
Largue importe use [(-1)^c|i<-[1..86400],(_,b,c)<-l,i==b].
nimi
Preciso dos carros que chegam antes dos que saem, por isso é um pouco mais complicado, mas ainda pude salvar 2 bytes com a sua ideia. Obrigado!
Christian Sievers
2

PHP 7.1, 126 117 bytes

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;

recebe entrada do arquivo i, ignora a primeira linha. Corra com -r.
Requer uma nova linha à direita na entrada. Substitua -2por -3para Windows.

demolir

# 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
fonte
Desculpe, você pode usar uma matriz de triplos como entrada se estiver escrevendo uma função. Meus amigos e eu acreditamos que é uma boa maneira de tornar a linguagem não-golfe mais competitiva se estivermos falando de um problema sem informações complicadas.
Keyu Gan
@KeyuGan: Obrigado pela dica; mas com uma matriz como entrada, eu precisaria de uma função, e isso custaria dois bytes, ambos com uma matriz de trigêmeos e com um trigêmeo de matrizes. funções, mapeamento de array e classificação personalizada são volumosas no PHP. A única maneira de salvar qualquer coisa seria o meu preparado $dcomo entrada ou entrada classificada (por hora e entrada / saída). E isso exigiria muito do desafio. A entrada alinhada ttttt i plateeconomizaria 17 bytes, mais 19 com a contagem alinhada com o número da placa.
Titus
2

C, 147 bytes

Um programa completo, lê as entradas de 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);}

Experimente em ideone .

owacoder
fonte
Eu acredito que é seguro remover espaços entre%d
Keyu Gan
Opa, obrigado. Eu não uso o scanfsuficiente, eu acho.
owacoder
Eu amo cin. LOL
Keyu Gan
118 bytes
ceilingcat 11/10
2

Oitava, 50 , 64 38 bytes

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

Igual à resposta do Mathematica de @Greg Martin

A função obtém uma matriz com 3 colunas [time, i/o,plateN]

resposta anterior:

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

A função recebe apenas duas entradas t: time e O: I / O dos dois primeiros elementos de uma matriz de células Aque contém entradas triplas!

Uma matriz esparsa criada para contar para cada número de tempo registrado de carros existentes. Para isso, o tempo de saída + 1 é considerado para a saída do carro e 1 alteração correspondente a -1 e 0 alterado para 1. O
uso de escassos aqui é muito importante, pois vários carros podem chegar ou sair ao mesmo tempo.
A soma acumulada calculada representa o número de carros atuais no lote e o máximo é encontrado.

rahnema1
fonte
Lembro-me de Octave suportar matriz de células, o que significa que você só pode usar uma matriz de triplos como entrada. A restrição está de acordo com a edição anterior à M5 e afirma 'uma série de triplos'. Eu esclarei isso em M5
Keyu Gan
@KeyuGan Eu acho que a sua nova restrição inventada é desnecessária e aumentou 14 bytes do meu código. Portanto, como você é novo neste site, é melhor ter perguntas com um número mínimo de restrições para atrair mais colaboradores.
precisa saber é o seguinte
2

JavaScript (ES6), 63 73 71 bytes

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

Isso aceita entrada como uma matriz de entradas solicitadas [time, inout, plate]. Infelizmente, devido ao fato de que tempos de inout idênticos significam que os dois carros são considerados no lote no momento, o algoritmo de classificação deve solicitar 0antes 1, o que custou 11 bytes.

Créditos

  • Salvei 1 byte movendo completamente a mudança e a multiplicação dentro da função de mapa (obrigado Neil).
  • Salvei mais dois bytes usando um argumento desestruturado na função de classificação (obrigado 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
fonte
Parece que seu código não funciona bem, d=[[16400,75487,0],[16500,75487,1],[16500,99999,0],[16600,99999,1]];eu deveria imprimir 2?
Keyu Gan
Bem, no caso de teste de 4 entradas, existem apenas 2 carros. Eu o formatei para atender à sua ordem de entrada.
Keyu Gan
@KeyuGan, desculpe-me pelo mal-entendido, não sabia que você estava se referindo ao segundo exemplo. Está consertado agora.
Patrick Roberts
Eu sei que seu algoritmo não depende do número da placa. No entanto, sugiro que devem ser incluídos na definição de ordem de entrada, apenas deixá-lo até o último;)
Keyu Gan
1
@ edc65 na verdade, apenas 2 bytes, não 4. Isso também é 71 bytes: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 bytes

EDIT: corrigido para suportar o segundo exemplo

Recebe a entrada como uma matriz de [in_out, time, plate]matrizes. Mas a platecoluna é realmente ignorada.

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

Teste

Arnauld
fonte
Lendo a in_outcoluna em vez da platecoluna deve poupar seis bytes: v=>n+=1-v[2]*2.
Neil
Isso está incorreto para o segundo exemplo; portanto, se você editar novamente, precisará levar isso em conta. (Desde a última edição desta era antes do segundo exemplo foi adicionado, é tecnicamente isentar do cumprimento a ele, e eu não estou de todo ciumento!)
Patrick Roberts
@PatrickRoberts vai tentar corrigir isso quando eu estou de volta na frente de um computador ^^
Arnauld
@ Neil Boa captura! Tive que reescrevê-lo de qualquer maneira para dar suporte ao segundo exemplo, mas acabei seguindo seus conselhos.
Arnauld