# Through Space and Time

## Introduction:

In general we usually speak of four dimensions: three space dimensions for x, y, and z; and one time dimension. For the sake of this challenge however, we'll split the time dimension into three as well: past, present, and future.

## Input:

Two input-lists. One containing integer x,y,z coordinates, and one containing integer years.

## Output:

One of any four distinct and constant outputs of your own choice. One to indicate the output space; one to indicate the output time; one to indicate the output both space and time; and one to indicate the output neither space nor time.

We'll indicate we went to all three space dimensions if the differences of the integer-tuples is not 0 for all three dimensions.
We'll indicate we went to all three time dimensions if there is at least one year in the past, at least one year in the future, and at least one year equal to the current year (so in the present).

## Example:

Input:
Coordinates-list: [{5,7,2}, {5,3,8}, {-6,3,8}, {5,7,2}]
Year-list: [2039, 2019, 2018, 2039, 2222]

Output:
Constant for space

Why?
The x coordinates are [5,5,-6,5]. Since they are not all the same, we've went through the x space dimension.
The y coordinates are [7,3,3,7]. Since they are not all the same, we've also went through the y space dimension.
The z coordinates are [2,8,8,2]. Since they are not all the same, we've also went through the z space dimension.
The current year is 2018. There are no years before this, so we did not visit the past time dimension.
There is a 2018 present in the year-list, so we did visit the present time dimension.
There are multiple years above 2018 ([2039, 2019, 2039, 2222]), so we also visited the future time dimension.

Since we've visited all three space dimensions, but only two of the three time dimensions, the output will only be (the constant for) space.

## Challenge rules:

• You can use any four distinct and constant outputs for the four possible states.
• Input can be in any reasonable format. Coordinates list can be tuples, inner lists/arrays of size 3, strings, objects, etc. List of years may be a list of date-objects instead of integers as well if it would benefit your byte-count.
• You can assume the x,y,z coordinates will be integers, so no need to handle floating point decimals. Any of the x, y, and/or z coordinates can be negative values, though.
• You cannot take the input-lists pre-ordered. The input-lists should be in the order displayed in the test cases.
• You can assume all year values will be in the range [0,9999]; and you can assume all coordinates are in the range [-9999,9999].
• If your language doesn't have ANY way to retrieve the current year, but you'd still like to do this challenge, you may take it as additional input and mark your answer as (non-competing).

## General rules:

• This is , so shortest answer in bytes wins.
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
• Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
• Default Loopholes are forbidden.

## Test cases:

Coordinates-input: [{5,7,2}, {5,3,8}, {-6,3,8}, {5,7,2}]
Years-input:       [2039, 2019, 2018, 2039, 2222]
Output:            space

Coordinates-input: [{0,0,0}, {-4,-4,0}, {-4,2,0}]
Years-input:       [2016, 2019, 2018, 2000]
Output:            time

Coordinates-input: [{-2,-2,-2}, {-3,-3,-3}]
Years-input:       [2020, 1991, 2014, 2018]
Output:            both

Coordinates-input: [{5,4,2}, {3,4,0}, {1,4,2}, {9,4,4}]
Years-input:       [2020, 1991, 2014, 2017, 2019, 1850]
Output:            neither

• What range of years do we need to be able to handle? Nov 9, 2018 at 12:51
• @Shaggy I will add it to the challenge description. [0,9999] is fine (and [-9999,9999] for the coordinates is fine as well. Nov 9, 2018 at 12:52
• Dang, there goes one of my ideas! Nov 9, 2018 at 12:57
• @Shaggy Out of curiosity, what range were you hoping for? Nov 9, 2018 at 13:09
• May we take the current year as input? (Some languages cannot get the current year e.g.BF, others can only do so by evaluating code in another language - e.g. Jelly; others, maybe many, will find this golfier too) Nov 9, 2018 at 13:30

# Python 2, 111 109 bytes

lambda S,T:(min(map(len,map(set,zip(*S))))>1,date.today().year in sorted(set(T))[1:-1])
from datetime import*


Try it online!

• Why do you make T a set before sorting? Nov 9, 2018 at 13:14
• @BlackOwlKai Otherwise the two entries removed by [1:-1] may not be in the past / future Nov 9, 2018 at 16:04

# Perl 6, 47 46 bytes

-1 byte thanks to nwellnhof

{Set(@^b X<=>Date.today.year)>2,max [Z==] @^a}


Try it online!

Anonymous code block that takes two lists and returns a tuple of booleans, with the first element being whether you traveled in time, and the second being whether you didn't traveled in space.

### Explanation

{                                            }  # Anonymous code block
@^b X         # Map each element of the year list to:
<=>      # Whether it is smaller, equal or larger than
Date.today.year  # The current year
Set(                       )    # Get the unique values
>2  # Is the length larger than 2?
,
[Z  ] @^a   # Reduce by zipping the lists together
max       # And return if any of them are
==  # All equal


# Japt, 22 bytes

Takes input as a 2D-array of integers for the space dimensions and a 1D-array of integers for the years. Outputs 2 for space only, 1 for time only, 3 for both and 0 for neither.

yâ mÊeÉ Ñ+!Jõ kVmgKi¹Ê


Try it

                           :Implicit input of 2D-array U=space and array V=time
y                          :Transpose U
â                         :Deduplicate columns
m                       :Map
Ê                      :  Lengths
e                     :All truthy (not 0) when
É                    :  1 is subtracted
Ñ                  :Multiply by 2
J               :-1
õ              :Range [-1,1]
k            :Remove all the elements present in
Vm          :  Map V
g         :    Signs of difference with
Ki       :    The current year
¹      :End removal
Ê     :Length
+!                :Negate and add first result


# 05AB1E, 15 bytes

Output is a list [space, time] where 1 stands for x and 0 stands for no x

ø€Ë_Psžg.SÙg3Q)


Try it online!

Explanation

    ø                 # zip space coordinates
€Ë               # for each axis, check that all values are equal
_              # logical negation
P             # product (1 for space, 0 for no space)
s            # put the time list on top of the stack
žg.S        # compare each with the current year
Ù       # remove duplicates
g3Q    # check if the length is 3
)   # wrap the space and time values in a list

• Obvious +1 from me. The same as the 16-byter I prepared, except that I used -.± instead of .S (hence the +1 byte..) and ‚ (pair) instead of ) Nov 9, 2018 at 13:38
• @KevinCruijssen: I really want another way to do Ùg3Q, which feels like the largest byte-thief, but I'm not sure it's possible :/ Nov 9, 2018 at 13:42
• I doubt it can be done shorter tbh. I can think of a few 4-byte alternatives, and been trying to do something with ê and some bitwise operation or deltas or something, but I'm unable to find any 3-byte alternatives. Nov 9, 2018 at 14:08

# Japt, 25 bytes

I'm 100% sure this is not the best approach, still looking for some shorter way to do this :c

Returns a tuple of booleans. The first is if you traveled in space and the second if you traveled in time

[Uyâ e_Ê¦1ÃV®-Ki)gÃâ Ê¥3]


[Uyâ e_Ê¦1ÃV®-Ki)gÃâ Ê¥3]   Full Program, U = Space, V = Time
-- U = [[-2,-2,-2], [-3,-3,-3]]
-- V = [2020, 1991, 2014, 2018]
[                       ]   Return array containing....
Uyâ                        Transpose Space coords
-- U = [[-2,-3], [-2,-3], [-2,-3]]
and map Z
_Ê¦1                  Z length greater than 1?
-- U = [true, true, true]
e                      return true if all Z are true
-- U = true
V®                Map each time
-Ki)            Subtract current year
-- V = [2,-27,-4,0]
gÃ          get sign (-1,0,1)
-- V = [1,-1,-1,0]
â        unique elements
-- V = [1,-1,0]
Ê¥3    return true if length == 3
-- V = true


Try it online!

• Uhm, I think this fails on the testcase you've provided in the link? (yâ transposes, takes unique items, and transposes back, so you'll probably want to do Uy e_â Ê¦1Ã instead) Nov 10, 2018 at 15:08
• Only seeing this now, looks like you might have posted it before mine (on my phone so can't tell properly). If so, let me know if you want mine given the similarities and I'll delete it. Nov 10, 2018 at 15:20
• @ETHproductions, it does seem to work. I had â within the e method on my first try, too, before moving it to y on a whim to see if it'd work. Nov 10, 2018 at 15:22
• @Shaggy Well I'll be darned, it does actually work... but why doesn't it transpose back in this case? Nov 10, 2018 at 15:26
• @Shaggy Oh dear, the code that checks whether to tranpose it back checks if for every q in the mapped transposed array, typeof q instanceof Array... what a convenient bug :P Guess I can't fix it now until releasing 1.4.6... Nov 10, 2018 at 15:29

# JavaScript (ES6), 104 100 bytes

Takes input as (space)(time). Returns $$\1\$$ for time, $$\2\$$ for space, $$\3\$$ for both or $$\0\$$ for neither.

24% of the code is spent figuring out in which year we are ... \o/

s=>t=>2*s.every((x,i)=>s.some(b=>x-b[i]))|t.some(y=>(s|=(y/=(new Date).getFullYear())>1?4:y+1)>6)


Try it online!

### Commented

s => t =>              // s[] = space array; t[] = time array
2 *                  // the space flag will be doubled
s.every((x, i) => // for each coordinate x at position i in the first entry of s[]:
s.some(b =>        //   for each entry b in s[]:
x - b[i]         //     if we've found b such that b[i] != x, the coordinate is valid
)                  //   end of some()
)                    // end of every()
|                    // bitwise OR with the time flag
t.some(y =>          // for each year y in t[]:
(s |=              //   update the bitmask s (initially an array, coerced to 0)
( y /=           //     divide y
(new Date)     //     by the current year (this is safe as long as no time-travel
.getFullYear() //     machine is available to run this it at year 0)
) > 1 ?          //   if the result is greater than 1:
4              //     do s |= 4 (future)
:                //   else:
y + 1          //     do s |= y + 1; y + 1 = 2 if both years were equal (present)
//     otherwise: y + 1 is in [1, 2), which is rounded to 1 (past)
) > 6              //   set the time flag if s = 7
)                    // end of some()

• Fail on console.log(f([[5,4,2], [3,4,0], [1,4,2], [9,4,4]])()) // neither
– l4m2
Nov 12, 2018 at 13:29
• @l4m2 Hmm. Fixed at the cost of 1 byte. I can't think of a 99-byte solution off the top of my head. Nov 12, 2018 at 14:00

# R, 106, 105 bytes

function(s,t)all((x<-apply(s,1,range))[1,]-x[2,])-2*all((-1:1)%in%sign(as.POSIXlt(Sys.Date())\$ye+1900-t))


Try it online!

Input :

s : matrix of space coordinates (3 x N)
t : vector time years


Output an integer value equal to :

 1 : if traveled through space only
-2 : if traveled through time only
-1 : if traveled through space and time
0 : if traveled neither through space nor time


## Batch, 353 bytes

@echo off
set/as=t=0,y=%date:~-4%
for %%a in (%*) do call:c %~1 %%~a
if %s%==7 (if %t%==7 (echo both)else echo space)else if %t%==7 (echo time)else echo neither
exit/b
:c
if "%6"=="" goto g
if %1 neq %4 set/as^|=1
if %2 neq %5 set/as^|=2
if %3 neq %6 set/as^|=4
exit/b
:g
if %4 lss %y% (set/at^|=1)else if %4==%y% (set/at^|=2)else set/at^|=4


Note: Since commas are argument separators in Batch, in order to input the space coordinates you need to quote then e.g.

spacetime "5,7,2" "5,3,8" "-6,3,8" "5,7,2" 2000 2002


Explantion:

@echo off


Turn off unwanted output.

set/as=t=0,y=%date:~-4%


Set up two bitmasks and also extract the current year. (In YYYY-MM-DD locales use %date:~,4% for the same byte count.)

for %%a in (%*) do call:c %~1 %%~a


Loop over all the arguments. The ~ causes coordinate values to be split into separate parameters.

if %s%==7 (if %t%==7 (echo both)else echo space)else if %t%==7 (echo time)else echo neither
exit/b


Check whether the bitmasks are fully set and output the appropriate result.

:c
if "%6"=="" goto g


See whether this is a pair of coordinates or a coordinate and a year.

if %1 neq %4 set/as^|=1
if %2 neq %5 set/as^|=2
if %3 neq %6 set/as^|=4
exit/b


If it's a coordinate then update the space bitmask according to whether the relevant spacial dimension was visited.

:g
if %4 lss %y% (set/at^|=1)else if %4==%y% (set/at^|=2)else set/at^|=4


If it's a year then update the time bitmask according to whether the relevant time dimension was visited.

# Java 10, 154 bytes

s->t->{int y=java.time.Year.now().getValue(),c=0,d=1,i=3;for(;i-->0;d*=c,c=0)for(var l:s)c=l[i]!=s[i]?1:c;for(int a:t)c|=a>y?4:a<y?1:2;return c/7*2+d;}


Returns 1 for space, 2 for time, 3 for both, 0 for neither. Try it online here.

Ungolfed:

s -> t -> { // lambda taking two parameters in currying syntax
// s is int[][], t is int[]; return type is int

int y = java.time.Year.now().getValue(), // the current year
c = 0, // auxiliary variable used for determining both space and time
d = 1, // initally, assume we have moved in all three space dimensions
i = 3; // for iterating over the three space dimensions

for(; i -- > 0; d *= c, c = 0) // check all coordinates for each dimension, if we have not moved in one of them, d will be 0
for(var l : s) // check the whole list:
c = l[i] != s[i] ? 1 : c; // if one coordinate differs from the first, we have moved

for(int a : t) // look at all the years; c is 0 again after the last loop
c |= a > y ? 4 : a < y ? 1 : 2; // compare to the current year, setting a different bit respectively for past, present and future

return c / 7 // if we have been to past, the present and the future ...
* 2   // ... return 2 ...
+ d;  // ... combined with the space result, otherwise return just the space result
}