다시 할로윈이야!


10

문제 설명

우리는 모두 Twix를 좋아하지만 (최상의 사탕이기 때문에) 이것은 아이들의 첫 번째 할로윈입니다 --- 우리는 그들을 위해 각 사탕 유형 중 적어도 하나를 가져와야합니다. Numberline 애비뉴에 거주하는 모든 할로윈 사람들은 올해 어떤 종류의 사탕을 줄지 이메일을 보냅니다.

오! 그리고 우리는 1D 세계에 살고 있습니다.

어떤면에서는 예외적으로 게으르고 다른면에서는 게으르지 않기 때문에 거리를 따라 위치를 제공하는 주택지도를 만들었습니다. 우리는 또한 그들이 가지고있는 사탕의 종류에 주목했습니다. 올해 우리가 만든지도는 다음과 같습니다.

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

아이들의 작은 다리를 위해서, 우리 는 각 유형의 사탕 중 적어도 하나 를 모으기 위해 이웃의 어느 집에서나 가장 짧은 산책을 해야합니다 .

몇 명의 사용자 (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 칸을 걸어 사탕 할당량을 채우지 만 가장 짧은 해결책입니까?

규칙

출품작은 예제와 비슷하게 구조화 된 단일 주장을 취하고 가장 짧은 솔루션으로 방문 할 주택의 지수를 출력해야합니다.

전형적인 코드 골프 규칙이 적용됩니다 : 바이트 단위의 가장 짧은 정확한 솔루션이 승리합니다!

추신 이것은 세계 최대의 기술 회사 중 하나에 의해 나에게 주어진 인터뷰 질문이었습니다. 골프가 마음에 들지 않으면, k는 캔디 유형의 수이고 n은 주택 수인 O (k * n) 시간 솔루션을 찾으십시오.

편집하다

Jonathon Allan이 지적했듯이이 경우 "표시"의 의미에 대해 약간의 혼란이 있습니다. 차선의 좌표가 아니라 인수 목록에 주택 위치를 출력하려고합니다 .


6
이것은 실제 예제와 일부 테스트 사례가 필요합니다.
얽히고 설킨

2
우리는 두 가지 주장을 취할 수 있습니까? 집 번호 목록과 해당 사탕 유형 목록?
Adám

1
@KevinCruijssen 어느 쪽도 : 가장 짧은 해결책으로 방문 할 집의 지수를 출력하십시오
Adám

2
나는 "표시들"과 "포지션들"이 동의어라고 가정했다.
Jonathan Allan

1
@KevinCruijssen 좋은 질문입니다! 숫자는 입력 순서대로 보장됩니다. 그리고 숫자로 알고있는 모든 사탕 (100 개 그랜드, 3 개 총사)으로 철자를 표기하기 때문에 문자열에 숫자가 없다고 가정합니다. :)
Qfwfq

답변:


3

젤리 , 16 바이트

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

가장 낮은 번호의 집에서 가장 높은 번호의 집 으로 정렬 된 목록에 설명 된대로 입력을 수락하는 모나드 링크 (주문을 수락해야하는 경우 )를 앞에 붙일 수 있습니다.

온라인으로 사용해보십시오!

가장 짧은 경로를 모두 찾으려면 후행 바이트 ( ÞḢ)를 ÐṂ; 이것은 또한 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
좋은. 당신의 설명을 위해, 나는 당신이 두 번째 빨리 최대를 의미한다고 생각합니다.
Nick Kennedy

그렇습니다.
Jonathan Allan


2

05AB1E , 22 바이트

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

입력 목록의 숫자가 가장 낮은 순서로 정렬되어 있다고 가정합니다.
둘 이상의 솔루션이 발견되면 모든 솔루션이 출력됩니다.

온라인으로 사용해보십시오.

설명:

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

하스켈 , 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

첫번째 시도


당신은 해당 튜플의 세 번째 요소를 반환해야합니다, 당신은 당신의 수입 후 관계없는 줄 바꿈이
ASCII 전용

315? (여전히 세 번째 요소 만 반환해야 함)
ASCII 전용


따라서 길이를 하드 코딩 할 수 없습니다
ASCII 전용


0

O (k * n) 공간이있는 O (k * n) 시간 솔루션

엑스나는나는0나는<엑스나는나는나는

나는1제이1나는0<나는1나는0제이0나는0제이0

따라서 알고리즘은 다음과 같습니다.

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

테이크 의 구성영형(케이)영형(케이)영형()영형(케이)영형(케이)영형(케이)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.