駐車場スーパーバイザー


13

前書き

あなたは駐車場のスーパーバイザーであり、マネージャーはサイズを極端に縮小する準備をしています。

これは、昨年のPATの問題を単純化および適合させたバージョンですトップレベルです。

チャレンジ

あなたは、同時に多くしているどのように多くの車を計算するように要求され、最大で

標準ルールが適用されます。そしてこれはコードゴルフなので、最短のコードが勝ちます。

最初の行は、エントリの量(超えないで100,000あなたが好きならば、あなたの入力は、どこ入力端を決定する唯一のその場しのぎであるため、この行を含めることはできません)。次のテキストには、1行に1つのエントリが含まれています。また、各エントリには3つの数字が含まれています。

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

修正2:入力としてトリプルの配列を使用しても問題ありません。

変更3: 1つのエントリの番号の順序を変更できます。そして、使用するものを選択できます。(備考セクションを参照)

次のことを前提として、入力が有効であることが保証されます。

  • Car plate number10000〜の範囲の整数です99999
  • Time0〜の範囲の整数です86400

そして

  • エントリは必ずしも時系列に並んでいるとは限りません
  • 最初の秒の前に車はありません。
  • 最後の1秒が過ぎても必ずしも車がなくなるわけではありません
  • 車は入る前に出発しません。
  • 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駐車場にいた。

備考

実際には、3つすべてが出力に必要なわけではありません。少なくとも、結果にはプレート+時間またはイン/アウト+時間のみが必要です。しかし、アルゴリズムは2つの状況下でわずかに異なるため、特定の言語では、短い方の選択は不明のままです。そしてもちろん、3つの数字すべてを使用できます。だから私は彼らを挑戦に任せた。


車のプレート番号は常に5桁の長さですか?
タイタス

1
@Titus 10000から99999までの数字は常に5桁の長さだと思います。
キーガン

3
うん、今日は盲目だ。
タイタス

初めて出発する前に車が再び入ることはできないと思いますか?それは明示的に述べられていないようです。
ジョンドヴォルザーク

@JanDvorakええすみません。いいえ、できません。車のプレート番号が一意であることが暗示されているのは、実際には、同じ車がすでにその中にある場合、そのロットに入ることは不可能だからです。
キーガン

回答:


7

Mathematica、33バイト

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

ナンバープレート情報を必要としないはるかに単純なアルゴリズムがあることを理解するために、問題の説明をよく読む必要がありました。

整数を返す名前のない関数。入力形式は、形式の順序付きトリプルのリストです{time, 0|1, license plate}。まずSortingから始めます。これは、リストを時系列にし、0sをsの前に並べ替えることによって時間的なつながりを壊し1ます。その後2#2-1&@@@、到着/出発情報を保持し、残りを忘れ、0sを-1 sにます。

Accumulateそのリストの現在の合計を計算します。結果は、到着/出発ごとに駐車場にある車の数のマイナスのリストです。次にMin、これらの最小(最も負)を選択し、負の符号を取り除きます。

Mathematica、56バイト

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

元の投稿(最初のいくつかのコメントはこの投稿を参照)。整数を返す名前のない関数。入力形式は、次の形式の順序付きトリプルのリストです{time, 0|1, license plate}

タイムエントリを最初に、イン/アウトエントリを2番目に配置することを選択する理由はSort@#、リストを時系列でソートし、同時の場合は出発前に到着を記録するためです。その後#3->#2&@@@、フォームの「ルール」のリストを返します。これは、license plate -> 0|1時間順にソートされたままです。

次に、FoldList[List,{},...]そのルールのリストのすべての初期セグメントのリストを作成します。実際、最初のセグメントを台無しにします。k深さ2に1つのルール、深さ3に1つのルール、...、及び深さに1つの規則にリストされてアップ番目初期セグメント終了k+1。(FoldList[Append,{},...]より自然な結果が得られます。)ただし、<|#|>これらの初期セグメントのそれぞれを「関連付け」に変換します。これには、2つの望ましい効果があります。まず、作成したネストリスト構造を完全にフラット化します。第二に、後のルールが以前のルールを上書きすることを強制します。これはまさにここで必要なことです。駐車場を出た車の場合、最初のエントリの記録は完全になくなります(再入車の場合も同様) 。

したがって、あとは、これらの各アソシエーションにsがCountいくつあるかだけで0、を取得しMaxます。


1
車が同時に出入りする場合、これは常に正しいことを行いますか?
クリスチャンジーバーズ

あなたの答えは間違っているかもしれません。車が再び入ったときに必ずしも最大になるとは限らないため、関連付けを使用してエントリを消去するのは安全ではありません。この写真を参照してください:i.imgur.com/D5xUl3z.pngが明らか16500.で3台がある
Keyuガン

@KeyuGan:車が再び入ったときに最大になるとは言わなかった。私のソリューションでは、入出庫のたびに駐車場の車の数をカウントし、それらの最大数を取得することに注意してください。
グレッグマーティン

1
たぶん、あなたは例2試みることができる
Keyuガン

1
個人的に私はあなたに同意します。:)私がやったことは、元の問題から定義をコピーすることです。主な違いは、元のものは画像から車のプレートを認識し、最終結果として印刷する必要があることです。
キーガン

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バイト節約できます。ありがとう!
クリスチャンシーバーズ

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;

fileから入力を受け取りi、最初の行を無視します。で実行し-rます。
入力には末尾の改行が必要です。交換する-2-3Windows用。

壊す

# 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

関数を作成している場合は、入力としてトリプルの配列を使用できます。友人と私は、複雑な入力なしで問題について話している場合、非ゴルフ言語をより競争力のあるものにする良い方法だと信じています。
キーガン

@KeyuGan:ヒントをありがとう。しかし、入力として配列を使用すると、関数が必要になります。これには、トリプレットの配列とトリプレットの配列の両方で2バイトかかります。PHPでは、関数、配列マッピング、カスタムソートはかさばります。何かを保存できる唯一の方法は$d、入力またはソートされた入力として(時間とイン/アウトで)準備することです。そして、thastはこのチャレンジから多くを奪いすぎました。ttttt i plate位置合わせされた入力は17バイトを節約し、さらに19バイトがプレート番号に合わせられます。
タイタス

2

C、147バイト

完全なプログラム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);}

ideoneで試してみてください


私は間のスペースを削除しても安全であると信じて%d
Keyuガン

おっと、ありがとう。私はscanf十分に使用していないと思います。
-owacoder

大好きcinです。LOL
Keyuガン


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}

この関数は、3つの入力を含むセル配列の最初の2つの要素からのt時間とOI / Oの2つの入力のみを取得Aします!

既存の車の記録された時間数ごとにカウントするために作成されたスパース行列。退出時間+ 1が車の出口に考慮され、対応する1が-1に変更され、0が1に変更されます

次に、ロット内の現在の車の数と最大数を表す計算された累積合計が求められます。


Octaveはセル配列をサポートしていることを覚えています。つまり、入力としてトリプルの配列を1つだけ使用できます。この制限は、M5以前のエディションによるもので、「トリプルの配列」と記載されています。M5
Keyu Ganで

@KeyuGanあなたの新しい発明された制限は、私のコードの14バイトを増やす必要はないと思います。このサイトは初めてなので、制限を最小限に抑えて質問をして、より多くの貢献者を引き付ける方が良いでしょう。
rahnema1

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]。残念ながら、同一のinout時間は、現時点で両方の車がロット内で考慮されることを意味するため、ソートアルゴリズムは11バイトのコストの0前に注文する必要があり1ます。

クレジット

  • map関数内でシフトと乗算を完全に移動して1バイトを節約しました(Neilに感謝)。
  • sort関数で非構造化引数を使用して、さらに2バイトを保存しました(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で印刷するはずだとうまく動作しないようです?
キーガン

4エントリのテストケースでは、2台の車しかありません。入力順序に合わせてフォーマットしました。
キーガン

@KeyuGanは誤解して申し訳ありませんが、2番目の例を参照していることに気付きませんでした。現在修正されています。
パトリックロバーツ

私はあなたのアルゴリズムがプレート番号に依存しないことを知っています。ただし、入力順序の定義に含める必要があることをお勧めします。最後に任せてください;)
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))
パトリック・ロバーツ

2

JavaScript(ES6)、8368 70バイト

編集:2番目の例をサポートするために修正

入力を配列の[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列ではなく列を読み取ると、plate6バイト節約できますv=>n+=1-v[2]*2
ニール

2番目の例ではこれは正しくないため、これを再度編集する場合は、それを考慮する必要があります。(これに関する最後の編集は2番目の例が追加される前だったので、技術的にそれに従うことは免除されており、私はまったくjeしていません!)
パトリックロバーツ

@PatrickRobertsは^^私はコンピュータの前に戻ってきたときにことを解決しようとする
アルノー

@ニール良いキャッチ!2番目の例をサポートするために、とにかく書き直さなければなりませんでしたが、私はあなたのアドバイスに従いました。
アーナウド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.