Ini Halloween lagi!

10

Deskripsi Masalah

Kita semua suka Twix (karena ini adalah permen terbaik), tapi ini Halloween pertama anak-anak --- kita harus mengambil setidaknya satu dari setiap jenis permen untuk mereka. Setiap Halloween, semua penghuni Numberline avenue mengirimkan email yang mengatakan jenis permen apa yang akan mereka bagikan tahun ini.

Oh! Dan kita hidup di dunia 1D.

Menjadi sangat malas dalam beberapa hal dan tidak dalam hal lain, kami telah membuat peta rumah-rumah yang memberikan posisi mereka di sepanjang jalan. Kami juga mencatat jenis permen yang mereka miliki. Inilah peta yang kami buat untuk tahun ini:

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

Demi kaki kecil anak-anak, kita perlu mencari jalan kaki paling pendek mulai dari rumah mana pun di lingkungan itu untuk mengumpulkan setidaknya satu dari setiap jenis permen.

Contohnya

Atas permintaan beberapa pengguna (termasuk Shaggy), saya akan memberikan beberapa contoh yang berhasil. Semoga ini jelas. :) Masukan:

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

Keluaran:

[1, 2, 3]

Peta dan solusi lain ...

Memasukkan:

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

Keluaran :

[0, 1, 2]

Kita bisa mulai di rumah koordinasi 9 rumah mengumpulkan permen di rumah 6 dan 1. Itu memenuhi kuota permen dengan berjalan 8 unit, tetapi apakah itu solusi terpendek?

Aturan

Entri harus mengambil argumen tunggal terstruktur yang sama dengan contoh dan menampilkan indeks rumah untuk dikunjungi dalam solusi terpendek.

Aturan golf khas kode berlaku: solusi terpendek yang benar dalam bytes menang!

PS Ini adalah pertanyaan wawancara yang diberikan kepada saya oleh salah satu perusahaan teknologi terbesar di dunia. Jika Anda tidak suka golf, coba temukan solusi waktu O (k * n) di mana k adalah jumlah jenis permen dan n adalah jumlah rumah.

Edit

Seperti yang ditunjukkan Jonathon Allan, ada beberapa kebingungan di sekitar apa yang dimaksud dengan "indeks" dalam kasus ini. Kami ingin menampilkan posisi rumah dalam daftar argumen dan bukan koordinatnya di jalur.

Qfwfq
sumber
6
Ini perlu contoh yang berhasil dan beberapa kasus uji.
Shaggy
2
Bisakah kita mengambil dua argumen; daftar nomor rumah dan daftar jenis permen yang sesuai?
Adam
1
@KevinCruijssen Baik: output indeks rumah untuk dikunjungi dalam solusi terpendek
Adám
2
Saya berasumsi "indeks" dan "posisi" sama artinya (yaitu bahwa alamat di Numberline Avenue akan menjadi apa yang harus kami kembalikan) apakah itu salah?
Jonathan Allan
1
@KevinCruijssen Pertanyaan bagus! Angka-angka dijamin dalam urutan input. Dan saya akan membiarkan asumsi bahwa string tidak mengandung digit karena semua permen yang saya tahu dengan angka menguraikannya (Seratus Grand, dan Three Musketeers). :)
Qfwfq

Jawaban:

3

Jelly , 16 byte

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

Tautan monadik yang menerima input seperti yang dijelaskan dalam daftar yang diurutkan dari rumah Numberline Avenue tertinggi (jika kita perlu menerima pemesanan apa pun, kita dapat menambahkan ) yang menghasilkan jalur terpendek mulai dari rumah bernomor terendah dan perjalanan menyusuri Avenue.

Cobalah online!

Jika kita ingin menemukan semua jalur terpendek seperti itu, ganti byte trailing ÞḢ,, dengan ÐṂ; ini juga 16 byte.

Bagaimana?

Œ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)
Jonathan Allan
sumber
1
Bagus. Untuk penjelasan Anda, saya pikir maksud Anda maksimal untuk quick kedua.
Nick Kennedy
Ya yang saya lakukan.
Jonathan Allan
3

Python 2 , 133 130 127 byte

def f(l):r=range(len(l));v,c=zip(*l);print min((v[j]-v[i],r[i:j+1])for i in r for j in r if s(*c)==s(*c[i:j+1]))[1]
s={0}.union

Cobalah online!

TFeld
sumber
2

05AB1E , 22 byte

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

Mengasumsikan angka-angka dalam daftar input disortir dari yang terendah ke yang tertinggi.
Jika lebih dari satu solusi ditemukan, itu akan menampilkan semuanya.

Cobalah online.

Penjelasan:

æ            # 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)
Kevin Cruijssen
sumber
1

Perl 6 , 70 byte

{grep({.[@^i;1]⊇.[*;1]},combinations ^$_).min:{[-] .[@^i[*-1,0];0]}}

Cobalah online!

nwellnhof
sumber
0

Haskell , 343 372 byte

Berkat @ ASCII-only untuk peningkatan, ada juga varian 271 byte yang ia usulkan di komentar :)

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

Cobalah online!


Tidak disatukan

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

Percobaan pertama

bug
sumber
Anda hanya harus mengembalikan elemen ketiga dari tuple itu, dan Anda memiliki baris baru yang asing setelah impor Anda
ASCII
315? (masih harus mengembalikan hanya elemen ketiga)
ASCII-only
Yah, sebenarnya ... itu bahkan tidak bekerja pada testcase kedua
ASCII-hanya
jadi ya Anda tidak bisa meng-hardcode panjangnya
ASCII
358
ASCII
0

Solusi waktu O (k * n), dengan ruang O (k * n)

xii0i<nxicii

i1j1i0<i1i0j0i0j0

Dengan demikian, algoritma kami adalah:

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

bb94
sumber