またハロウィンです!


10

問題の説明

私たちは皆、Twixが大好きです(最高のキャンディだからです)が、これは子供の最初のハロウィーンです---それぞれのタイプのキャンディを少なくとも1つは手に入れなければなりません。ハロウィーンごとに、ナンバーラインアベニューのすべての居住者は、彼らが今年提供するキャンディーの種類を示すメールを送信します。

ああ!そして、私たちは1Dの世界に住んでいます。

一部の方法では例外的に怠惰であるため、他の方法ではなく、家の地図を作成し、通り沿いの位置を示しています。また、お菓子の種類についても触れました。今年作成した地図は次のとおりです。

 [(-2, {"Kisses", "KitKats"}),
 (1, {"KitKats", "Peanut Butter Cups"}),
 (6, {"Kisses", "Twix"}),
 (9, {"Skittles"}),
 (10, {"Twix"})]

子供たちの小さな足のために、近所の家から始めて、各種類のキャンディーを少なくとも1つ集めるために、最短の散歩を見つける必要があります。

例

カップルのユーザー(Shaggyを含む)のリクエストに応じて、実際に動作する例をいくつか紹介します。うまくいけば、これで問題が解決します。:) 入力:

 [(-2, {"Kisses", "KitKats"}),
 (1, {"KitKats", "Peanut Butter Cups"}),
 (6, {"Kisses", "Twix"}),
 (9, {"Skittles"}),
 (10, {"Twix"})]

出力:

[1, 2, 3]

別の地図と解決策...

入力:

[(-3, {"KitKats", "Twix"}),
(-1, {"Hundred Grands"}),
(3, {"Kisses"}),
(12, {"Hundred Grands", "Twix", "KitKats"})]

出力:

[0, 1, 2]

座標9の家から6と1の家にキャンディーを集めることから始めることができます。これは、8ユニットを歩くことでキャンディーの割り当てを満たしますが、これが最も短い解決策ですか?

ルール

エントリは、例と同様に構造化された単一の引数を取り、訪問する家のインデックスを最短のソリューションで出力する必要があります。

典型的なコードゴルフルールが適用されます。

PSこれは、世界最大のテクノロジー企業の1つから私に与えられたインタビューの質問でした。ゴルフが気に入らない場合は、O(k * n)時間解を見つけてみてください。kはキャンディーの種類の数で、nは家の数です。

編集する

Jonathon Allanが指摘したように、この場合の「インデックス」が何を意味するかについて、いくつかの混乱が存在します。レーン上の座標ではなく、引数リストの家の位置を出力したいと思います。


6
これは実際に動作する例といくつかのテストケースが必要です。
— Shaggy

2
2つの引数を取ることができますか。家番号のリストと対応するキャンディータイプのリスト?
— アダム

1
@KevinCruijssenどちら:出力最短溶液中での訪問に家屋の指標
— アダム

2
「インデックス」と「ポジション」は同義語である(つまり、ナンバーラインアベニューの住所は返すべきものである)と思いましたが、それは間違いですか。
— ジョナサンアラン

1
@KevinCruijssen素晴らしい質問です!数値は入力で正しい順序であることが保証されています。そして、数字で知っているすべてのキャンディーがそれらをスペルアウトするので、文字列には数字が含まれていないという仮定を許可します(100グランド、3つのマスケット銃兵)。:)
— Qfwfq

回答:


3

ゼリー、16 バイト

ŒPṪ€ẎQLƲÐṀẎISƊÞḢ

Numberline Avenueの最も低い家から最も高い家まで並べられたリストで説明されているように入力を受け入れるモナディックリンク(順序を受け入れる必要がある場合はṢ、先頭にを付けることができます)。これにより、最も小さい番号の家から始まり、Avenueまで移動する最短パスが生成されます。

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

そのような最短のパスをすべて検索したい場合は、後続のバイトÞḢをÐṂ;に置き換えます。これも16バイトです。

どうやって?

ŒPṪ€ẎQLƲÐṀẎISƊÞḢ - Link: list of [index, candies]
ŒP               - power-set
        ÐṀ       - keep those for which this is maximal:
       Ʋ         -   last four links as a monad:
  Ṫ€             -     tail €ach -- this removes the candies lists from the current list
                 -                  and yields them for use now
    Ẏ            -     tighten (to a flat list of candies offered by these hoses)
     Q           -     de-duplicate (get the distinct candies offered)
      L          -     length (how many distinct candies are on offer)
              Þ  - sort (now just the indexes of remaining sets due to Ṫ) by:
             Ɗ   -   last three links as a monad:
          Ẏ      -     tighten (to a flat list of indexes since Ṫ leaves a list behind)
           I     -     incremental differences (distances between houses)
            S    -     sum
               Ḣ - head (get the first)

1
いいね。あなたの説明として、私はあなたが2番目のクイックにとって最大であることを意味すると思います。
— Nick Kennedy

そうだね。
— ジョナサンアラン


2

05AB1E、22 バイト

æʒ€θ˜I€θ˜åP}€€нD€¥OWQÏ

input-list内の数値が最低から最高にソートされていると仮定します。
複数のソリューションが見つかると、それらすべてが出力されます。

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

説明:

æ            # Get the powerset (all possible combinations) of the (implicit) input-list
 ʒ           # Filter this list of combinations by:
  €θ         #  Get the last items of each (the list of strings)
    ˜        #  Flatten the list
  I          #  Get the input-list again
   €θ˜       #  Get the last items of each (the list of strings) flattened as well
      å      #  Check for each if it is in the list of strings of this combination
       P     #  Check if all are present
 }           # Close the filter (we now have all combinations, containing all unique strings)
  €€н        # Only leave the first items of each item in the combination (the integers)
     D       # Duplicate this list
      €¥     # Get the deltas (forward differences) of each
        O    # Sum these deltas
         W   # Get the lowest sum (without popping the list)
          Q  # Check for each if it's equal to this minimum
           Ï # And only leave the list of integers at the truthy indices
             # (which are output implicitly as result)


0

Haskell、343 372バイト

@ASCII のみの改善のおかげで、コメントで提案した271バイトのバリアントもあります:)

import Data.List
import Data.Function
f s=subsequences(map(\a@(x,y)->(x,y,[(a`elemIndices`s)!!0]))s)
g f s=if f*s<=0 then f+abs f+abs s else f+abs(f-s)
h=foldl(\(a,b,c)(d,e,f)->(g a d,nub(b++e),c++f))(0,[],[])
i s=map h(filter(not.null)s)
l m=filter(\(_,x,_)->length x==(maximum$map(\(_,x,_)->length x)m))m
m=minimumBy(compare`on`(\(p,_,_)->p))
n s=(\(_,_,l)->l)$m$l$i$f s

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


未ゴルフ

import Data.List
import Data.Function

allPaths :: [(Integer, [String])] -> [[(Integer, [String], [Int])]]
allPaths xs = subsequences(map (\a@(x,y) -> (x,y,[(a`elemIndices`s) !! 0])) s)

pathLength :: Integer -> Integer -> Integer
pathLength f s = if f*s <= 0 then f + abs f + abs s else f + abs(f - s)

traversePath :: [(Integer, [String], [Int])] -> (Integer, [String], [Int])
traversePath = foldl (\(n1, a1, c1) (n2, a2, c2) -> (pathLength n1 n2, nub (a1 ++ a2), c1 ++ c2)) (0, [], [])

allTraversedPaths :: [[(Integer, [String], [Int])]] -> [(Integer, [String], [Int])]
allTraversedPaths xs = map traversePath (filter (not . null) xs)

getCompletePaths :: [(Integer, [String], [Int])] -> [(Integer, [String], [Int])]
getCompletePaths m = filter (\(_,x,_) -> length x == ( maximum $ map (\(_,x,_) -> length x) m)) m

getFastestPath :: [(Integer, [String], [Int])] -> (Integer, [String], [Int])
getFastestPath = minimumBy (compare `on` (\(p, _, _) -> p))

getPath :: [(Integer, [String])] -> (Integer, [String], [Int])
getPath xs = (\(_,_,l) -> l) getFastestPath $ getCompletePaths $ allTraversedPaths $ allPaths xs

最初の試み


そのタプルの3番目の要素のみを返す必要があり、インポート後に無関係な改行が発生します
— ASCIIのみ

315?(ただし、3番目の要素のみを返す必要があります)
— ASCIIのみ


ええ、長さをハードコードすることはできません
— ASCIIのみ


0

O(k * n)時間解、O(k * n)空間あり

xii0≤i<nxicii

i1j1i0<i1i0j0i0≤j0

したがって、アルゴリズムは次のとおりです。

// A[k] is the number of each candy we get from the first k houses
A := array of n bags
A[0] := {}
for k := 0 to n - 1
  A[k] := A[k - 1] + c[k - 1]
end
best_distance := ∞
best_i := -1
best_j := -1
// Find the range [i, j] such that we get all candy types
j := n
for i := n - 1 to 0
  while j > i and (A[j - 1] - A[i]) has all candy types
    j := j - 1
  end
  if (A[j] - A[i]) does not have all candy types then continue end
  distance = x[j - 1] - x[i]
  if distance < best_distance then
    best_distance = distance
    best_i = i
    best_j = j
  end
end
return best_i ..^ best_j

AO(k)O(nk)nnnO(n)O(nk)O(k)O(nk)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.