Paradox der Zeitreise

17

Ein Mann hat zwei Geräte.

  • Eine Zeitmaschine - Er kann diese Maschine durch Denken steuern. Es ermöglicht ihm, in kürzester Zeit von einem beliebigen Zeitpunkt zu einem anderen Zeitpunkt in der Vergangenheit oder Zukunft (oder sogar zum gegenwärtigen Zeitpunkt) zu reisen. Beachten Sie, dass, wenn er von B nach A in die Vergangenheit reist, alle normalen Ereignisse (Zeitmaschinen, Generatoren ausgenommen) von A nach B auf genau die gleiche Weise wiederholt werden müssen. Dann wird er von Punkt B zu Punkt A zurückgebracht. Auf diese Weise erzeugt eine einzelne Zeitreise eine Endlosschleife.
  • Lichtmaschine - Als er dieses Problem erkennt, erstellt er eine weitere Maschine. Er bemerkt, dass seine Gedanken möglicherweise anders sind, obwohl sich alle physischen Ereignisse in einer Schleife wiederholen. Daher wurde diese Maschine so konstruiert, dass sie auch durch Gedanken gesteuert werden kann. Die Maschine kann jederzeit verwendet werden, um eine alternative Zukunft (aber nicht Vergangenheit) in Bezug auf die Zeit bereitzustellen, die er sie verwendet hat.

Beispiel

Ich werde alle Details anhand eines langen Beispiels erklären.

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 Jahre vergehen. Es ist jetzt das Jahr 1000.
  • Er reist von 1000 bis 1250.
  • 250 Jahre vergehen. Es ist jetzt das Jahr 1500.
  • Er reist von 1500 bis 1500. Dies hat keine Auswirkungen (und kann ignoriert werden).
  • 500 Jahre vergehen. Es ist jetzt Jahr 2000
  • Er reist von 2000 bis 1800.
  • 100 Jahre vergehen. Es ist jetzt das Jahr 1900.
  • Er reist von 1900 bis 1850.
  • 125 Jahre vergehen: Diesmal ist es jedoch anders, da er sich in einer Schleife befindet. 50 Jahre vergehen von 1850 bis 1900. Er kehrt bis 1850 zurück. Weitere 50 Jahre vergehen von 1850 bis 1900. Er kehrt wieder zurück. 25 Jahre vergehen und es ist 1875, womit 125 Jahre vollendet sind.
  • Er benutzt die Lichtmaschine. Jetzt gibt es eine alternative Zukunft für das Jahr 1875, in dem er sich jetzt befindet. Die Vergangenheit hat sich nicht geändert.
  • 225 Jahre vergehen. Es ist jetzt Jahr 2100.
  • Er reist von 2100 bis 1700.
  • 500 Jahre vergehen: 175 Jahre von 1700 bis 1875 vergehen normalerweise. Nein, er trifft wieder auf die Lichtmaschine, was bedeutet, dass nach 1875 eine dritte Zukunft geschaffen wurde. Normalerweise vergehen 325 Jahre, also 2200 Jahre.
  • Die Verwendung eines Generators hat jetzt keine Auswirkung (und kann ignoriert werden), da es nur eine Zukunft für 2200 gibt, die noch nicht definiert wurde.
  • 100 Jahre vergehen. Es ist jetzt 2300.
  • Er reist von 2300 bis 2100.
  • 150 Jahre vergehen: 100 Jahre von 2100 bis 2200 vergehen normalerweise. Eine zweite Zukunft entsteht ab 2200. 50 Jahre vergehen und es ist jetzt das Jahr 2250.
  • Er soll von 2250 bis 2225 gehen. Es gibt jedoch jetzt zwei 2225 in zwei verschiedenen Zeitlinien. Dies führt daher zu einem Paradoxon, da wir nicht bestimmen können, welchen Zeitpunkt er erreichen wird. (Wir gehen nicht davon aus, dass er zur aktuelleren Zeitachse wechselt.) Damit ist unsere Simulation beendet.
  • Alles weitere 100 T+100 50 A 25wird komplett ignoriert, da ein Paradoxon aufgetreten ist und unsere Simulation nicht mehr läuft.

Tipp: Wenn Sie Schwierigkeiten haben, das Beispiel zu verstehen, stellen Sie sich die Zeit wie einen Pfad vor, den Sie in der Erde graben. Wenn Sie auf Zeitreise sind, erstellen Sie einen Teleporter. Wenn Sie die Lichtmaschine verwenden, graben Sie einen neuen Pfad in die Wand eines vorhandenen Pfads.

Paradox

Angenommen, A, B und C sind drei Zeitpunkte (nacheinander). Ein Paradox soll vorgekommen sein, wenn:

  • Sie befinden sich an einem Punkt C, an einem Punkt B gibt es eine Lichtmaschine, es gibt mehr als eine Zukunft für Punkt B (und Sie befinden sich in einer davon), und Sie versuchen, über eine Zeitreise auf einen beliebigen Punkt zwischen B und C zuzugreifen.
  • Sie befinden sich an einem Punkt A, es gibt eine Lichtmaschine an einem Punkt B, es gibt mehr als eine Zukunft für Punkt B und Sie versuchen, über eine Zeitreise auf einen Punkt C (nach B) zuzugreifen.

Eingang

Eine Reihe von Ereignissen, ähnlich dem Beispiel. (Format ist flexibel.)

Ausgabe

Ein wahrer / falscher Wert, der angibt, ob ein Paradoxon aufgetreten ist.

Herausforderung

Kürzester Code (in Bytes) gewinnt.

ghosts_in_the_code
quelle
wie flexibleist das format?
Katze
@ GlennRanders-Pehrson Oh, ich habe verstanden, was du meintest. Bearbeitet
ghosts_in_the_code
2
@sysreq Zusätzliche Satzzeichen (Leerzeichen, Kommas, Klammern usw.) in Eingaben sind zulässig. Alle Zeichen, die zwischen Zeitreise und Lichtmaschine unterscheiden dürfen. Beliebige Zeichen, die anstelle von + und - verwendet werden dürfen (vorwärts / rückwärts). Zahlen können in einer beliebigen Basis sein (binär, dezimal usw.). Ereignisse werden nur in derselben Reihenfolge eingegeben. Es werden keine tatsächlichen Jahreszahlen angegeben. Sie müssen davon ausgehen, dass der Anfang Null ist (oder eine beliebige andere Ganzzahl), und die tatsächlichen Jahreszahlen selbst ermitteln (falls erforderlich).
ghosts_in_the_code
Es würde mir helfen, wenn es mehrere kleine Beispiele anstelle eines großen gäbe, aber ich habe trotzdem abgestimmt!
Don Bright

Antworten:

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

Eingang

Wie zum Beispiel

Ausgabe

0 = kein Paradoxon, 1 = Paradoxon

Stichprobe

Die bereitgestellte Beispieleingabe: gibt 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 zurück 1, was auf ein aufgetretenes Paradox hinweist.

Anmerkungen

Dies ist nicht nur die erste Übung, die ich versuche, sondern auch das erste Ruby-Programm, das ich geschrieben habe. Daher könnte es wahrscheinlich noch kürzer sein.

Kurze Erklärung

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

Endlosschleifen treten nur auf, wenn Sie rechtzeitig vorwärts fahren. Ich freue mich über jede Rückmeldung - insbesondere, wenn es um eine bessere Lösung geht.

Peter Abolins
quelle
Können Sie einige Beispiele für Ein- / Ausgabedaten bereitstellen?
Addison Crump
@VoteToClose - Neben den in der Frage angegebenen Daten kann ich bei Bedarf weitere Beispieldaten erstellen?
Peter Abolins
Oh Mann, ich habe diesen "Sample" Teil komplett verpasst. Ich bin ein Idiot. +1
Addison Crump
3
Alle thens sind unnötig und können entfernt werden. Außerdem sollten Sie verwenden {...}statt , do...endum mehr Zeichen zu speichern. mapSpeichert ein Byte eachund splitteilt es standardmäßig in Leerzeichen auf. Die ersten vier Zeilen der Initialisierung können auf gekürzt werden p=[];w=[n=x=0].
Türknauf
2
Ich weiß, es sind 3,5 Jahre vergangen (lol ..), aber ich denke, Sie können Ihren aktuellen Code auf 288 Bytes golfen (nicht ganz sicher, da ich Ruby nicht so gut kenne). Ihr aktueller Code berücksichtigt jedoch keine Paradoxien bei der Zeitreise in Vorwärtsrichtung (der zweite Aufzählungspunkt in der Beschreibung von 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

Die Eingabe erfolgt im gleichen Format wie in der Beschreibung Herausforderung, mit der Ausnahme , dass Lichtmaschine Aist abcdefghijklmnopqrstuvwxyzstattdessen ein Byte zu speichern.
Gibt aus, 1wenn ein Paradoxon aufgetreten ist, oder die Eingabe selbst, wenn nicht ( 1in 05AB1E ist nur wahr, alles andere ist falsch).

Basiert lose auf meiner Java 10-Antwort .

Probieren Sie es online aus.

Oder versuchen Sie es online mit hinzugefügten Debug-Zeilen ( TODO: Richtige Testsuite mit allen Testfällen auf einmal erstellen. ):
- Testfall mit Zeitreise-Paradoxon: Versuchen Sie es online.
- Testfall mit Zeitreise-Paradoxon: Probieren Sie es online aus.
- Testfall ohne Zeitreise-Paradoxon: Probieren Sie es online aus.

Erläuterung:

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

Die Eingabe erfolgt (vorerst) im gleichen Format wie in der Challenge-Beschreibung.

-13 Bytes dank @BenjaminUrquhart .
-7 Bytes dank @ceilingcat .

Probieren Sie es online aus oder probieren Sie es online mit hinzugefügten Debug-Zeilen .

Erläuterung:

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
quelle
Warum nicht benutzen Long?
Benjamin Urquhart
1
@BenjaminUrquhart Gute Frage .. Ursprünglich waren meine Liste und Karte roh geschrieben, daher intwar sie kürzer, aber das gab Fehler bei den Schlüsselwertpaaren für Karteneintrag. Ich habe nicht daran gedacht, alles danach auf Long zu ändern. Danke für -13!
Kevin Cruijssen