サンタがプレゼントを届けるのにどれくらいかかりますか?


12

サンタさんがプレゼントを届けるのに必要なエルフの数に関係するこのチャレンジを少し前に投稿しました。

人口の増加により、サンタは今年はもう少し迫られています。過去には非常に非同期で動作していましたが、より同期化する実験を始めています。そのため、サンタは、与えられた数のエルフで各地域にプレゼントを届けるのにどれくらいかかるかを知る必要があります。

石炭の重量は過去2年で変化していません。現在よりも重いので、サンタは家のいたずらな人ごとに3つのエルフ、家のいい人ごとに2つのエルフを必要とします。

エルフはクリスマスのために一年中トレーニングをしているので、配達の間に休む必要はありません。彼らはプレゼントを一度に1つの家にしか届けることができず、サンタのそりに戻り、次の家に行く前に次の贈り物を集める必要があります。私が共有する自由がない理由のために、エルフはサンタのそりと家の間を移動する時間を費やしません(しかし、サンタのそりが屋根の上にあるときのみ移動できます)、そして彼のそりは家から家への移動に時間を費やしません。(サンタのそり、燃料を集めるために家から家へ移動する必要がありますが、私はすでに言いすぎです)。

プレゼントを配達しているエルフは4秒を費やす必要があります*それぞれプレゼントを配達し、石炭を配達しているエルフは5秒を費やす必要があります*サンタ航空管理規則により、石炭粉が付いた手袋はすぐに焼却する必要がありますそりに乗るには時間がかかります)。さらに、家はマップ上で左から右の順番で訪問する必要があり、エルフは現在の家にすべてのプレゼントが配達されるまで他の家にプレゼントを配達することができません。

サンタがこの地域に十分なエルフを持っていると仮定した場合、いたずらリストの誰かにプレゼントを届けるのにかかるのは、家ごとに5秒、みんながいいなら家ごとに4秒かかります。

ただし、前のシーズンとは異なり、このクリスマスサンタは各地域に十分なエルフを持たない可能性があるため、4秒が絶対最小時間*である場合を除き、特定の家にプレゼントを配達するのにかかるいい人と0人のいたずらな人は、0秒かかります。

さらに、家の1つでもいたずらリストに誰かがいる場合、サンタは少なくとも3つのエルフを必要とします。少なくとも1つの家にナイスリストに誰かがいて、誰もいたずらリストに人がいない場合、サンタは少なくとも2つのエルフを必要とします。どの家もクリスマススピリットに含まれていない場合、エルフの数(0を含む)は0秒かかります。

サンタの地図では、家はで表され、*各家はで分割されてい+ます。サンタはまだ他のチャレンジと同じマップを使用していますが、ここでそれらについてのドキュメントを含めます。

家の両側に数字が表示されます。左の数字は家の中のいたずら好きな人の数を表し、右の数字は家の中のいい人の数を表します。片側に番号がない場合は、0として解釈されます。

気が狂ったように聞こえるかもしれませんが、一部の人は「クリスマスが好きではない」ため、家の両側に番号がない場合があります。

サンタの地図の1つは次のようになります。

1*3+2*+*5+*+4*7

サンタのそりに9匹のエルフがいるとしましょう。

  1. (0s)最初の家にはいたずらが1人、素敵な人が3人います。エルフのうち3人が5秒かかって石炭を配達し、6人が4秒かかってプレゼントを配達します。5秒後、サンタのそりは次の家に移動します

  2. (5秒)2番目の家にはいたずら2人といい人0人がいます。エルフのうち6人が石炭を配達し、5秒かかります。5秒後、サンタのそりは次の家に移動します

  3. (10代)3番目の家にはいたずらが0人、いい人が5人います。エルフのうち8人が4つのプレゼントを配達します(取り残されたものはプレゼントを配達できません)。4秒後、すべてのエルフが戻ってきて、2人はもう1つのプレゼントを渡しに行きます(そりはエルフが戻るのを待ってから次の家に行く必要があります)、さらに4秒かかります

  4. (18代)4番目の家はクリスマスの精神ではないので、いたずらな人が0人、素敵な人が0人いて、スキップされます

  5. (18代)5番目の家には4人のいたずらな人と7人の素敵な人がいます。これは少し複雑になります...

    I. 9人のエルフ全員が、3つの石炭を贈ります(t + 0を残し、t + 5を返します)II。5秒後、彼らはすべてそりに戻り、そのうち3人は石炭の最後のプレゼントを届けに行き(t + 5sを残し、t + 10sを返します)、残りの6人は3つの素敵なプレゼントを届けます(t + 5秒、t + 9秒を返します)。

    III。4秒後、6人のエルフが戻ってきて、さらに3つの素敵なプレゼントを届けに行きます(t + 9秒のまま、t + 13秒を返します)。

    IV。出てから1秒後に、石炭プレゼントを配達していた3人のエルフが戻り、そのうち2人が最後の素敵なプレゼントを配達するために出発します(Leave + 10s、Return t + 14s)

  6. (18 + 14 = 32秒)サンタはその地域へのプレゼントの配達を終了します。

ご覧のとおり、サンタがこの地域にプレゼントを配達するには合計で32秒かかります。ただし、これはサンタの地図の1つを単純化しすぎたバージョンでした。通常、サンタの地図には複数の線があり、リストに収まるように正方形になっています。法線マップは次のようになります(\n各行の最後)

1*2+*+*4+1*
2*4+3*+1*6+*
*+*+4*2+1*1
*4+*3+1*+2*3
3*10+2*+*5+*

26人のエルフ(または任意のより多くの量)、それはサンタかかるだろう71秒
20のエルフ、それはサンタかかるだろう76秒
15のエルフ、それはサンタかかるだろう80秒
3つのエルフ、それはサンタかかるだろう288秒
2人のエルフ(または任意の低い量)、それは次のようになり不可能。

ああ、もう1つ- エルフがプレゼントを配達する順序は重要ですプレゼントを配達する時間の差はいたずら/素敵な人だからです)

チャレンジ

指定された数のエルフがプレゼントを配達するのにかかる時間をサンタが決めるのを助けます。

住宅

  • 家は *
  • 家は +
  • 家の左側の数字は、いたずらな人の数を表しています(数字は0を意味しません)
  • 右側の数字は、素敵な人の数を表しています(数字は0を意味しません)
  • \n入力に改行()がある場合がありますが、これも分割として処理する必要があります

エルフ

  • サンタはいたずらな人々のために3つのエルフの助けを必要としています(石炭はプレゼントよりもはるかに重いです)。プレゼントを配達するには5秒かかります*
  • サンタは素敵な人々のために2人のエルフの助けを必要とし、これらのエルフはプレゼントを届けるのに4秒かかります*
  • 家の両側に番号がない場合、サンタはその家を訪問せず、そのため時間はかかりません(クリスマスの精神がない人は石炭に値しません)

サンタさん

  • サンタは家に一つずつプレゼントを届けなければなりません
  • すべてのエルフがそりに戻り、プレゼントがすべてその家に届けられるまで、サンタは次の家に移動することはできません(エルフを置き去りにしたくありません。
  • サンタのそりは家から家への旅行に時間を費やしていません(繰り返しますが、私は共有する自由がないので)

何をすべきか

家と多数のエルフの地図が与えられたら、サンタが地図上の家にプレゼントを届けるのにかかる時間を印刷します。

*(エルフがプレゼントを配達するのにかかる時間を共有できない場合があります。このチャレンジに含まれる時間が正しいことを確認も否定もできません)

ルール

  • マップとエルフの数という2つの入力があります。入力は、関数への引数として、またはSTDINまたは同等のものから取得できます。2つの入力を取っていない通常の入力ではあなたには、いくつかの文字で区切られた単一の入力文字列として2つの入力を、受け入れることができ、その後だけにして、あなたの言語では不可能である場合には(ないの1 +*\nまたは0-9-入力文字列が曖昧にすることはできません)例えば ,
  • エルフの数は常に負でない整数になります(0が有効です)
  • 出力は、関数の戻り値、またはSTDOUTまたは同等のものに出力できます。サンタが特定の数のエルフで特定の地域にプレゼントを届けることが不可能な場合は、一貫した負の数、または番号のない一貫したメッセージ出力する必要があります
  • STDERRに出力されるものはすべて無視されるため、結果またはエラーメッセージをSTDERRに出力することはできません。
  • リージョンに対して無効な数のエルフが与えられた場合、プログラムはクラッシュしません
  • 出力は、指定された数のエルフでサンタがプレゼントを配達するのにかかる合計時間のみである必要があります。
  • 出力は常に、エルフがプレゼントを配達するのに必要な最短時間でなければなりません
  • 入力は数字のみ、含まれています+*と改行を\n(入力が含まれる別の文字を指定しない限り、あなたの言語には2つの入力を取ることができない場合は最初のルールで(見て)
  • 標準的な抜け穴が適用されます

テストケース

"1*1", 5 elves => 5
"1*1", 3 elves => 9
"1*2", 7 elves => 5
"1*2", 5 elves => 10
"1*2", 3 elves => 13
"2*1", 8 elves => 5
"2*1", 5 elves => 9
"2*1", 3 elves => 14
"1*" , 3 elves => 5
"1*" , 2 elves => (error message)
"*1" , 2 elves => 4
"*1" , 0 elves => (error message)
"*"  , 0 elves => 0

"1*1+1*1",   5 elves => 10
"1*1+1*1",   3 elves => 18
"1*1+*+1*1", 3 elves => 18
"1*2+2*1",   8 elves => 10
"1*2+2*1",   7 elves => 14
"1*2+2*1",   6 elves => 18
"1*2+2*1",   3 elves => 27
"1*2+2*1",   2 elves => (error message)
"*+*+*+*",   2 elves => 0
"*+*+*+*",   0 elves => 0

"1*3+2*+*5+*+4*7", 9 elves => 32

(うまくいけば、私はそのすべてを正しくした)

得点

サンタは毎日たくさんのことを見て過ごします-彼が届けようとしているすべてのプレゼント、彼が持っているすべてのエルフ、彼がプレゼントを届けるすべての家...サンタにとって、最高のクリスマスプレゼントは少し見ることができます。このため、バイト単位の最短の送信が優先されます

リーダーボード

これは、リーダーボードと言語ごとの勝者の概要の両方を生成するスタックスニペットです。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください

## Language Name, N bytes

Nは、送信のサイズ(バイト単位)です。

ヘッダーに複数の数字を含める場合(たとえば、古いスコアを打つ、またはバイトカウントにフラグを含める)、実際のスコアがヘッダーの最後の数字であることを確認してください

## Language Name, <s>K</s> X + 2 = N bytes


私が思うに288は読むべき281(1+0+0+1+2+3+1+0+0+0+4+1+0+0+1+2+3+2+0+0)*5+(2+0+4+0+4+0+6+0+0+0+2+1+4+3+0+3+10+0+5+0)*4=21*5+44*4=105+176=281(!私は全体の「エッセイ」を読んでいないと言わなければならないが)
ジョナサン・アラン

@JonathanAllan Yea ...私は偶然チャレンジを書くのにあまりにも多くの時間を費やしました...おっと...とにかく、欠けている重要なことは、サンタのそりがすべてのエルフがボードに戻るまで待たなければならないことです隣の家なので、すべての数値を足し合わせて乗算しても機能する場合がありますが、ほとんどの場合は機能しません。たとえば、9エルフの場合、家4*7は14秒かかります(2Dマップが導入される直前の「エッセイ」の約半分をカバーします)が、(4 * 5)+(7 * 4)= 48
Jojodmo

288の値は3つのエルフの例であるため、naughty*5+nice*4各家で常に完全な強打を実行する必要がありますよね?(4*7その例にはないことに注意してください)
ジョナサンアラン

エルフは常にあなたの例のように最初に邪魔にならないようにしますか、それとも効率的にスケジュールしますか?たとえば、マップが5*15あり、9エルフがいた場合、(最短)20秒または22秒かかりますか?参照してください。これらのテキスト表現をその一例の図を参照します。
ジョナサンアラン

上記のEDITを5*15読む必要があります4*15
ジョナサンアラン

回答:


4

ルビー433400バイト

まあ、これは本当に難しいです。なぜなら、エルフのスケジューリングはNPが難しいからです。

また、素敵なことに、これは私の最初の提出ですので、明らかな最適化を見逃しているかもしれません:

->e,h{h.split(/\+|\n/).map{|h|n,g=h.split(?*).map(&:to_i)+[0,0];return-1if(g>0&&e<2)||(n>0&&e<3);([[3,5]]*n+[[2,4]]*g).permutation.map{|j|c=[0]*e;j.map{|q|w,y=q;k=l=0;r=c.map{|x|a=b=0;c[k..e].map{|r|r<=x ?a+=1:break};(t=k+=1).times{c[t-=1]<=x ?b+=1:break};[a,b]};d=r.inject([]){|v,x|v<<l if x[0]>=w;l+=1;v}.min{|a,b|c[a]<=>c[b]};b=d-r[d][1]+1;z=c[d]+y;(b..(b+w-1)).map{|x|c[x]=z}};c.max}.min||0}.sum}

オンラインでお試しください!

最初はより長いテストケースがありましたが、場合によってはスケジューリングに可能なすべての順列を繰り返し処理するために時間がかかるため、削除しました。


2
PPCGへようこそ!あなたは間違いなくあなたの最初の答えのために難しい挑戦を選んだ
ジョーキング

2

Java(OpenJDK 8)、344バイト

Elfのスケジューリングは思ったよりも難しいので、これには少し時間がかかり、かなり長くなります。

それにもかかわらず、これは間違いなくコードゴルフへの私のお気に入りの挑戦でした!

(e,d)->{int r=0,x,y,c,p,b,g,m;for(String h:d[0].split("\\+")){d=h.split("\\*",-1);b=new Byte("0"+d[0]);g=new Byte("0"+d[1]);m=-1>>>1;for(y=1;y<=e/3&(x=(e-y*3)/2)>0;c=b/y+(b%y++<1?0:1),p=g/x+(g%x<1?0:1),x=c*5>p*4?c*5:p*4,m=x<m?x:m);for(y=0;b+g>0;b-=c,g-=p){c=e/3<b?e/3:b;x=(e-c*3)/2;p=x<g?x:g;if(c+p<1)return-1;y+=c>0?5:4;}r+=m<y?m:y;}return r;}

(すべてのテストで)オンラインで試してください!

説明;

自分を引き締める:それは長い

    int r=0,x,y,c,p,b,g,m;               // Define all the variables I need

    for(String h:d[0].split("\\+")){     // Split houses on '+' and loop through them

        d=h.split("\\*",-1);             // Split the current house on '*' using the limit
                                         // to preserve empty strings.

        b=new Byte("0"+d[0]);            // Parse the naughty (b) and nice (g) people
        g=new Byte("0"+d[1]);

        m=-1>>>1;                        // Initialise minimum time as max integer using
                                         // overflow

        for(y=1;y<=e/3&(x=(e-y*3)/2)>0;  // For each number of elves that can concurrently
                                         // deliver coal, and still leave enough elves to
                                         // deliver presents

            c=b/y+(b%y++<1?0:1),         // Determine the number of runs needed to deliver
                                         // all coal using this number of elves

            p=g/x+(g%x<1?0:1),           // Determine the number of runs needed to deliver
                                         // all presents using this number of elves

            x=c*5>p*4?c*5:p*4,           // Get the maximum time required for the
                                         // delivery of coal or presents

            m=x<m?x:m);                  // If this is less than the current minimum time,
                                         // set it as the minimum time


        for(y=0;b+g>0;b-=c,g-=p){        // While there are still people to deliver to;

            c=e/3<b?e/3:b;               // Determine the max amount of coal to deliver

            x=(e-c*3)/2;                 // Determine how many presents can be
                                         // delivered with the remaining elves.

            p=x<g?x:g;                   // If this number is more than nice people
                                         // remaining, just use the nice people remaining

            if(c+p<1)return-1;           // If no presents can be delivered, return the
                                         // error code (-1)

            y+=c>0?5:4;                  // Increase the time by 5 if coal was
                                         // delivered, and 4 if only presents

        }                                // At the end of each loop (see above)
                                         // remove the presents and coal delivered
                                         // from the number of naughty and nice houses

        r+=m<y?m:y;                      // Increment the total time by which ever
                                         // is smaller of the calculated times
    }
    return r;                            // Return the total time

NB:この答えは、テストケースに対する修正が正しいかどうかに依存します


私は(e-y*3)/2-> e-y*3>>1バイトを節約すると思います。(ほとんどの場合にも適用され(e-c*3)/2ます。)
ジョナサンフレッチ

runTest("1*4",5,12);失敗します("1*4", 5 elves => 13 FAILED数秒でスケジューリングするのにアルゴリズムが非常に優れていたことに驚いたので、0から7(elves、naughty、nice)のすべての可能な組み合わせに対してそれを実行し、失敗する場所をいくつか見つけました最適な時間を提供しますこれは失敗した場合の最小の組み合わせですところで、スケジュールするための驚くべきロジック、長い間私はあなたがそれをどのようにしたのか全く
知り
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.