Determinar se um carro pode percorrer uma rota com uma quantidade limitada de gasolina

8

Usando qualquer linguagem de programação que suporte funções, tenha a função

is_enough(strArr) 

aquela tomada strArrque será uma matriz composta pelos seguintes elementos:

  • N qual será o número de postos de gasolina em uma rota circular
  • e cada elemento subsequente será a string g:cem que
    • g é a quantidade de gás em galões naquele posto de gasolina e
    • c será a quantidade de galões de gás necessária para chegar ao seguinte posto de gasolina.

Por exemplo, strArrpode ser:

["4","3:1","2:2","1:2","0:1"]. 

Seu objetivo é retornar o índice do posto de gasolina inicial que permitirá que você viaje ao longo de todo o percurso uma vez; caso contrário, retorne a string "impossível" .

Para o exemplo acima, existem 4 postos de gasolina e seu programa deve retornar a string "1" porque:

  • Começando na estação 1, você recebe 3 galões de gasolina e gasta 1 na próxima estação.

  • Então você tem 2 galões + mais 2 na próxima estação e você gasta 2 para ter 2 galões quando chegar à 3ª estação.

  • Você tem 3, mas gasta 2 chegando à estação final,

  • Na estação final, você recebe 0 galões e gasta seu galão final chegando ao ponto de partida.

Começar em qualquer outro posto de gasolina tornaria impossível a locomoção da rota, então a resposta é "1" .

Se houver vários postos de gasolina em que é possível iniciar, retorne o menor índice (do posto de gasolina). Nserá >= 2.

Resultados corretos da amostra:

Input: ["4","1:1","2:2","1:2","0:1"]
Output: "impossible"

Input: ["4","0:1","2:2","1:2","3:1"]
Output: "4"

O vencedor será aquele que usar o código mais curto, embora seja longo.

Vamos lá
fonte
1
Qual é o critério objetivo de ganhar? Estou votando para fechar porque não há como dizer quem é o vencedor.
Maçaneta da porta
Basta colocar uma etiqueta de código de golfe e tudo ficará bem.
Daniero
3
A votação para fechar apenas por falta de uma etiqueta é um pouco draconiana, você não diria? Basta adicionar a tag.
Timwi
Sempre existem N+1elementos precisos strArr? Isso seria Nredundante caso a linguagem já forneça uma maneira de obter o comprimento da matriz, certo? (ainda seria útil para, por exemplo, C).
FireFly
2
Duas das respostas estão interpretando a especificação como exigindo o nome is_enough(9 caracteres); três estão usando um nome de caractere único e um não nomeia a função. Você poderia esclarecer o que é permitido?
Peter Taylor

Respostas:

1

APL (70)

{×⍴G←Z/⍨0∧.≤¨+\¨¯1⌽⌽∘K¨Z←⍳⍴K←{⎕ML←3⋄-/⍎¨⍵⊂⍨⍵≠':'}¨1↓⍵:⊃G⋄'impossible'}

Explicação:

  • 1↓⍵: solte o primeiro elemento (comprimento), não precisamos dele
  • {... : para cada posto de gasolina ...
    • ⎕ML←3: definido ⎕MLcomo 3 na função interna (altera o comportamento de )
    • ⍵⊂⍨⍵≠':': divida a string em :
    • ⍎¨: avalie cada parte
    • -/: subtrair o segundo número do primeiro (fornecendo efeito líquido para cada posto de gasolina)
  • K←: armazene-os em K
  • Z←⍳⍴K: obtenha os índices para o posto de gasolina ( 1comprimento deK ), armazene emZ
  • ⌽∘K¨Z: gire Kpor cada valor de Z, fornecendo uma matriz de matrizes
  • ¯1⌽: gire esse array para a esquerda por 1 (para colocar o inalterado primeiro em vez de por último)
  • +\¨: faça uma soma em execução para cada matriz interna
  • 0∧.≤¨: para cada soma em execução, veja se há valores negativos
  • Z/⍨: selecione Zaqueles elementos para os quais a soma em execução não tinha valores negativos
  • ×⍴G←: armazenar em G. Se Gpossui algum elemento:
  • :⊃G: retorna o primeiro elemento de G.
  • ⋄'impossible': caso contrário, retorne impossible.
marinus
fonte
1

Bash 178 170 161 157

Um pouco direto.

is_enough(){((t=(n=$1-1)<0))&&echo impossible||(x=(n ${@:3} $2);for z in ${@:2};do(((t+=${z%:*}-${z#*:})<0))&&is_enough ${x[*]}&&return;done;echo $[$#-++n])}

Espaçados:

is_enough() {
     ((t=(n=$1-1)<0)) && echo impossible || (
         x=(n ${@:3} $2);
         for z in ${@:2};do
             (((t+=${z%:*}-${z#*:})<0)) && is_enough ${x[*]} && return;
         done;
         echo $[$#-++n]
     )
}
Runium
fonte
1

Ruby, 111

Aqui está uma solução Ruby usando eval:

is_enough=->a{_,*s=a
"#{(1..s.size).find{|i|g=0;s.rotate(i-1).all?{|x|g+=eval x.tr ?:,?-;g>=0}}||:impossible}"}

Exemplo de uso:

is_enough[%w(4 3:1 2:2 1:2 0:1)] #=> "1"
is_enough[%w(4 1:1 2:2 1:2 0:1)] #=> "impossible"
is_enough[%w(4 0:1 2:2 1:2 3:1)] #=> "4"
is_enough[%w(4 1:2 2:1 4:3 0:1)] #=> "2"
is_enough[%w(4 0:1 2:2 1:2 3:1)] #=> "4"
is_enough[%w(4 0:1 0:1 4:1 0:1)] #=> "3"
is_enough[%w(8 0:1 0:1 4:1 0:1 2:1 3:1 0:0 0:1)] #=> "3"

EDIT : Nome da função e tipo de retorno corrigidos.

Paul Prestidge
fonte
0

Ruby 132

g=->a{n,*a=a.map{|e|e.split(?:).map &:to_i}
(r=(0...n[0]).find{|i|a.rotate(i).inject(0){|m,(j,k)|m&&m>=0&&m+j-k}})?r+1:"impossible"}

Teste:

irb(main):003:0> g[["4","1:1","2:2","1:2","0:1"]]
=> "impossible"
irb(main):004:0> g[["4","0:1","2:2","1:2","3:1"]]
=> 4
daniero
fonte
Spec requer que uma string seja retornada em todos os casos.
precisa saber é o seguinte
@ Boothby Não consigo encontrar esse requisito em nenhum lugar da especificação. Você pode citar?
John Dvorak
1
Para o exemplo acima, existem 4 postos de gasolina e seu programa deve retornar a string "1" porque:
boothby
Ah, que se dane; Solução de Chron é muito mais curto de qualquer maneira: D
daniero
0

Python, 131

Acho essa frase bastante satisfatória.

E=lambda s:([`i`for i in range(1,len(s)+1)if reduce(lambda r,t:r+eval(t[0]+'-'+t[-1])*(r>=0),s[i:]+s[1:i],0)>=0]+['impossible'])[0]
boothby
fonte
o que tem reduce()aqui? Estou recebendo um erroNameError: name 'reduce' is not defined
Er Harsh Rathore
@ErHarshRathore esse é o Python 2. No Python 3, reduceainda está na biblioteca padrão, mas foi movido para o functoolsmódulo.
alkasm
sim! Eu consegui from functools import reducegraças
Er Harsh Rathore
@ErHarshRathore Além disso, os acentos graves `i`aqui é equivalente a str(i)em Python 3.
alkasm
Você acha que este post deve ser atualizado agora para o python 3.x?
Er Harsh Rathore
0

GolfScript (72 caracteres)

{(~\{':'/{~}/-}%[\),1>{;.{1$-1>*+}*-1>\(+\},~"impossible"]1=}:is_enough;

Demonstração online

Isso executa a abordagem óbvia da força bruta. O bit IMO mais interessante é a determinação de se as somas parciais de uma matriz de combustível delta caem abaixo de 0:

{1$-1>*+}*-1>

Isso economiza 1 caractere sobre o mais óbvio

[{1$+}*]{0<},!

Se a saída fosse indexada em 0 e não em 1, seria preferível uma abordagem alternativa para girar a matriz:

{(;{':'/{~}/-}%:A[,,{A\{(+}*{1$-1>*+}*-1>},~"impossible"]0=}:is_enough;

Mas essa abordagem não é facilmente adotada para indexação em 1:

{(;{':'/{~}/-}%:A[,),1>{A\({(+}*{1$-1>*+}*-1>},~"impossible"]0=}:is_enough;

ou

{(;{':'/{~}/-}%:A[,,{A\{(+}*{1$-1>*+}*-1>},{)}%~"impossible"]0=}:is_enough;
Peter Taylor
fonte