Superviseur de stationnement

13

introduction

Vous êtes superviseur d'un parking et votre manager se prépare à réduire à l'extrême la taille.

Il s'agit d'une version simplifiée et adaptée d'un problème du niveau supérieur PAT de l'an dernier .

Défi

On vous demande de calculer le nombre de voitures dans le lot en même temps, au maximum .

Des règles standard s'appliquent. Et c'est un code-golf donc le code le plus court gagne.

La première ligne est la quantité d'entrées (pas plus que 100,000, votre entrée peut ne pas contenir cette ligne si vous le souhaitez, car il ne s'agit que d'une fortune pour déterminer où se termine l'entrée ). Le texte suivant contient une entrée par ligne. Et chaque entrée comprend trois chiffres:

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

Modification 2: Il est correct d'utiliser un tableau de triplets en entrée.

Modification 3: Vous pouvez modifier l'ordre des numéros en une seule entrée. Et vous pouvez choisir lequel utiliser. (voir la section Remarques)

L'entrée est garantie pour être valide, en supposant que:

  • Car plate numberest un nombre entier compris entre 10000~99999
  • Timeest un nombre entier compris entre 0~86400

Et

  • Les inscriptions ne sont pas nécessairement classées par ordre chronologique.
  • Il n'y a pas de voiture avant la première seconde.
  • Il n'y a pas forcément de voiture après la dernière seconde.
  • Une voiture ne partirait pas avant d'entrer.
  • Car plate numberest unique. (mais une même voiture peut visiter plusieurs fois)
  • Il est donc impossible pour une voiture de pénétrer dans le lot lorsqu'elle est déjà dedans.
  • Une même voiture n'entrerait pas et ne sortirait pas en même temps time.
  • Une voiture est considérée comme faisant partie du lot au moment de l'entrée / sortie.

Exemple 1

Contribution

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

Production

3

Explication

À 16500, voiture 12345et 75487étaient dans le parking.

Exemple 2

J'ai fait cela parce que j'ai trouvé que beaucoup de code échouaient dessus.

Entrée (avec la première ligne omise)

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

Production

2

Explication

À 16500, voiture 12345et 75487étaient dans le parking.

Remarques

En fait, les trois ne sont pas tous requis pour la sortie. Au moins, vous avez seulement besoin de plaque + temps ou d'entrée / sortie + temps pour le résultat. Mais l'algorithme est légèrement différent dans deux circonstances, donc le choix d'être plus court reste inconnu dans une certaine langue. Et bien sûr, vous pouvez utiliser les trois nombres. Je les laisse donc dans le défi.

Keyu Gan
la source
Les numéros de plaque d'immatriculation comportent-ils toujours 5 chiffres?
Titus
1
@Titus Je crois que les nombres de 10000 à 99999 sont toujours composés de 5 chiffres.
Keyu Gan
3
Gee je suis aveugle aujourd'hui.
Titus
Je suppose qu'une voiture ne peut pas rentrer avant de partir la première fois? Cela ne semble pas être énoncé explicitement.
John Dvorak
@JanDvorak eh désolé. Non, ça ne peut pas. Il est sous-entendu que le numéro de plaque d'immatriculation de la voiture est unique car en réalité, il est impossible pour une même voiture d'entrer dans le lot lorsqu'elle est déjà dedans.
Keyu Gan

Réponses:

7

Mathematica, 33 octets

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

J'ai dû mieux lire l'énoncé du problème pour réaliser qu'il existe un algorithme beaucoup plus simple qui ne nécessite pas les informations de la plaque d'immatriculation.

Fonction sans nom renvoyant un entier; le format d'entrée est une liste de triplets ordonnés dans le formulaire {time, 0|1, license plate}. Nous commençons par Sorting, ce qui rend la liste chronologique et rompt également les liens temporels en triant 0s avant 1s; 2#2-1&@@@conserve ensuite les informations d'arrivée / de départ et oublie le reste, et convertit également 0s en -1s.

Accumulatecalcule les totaux cumulés de cette liste; le résultat est une liste des points négatifs du nombre de voitures dans le parking après chaque arrivée / départ. MinChoisit ensuite le plus petit (le plus négatif) de ceux-ci et le signe négatif est supprimé.

Mathematica, 56 octets

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

La communication d'origine (les premiers commentaires font référence à cette communication). Fonction sans nom renvoyant un entier; le format d'entrée est une liste de triplets ordonnés dans le formulaire {time, 0|1, license plate}.

La raison pour laquelle nous choisissons de mettre la première entrée de temps et la deuxième entrée / sortie est de sorte que Sort@#trie la liste chronologiquement et enregistre les arrivées avant les départs si elles sont simultanées. Après cela, #3->#2&@@@retourne une liste de "règles" du formulaire license plate -> 0|1, toujours triées chronologiquement.

Ensuite, FoldList[List,{},...]crée une liste de tous les segments initiaux de cette liste de règles. En fait, cela gâche vraiment ces segments initiaux; le ke segment initial finit par être une liste avec une règle à la profondeur 2, une règle à la profondeur 3, ..., et une règle à la profondeur k+1. ( FoldList[Append,{},...]donnerait le résultat le plus naturel.) Cependant,<|#|> transforme chacun de ces segments initiaux en une "association", qui a deux effets souhaitables: premièrement, il aplatit complètement la structure de liste imbriquée que nous venons de créer; et deuxièmement, il oblige les règles ultérieures à remplacer les règles antérieures, ce qui est exactement ce dont nous avons besoin ici - pour toute voiture qui a quitté le parking, le dossier de son entrée initiale a maintenant complètement disparu (et de même pour les voitures qui rentrent) .

Il ne reste donc plus qu'à Countsavoir combien 0il y a de s dans chacune de ces associations, et à prendre le Max.

Greg Martin
la source
1
Est-ce que cela fera toujours la bonne chose si les voitures vont et viennent en même temps?
Christian Sievers
Votre réponse est peut-être fausse. Le maximum ne se produit pas nécessairement lorsqu'une voiture entre à nouveau, il est donc dangereux d'effacer les entrées en utilisant l'association. Voir cette photo: i.imgur.com/D5xUl3z.png Évidemment, il y a 3 voitures à 16500.
Keyu Gan
@KeyuGan: Je n'ai pas prétendu que le maximum se produit quand une voiture rentre. Notez que ma solution compte le nombre de voitures dans le parking au moment de chaque entrée / départ et en prend le maximum.
Greg Martin
1
Vous pourriez peut-être essayer l'exemple 2.
Keyu Gan
1
Personnellement, je suis d'accord avec vous. :) Ce que j'ai fait est de copier la définition du problème d'origine. La principale différence est que l'original nécessite que les plaques de voiture soient reconnues à partir des images et imprimées comme résultat final.
Keyu Gan
5

Haskell, 76 63 61 octets

2 octets enregistrés par une variation de la suggestion de @ nimi.

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

Attend l'argument comme une liste de triplets dans l'ordre donné par l'énoncé du problème.

Pour chaque fois possible (et quelques autres), nous cherchons d'abord à venir puis à quitter les événements de voiture et les transformons en une liste de plus ou de moins. Nous prenons les sommes partielles de cette liste puis le maximum de ces sommes partielles.

Christian Sievers
la source
Déposez le importet utilisez [(-1)^c|i<-[1..86400],(_,b,c)<-l,i==b].
nimi
J'ai besoin des voitures entrantes avant celles sortantes, c'est donc un peu plus compliqué, mais je pourrais encore économiser 2 octets avec votre idée. Merci!
Christian Sievers
2

PHP 7.1, 126 octets

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;

prend l'entrée du fichier i, ignore la première ligne. Courez avec -r.
Nécessite une nouvelle ligne de fin en entrée. Remplacer-2 par -3pour Windows.

panne

# 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
la source
Désolé, vous pouvez utiliser un tableau de triplets en entrée si vous écrivez une fonction. Mes amis et moi pensons que c'est un bon moyen de rendre le langage non golfique plus compétitif si nous parlons d'un problème sans contribution compliquée.
Keyu Gan
@KeyuGan: Merci pour l'astuce; mais avec un tableau en entrée, j'aurais besoin d'une fonction, et cela coûterait deux octets, à la fois avec un tableau de triplets et avec un triplet de tableaux. les fonctions, le mappage de tableaux et le tri personnalisé sont volumineux en PHP. La seule façon dont je pourrais enregistrer quoi que ce soit serait ma préparation $den entrée ou en entrée triée (par heure et entrée / sortie). Et cela prendrait trop du défi. Une entrée ttttt i platealignée économiserait 17 octets, 19 de plus avec le nombre aligné avec le numéro de plaque.
Titus
2

C, 147 octets

Un programme complet, lit les entrées 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);}

Essayez-le sur ideone .

owacoder
la source
Je crois qu'il est sûr de supprimer les espaces entre%d
Keyu Gan
Oups, merci. Je n'en utilise pas scanfassez, je suppose.
owacoder
J'adore cin. LOL
Keyu Gan
118 octets
plafondcat
2

Octave, 50 , 64 38 octets

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

Identique à la réponse Mathematica de @Greg Martin

La fonction obtient un tableau à 3 colonnes [time, i/o,plateN]

réponse précédente:

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

La fonction ne reçoit que deux entrées t: temps etO : I / O des deux premiers éléments d'un tableau de cellules Aqui contient des entrées triples!

Une matrice clairsemée créée pour compter pour chaque nombre de fois enregistré de voitures existantes. Pour cela, le temps de sortie + 1 est pris en compte pour la sortie de la voiture et le changement correspondant de 1 à -1 et 0 changé à 1. L'
utilisation de rares ici est très importante car plusieurs voitures peuvent arriver ou partir en même temps.
Ensuite, la somme cumulée calculée représentant le nombre de voitures actuelles dans le lot et le maximum de celui-ci est trouvée.

rahnema1
la source
Je me souviens du tableau de cellules de support Octave, ce qui signifie que vous ne pouvez utiliser qu'un seul tableau de triplets en entrée. La restriction est conforme à l'édition antérieure à M5 et indique «un tableau de triplets». Je l'ai clarifié dans M5
Keyu Gan
@KeyuGan Je pense que votre nouvelle restriction inventée n'est pas nécessaire a augmenté de 14 octets de mon code. Donc, vous êtes nouveau sur ce site, il est préférable d'avoir des questions avec un nombre minimal de restrictions pour attirer plus de contributeurs.
rahnema1
2

JavaScript (ES6), 63 73 71 octets

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

Cela accepte l'entrée comme un tableau d'entrées ordonnées [time, inout, plate]. Malheureusement, en raison du fait que des temps d'entrée identiques signifient que les deux voitures sont prises en compte dans le lot à l'heure actuelle, l'algorithme de tri doit commander 0avant 1, ce qui a coûté 11 octets.

Crédits

  • J'ai économisé 1 octet en déplaçant complètement le décalage et la multiplication dans la fonction de carte (merci Neil).
  • J'ai enregistré deux autres octets en utilisant un argument destructuré dans la fonction de tri (merci edc65).

Démo

// 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
la source
Il semble que votre code ne fonctionne pas bien, d=[[16400,75487,0],[16500,75487,1],[16500,99999,0],[16600,99999,1]];je suppose qu'il devrait afficher 2?
Keyu Gan
Eh bien, dans le cas de test à 4 entrées, il n'y a que 2 voitures. Je l'ai formaté pour répondre à votre commande d'entrée.
Keyu Gan
@KeyuGan désolé pour le malentendu, je ne savais pas que vous faisiez référence au deuxième exemple. C'est réparé maintenant.
Patrick Roberts
Je sais que votre algorithme ne dépend pas du numéro de plaque. Cependant, je suggère qu'il devrait être inclus dans la définition de l'ordre d'entrée, laissez-le au dernier;)
Keyu Gan
1
@ edc65 en fait, seulement 2 octets, pas 4. C'est aussi 71 octets: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 octets

EDIT: corrigé pour supporter le 2ème exemple

Prend l'entrée comme un tableau de [in_out, time, plate]tableaux. Mais la platecolonne est en fait ignorée.

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

Tester

Arnauld
la source
Reading the in_out column instead of the plate column should save you six bytes: v=>n+=1-v[2]*2.
Neil
This is incorrect for the second example, so if you edit this again, you'll need to take that into account. (Since the last edit on this was before the second example was added, it's technically exempt from complying to it, and I'm not at all jealous!)
Patrick Roberts
@PatrickRoberts Will try to fix that when I'm back in front of a computer ^^
Arnauld
@Neil Good catch! I had to rewrite it anyway to support the 2nd example, but I ended up following your advice.
Arnauld