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.


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.


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.


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

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

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.


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


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), 83 … 68 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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.