停车场主管


13

介绍

您是停车场的主管,而您的经理正在为缩小规模做准备。

它是去年PAT最高级别中问题的简化版本。

挑战

你被要求计算有多少车是在很多的同时,在最

适用标准规则。这是一个代码高尔夫球,因此最短的代码获胜。

第一行是条目的数量(不超过100,000如果您愿意,您的输入可能不包含此行,因为这只是确定输入在何处结束的临时命令)。以下文本每行包含一个条目。每个条目包括三个数字:

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

修改2:可以使用三元组数组作为输入。

修改3:您可以在一个条目中更改数字的顺序。您可以选择使用哪个。(请参阅“备注”部分)

假定以下条件,则输入是有效的:

  • Car plate number10000〜范围内的整数99999
  • Time0〜范围内的整数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,车1234575487人在停车场。

例子2

我这样做是因为我发现很多代码都失败了。

输入(省略第一行)

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

输出量

2

说明

16500,车1234575487人在停车场。

备注

实际上,并非所有三个输出都需要。至少,您只需要plate + time或in / out + time作为结果。但是在两种情况下,该算法略有不同,因此较短的选择在某种语言中仍然是未知的。当然,您可以使用所有三个数字。所以我让他们处于挑战之中。


车牌号是否总是5位长?
泰特斯

1
@Titus我相信从10000到99999的数字总是5位数字。
Keyu Gan

3
哎呀,我今天瞎了。
泰特斯(Titus)

我认为汽车在第一次离开前不能再次进入吗?似乎没有明确说明。
John Dvorak

@JanDvorak嗯,抱歉。不,它不能。车牌号暗示的是唯一的,因为实际上同一辆车不可能已经进入同一批车。
Keyu Gan

Answers:


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一个规则,...,和在深度一个规则的列表k1。(FoldList[Append,{},...]将产生更自然的结果。)但是,<|#|>将这些初始片段中的每一个都变成一个“关联”,这具有两个理想的效果:首先,它完全使我们刚刚创建的嵌套列表结构变平;其次,它迫使以后的规则优先于以前的规则,这正是我们在这里所需要的-对于任何离开停车场的汽车,其初始进入的记录现在已经完全消失了(对于重新进入的汽车也是如此) 。

因此,剩下要做的就是每个关联中有Count多少个0,然后取Max


1
如果汽车同时出入,这是否总是做正确的事情?
Christian Sievers

您的答案可能是错误的。最大值不一定会在汽车再次进入时发生,因此使用关联擦除条目是不安全的。看到这样的画面:i.imgur.com/D5xUl3z.png显然,在16500有3辆汽车
科宇甘

@KeyuGan:我没有说最大的事故发生在汽车重新进入时。请注意,我的解决方案计算每次进入/离开时停车场中的汽车数量,并取其中的最大值。
格雷格·马丁

1
也许你可以试试例2
柯宇甘

1
我个人同意你的看法。:)我所做的是从原始问题中复制定义。主要区别在于,原始图像需要从图像中识别出车牌并作为最终结果进行打印。
Keyu Gan

5

Haskell,76 63 61字节

@nimi的建议的变体节省了2个字节。

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]
nimi

我需要在来车之前先来车,所以有点复杂,但是您的想法还是可以节省2个字节。谢谢!
Christian Sievers

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

抱歉,如果您要编写函数,则可以使用三元组数组作为输入。我和我的朋友们认为,如果我们在谈论没有复杂输入的问题时,这是使非高尔夫语言更具竞争力的好方法。
Keyu Gan

@KeyuGan:感谢提示;但是使用数组作为输入时,我需要一个函数,该函数将花费两个字节,既包含三元组数组又包含三元组数组。函数,数组映射和自定义排序在PHP中非常庞大。我可以保存任何内容的唯一方法是将我准备$d为输入或已排序的输入(按时间和输入/输出)。面对挑战,束手无策。对齐的输入ttttt i plate将节省17个字节,而计数与板号对齐则将节省19个字节。
泰特斯(Titus)


2

八度,5064 38个字节

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

与@Greg Martin的Mathematica答案相同

该函数获取3列数组 [time, i/o,plateN]

先前的答案:

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

该函数仅从包含三个输入的单元格数组的前两个元素中获得两个输入t:time和O:I / O A

创建一个稀疏矩阵以对每个记录的现有汽车数量进行计数。因此,考虑退出时间+ 1代表轿厢退出,并且将1更改为-1,将0更改为1。
在这里使用稀疏非常重要,因为可能同时有多辆轿厢到达或离开。
然后找到计算得出的总和,代表该批次中当前汽车的数量和最大数量。


我记得八度支持单元格数组,这意味着您只能使用一个三元组数组作为输入。该限制是根据M5之前的版本进行的,它规定了“一组三元组”。我在M5澄清它
科宇甘

@KeyuGan我认为您的新发明限制不必要地增加了我代码的14个字节。因此,您是本网站的新手,最好是提出一些具有最少限制的问题,以吸引更多的贡献者。
rahnema17年

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个字节。

学分

  • 通过完全移动map函数内部的移位和乘法,我节省了1个字节(感谢Neil)。
  • 我在sort函数中使用了一个分解后的参数,节省了另外两个字节(感谢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的地方效果不佳?
Keyu Gan

在4项测试用例中,只有2辆车。我已经格式化它以满足您的输入命令。
Keyu Gan

@KeyuGan对您的误会表示抱歉,但我没有意识到您是在指第二个示例。现在已修复。
Patrick Roberts

我知道您的算法不取决于车牌号。但是,我建议应将其包括在输入顺序的定义中,只需将其放在最后即可;)
Keyu Gan

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))
Patrick Roberts

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

测试


读取该in_out列而不是该plate列将为您节省六个字节:v=>n+=1-v[2]*2
尼尔(Neil)

对于第二个示例,这是不正确的,因此,如果再次进行编辑,则需要考虑到这一点。(由于对此的最后修改是在添加第二个示例之前进行的,因此从技术上讲,它不遵守它,并且我一点也不嫉妒!)
Patrick Roberts

@PatrickRoberts当我回到电脑前时,将尝试解决此问题^^
Arnauld

@Neil好抓住!无论如何,我必须重写它以支持第二个示例,但最终还是听从了您的建议。
Arnauld
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.