Surreal Numbers

5

Surreal Numbers

Surreal numbers are one way of describing numbers using sets. In this challenge you will determine the value of a surreal number.

Intro

A surreal number consists of two sets: a left and right. The value of the surreal number must be greater than all numbers in the left set and less than all numbers in the right set. We define 0 as having nothing in each set, which we write as {|}. Each surreal number also has a birth date. 0 is born on day 0. On each successive day, new surreal numbers are formed by taking the numbers formed on previous days and placing them in the left/right sets of a new number. For example, {0|} = 1 is born on day 1, and {|0} = -1 is also born on day 1.

To determine the value of a surreal number, we find the number "between" the left and right sets that was born earliest. As a general rule of thumb, numbers with lower powers of 2 in their denominator are born earlier. For example, the number {0|1} (which is born on day 2 by our rules) is equal to 1/2, since 1/2 has the lowest power of 2 in its denominator between 0 and 1. In addition, if the left set is empty, we take the largest possible value, and vice versa if the right set is empty. For example, {3|} = 4 and {|6} = 5.

Note that 4 and 5 are just symbols that represent the surreal number, which just happen to align with our rational numbers if we define operations in a certain way.

Some more examples:

{0, 1|} = {1|} = {-1, 1|} = 2
{0|3/4} = 1/2
{0|1/2} = 1/4
{0, 1/32, 1/16, 1/2 |} = 1

Input

A list/array of two lists/arrays, which represent the left and right set of a surreal number. The two lists/arrays will be sorted in ascending order and contain either dyadic rationals (rationals with denominator of 2^n) or other surreal numbers.

Output

A dyadic rational in either decimal or fraction form representing the value of the surreal number.

Examples

Input -> Output
[[], []] -> 0
[[1], []] -> 2
[[], [-2]] -> -3
[[0], [4]] -> 1
[[0.25, 0.5], [1, 3, 4]] -> 0.75
[[1, 1.5], [2]] -> 1.75
[[1, [[1], [2]]], [2]] -> 1.75

This is , so shortest code wins.

Quintec

Posted 2019-01-03T23:29:32.947

Reputation: 2 801

Isn't 0 always born the earliset, since it's born on day 0? – Embodiment of Ignorance – 2019-01-03T23:42:13.127

@EmbodimentofIgnorance Yes, but 0 isn't always within the bounds of the left and right set. – Quintec – 2019-01-03T23:44:00.073

What does "between" the two sets mean? – Embodiment of Ignorance – 2019-01-03T23:50:35.990

And for the last example, is the [[1],[2]] a surreal number? If so, do we evaluate the value of surreal numbers inside the set first, then use the values as regular rational integers to find the value of the outside surreal number? – Embodiment of Ignorance – 2019-01-03T23:56:46.777

@EmbodimentofIgnorance For your second comment: yes, that's correct on both counts. – Quintec – 2019-01-04T00:07:54.903

@EmbodimentofIgnorance "Between" means greater than all members of the left set and less than all members of the right set. – Quintec – 2019-01-04T00:22:58.010

Can I take the input as a string, since I don't get how to implement the surreal numbers in the arrays thing? (Since hypothetically, those surreal numbers can have surreal numbers which in turn have more surreal numbers in them...) – Embodiment of Ignorance – 2019-01-04T00:26:59.697

Let us continue this discussion in chat. @EmbodimentofIgnorance

– Quintec – 2019-01-04T00:29:03.103

{|6} Should be 0, not 5, in the real surreal numbers. – jimmy23013 – 2019-07-15T02:16:30.267

Closely related: https://codegolf.stackexchange.com/q/38425/25180. Maybe a duplicate. The only difference (if fixed) is this challenge uses sets. But they don't add much for finite numbers.

– jimmy23013 – 2019-07-15T02:17:09.350

Answers

1

Python, 371 362 261 251 248 241 236 234 231 bytes

-122 bytes thanks to @ASCII-only

def f(s):
 if s<[]:return s
 a=map(f,s[1]+[1e999,-1e999]+s[0]);m,n,u=a[-1],a[0],1
 while n-m<=1:m*=2;n*=2;u/=2.
 x,y=abs(m)-1,abs(n)-1;s=m>0>n or m<0<n;r=[[m-x*s,m+x*s][m<0]+1,[n-y*s,n+y*s][n<0]-1][x>y];return u*int([0,r][`r`<"m"])

Try it online!

Quintec

Posted 2019-01-03T23:29:32.947

Reputation: 2 801

Fail on [[-8],[5]] I guess, though I don't knows what it is – l4m2 – 2019-01-07T05:05:05.890

Yeah, invalid. Probably should be 0? – ASCII-only – 2019-01-07T06:39:00.640

half fixed – ASCII-only – 2019-01-07T08:11:13.193

there we go, now to golf it – ASCII-only – 2019-01-07T08:25:22.563

Still invalid though, only works up to 9e9 in either direction, unless you change the spec to, say, require only up to the limits of a float32 or float64 – ASCII-only – 2019-01-07T08:48:23.953

removed log – ASCII-only – 2019-01-07T09:05:58.707

works up to float limit – ASCII-only – 2019-01-07T23:59:11.607

@ASCII-only Wow thanks so much – Quintec – 2019-01-08T00:44:33.090

@Quintec Gotta make sure that's what you want it to do though – ASCII-only – 2019-01-08T00:46:52.593

also... The two lists/arrays will be sorted in ascending order? then you can do this (wait. is it broken

– ASCII-only – 2019-01-08T00:47:58.640

fixed – ASCII-only – 2019-01-08T00:53:51.283

@ASCII-only yer a wizard – Quintec – 2019-01-08T00:57:07.533

248 – ASCII-only – 2019-01-08T00:57:22.473

241 (note that 1e999 is greater than float limit (~4e308?), so it's the same as float infinity) – ASCII-only – 2019-01-08T01:00:14.843

@ASCII-only you ninja'd me doing it darn – Quintec – 2019-01-08T01:00:41.463

Let us continue this discussion in chat.

– ASCII-only – 2019-01-08T01:01:16.763