Paradoks podróży w czasie

17

Mężczyzna ma dwa urządzenia.

  • Wehikuł czasu - może kontrolować tę maszynę, myśląc. Pozwala mu na podróż z dowolnego miejsca w czasie do przeszłości lub przyszłości (a nawet teraźniejszości) w mgnieniu oka. Zauważ, że jeśli podróżuje do przeszłości z B do A, wówczas wszystkie normalne zdarzenia (z wyłączeniem wehikułów czasu, alternatorów) z A do B muszą powtarzać się dokładnie w ten sam sposób. Następnie z punktu B jest przenoszony z powrotem do punktu A. Zatem pojedyncza podróż w czasie tworzy nieskończoną pętlę.
  • Alternator - zdając sobie sprawę z tego problemu, tworzy kolejną maszynę. Zauważa, że ​​chociaż wszystkie zdarzenia fizyczne powtarzają się w pętli, jego myśli mogą być inne. Dlatego też ta maszyna została zaprojektowana tak, aby można ją było kontrolować również za pomocą myśli. Maszyny można użyć w dowolnym momencie, aby zapewnić alternatywną przyszłość (ale nie przeszłość) w odniesieniu do czasu, w którym z niej korzystał.

Przykład

Wyjaśnię wszystkie szczegóły na długim przykładzie.

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
  • Minęło 1000 lat. Teraz jest rok 1000.
  • Podróżuje od 1000 do 1250.
  • Minęło 250 lat. Teraz jest rok 1500.
  • Podróżuje od 1500 do 1500. Nie ma to żadnego efektu (i można go zignorować).
  • Minęło 500 lat. Jest teraz rok 2000
  • Podróżuje od 2000 do 1800.
  • Minęło 100 lat. Jest rok 1900.
  • Podróżuje od 1900 do 1850 roku.
  • Minęło 125 lat: tym razem jednak, gdy jest w pętli, sprawy wyglądają inaczej. Mija 50 lat od 1850 do 1900. Pętla wraca do 1850. Kolejne 50 lat mija od 1850 do 1900. Pętla znów. Minęło 25 lat i jest to rok 1875, co kończy 125 lat.
  • On używa alternatora. Teraz istnieje alternatywna przyszłość w stosunku do roku 1875, w którym się znajduje. Przeszłość się nie zmieniła.
  • Minęły 225 lat. Jest teraz rok 2100.
  • Podróżuje od 2100 do 1700.
  • Minęło 500 lat: 175 lat od 1700 do 1875 minęło normalnie. Nie, on ponownie napotyka alternator, co oznacza, że po 1875 r. Powstała 3. przyszłość. 325 lat mija normalnie, co daje rok 2200.
  • Korzystanie z alternatora nie ma teraz efektu (i można go zignorować), ponieważ istnieje tylko jedna przyszłość do 2200, która nie została jeszcze zdefiniowana.
  • Minęło 100 lat. Teraz jest 2300.
  • Podróżuje od 2300 do 2100.
  • Minęło 150 lat: 100 lat od 2100 do 2200 minęło normalnie. Druga przyszłość powstaje z 2200 roku. Mija 50 lat, a teraz jest rok 2250.
  • Powinien przejść od 2250 do 2225. Jednak obecnie istnieją dwa 2225 w dwóch różnych ramach czasowych. Stąd prowadzi to do paradoksu, ponieważ nie jesteśmy w stanie ustalić, w którym momencie on osiągnie. (Nie zakładamy, że idzie do najnowszej osi czasu). To kończy naszą symulację.
  • Wszystko inne 100 T+100 50 A 25jest całkowicie ignorowane od czasu wystąpienia paradoksu, a nasza symulacja przestała działać.

Wskazówka: Jeśli próbujesz zrozumieć przykład, wyobraź sobie, że czas jest jak ścieżka, którą kopiesz w ziemi. Jeśli podróżujesz w czasie, tworzysz teleporter. Jeśli używasz alternatora, kopiesz nową ścieżkę w ścianie istniejącej ścieżki.

Paradoks

Załóżmy, że A, B i C to trzy punkty w czasie (jeden po drugim). Mówi się, że miał miejsce paradoks:

  • jesteś w punkcie C, w punkcie B istnieje alternator, istnieje więcej niż jedna przyszłość do punktu B (i jesteś w jednym z nich), i próbujesz uzyskać dostęp do dowolnego punktu między B i C podczas podróży w czasie.
  • jesteś w punkcie A, w punkcie B istnieje alternator, istnieje więcej niż jedna przyszłość do punktu B, i próbujesz dostać się do punktu C (po B) poprzez podróż w czasie.

Wejście

Seria wydarzeń, podobnych do przykładu. (Format jest elastyczny.)

Wynik

Wartość true / falsey, wskazująca, czy wystąpił paradoks.

Wyzwanie

Najkrótszy kod (w bajtach) wygrywa.

ghosts_in_the_code
źródło
jak flexiblejest format?
kot
@ GlennRanders-Pehrson Oh, rozumiem co miałeś na myśli. Edytowane.
ghosts_in_the_code
2
@sysreq Wszelkie dodatkowe znaki interpunkcyjne (białe znaki, przecinki, nawiasy itp.) w danych wejściowych są dozwolone. Każda postać (postaci), która może rozróżnić podróż w czasie od alternatora. Dowolny znak (i) może być używany zamiast + i - (podróż do przodu / do tyłu). Liczby mogą być dowolne (binarne, dziesiętne itp.). Wydarzenia będą wprowadzane tylko w tej samej kolejności. Nie zostaną podane żadne rzeczywiste numery roku, należy założyć, że wartość początkowa wynosi zero (lub dowolna inna liczba całkowita) i samodzielnie ustalić rzeczywiste numery lat (jeśli trzeba).
ghosts_in_the_code
pomogłoby mi, gdyby istniało kilka małych przykładów zamiast jednego dużego, ale nadal głosowałem!
don bright

Odpowiedzi:

4

Rubinowy, 510 460 bajtów

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

Wejście

Jak na przykład

Wynik

0 = brak paradoksu, 1 = paradoks

Próba

Podane przykładowe dane wejściowe: 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 zwraca 1, wskazując na wystąpienie paradoksu.

Notatki

Jest to nie tylko pierwsze ćwiczenie które próbuję, ale także pierwszy napisany mnie program Ruby. Dlatego prawdopodobnie może być nawet krótszy.

Krótkie wyjaśnienie

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

Nieskończone pętle pojawią się tylko podczas podróży do przodu w czasie. Cieszę się z wszelkich informacji zwrotnych - szczególnie jeśli wskazuje to lepszy sposób na rozwiązanie tego problemu.

Peter Abolins
źródło
Czy możesz podać przykładowe dane wejściowe / wyjściowe?
Addison Crump
@VoteToClose - Oprócz danych podanych w pytaniu mogę w razie potrzeby utworzyć więcej przykładowych danych?
Peter Abolins,
O rany, całkowicie przegapiłem tę część „Próbki”. Jestem idiotą. +1
Addison Crump
3
Wszystkie thensą niepotrzebne i można je usunąć. Ponadto powinieneś użyć {...}zamiast, do...endaby zapisać więcej znaków. mapzapisuje bajt ponad eachi splitdomyślnie dzieli się na białe znaki. Pierwsze cztery linie inicjalizacji można skrócić p=[];w=[n=x=0].
Klamka
2
Wiem, że minęło 3,5 roku (lol ..), ale myślę, że możesz zagrać w swój obecny kod do 288 bajtów (nie do końca pewny, ponieważ nie znam zbyt dobrze Ruby). Jednak twój obecny kod nie uwzględnia paradoksów związanych z podróżowaniem w czasie do przodu (drugi punkt w opisie OP).
Kevin Cruijssen
3

05AB1E , 93 92 86 82 bajtów

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

Wejście jest w takim samym formacie jak w opisie wyzwanie, oprócz tego, że alternator Ajest abcdefghijklmnopqrstuvwxyzzamiast zapisać bajt.
Wyprowadza, 1jeśli wystąpił paradoks, lub samo wejście, jeśli nie ( 1jest prawdą tylko w 05AB1E, wszystko inne jest falsey).

Luźno oparty na mojej odpowiedzi Java 10 .

Wypróbuj online.

Lub wypróbuj online z dodanymi liniami debugowania ( TODO: Utwórz odpowiedni zestaw testów ze wszystkimi przypadkami testowymi jednocześnie .. ):
- Przypadek testowy z paradoksem wstecznej podróży w czasie: Wypróbuj online.
- Przypadek testowy z paradoksem podróży w czasie do przodu: Wypróbuj online.
- Przypadek testowy bez paradoksu podróży w czasie: Wypróbuj online.

Wyjaśnienie:

ð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
źródło
3

Java 10, 498 485 478 bajtów

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;}

Dane wejściowe są (na razie) w tym samym formacie, co w opisie wyzwania.

-13 bajtów dzięki @BenjaminUrquhart .
-7 bajtów dzięki @ceilingcat .

Wypróbuj online lub wypróbuj online z dodanymi liniami debugowania .

Wyjaśnienie:

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
źródło
Dlaczego nie użyć Long?
Benjamin Urquhart,
1
@BenjaminUrquhart Dobre pytanie .. Początkowo moja lista i mapa były napisane na surowo, więc intbyły krótsze, ale to dawało błędy w parach klucz-wartość-mapa-wpis. Nie myślałem o zmianie wszystkiego na Długo potem. Dzięki za -13!
Kevin Cruijssen