Paradoxo da viagem no tempo


17

Um homem tem dois dispositivos.

  • Uma máquina do tempo - Ele pode controlar essa máquina pensando. Isso permite que ele viaje de qualquer ponto no tempo para outro ponto no passado ou no futuro (ou até mesmo no presente), em nenhum momento. Observe que se ele viaja para o passado de B para A, todos os eventos normais (máquinas do tempo, alternadores excluídos) de A para B devem se repetir exatamente da mesma maneira. Então, do ponto B, ele é levado de volta ao ponto A. Assim, uma única viagem no tempo cria um loop infinito.
  • Alternador - Percebendo esse problema, ele cria outra máquina. Ele percebe que, embora todos os eventos físicos sejam repetidos em um ciclo, seus pensamentos podem ser diferentes. Portanto, esta máquina foi projetada para ser controlável pelo pensamento também. A máquina pode ser usada a qualquer momento para fornecer um futuro alternativo (mas não passado) com relação ao tempo em que ele foi usado.

Exemplo

Vou explicar todos os detalhes usando um exemplo longo.

1000 T+250 250 T+0 500 T-200 100 T-50 125 A 225 T-400 500 A 100 T-200 150 T-25 100 T+100 50 A 25
  • 1000 anos se passam. É o ano 1000 agora.
  • Ele viaja de 1000 a 1250.
  • 250 anos se passam. Estamos no ano 1500 agora.
  • Ele viaja de 1500 a 1500. Isso não tem efeito (e pode ser ignorado).
  • 500 anos se passam. Agora é o ano de 2000
  • Ele viaja de 2000 a 1800.
  • 100 anos se passam. Estamos no ano de 1900 agora.
  • Ele viaja de 1900 a 1850.
  • 125 anos se passam: No entanto, desta vez, como ele está em um loop, as coisas são diferentes. 50 anos passam de 1850 a 1900. Ele volta a 1850. Outros 50 anos passam de 1850 a 1900. Ele volta novamente. 25 anos se passam e é 1875, completando 125 anos.
  • Ele usa o alternador. Agora existe um futuro alternativo para o ano de 1875, no qual ele está agora. O passado não mudou.
  • 225 anos se passam. Agora é o ano de 2100.
  • Ele viaja de 2100 a 1700.
  • 500 anos passam: 175 anos de 1700 a 1875 passam normalmente. Não, ele encontra o alternador novamente, o que significa que agora um terceiro futuro foi criado após 1875. 325 anos passam normalmente, tornando-se o ano 2200.
  • O uso de um alternador agora não tem efeito (e pode ser ignorado), pois existe apenas um futuro para 2200 que ainda não foi definido.
  • 100 anos se passam. Agora são 2300.
  • Ele viaja de 2300 a 2100.
  • Passagem de 150 anos: 100 anos de 2100 a 2200 passam normalmente. Um segundo futuro é criado a partir de 2200. Passam 50 anos e agora é o ano 2250.
  • Ele deveria ir de 2250 a 2225. No entanto, agora existem dois 2225 em dois cronogramas diferentes. Portanto, isso leva a um paradoxo, já que não podemos determinar em que ponto ele chegará. (Não vamos supor que ele vá para a linha do tempo mais recente). Portanto, isso encerra nossa simulação.
  • Qualquer coisa além disso 100 T+100 50 A 25é completamente ignorada desde que ocorreu um paradoxo e nossa simulação parou de funcionar.

Dica: Se você está lutando para entender o exemplo, imagine o tempo como um caminho que você está cavando na terra. Se você estiver viajando no tempo, está criando um teleportador. Se você estiver usando o alternador, estará cavando um novo caminho na parede de um caminho existente.

Paradoxo

Suponha que A, B e C tenham três pontos no tempo (um após o outro). Diz-se que ocorreu um paradoxo se:

  • você está no ponto C, existe um alternador no ponto B, existe mais de um futuro no ponto B (e você está em um deles) e tenta acessar qualquer ponto entre B e C através da viagem no tempo.
  • você está no ponto A, existe um alternador no ponto B, existe mais de um futuro no ponto B e tenta acessar um ponto C (depois de B) através da viagem no tempo.

Entrada

Uma série de eventos, semelhante ao exemplo. (O formato é flexível.)

Resultado

Um valor de verdade / falsey, indicando se um paradoxo ocorreu.

Desafio

O código mais curto (em bytes) vence.


como flexibleestá o format?
gato

@ GlennRanders-Pehrson Oh, entendi o que você quis dizer. Editado.
ghosts_in_the_code

2
@sysreq Qualquer pontuação adicional (espaço em branco, vírgulas, colchetes etc.) na entrada permitida. Qualquer caractere (s) permitido (s) diferenciar entre viagem no tempo e alternador. Qualquer caractere (s) permitido (s) a ser usado em vez de + e - (deslocamento para frente / trás). Os números podem estar em qualquer base (binária, decimal etc.). Os eventos serão inseridos apenas na mesma ordem. Nenhum número real do ano será fornecido, você deve assumir que o zero é zero (ou qualquer outro número inteiro) e descobrir os números reais do ano (se necessário).
ghosts_in_the_code

me ajudaria se houvesse vários pequenos exemplos em vez de um grande, mas ainda assim votei!
don brilhante

Respostas:


4

Ruby, 510 460 bytes

p=[0];w=[n=x=0]
i=gets.split.map{|s|
if x!=1
if s[0]=="A"
w<<n
else
if s[0..1]=="T+"
t=n
q=s[2..-1].to_i
if w[-1]==t||(w[-1]>t&&w[-1]<n+q)
w<<w[-1]
n+=q
else
n+=(t<p[-1]&&n+q>p[-1])?q%(p[-1]-n):q
end
elsif s[0..1]=="T-"
t=n
p<<n
n-=s[2..-1].to_i
x=(x==0&&w[-1]>0&&t>w[-1]&&n>w[-1])?1:0
else
t=n
q=s.to_i
if w[-1]==t||(w[-1]>t&&w[-1]<n+q)
w<<w[-1]
n+=q
else
n+=(t<p[-1]&&n+q>p[-1])?q%(p[-1]-n):q
end
end
end
else
break
end}
p x

Entrada

Como por exemplo

Resultado

0 = Sem Paradox, 1 = Paradox

Amostra

A entrada da amostra forneceu: 1000 T+250 250 T+0 500 T-200 100 T-50 125 A 225 T-400 500 A 100 T-200 150 T-25 100 T+100 50 A 25 retornos 1, indicando um paradoxo.

Notas

Este não é apenas o primeiro exercício de eu tento, mas também o primeiro programa de Ruby que escrevi. Portanto, provavelmente poderia ser ainda mais curto.

Breve explicação

p: Infinite loops
w: Alternate timelines
n: Now (regardless of timeline)
x: Paradox

Loops infinitos ocorrerão apenas ao avançar no tempo. Estou feliz por qualquer feedback - especialmente se estiver apontando uma maneira melhor de resolver isso.


Você pode fornecer alguns dados de entrada / saída de amostra?
Addison Crump

@VoteToClose - Além dos dados fornecidos na pergunta, posso criar mais dados de amostra, se necessário?
Pedro Abolins

Oh, caramba, eu perdi completamente a parte "Amostra". Eu sou um idiota. +1
Addison Crump

3
Todos os thens são desnecessários e podem ser removidos. Além disso, você deve usar em {...}vez de do...endsalvar mais caracteres. mapsalva um byte eache splitdivide-se em espaço em branco por padrão. As quatro primeiras linhas de inicialização podem ser reduzidas para p=[];w=[n=x=0].
Maçaneta

2
Eu sei que já faz 3,5 anos (lol ..), mas acho que você pode jogar seu código atual em 288 bytes (não tenho muita certeza, já que não conheço Ruby muito bem). No entanto, seu código atual não leva em consideração paradoxos com a viagem no tempo (o segundo marcador na descrição do OP).
Kevin Cruijssen 31/05/19

3

05AB1E , 93 92 86 82 bytes

ðU0V#vyAQiYˆðUëy.ïiYy+DX˜såàiXD€нY@Ïн©θ-®¥OÄ%®θY-YOVëVëYy¦+©¯@àXðʘà*i1q}XY®Ÿª{U®V

A entrada é no mesmo formato como na descrição do desafio, exceto que o alternador Aé abcdefghijklmnopqrstuvwxyzem vez de salvar um byte.
Saída 1se ocorreu um paradoxo, ou a própria entrada se não (somente1 é verdade em 05AB1E, todo o resto é falsey).

Vagamente baseado na minha resposta do Java 10 .

Experimente online.

Ou experimente on-line com linhas de depuração adicionadas ( TODO: Crie um conjunto de testes adequado com todos os casos de teste de uma só vez .. ):
- Caso de teste com paradoxo de retrocesso no tempo: Experimente on-line.
- Caso de teste com paradoxo de viagem no tempo: experimente online.
- Caso de teste sem paradoxo da viagem no tempo: experimente online.

Explicação:

ðU                         # Set variable `X` (time-travels) to a space character " "
0V                         # Set variable `Y` (current year) to 0
#                          # Split the (implicit) input by spaces
 v                         # And loop over each event `y`:
  yAQi                     #  If the current event `y` is an alternator ("abcdefghijklmnopqrstuvwxyz"):
      Yˆ                   #   Add the current year `Y` to alternators-list `GB`
      ðU                   #   And reset variable `X` to " "
  ëyi                    #  Else-if the current event `y` is an integer:
       Yy+                 #   Calculate the current year `Y` plus the integer `y`
          D                #   Duplicate `Y+y`
           X˜såài          #   If this `Y+y` is within any of the time-travel ranges:
                 X €н      #    Get the starting positions of each time-travel
                     Y@    #    Check for each starting position if the current year `Y` is >= it
                  D    Ï   #    And only leave the time-travel ranges for which this is truthy
                        н  #    Then pop and push the first one
                         © #    Store this time-travel range in variable `r` (without popping)
                 θ         #    Pop and only leave the time-travel destination
                  -        #    Subtract it from the `Y+y` we duplicated
                       %   #    And modulo it with:
                   ®¥OÄ    #     The absolute distance of the time-travel `r`
                 ®θ        #    Then push the time-travel destination again
                   Y-      #    And subtract the current year `Y`
                 YO        #    Then sum these two and the current year `Y` together
                   V       #    And pop and store it as new year `Y`
       ë                   #   Else (`Y+y` is not within any time-travel ranges)
        V                  #    Simply pop and store the duplicated `Y+y` as new year `Y`
  ë                        #  Else (the current event `y` is a time-travel)
    y¦                     #   Remove the leading "T"
   Y  +                    #   And add the value to the current year `Y`
       ©                   #   Store this value in variable `r`
        ¯@à                #   Check if any alternator in list `GB` is >= this value
           XðÊ˜à           #   Check if there are any time-travels
                *i  }      #   And if both are truhy:
                  1        #    Push a 1
                   q       #    Stop the program
                           #    (after which the top of the stack is output implicitly)
    Y®Ÿ                    #   Create a list in the range [current year `Y`, new year `r`]
   X   ª                   #   Append it to the time-travels `X`
        {                  #   And then sort these time-travels
         U                 #   After which we pop and store it as updated `X`
   ®V                      #   And then set `Y` to the new year `r`
                           # (if we haven't reached `q`, the (implicit) input is output instead)

3

Java 10, 498 485 478 bytes

import java.util.*;s->{var a=new Stack<Long>();var m=new TreeMap<Long,Long>();long p=0,c=0,t,v,k;o:for(var S:s.split(" "))if((t=S.charAt(0))>65){var b=S.charAt(1)>44;v=new Long(S.substring(2));for(var A:a)p=A>c+(b?-v:v)|m.size()<1?p:1;if(v>0)m.put(c,b?c-v:c+v);c+=b?-v:v;}else if(t>64){a.add(c);m.clear();}else{t=new Long(S);e:for(var e:m.entrySet())if((k=e.getKey())>=c){for(v=c;v<=c+t;)if(a.contains(v++))break e;c=(v=e.getValue())+(c+t-v)%(k-v);continue o;}c+=t;}return p>0;}

A entrada está (por enquanto) no mesmo formato que na descrição do desafio.

-13 bytes graças a @BenjaminUrquhart .
-7 bytes graças a @ceilingcat .

Experimente on-line ou on -line com linhas de depuração adicionadas .

Explicação:

import java.util.*;            // Required import for the List and TreeMap
s->{                           // Method with String parameter and boolean return-type
  var a=new Stack<Long>();     //  Create a List for the alternators
  var m=new TreeMap<Long,Long>();
                               //  Create a sorted Map for the time-travels
  long p=0,                    //  Paradox-flag, initially 0
       c=0,                    //  Current year, initially 0
       t,v,k;                  //  Temp-values, uninitialized
  o:for(var S:s.split(" "))    //  Loop over the input substrings split by space:
    if((t=S.charAt(0))>65){    //   If the first character is a 'T':
      var b=S.charAt(1)>44;    //    Check if the second character is a '-'
      v=new Long(S.substring(2));
                               //    Convert the String-value to a number
      for(long A:a)            //    Loop over the alternators
        p=A>                   //     If an alternator is larger than:
            c+                 //      The current year, plus
              (b?              //      If we travel backwards in time:
                 -v            //       Subtract the value
                :              //      Else (we travel forward in time):
                 v)            //       Add the value
          |m.size()<1?         //     Or if no previous time-travels occurred:
           p                   //      Leave the paradox-flag the same
          :                    //     Else:
           1;                  //      Set the paradox-flag to 1
      if(v>0)                  //     If the value is not 0 (edge-case for "T+0")
        m.put(c,b?c-v:c+v);    //      Add the from-to time-travel to the Map
      c+=b?-v:v;}              //     Increase/decrease the year accordingly
    else if(t>64){             //   Else-if the character is an 'A':
      a.add(c);                //    Add the current year to the alternators-list
      m.clear();}              //    And empty the time-travel Map
    else{                      //   Else (it's a number)
      t=new Long(S);           //    Convert the String to a number
      e:for(var e:m.entrySet())//    Loop over the time-travels:
        if((k=e.getKey())      //     If the time-travel starting point is
                         >=c){ //     larger than or equal to the current year
          for(v=c;v<=c+t;)     //      Loop from the current year to the year+number:
            if(a.contains(v++))//       If the alternator-list contains any of these years
              break e;         //        Stop the time-travel loop
          c=                   //      Set the current year to:
             (v=e.getValue())  //       The time-travel destination
             +                 //       Plus:
              (c+t             //        The current year plus the number
                  -v)          //        minus the time-travel destination
                     %(k-v);   //        Modulo the time-travel from-to distance
          continue o;}         //      And then continue the outer input-loop
      c+=t;}                   //    Increase the current year by the number 
  return p>0;}                 //  Return whether the paradox-flag is 1

Por que não usar Long?
Benjamin Urquhart

11
@BenjaminUrquhart Boa pergunta ... Inicialmente, minha Lista e Mapa foram digitados em bruto, então interam mais curtos, mas geravam erros nos pares de valores-chave de entrada de mapa. Não pensei em mudar tudo para Muito tempo depois .. Obrigado por -13!
Kevin Cruijssen 31/05/19
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.