Lại là Halloween!


10

Mô tả vấn đề

Tất cả chúng ta đều yêu thích Twix (vì đó là kẹo tốt nhất), nhưng đây là Halloween đầu tiên của trẻ em --- chúng ta phải lấy ít nhất một trong số mỗi loại kẹo cho chúng. Mỗi dịp Halloween, tất cả cư dân của đại lộ Numberline đều gửi email cho biết họ sẽ tặng loại kẹo nào trong năm nay.

Oh! Và chúng ta sống trong một thế giới 1D.

Rất lười biếng trong một số cách và không phải ở những người khác, chúng tôi đã tạo ra một bản đồ của những ngôi nhà cho vị trí của họ dọc theo đường phố. Chúng tôi cũng lưu ý các loại kẹo họ có. Đây là bản đồ chúng tôi đã tạo cho năm nay:

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

Vì lợi ích của đôi chân nhỏ của trẻ em, chúng ta cần tìm một cuộc đi bộ ngắn nhất bắt đầu từ bất kỳ ngôi nhà nào trong khu phố để thu thập ít nhất một trong mỗi loại kẹo.

Ví dụ

Theo yêu cầu của một vài người dùng (bao gồm cả Shaggy), tôi sẽ đưa vào một số ví dụ hoạt động. Hy vọng điều này sẽ làm sáng tỏ mọi thứ. :) Đầu vào:

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

Đầu ra:

[1, 2, 3]

Một bản đồ và giải pháp khác ...

Đầu vào:

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

Đầu ra :

[0, 1, 2]

Chúng ta có thể bắt đầu ở tọa độ 9 nhà thu thập kẹo đến nhà 6 và 1. Điều đó làm đầy hạn ngạch kẹo bằng cách đi bộ 8 đơn vị, nhưng đó có phải là giải pháp ngắn nhất?

Quy tắc

Các mục nhập phải có một đối số duy nhất có cấu trúc tương tự với ví dụ và đưa ra các chỉ số của các ngôi nhà sẽ truy cập trong giải pháp ngắn nhất.

Quy tắc golf mã điển hình được áp dụng: giải pháp đúng ngắn nhất tính theo byte thắng!

Tái bút: Đây là một câu hỏi phỏng vấn được đưa ra cho tôi bởi một trong những công ty công nghệ lớn nhất thế giới. Nếu bạn không thích chơi gôn, hãy thử tìm giải pháp thời gian O (k * n) trong đó k là số loại kẹo và n là số lượng nhà.

Biên tập

Như Jonathon Allan đã chỉ ra, một số nhầm lẫn tồn tại xung quanh "chỉ số" nghĩa là gì trong trường hợp này. Chúng tôi muốn xuất các vị trí nhà trong danh sách đối số chứ không phải tọa độ của chúng trên làn đường.


6
Đây là một ví dụ cần thiết và một số trường hợp thử nghiệm.
Shaggy

2
Chúng ta có thể đưa ra hai đối số; một danh sách các số nhà và một danh sách các loại kẹo tương ứng?
Adám

1
@KevinCruijssen Neither: xuất các chỉ số của các ngôi nhà sẽ đến trong giải pháp ngắn nhất
Adám

2
Tôi cho rằng "chỉ số" và "vị trí" là đồng nghĩa (nghĩa là các địa chỉ trên Đại lộ Numberline sẽ là những gì chúng ta nên trả lại) có sai không?
Jonathan Allan

1
@KevinCruijssen Những câu hỏi hay! Các số được đảm bảo theo thứ tự trong đầu vào. Và tôi sẽ cho phép giả định rằng các chuỗi không chứa chữ số như tất cả các loại kẹo mà tôi biết với các con số đánh vần chúng (Hundred Grands và Three Musketeers). :)
Qfwfq

Câu trả lời:


3

Thạch , 16 byte

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

Liên kết đơn âm chấp nhận đầu vào như được mô tả trong danh sách được sắp xếp từ các nhà ở Đại lộ Numberline thấp nhất (nếu chúng tôi cần chấp nhận bất kỳ đơn đặt hàng nào, chúng tôi có thể trả trước ) dẫn đến con đường ngắn nhất bắt đầu từ nhà được đánh số thấp nhất và đi lên Đại lộ.

Hãy thử trực tuyến!

Nếu chúng ta muốn tìm tất cả các đường dẫn ngắn nhất như vậy thay thế các byte theo sau ÞḢ, bằng ÐṂ; đây cũng là 16 byte.

Làm sao?

Œ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
Đẹp. Đối với lời giải thích của bạn, tôi nghĩ bạn có nghĩa là tối đa cho lần thứ hai nhanh chóng.
Nick Kennedy

Đúng là tôi đã làm.
Jonathan Allan


2

05AB1E , 22 byte

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

Giả sử các số trong danh sách đầu vào được sắp xếp từ thấp nhất đến cao nhất.
Nếu có nhiều hơn một giải pháp được tìm thấy, nó sẽ xuất ra tất cả chúng.

Hãy thử trực tuyến.

Giải trình:

æ            # 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 byte

Nhờ @ ASCII - chỉ để cải tiến, còn có một biến thể 271 byte mà ông đề xuất trong các nhận xét :)

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

Hãy thử trực tuyến!


Ung dung

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

Lần thử đầu tiên


bạn chỉ nên trả lại phần tử thứ ba của bộ dữ liệu đó và bạn có một dòng mới không liên quan sau khi nhập
ASCII - chỉ

315? (vẫn phải trả lại chỉ phần tử thứ ba)
ASCII - chỉ


vì vậy, vâng, bạn không thể mã hóa độ dài
ASCII


0

Giải pháp thời gian O (k * n), với không gian O (k * n)

xTôiTôi0Tôi<nxTôicTôiTôi

Tôi1j1Tôi0<Tôi1Tôi0j0Tôi0j0

Do đó, thuật toán của chúng tôi là:

// 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

MộtÔi(k)Ôi(nk)nnnÔi(n)Ôi(nk)Ôi(k)Ôi(nk)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.