Um saco de pão preguiçoso


11

Eu trabalho em uma padaria que serve pão de trigo, centeio, cevada, grãos e francês, mas o padeiro é um pouco estranho - ele empilha os pães em ordem aleatória e, às vezes, deixa algumas prateleiras vazias no final.

Todos os dias, o mesmo cliente entra e pede um pedaço de pão, mas o mais complicado é que ele é um germofóbico; portanto, quando encho sua bolsa, não posso pegar pães de duas prateleiras adjacentes em seleções consecutivas.

Leva um segundo para caminhar entre as prateleiras adjacentes. É uma loja movimentada; para qualquer configuração aleatória de pães, eu gostaria de minimizar o tempo necessário para obter um de cada pão único. Eu posso começar e terminar em qualquer prateleira.

Se a ordem de hoje for W B W G F R W, um caminho possível é 0, 3, 5, 1, 4, por um total de 12 segundos:abs(3-0) + abs(5-3) + abs(1-5) + abs(4-1) = 12

( 1, 2, 3, 4, 5não funciona, porque o pão é colhido consecutivamente das prateleiras adjacentes.)

Se for B W B G B F B R B W B F, um caminho possível é 1, 3, 5, 7, 10, por um total de 9 segundos.

O gerente sempre se assegura de que haja uma solução possível, então não preciso me preocupar em capturar informações incorretas. Ele geralmente me envia o pedido em um arquivo, mas se eu quiser, posso digitá-lo em STDIN ou lê-lo de uma maneira diferente. Eu gostaria que o programa imprimisse os índices do melhor caminho, bem como seu tempo, de acordo com as regras de E / S padrão .

Em resumo:

  1. 5 tipos de pão.
  2. Os pedidos de pão aparecem como cadeias de ordem e comprimento aleatórios.
  3. É necessário selecionar um de cada pão exclusivo.
  4. Não é possível fazer seleções consecutivas adjacentes.
  5. Minimize a distância entre os índices de seleção.
  6. Não precisa se preocupar com entradas inválidas.
  7. Aplicam- se as regras de E / S padrão .

Isso é , a menor contagem de bytes vence.


0+3+5+1+4=13mas 1+3+5+7+10=26, não 9.
Shaggy

2
@LuisfelipeDejesusMunoz Não é bem assim, vários desses indeces consecutivos são adjacentes.
Nick Reed

4
Bem-vindo ao PPCG e bom primeiro desafio!
User202729

2
Não é importante para a tarefa real, mas estou curioso: por que ele ser um germófobo significa que você não pode pegar pães de duas prateleiras adjacentes em seleções consecutivas?
sundar - Restabelece Monica

1
Pode haver prateleiras vazias que não estejam nas extremidades? (por exemplo, é 'WBWG FRW'uma entrada válida também?
Jonathan Allan

Respostas:


3

JavaScript (ES6), 114 bytes

Guardado 1 byte graças a @Oliver

Recebe a entrada como uma matriz de caracteres. Gera uma sequência separada por vírgula, em que o primeiro valor é o tempo total e os próximos descrevem o caminho.

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

Experimente online!

Comentado

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 = [""]

0

Python 2 , 212 210 bytes

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*

Experimente online!

2 bytes thx para Jonathan Frech .


if len(...)==5and all(...)pode ser if(len(...)==5)&all(...)para salvar dois bytes.
Jonathan Frech
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.