Leniwy worek chleba

11

Pracuję w piekarni, która serwuje pszenicę, żyto, jęczmień, ziarno i francuski chleb, ale piekarz jest trochę dziwny - układa bochenki w przypadkowej kolejności, a czasami po prostu zostawia puste półki na końcu.

Każdego dnia ten sam klient przychodzi i prosi o jeden bochenek chleba, ale podstępem jest to, że jest on zarazkiem, więc kiedy napełniam jego torbę, nie mogę wziąć bochenków z dwóch sąsiednich półek w kolejnych selekcjach.

Przejście między sąsiednimi półkami zajmuje sekundę. To zatłoczony sklep; dla dowolnej losowej konfiguracji bochenków chciałbym zminimalizować czas potrzebny do uzyskania jednego z unikalnych bochenków. Mogę zaczynać i kończyć na dowolnej półce.

Jeśli dzisiejsze zamówienie jest W B W G F R Wmożliwe, możliwa jest ścieżka trwająca 0, 3, 5, 1, 4łącznie 12 sekund:abs(3-0) + abs(5-3) + abs(1-5) + abs(4-1) = 12

( 1, 2, 3, 4, 5nie działa, ponieważ chleb jest zbierany kolejno z sąsiednich półek).

Jeśli tak B W B G B F B R B W B F, możliwa jest ścieżka trwająca 1, 3, 5, 7, 10łącznie 9 sekund.

Menedżer zawsze upewnia się, że istnieje możliwe rozwiązanie, więc nie muszę się martwić o złapanie złych danych wejściowych. Zazwyczaj wysyła mi zamówienie w pliku, ale jeśli chcę, mogę wpisać go w STDIN lub odczytać w inny sposób. Chciałbym, aby program wydrukował wskaźniki najlepszej ścieżki, a także jej czas, zgodnie z domyślnymi regułami We / Wy .

W skrócie:

  1. 5 rodzajów chleba.
  2. Zamówienia na bochenek pojawiają się jako ciągi losowej kolejności i długości.
  3. Musisz wybrać jeden z każdego unikalnego bochenka.
  4. Nie można dokonać sąsiadujących kolejnych wyborów.
  5. Zminimalizuj odległość między wskaźnikami wyboru.
  6. Nie musisz się martwić o nieprawidłowe dane wejściowe.
  7. Obowiązują domyślne reguły we / wy .

To jest , wygrywa najmniejsza liczba bajtów.

Nick Reed
źródło
0+3+5+1+4=13ale 1+3+5+7+10=26nie 9.
Kudłaty
2
@LuisfelipeDejesusMunoz Niezupełnie, kilka z tych kolejnych indków sąsiaduje.
Nick Reed,
4
Witamy w PPCG i miłe pierwsze wyzwanie!
user202729,
2
Nie jest to ważne dla rzeczywistego zadania, ale jestem ciekawy: dlaczego jest on zarazkiem, co oznacza, że ​​nie możesz wziąć bochenków z dwóch sąsiednich półek w kolejnych selekcjach?
Sundar - Przywróć Monikę
1
Czy mogą być jakieś puste półki, których nie ma na końcach? (np. czy 'WBWG FRW'też jest poprawny?
Jonathan Allan,

Odpowiedzi:

3

JavaScript (ES6), 114 bajtów

Zapisano 1 bajt dzięki @Oliver

Pobiera dane wejściowe jako tablicę znaków. Zwraca ciąg rozdzielany przecinkami, gdzie pierwsza wartość to całkowity czas, a następne opisują ścieżkę.

a=>(b=g=(r,s=o='',c,p)=>s[c>b|4]?o=(b=c)+r:a.map((v,i)=>s.match(v)||(d=p<i?i-p:p-i)<2||g([r,i],s+v,~~c+d,i))&&o)``

Wypróbuj online!

Skomentował

a => (                          // a[] = input array
  b =                           // b = best score so far (initially a non-numeric value)
  g = (                         // g = recursive function taking:
    r,                          //   r = path
    s =                         //   s = string of collected loaves of bread
    o = '',                     //   o = final output
    c,                          //   c = current cost
    p                           //   p = index of the last visited shelf 
  ) =>                          //
    s[c > b                     // if the final cost is not greater than our best score
            | 4] ?              // and we've successfully collected 5 loaves of bread:
      o = (b = c) + r           //   update the current output and the best score
    :                           // else:
      a.map((v, i) =>           //   for each loaf of bread v at shelf i in a[]:
        s.match(v) ||           //     if we've already collected this kind of bread
        (d =                    //     or the distance d
          p < i ? i - p : p - i //     defined as the absolute value of p - i
        ) < 2 ||                //     is less than 2: stop recursion
        g(                      //     otherwise, do a recursive call to g() with:
          [r, i],               //       r updated with the index of the current shelf
          s + v,                //       s updated with the current loaf of bread
          ~~c + d,              //       c updated with the last distance
          i                     //       i as the index of the last shelf
        )                       //     end of recursive call
      )                         //   end of map()
      && o                      //   return the current output
  )``                           // initial call to g() with r = [""]
Arnauld
źródło
0

Python 2 , 212 210 bajtów

lambda s:min((sum(h(p)),p)for b in combinations(range(len(s)),5)for p in permutations(b)if(len(set(s[i]for i in p))==5)&all(d>1for d in h(p)))
h=lambda p:[abs(y-x)for x,y in zip(p,p[1:])]
from itertools import*

Wypróbuj online!

2 bajki dzięki Jonathanowi Frechowi .

Chas Brown
źródło
if len(...)==5and all(...)można if(len(...)==5)&all(...)zapisać dwa bajty.
Jonathan Frech,