时间旅行的悖论


17

一个人有两个装置。

  • 时间机器 -他可以通过思考来控制这台机器。它使他完全可以从过去或将来的任何时间点移动到另一个时间点(或什至现在的时间点)。请注意,如果他从B到A过去,那么从A到B的所有正常事件(时间机器,交流发电机除外)必须以完全相同的方式重复。然后从B点将他带回到A点。因此,单次行程会产生无限循环。
  • 交流发电机 -意识到这个问题,他创建了另一台机器。他注意到,即使所有物理事件都在循环中重复出现,他的想法也可能有所不同。因此,该机器的设计也可以通过思想来控制。可以随时使用机器来提供相对于他使用时间的替代未来(但不能是过去)。

我将通过一个冗长的示例来解释所有细节。

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年过去了。现在是1000年。
  • 他的旅行时间是1000到1250。
  • 250年过去了。现在是1500年。
  • 他从1500到1500旅行。这没有效果(可以忽略)。
  • 500年过去了。现在是2000年
  • 他从2000年到1800年旅行。
  • 100年过去了。现在是1900年。
  • 他从1900到1850年旅行。
  • 125年过去了:但是,这次,他处于一个循环中,情况有所不同。50年从1850年到1900年。他回溯到1850年。另外50年从1850年到1900年。他再次回溯。经过25年,现在是1875年,因此完成了125年。
  • 他使用交流发电机。现在存在着他现在所处的1875年的另一个未来。过去没有改变。
  • 225年过去了。现在是2100年。
  • 他从2100年旅行到1700年。
  • 500年过去:从1700年到1875年通常为175年。不,他不会再遇到交流发电机,这意味着现在已经在1875年之后创造了第三个未来。正常情况下,过去325年,所以是2200年。
  • 现在使用交流发电机无效(可以忽略),因为2200仅有一个尚未定义的未来。
  • 100年过去了。现在是2300。
  • 他从2300到2100旅行。
  • 150年通过:从2100到2200正常通过100年。从2200年开始创建第二个未来。过去50年,现在是2250年。
  • 他本应从2250年升至2225年。但是,现在在两个不同的时间轴中存在两个2225年。因此,这导致了一个悖论,因为我们无法确定他将到达哪个时间点。(我们不会假定他去了最近的时间轴)因此,这终止了我们的仿真。
  • 100 T+100 50 A 25由于发生了悖论并且我们的模拟已停止运行,因此任何其他事情都将被完全忽略。

暗示:如果您在努力理解示例,请想象时间就像您在大地上挖掘的道路一样。如果您正在旅行,则需要创建一个传送器。如果您使用的是交流发电机,则是在现有路径的墙壁上挖掘一条新路径。

悖论

假设A,B和C是三个时间点(一个接一个)。据说在以下情况下发生了悖论:

  • 您在C点,在B点存在一个交流发电机,在B点存在一个以上的未来(并且您在其中之一),并且您尝试通过时间旅行访问B和C之间的任何点。
  • 您在A点,在B点有一个交流发电机,在B点有一个以上的未来,并且您尝试通过时间旅行访问C点(在B之后)。

输入项

一系列事件,类似于示例。(格式灵活。)

输出量

真/假值,指示是否发生了悖论。

挑战

最短的代码(以字节为单位)获胜。


如何flexibleformat

@ GlennRanders-Pehrson哦,我明白你的意思了。编辑。
ghosts_in_the_code 2015年

2
@sysreq允许输入中包含任何其他标点符号(空格,逗号,方括号等)。允许区分时差和交流发电机的任何字符。允许使用任何字符代替+和-(向前/向后移动)。数字可以是任何基数(二进制,十进制等)。活动将仅以相同顺序输入。不会提供实际的年份数字,您必须假设start为零(或任何其他整数),然后自己计算实际的年份数字(如果需要)。
ghosts_in_the_code

如果有几个小例子而不是一个大例子,这将对我有帮助,但是我仍然投票赞成!
唐明亮

Answers:


4

红宝石,510个 460字节

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

输入项

按照例子

输出量

0 =无悖论,1 =悖论

样品

提供的样本输入: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 return 1,表明发生了悖论。

笔记

这不仅是我尝试的第一个练习,而且还是我编写的第一个Ruby程序。因此,它可能更短。

简要说明

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

无限循环只会在时间向前移动时发生。我很高兴收到任何反馈-特别是如果它指出了解决此问题的更好方法。


您可以提供一些示例输入/输出数据吗?
艾迪生·克伦普

@VoteToClose-除了问题中提供的数据之外,如有必要,我还可以创建更多示例数据?
彼得·阿波林斯

哦,天哪,我完全错过了“样本”部分。我是个白痴。+1
艾迪生·克兰普

3
所有thens都是不必要的,可以删除。另外,您应该使用{...}而不是do...end保存更多字符。map在上保存一个字节eachsplit默认情况下在空白处分割。初始化的前四行可以缩短为p=[];w=[n=x=0]
门把手

2
我知道已经有3.5年了(笑),但是我认为您可以将当前代码扩展到288个字节(不确定,因为我不太了解Ruby)。但是,您当前的代码无法解决正向旅行的矛盾(OP描述中的第二个要点)。
凯文·克鲁伊森

3

05AB1E93 92 86 82 字节

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

输入是在相同的格式,在挑战的描述,除了发电机Aabcdefghijklmnopqrstuvwxyz不是保存字节。如果发生悖论,则
输出;1否则,则输入自身(仅1在05AB1E中为真,其他均为假)。

松散地基于我的Java 10答案

在线尝试。

或添加调试线在线试用(TODO:建立适当的测试套件的所有测试用例一次..:)
与落后的时间旅行的悖论测试案例: - 在线试玩。
-具有向前时间旅行悖论的测试用例:在线尝试。
-没有时间旅行悖论的测试用例:在线尝试。

说明:

ð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字节

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

(目前)输入的格式与挑战说明中的格式相同。

-13个字节,感谢@BenjaminUrquhart
-7个字节,感谢@ceilingcat

在线尝试使用添加的debug-lines 在线尝试

说明:

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

为什么不使用Long
本杰明·厄克特

1
@BenjaminUrquhart很好的问题。最初,我的List和Map是原始类型的,所以int比较短,但是这给map-Entry键值对带来了错误。之后没有考虑将所有内容更改为Long ..谢谢-13!
凯文·克鲁伊森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.