Supervisore del parcheggio


13

introduzione

Sei un supervisore di un parcheggio e il tuo manager si sta preparando a ridurre le dimensioni all'estremo.

È una versione semplificata e adattata di un problema dell'anno scorso massimi livelli PAT .

Sfida

Ti viene chiesto di calcolare quante macchine sono nel lotto allo stesso tempo, al massimo .

Si applicano le regole standard. E questo è un codice-golf quindi vince il codice più breve.

La prima riga è la quantità di voci (non più 100,000, il tuo input potrebbe non contenere questa riga se vuoi, perché è solo un caso per determinare dove finisce l'input ). Il testo seguente contiene una voce per riga. E ogni voce include tre numeri:

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

Modifica 2: È OK utilizzare una matrice di triple come input.

Modifica 3: è possibile modificare l'ordine dei numeri in una voce. E puoi scegliere quale usare. (vedi la sezione Osservazioni)

L'input è garantito per essere valido, supponendo che:

  • Car plate numberè un numero intero nell'intervallo di 10000~99999
  • Timeè un numero intero nell'intervallo di 0~86400

E

  • Le voci non sono necessariamente ordinate cronologicamente.
  • Non c'è macchina prima del primo secondo.
  • Non c'è necessariamente nessuna macchina dopo l'ultimo secondo.
  • Un'auto non sarebbe partita prima di entrare.
  • Car plate numberè unico. (ma una stessa auto può visitare più di una volta)
  • Quindi è impossibile per un'auto entrare nel lotto quando è già dentro.
  • Una stessa macchina non entrerebbe e uscirà allo stesso modo time.
  • Un'auto è considerata nel lotto al momento dell'ingresso / uscita.

Esempio 1

Ingresso

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

Produzione

3

Spiegazione

A 16500, macchina 12345ed 75487eravamo nel parcheggio.

Esempio 2

L'ho fatto perché ho trovato molti codici falliti su di esso.

Input (con la prima riga esclusa)

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

Produzione

2

Spiegazione

A 16500, macchina 12345ed 75487eravamo nel parcheggio.

Osservazioni

In realtà, non tutti e tre sono richiesti per l'output. Almeno, hai solo bisogno di plate + time o in / out + time per il risultato. Ma l'algoritmo è leggermente diverso in due circostanze, quindi la scelta di essere più breve rimane sconosciuta in una determinata lingua. E ovviamente puoi usare tutti e tre i numeri. Quindi li lascio nella sfida.


I numeri di targa dell'auto sono sempre lunghi 5 cifre?
Tito

1
@Titus Credo che i numeri da 10000 a 99999 siano sempre lunghi 5 cifre.
Keyu Gan,

3
Accidenti, sono cieco oggi.
Tito

Presumo che un'auto non possa entrare di nuovo prima di partire per la prima volta? Non sembra essere esplicitamente dichiarato.
John Dvorak,

@JanDvorak eh sorry. No non può. È implicito che il numero di targa dell'auto è unico perché in realtà è impossibile per una stessa auto entrare nel lotto quando è già presente.
Keyu Gan,

Risposte:


7

Mathematica, 33 byte

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

Ho dovuto leggere meglio la dichiarazione del problema per rendermi conto che esiste un algoritmo molto più semplice che non richiede le informazioni sulla targa.

Funzione senza nome che restituisce un numero intero; il formato di input è un elenco di triple ordinate nel modulo {time, 0|1, license plate}. Iniziamo con Sorting, il che rende cronologico l'elenco e rompe anche i vincoli di tempo ordinando 0s prima di 1s; quindi 2#2-1&@@@conserva le informazioni di arrivo / partenza e dimentica il resto e converte anche 0s in -1s.

Accumulatecalcola i totali correnti di tale elenco; il risultato è un elenco dei negativi del numero di auto nel parcheggio dopo ogni arrivo / partenza. Quindi Minseleziona il più piccolo (il più negativo) di questi e il segno negativo viene rimosso.

Mathematica, 56 byte

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

La presentazione originale (i primi parecchi commenti si riferiscono a questa presentazione). Funzione senza nome che restituisce un numero intero; il formato di input è un elenco di triple ordinate nel modulo{time, 0|1, license plate} .

Il motivo per cui scegliamo di inserire prima l'orario e il secondo ingresso / uscita è quello che Sort@#ordina cronologicamente l'elenco e registra gli arrivi prima delle partenze se sono simultanei. Successivamente, #3->#2&@@@restituisce un elenco di "regole" del modulo license plate -> 0|1, ancora ordinate cronologicamente.

Quindi, FoldList[List,{},...]crea un elenco di tutti i segmenti iniziali di tale elenco di regole. In realtà, incasina davvero quei segmenti iniziali; il ksegmento iniziale finisce per essere un elenco con una regola alla profondità 2, una regola alla profondità 3, ... e una regola alla profondità k+1. ( FoldList[Append,{},...]produrrebbe il risultato più naturale.) Tuttavia,<|#|> trasforma ciascuno di questi segmenti iniziali in una "associazione", che ha due effetti desiderabili: in primo luogo, appiattisce completamente la struttura dell'elenco nidificato che abbiamo appena creato; e in secondo luogo, obbliga le regole successive a sovrascrivere le regole precedenti, che è esattamente ciò di cui abbiamo bisogno qui - per qualsiasi auto che ha lasciato il parcheggio, il record della sua entrata iniziale è ora completamente sparito (e allo stesso modo per le auto che rientrano) .

Quindi tutto ciò che resta da fare è Countquanti 0s ci sono in ciascuna di queste associazioni, e prendere il Max.


1
Questo farà sempre la cosa giusta se le auto vanno e vengono allo stesso tempo?
Christian Sievers,

La tua risposta potrebbe essere sbagliata. Il massimo non si verifica necessariamente quando un'auto è entrata di nuovo, quindi non è sicuro cancellare le voci usando l'associazione. Vedi questa immagine: i.imgur.com/D5xUl3z.png Ovviamente ci sono 3 macchine al 16500.
Keyu Gan

@KeyuGan: non ho sostenuto che il massimo si verifichi quando rientra un'auto. Nota che la mia soluzione conta il numero di auto nel parcheggio al momento di ogni singola entrata / partenza e prende il massimo di quelle.
Greg Martin,

1
Forse potresti provare l'esempio 2.
Keyu Gan,

1
Personalmente sono d'accordo con te. :) Quello che ho fatto è copiare la definizione dal problema originale. La differenza principale è che quella originale richiede il riconoscimento delle targhe automobilistiche dalle immagini e la stampa come risultato finale.
Keyu Gan,

5

Haskell, 76 63 61 byte

2 byte salvati da una variazione del suggerimento di @nimi.

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

Si aspetta l'argomento come un elenco di triple nell'ordine indicato dalla dichiarazione del problema.

Per ogni possibile momento (e altro ancora), cerchiamo prima gli eventi in arrivo e poi quelli in uscita dall'auto e li trasformiamo in un elenco di più o meno. Prendiamo le somme parziali di questo elenco e quindi il massimo di queste somme parziali.


Rilascia importe usa [(-1)^c|i<-[1..86400],(_,b,c)<-l,i==b].
nimi,

Ho bisogno delle macchine in arrivo prima di quelle in uscita, quindi è un po 'più complicato, ma potrei comunque salvare 2 byte con la tua idea. Grazie!
Christian Sievers,

2

PHP 7.1, 126 117 byte

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;

accetta input dal file i, ignora la prima riga. Corri con -r.
Richiede una nuova riga finale in input. Sostituisci -2con -3per Windows.

abbattersi

# 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

Mi dispiace che tu possa usare una serie di triple come input se stai scrivendo una funzione. I miei amici e credo che sia un buon modo per rendere il linguaggio non golf più competitivo se stiamo parlando di un problema senza input complicati.
Keyu Gan,

@KeyuGan: grazie per il suggerimento; ma con una matrice come input, avrei bisogno di una funzione, che costerebbe due byte, sia con una matrice di terzine che con una terzina di matrici. funzioni, mappatura di array e ordinamento personalizzato sono ingombranti in PHP. L'unico modo per salvare qualsiasi cosa sarebbe il mio preparato $dcome input o input ordinato (per tempo e in / out). E questo richiederebbe troppo dalla sfida. L'ingresso allineato ttttt i platerisparmierebbe 17 byte, altri 19 con il conteggio allineato al numero di targa.
Tito


2

Ottava, 50 , 64 38 byte

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

Come la risposta Mathematica di @Greg Martin

La funzione ottiene un array con 3 colonne [time, i/o,plateN]

risposta precedente:

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

La funzione ottiene solo due input t: time e O: I / O dai primi due elementi di un array di celle Ache contiene input triple!

Una matrice sparsa creata per contare per ogni numero di tempo registrato delle auto esistenti. Per questo il tempo di out + 1 è considerato per l'uscita dell'auto e il corrispondente 1 cambia in -1 e 0 è cambiato in 1. L'
uso di rado qui è molto importante poiché più auto possono arrivare o partire contemporaneamente.
Quindi viene calcolata la somma cumulativa che rappresenta il numero di auto correnti nel lotto e ne viene trovata la quantità massima.


Ricordo la matrice di celle di supporto di Octave, il che significa che è possibile utilizzare solo una matrice di triple come input. La restrizione è secondo l'edizione precedente a M5 e indica "una serie di triple". L'ho chiarito in M5
Keyu Gan il

@KeyuGan Penso che la tua nuova restrizione inventata non sia necessaria aumentando di 14 byte il mio codice. quindi sei nuovo su questo sito, è meglio avere domande con un numero minimo di restrizioni per attirare più partecipanti.
rahnema1,

2

JavaScript (ES6), 63 73 71 byte

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

Questo accetta l'input come una matrice di voci ordinate [time, inout, plate] . Sfortunatamente a causa del fatto che tempi di inout identici significano che entrambe le auto sono considerate nel lotto al momento, l'algoritmo di ordinamento deve ordinare 0prima 1, che costa 11 byte.

Titoli di coda

  • Ho salvato 1 byte spostando completamente lo spostamento e la moltiplicazione all'interno della funzione della mappa (grazie Neil).
  • Ho salvato altri due byte usando un argomento destrutturato nella funzione di ordinamento (grazie a edc65).

dimostrazione

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


Sembra che il tuo codice non funzioni bene su d=[[16400,75487,0],[16500,75487,1],[16500,99999,0],[16600,99999,1]];suppongo che dovrebbe stampare 2?
Keyu Gan,

Bene, nel caso di test a 4 voci, ci sono solo 2 auto. L'ho formattato per soddisfare il tuo ordine di input.
Keyu Gan,

@KeyuGan mi dispiace per l'incomprensione, non mi ero reso conto che ti stavi riferendo al secondo esempio. Ora è riparato.
Patrick Roberts,

So che il tuo algoritmo non dipende dal numero di targa. Comunque suggerisco che dovrebbe essere incluso nella definizione dell'ordine di input, basta lasciarlo all'ultimo;)
Keyu Gan

1
@ edc65 in realtà, solo 2 byte, non 4. Anche 71 byte: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 byte

EDIT: risolto per supportare il secondo esempio

Accetta l'input come una matrice di [in_out, time, plate]array. Ma la platecolonna è in realtà ignorata.

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

Test


Leggendo la in_outcolonna anziché il platecolonna dovrebbe risparmiare sei byte: v=>n+=1-v[2]*2.
Neil

Questo non è corretto per il secondo esempio, quindi se lo modifichi di nuovo, dovrai tenerne conto. (Dal momento che l'ultima modifica su questo era precedente
Patrick Roberts,

@PatrickRoberts proverà a risolverlo quando torno davanti a un computer ^^
Arnauld

@Neil Buona cattura! Ho dovuto riscriverlo comunque per supportare il secondo esempio, ma ho finito per seguire il tuo consiglio.
Arnauld,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.