Paradoja del viaje en el tiempo

17

Un hombre tiene dos dispositivos.

  • Una máquina del tiempo : puede controlar esta máquina pensando. Le permite viajar desde cualquier punto en el tiempo a otro punto en el pasado o en el futuro (o incluso en el presente) en muy poco tiempo. Tenga en cuenta que si viaja al pasado de B a A, entonces todos los eventos normales (máquinas del tiempo, alternadores excluidos) de A a B deben repetirse exactamente de la misma manera. Luego, desde el punto B, vuelve al punto A. Por lo tanto, un solo viaje en el tiempo crea un bucle infinito.
  • Alternador : al darse cuenta de este problema, crea otra máquina. Se da cuenta de que, aunque todos los eventos físicos se repiten en un bucle, sus pensamientos pueden ser diferentes. Por lo tanto, esta máquina también fue diseñada para ser controlable por pensamiento. La máquina se puede usar en cualquier momento para proporcionar un futuro alternativo (pero no pasado) con respecto al tiempo que la usó.

Ejemplo

Explicaré todos los detalles con un extenso ejemplo.

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
  • Pasan 1000 años. Es el año 1000 ahora.
  • Viaja de 1000 a 1250.
  • Pasan 250 años. Es el año 1500 ahora.
  • Viaja de 1500 a 1500. Esto no tiene ningún efecto (y puede ser ignorado).
  • Pasan 500 años. Ahora es el año 2000
  • Viaja de 2000 a 1800.
  • Pasan 100 años. Es el año 1900 ahora.
  • Viaja de 1900 a 1850.
  • Pasan 125 años: sin embargo, esta vez, como él está en un bucle, las cosas son diferentes. Pasan 50 años desde 1850 hasta 1900. Vuelve en bucle hasta 1850. Pasan otros 50 años desde 1850 hasta 1900. Vuelve en bucle nuevamente. Pasan 25 años y es 1875, completando así 125 años.
  • Él usa el alternador. Ahora existe un futuro alternativo para el año 1875, en el que se encuentra ahora. El pasado no ha cambiado.
  • Pasan 225 años. Ahora es el año 2100.
  • Viaja de 2100 a 1700.
  • Pase de 500 años: 175 años de 1700 a 1875 pasan normalmente. No, vuelve a encontrarse con el alternador, lo que significa que ahora se ha creado un tercer futuro después de 1875. 325 años pasan normalmente, por lo que es el año 2200.
  • El uso de un alternador ahora no tiene ningún efecto (y puede ignorarse) ya que solo existe un futuro para 2200 que aún no se ha definido.
  • Pasan 100 años. Ahora es 2300.
  • Viaja de 2300 a 2100.
  • Pase de 150 años: 100 años de 2100 a 2200 pasan normalmente. A partir de 2200 se crea un segundo futuro. Pasan 50 años y ahora es el año 2250.
  • Se supone que debe ir de 2250 a 2225. Sin embargo, ahora existen dos 2225 en dos líneas de tiempo diferentes. Por lo tanto, esto lleva a una paradoja, ya que no podemos determinar a qué punto en el tiempo llegará. (No asumiremos que va a la línea de tiempo más reciente) Por lo tanto, esto termina nuestra simulación.
  • Todo lo demás 100 T+100 50 A 25se ignora por completo ya que ha ocurrido una paradoja y nuestra simulación ha dejado de funcionar.

Sugerencia: si te cuesta entender el ejemplo, imagina que el tiempo es como un camino que estás cavando en la tierra. Si viaja en el tiempo, está creando un teletransportador. Si está utilizando el alternador, está cavando una nueva ruta en la pared de una ruta existente.

Paradoja

Suponga que A, B y C son tres puntos en el tiempo (uno tras otro). Se dice que ocurrió una paradoja si:

  • estás en un punto C, existe un alternador en un punto B, existe más de un futuro para el punto B (y estás en uno de ellos) e intentas acceder a cualquier punto entre B y C a través del viaje en el tiempo.
  • usted está en un punto A, existe un alternador en un punto B, existe más de un futuro para el punto B e intenta acceder a un punto C (después de B) a través del viaje en el tiempo.

Entrada

Una serie de eventos, similar al ejemplo. (El formato es flexible).

Salida

Un valor verdadero / falso, que indica si se ha producido una paradoja.

Desafío

El código más corto (en bytes) gana.

fantasmas_en_el_código
fuente
cómo flexiblees el format?
gato
@ GlennRanders-Pehrson Oh, entendí lo que querías decir. Editado
ghosts_in_the_code
2
@sysreq Se permite cualquier puntuación adicional (espacios en blanco, comas, corchetes, etc.) en la entrada. Cualquier personaje (s) permitido diferenciar entre viaje en el tiempo y alternador. Cualquier caracter (es) permitido (s) para ser utilizado en lugar de + y - (avance / retroceso). Los números pueden estar en cualquier base (binario, decimal, etc.). Los eventos se ingresarán solo en el mismo orden. No se proporcionarán números de año reales, debe asumir que comienza a ser cero (o cualquier otro número entero) y calcular los números de año reales usted mismo (si es necesario).
ghosts_in_the_code
Me ayudaría si hubiera varios ejemplos pequeños en lugar de uno grande, ¡pero aún así voté!
Don brillante

Respuestas:

4

Rubí, 510460 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 ejemplo

Salida

0 = sin paradoja, 1 = paradoja

Muestra

La entrada de muestra proporcionada: 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 retorna 1, indicando que ocurrió una paradoja.

Notas

Este no es solo el primer ejercicio de que intento, sino que también es el primer programa de Ruby que he escrito. Por lo tanto, probablemente podría ser aún más corto.

Breve explicacion

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

Los bucles infinitos solo ocurrirán mientras se viaja hacia adelante en el tiempo. Me alegra cualquier comentario, especialmente si señala una mejor manera de resolver esto.

Peter Abolins
fuente
¿Puede proporcionar algunos datos de entrada / salida de muestra?
Addison Crump
@VoteToClose: además de los datos proporcionados en la pregunta, ¿puedo crear más datos de muestra, si es necesario?
Peter Abolins
Oh, Dios mío, me perdí esa parte de "Muestra" por completo. Soy un idiota. +1
Addison Crump
3
Todos los thens son innecesarios y se pueden eliminar. Además, debe usar en {...}lugar de do...endguardar más caracteres. mapguarda un byte eachy se splitdivide en espacios en blanco de forma predeterminada. Las primeras cuatro líneas de inicialización pueden acortarse a p=[];w=[n=x=0].
Pomo de la puerta
2
Sé que han pasado 3,5 años (risas ...), pero creo que puedes jugar golf con tu código actual a 288 bytes (no del todo seguro, ya que no conozco demasiado bien a Ruby). Sin embargo, su código actual no tiene en cuenta las paradojas con el viaje en el tiempo hacia adelante (el segundo punto en la descripción de OP).
Kevin Cruijssen
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

La entrada está en el mismo formato que en la descripción del desafío, excepto que el alternador Aes abcdefghijklmnopqrstuvwxyzpara guardar un byte.
Salidas 1si ocurrió una paradoja, o la entrada en sí si no (solo 1es verdad en 05AB1E, todo lo demás es falsey).

Basada en mi respuesta de Java 10 .

Pruébalo en línea.

O pruébelo en línea con líneas de depuración agregadas ( TODO: Cree un conjunto de pruebas adecuado con todos los casos de prueba a la vez ... ):
- Caso de prueba con paradoja de viaje en el tiempo hacia atrás: Pruébelo en línea.
- Caso de prueba con paradoja de viaje en el tiempo hacia adelante: Pruébelo en línea.
- Caso de prueba sin paradoja de viaje en el tiempo: Pruébelo en línea.

Explicación:

ð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)
Kevin Cruijssen
fuente
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;}

La entrada está (por ahora) en el mismo formato que en la descripción del desafío.

-13 bytes gracias a @BenjaminUrquhart .
-7 bytes gracias a @ceilingcat .

Pruébelo en línea o pruébelo en línea con líneas de depuración adicionales .

Explicación:

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
Kevin Cruijssen
fuente
¿Por qué no usar Long?
Benjamin Urquhart
1
@BenjaminUrquhart Buena pregunta ... Inicialmente, mi Lista y Mapa estaban en bruto, por lo que intera más corto, pero eso dio errores con los pares de valores-clave de entrada de mapa. No pensé en cambiar todo a mucho después de eso ... ¡Gracias por -13!
Kevin Cruijssen