Shift right by half a bit

33

7

The challenge is to implement a program or function (subsequently referred to as "program") that takes a nonnegative integer \$n\$ as input and returns \$n\over\sqrt{2}\$ (the input divided by the square root of two) as output, rounded to a nonnegative integer.

You may take your input and output in any reasonable format; for example stdin/stdout, files, or arguments/return values would all be acceptable.

You are required to use, at minimum, the largest fixed-size integer type offered by your language, and if an unsigned variant of this is available, you must use it. If your language has no built-in integer type (e.g. JavaScript) you are allowed to use its default numerical type (e.g. floating point); for languages with no concept of a number (e.g. regex), input and output can be e.g. the length of a string.

It is not required to reject negative integers; a submission that returns correct answers for negative inputs is allowed, but not required. Undefined behavior with negative inputs is allowed.

You are allowed and encouraged to use arbitrary-precision integer types if you so desire, but the type must either be a built-in, part of a standard library, or implemented from scratch in your program. As such, there are two categories of competition in this challenge:

  1. Precision limited by built-in types (fixed-size integer, floating point, etc.)
  2. Arbitrary precision (recursion and memory allocation, if used, can be assumed to be unlimited, where appropriate to the language in question)

Despite what the title might imply, you may use any rounding algorithm you want (floor, ceiling, nearest half up, nearest half even, arbitrary, or even random), as long as the difference between the integer returned value and the theoretical exact (irrational) value is always less than \$1\$ for all inputs that fit in your chosen integer type (but exactly 0 for an input of 0). All inputs up to the maximum representable value must return a correct output.

In a way, the job of this program is to calculate the irrational number \$\sqrt{2}\$ to the requested precision, presenting it in the form of an integer. This is why solutions using arbitrary-precision types are encouraged, but not required.

This is a challenge. Standard loopholes are denied. The program with the least number of bytes wins. That said, this challenge is not only about which answer wins overall; it's also about seeing how concisely the challenge can be solved in each language, seeing how each language "prefers" to handle rounding, and how hard it is to solve in esoteric languages. And for those submissions that choose to use arbitrary precision, it's about seeing how concisely this can be done in the language.

Test cases

Within the Precision-limited category, only the cases that are in range of the language's capability are required to pass.

If your solution is too slow to demonstrably pass the larger inputs (or runs out of memory/stack), it becomes all the more important to explain it sufficiently well, so that it can be understood that it would pass.

Input → Floor or Ceiling
0 → 0 (this is the only input that can only result in one valid output)
1 → 0 or 1
2 → 1 or 2
3 → 2 or 3
4 → 2 or 3
5 → 3 or 4
10 → 7 or 8
32 → 22 or 23
500 → 353 or 354
1000 → 707 or 708
1000000 → 707106 or 707107
186444716 → 131836322 or 131836323
1000000000 → 707106781 or 707106782
2147483647 → 1518500249 or 1518500250
3037000499 → 2147483647 or 2147483648
4294967295 → 3037000499 or 3037000500
4503599627370496 → 3184525836262886 or 3184525836262887
9223372036854775807 → 6521908912666391105 or 6521908912666391106
18446744073709551615 → 13043817825332782211 or 13043817825332782212
10000000000000000000000000000000000000 → 7071067811865475244008443621048490392 or 7071067811865475244008443621048490393
956287480911872131784896176254337633353980911149964074434383 → 676197362516585909969655173274459790030028262421622111830069 or 676197362516585909969655173274459790030028262421622111830070

Deadcode

Posted 2020-01-24T06:03:21.767

Reputation: 3 022

9

Just in case someone is tempted to use Brainbool or something similar, I'll just leave a link to the appropriate loophole here.

– FryAmTheEggman – 2020-01-24T06:26:28.873

6Shifting half a bit requires more than bitwise insight to solve. – None – 2020-01-24T10:29:38.570

4Suggested test case: 9223372036854775807 – 640KB – 2020-01-24T22:18:45.567

Answers

47

Regex (ECMAScript+(?*)), 1169 929 887 853 849 bytes

Regex was never designed to do mathematics. It has no concept of arithmetic. However, when input is taken in the form of bijective unary, as a sequence of identical characters in which the length represents a natural number, it is possible to do a wide range of operations, building up from the simple primitives available, which basically amount to addition, comparison, multiplication by a constant, and modulo. Everything must fit inside the input; it isn't possible to directly operate on numbers larger than that.

In ECMAScript regex, it's especially difficult (and therefore interesting) to do even some of the simplest of operations, because of the limitation that all backrefs captured in a loop are reset to empty at the beginning of each iteration – which makes it impossible to count anything directly. It's nevertheless possible to match prime numbers, powers of N, Nth powers, arbitrary multiplication and exponentiation, Fibonacci numbers, factorial numbers, abundant numbers, and more, much of which is demonstrated in my other answers.

One of the operations that turns out to be far more verbose than the rest is to "calculate an irrational number". I initially discussed this with teukon back in 2014. The only known way to do this is to emulate operations on numbers larger than the input, and probably the simplest way to do this is by working in a number base chosen based on what can fit into the input.

It wasn't until late 2018 that I finally set about to implementing the theory I had sketched in 2014. Implementing it involved adapting the multiplication algorithm to work with factors of 0, which turned out to golf rather elegantly. (The underlying multiplication algorithm is explained in this post.) The basic algorithm is this:

For input \$N\$, we want to calculate \$M=\lfloor{N\over\sqrt2}\rfloor\$. So we want the largest \$M\$ such that \$2M^2\le N^2\$.

If we take the "number base" to be \$k=\lceil\sqrt N\rceil\$ or \$\lfloor\sqrt N\rfloor\!+\!1\$, all multiplication operations \$m\cdot n\$ on \$0\leq m,n<k\$ are guaranteed to fit in the available space.

So if \$N=A k+B\$, where \$0\leq A,B\lt k\$, we can calculate \$N^2\$:

$$N^2=(A k+B)^2=A^2 k^2+2 A B k+B^2$$

We must then do division, modulo, and carry to bring \$A^2\$, \$2 A B\$, and \$B^2\$ back into the range of a base \$k\$ "digit". A similar operation is then done to calculate \$2 M^2\$ iterated over the decreasing consecutive possible values of \$M\$, using digit-by-digit comparison to test for \$2M^2\le N^2\$, until the first \$M\$ is found that passes the test.

So while the basic concept is simple enough, it adds up to a lot of calculations, and the regex is huge! And this is probably the simplest calculation of an irrational number that can be done in ECMAScript regex. (It is still unknown whether it's possible to calculate a transcendental number to arbitrary precision in regex.)

This regex uses molecular lookahead, a.k.a. non-atomic lookahead, represented as (?*...). Without this feature, it would be much harder (or at least much more verbose) to implement.

Note that there is one departure from pure code golf in this version of the regex. I chose to use \$k=\lceil\sqrt N\rceil\$ because it has the very neat property of making the calculations fit perfectly into \$N\$ if \$N\$ is a perfect square, whereas \$k=\lfloor\sqrt N\rfloor\!+\!1\$ is basically chaotic for all inputs. They both yield the same final outputs, but the former is just cleaner. This only involved increasing the total length of the regex by 8 bytes, so I figured it was worth it. This change is in the git version history.

(?=(x(x*))(x)*(?=\1*$)\2+$)(?=(x(\2\3))+(x?(x*)))(?=\6(x(x*))(?=\8*$)\5\9*$)(?=.*(?=(?=\6*$)\6\7+$)(x*?)(?=\4*$)(x?(x*))(?=\11*$)((?=\5+$)\5\12*$|$\11))(?=.*(?=(?=\6*$)(?=\8*$)(?=\6\9+$)\8\7+$|$\6)(x*?)(?=\4*$)(x?(x*))(?=\15*$)((?=\5+$)\5\16*$|$\15))(?=.*(?=\14\14\11$)(x*?)(?=\4*$)(x?(x*))(?=\19*$)((?=\5+$)\5\20*$|$\19))(?*.*?(?=((?=\4*(x?(x*)))\23(x(x*))(?=\25*$)\5\26*$)))(?=.*(?=\25*$)(\25\26+$))(?=.*(?=(?=\23*$)\23\24+$)(x*?)(?=\4*$)(x?(x*))(?=\29*$)((?=\5+$)\5\30*$|$\29))(?=.*(?=(?=\23*$)(?=\25*$)(?=\23\26+$)\25\24+$|$\23)(x*?)(?=\4*$)(x?(x*))(?=\33*$)((?=\5+$)\5\34*$|$\33))(?=.*(?=\32\32\29$)(x*?)(?=\4*$)(x?(x*))(?=\37*$)((?=\5+$)\5\38*$|$\37))(?=.*(?=\28\28)(?=\4*(x*))(\5(x)|))(?=.*(?=\36\36\42)(?=\4*(x*))(\5(x)|))(?=(?=(.*)\15\15\19(?=\8*$)\8\9+$)\46(x+|(?=.*(?!\18)\43|(?!.*(?!\40)\10).*(?=\18$)\43$))(\27\33\33\37){2}\45$)\22|x\B|

Try it on repl.it

This regex is on GitHub with a full version history.

# Giving an input number N in the domain ^x*$, this regex returns floor(N / sqrt(2))
(?=
  (x(x*))                # \1 = will be the square root of the main number, rounded down; \2 = \1 - 1
  (x)*(?=\1*$)           # \3 = tool to round up instead of down
  \2+$
)

# Step 1: Calculate N*N in base ceil(sqrt(N))

(?=(x(\2\3))+(x?(x*)))   # \4 = \1 + \3 = ceil(sqrt(N)), the number base to work in; \5 = \4-1; \6 = N % \4; \7 = \6-1, or 0 if \6==0
(?=
  \6
  (x(x*))                # \8 = floor(N / \4); \9 = \8-1
  (?=\8*$)               # we can skip the test for divisibility by \5 because it's guaranteed that \5 <= \8
  \5\9*$
)
(?=
  .*
  (?=
    (?=\6*$)             # tail = \6 * \6
    \6\7+$
  )
  (x*?)(?=\4*$)          # \10 =       (\6 * \6) % \4, the base-\4 digit in place 0 of the result for N*N
  (x?(x*))               # \11 = floor((\6 * \6) / \4); \12 = \11-1, or 0 if \11==0
  (?=\11*$)
  (
    (?=\5+$)
    \5\12*$
  |
    $\11                 # must make a special case for \11==0, because \5 is nonzero
  )
)
(?=
  .*
  (?=
    (?=\6*$)             # tail = \6 * \8; must do symmetric multiplication, because \6 is occasionally 1 larger than \8
    (?=\8*$)
    (?=\6\9+$)
      \8\7+$
  |
    $\6                  # must make a special case for \6==0, because \8 might not be 0
  )
  (x*?)(?=\4*$)          # \14 =       (\6 * \8) % \4
  (x?(x*))               # \15 = floor((\6 * \8) / \4); \16 = \15-1, or 0 if \15==0
  (?=\15*$)
  (
    (?=\5+$)
    \5\16*$
  |
    $\15                 # must make a special case for \15==0, because \5 is nonzero
  )
)
(?=
  .*(?=\14\14\11$)       # tail =       2 * \14 + \11
  (x*?)(?=\4*$)          # \18 =       (2 * \14 + \11) % \4, the base-\4 digit in place 1 of the result for N*N
  (x?(x*))               # \19 = floor((2 * \14 + \11) / \4); \20 = \19-1, or 0 if \19==0
  (?=\19*$)
  (
    (?=\5+$)
    \5\20*$
  |
    $\19                 # must make a special case for \19==0, because \5 is nonzero
  )
)                        # {\8*\8 + 2*\15 + \19} = the base-\4 digit in place 2 of the result for N*N, which is allowed to exceed \4 and will always do so;
                         # Note that it will be equal to N iff N is a perfect square, because of the choice of number base.

# Step 2: Find the largest M such that 2*M*M is not greater than N*N

# Step 2a: Calculate M*M in base \4
(?*
  .*?                    # Determine value of M with backtracking, starting with largest values first
  (?=
    (                    # \22 =       M
      (?=\4*(x?(x*)))\23 # \23 =       M % \4; \24 = \23-1, or 0 if \23==0
      (x(x*))            # \25 = floor(M / \4); \26 = \25-1
      (?=\25*$)          # we can skip the test for divisibility by \5, but I'm not sure why; TODO: figure out why this is
      \5\26*$
    )
  )
)
(?=
  .*
  (?=\25*$)
  (\25\26+$)             # \27 = \25 * \25
)
(?=
  .*
  (?=
    (?=\23*$)            # tail = \23 * \23
    \23\24+$
  )
  (x*?)(?=\4*$)          # \28 =       (\23 * \23) % \4, the base-\4 digit in place 0 of the result for M*M
  (x?(x*))               # \29 = floor((\23 * \23) / \4); \30 = \29-1, or 0 if \29==0
  (?=\29*$)
  (
    (?=\5+$)
    \5\30*$
  |
    $\29                 # must make a special case for \29==0, because \5 is nonzero
  )
)
(?=
  .*
  (?=
    (?=\23*$)            # tail = \23 * \25; must do symmetric multiplication, because \23 is occasionally 1 larger than \25
    (?=\25*$)
    (?=\23\26+$)
      \25\24+$
  |
    $\23                 # must make a special case for \23==0, because \25 might not be 0
  )
  (x*?)(?=\4*$)          # \32 =       (\23 * \25) % \4
  (x?(x*))               # \33 = floor((\23 * \25) / \4); \34 = \33-1, or 0 if \33==0
  (?=\33*$)
  (
    (?=\5+$)
    \5\34*$
  |
    $\33                 # must make a special case for \33==0, because \5 is nonzero
  )
)
(?=
  .*(?=\32\32\29$)       # tail =       2 * \32 + \29
  (x*?)(?=\4*$)          # \36 =       (2 * \32 + \29) % \4, the base-\4 digit in place 1 of the result for M*M
  (x?(x*))               # \37 = floor((2 * \32 + \29) / \4); \38 = \37-1, or 0 if \37==0
  (?=\37*$)
  (
    (?=\5+$)
    \5\38*$
  |
    $\37                 # must make a special case for \37==0, because \5 is nonzero
  )
)                        # {\27 + 2*\33 + \37} = the base-\4 digit in place 2 of the result for M*M, which is allowed to exceed \4 and will always do so

# Step 2b: Calculate 2*M*M in base \4
(?=
  .*
  (?=\28\28)             # tail =       2*\28
  (?=\4*(x*))            # \40 =       (2*\28) % \4, the base-\4 digit in place 0 of the result for 2*M*M
  (\5(x)|)               # \42 = floor((2*\28) / \4) == +1 carry if {2*\28} does not fit in a base \4 digit
)
(?=
  .*
  (?=\36\36\42)          # tail =       2*\36 + \42
  (?=\4*(x*))            # \43 =       (2*\36 + \42) % \4, the base-\4 digit in place 1 of the result for 2*M*M
  (\5(x)|)               # \45 = floor((2*\36 + \42) / \4) == +1 carry if {2*\36 + \42} does not fit in a base \4 digit
)                        # 2*(\27 + 2*\33 + \37) + \45 = the base-\4 digit in place 2 of the result for 2*M*M, which is allowed to exceed \4 and will always do so

# Step 2c: Require that 2*M*M <= N*N

(?=
  (?=
    (.*)                 # \46
    \15\15\19
    (?=\8*$)             # tail = \8 * \8
    \8\9+$
  )
  \46                    # tail = {\8*\8 + 2*\15 + \19}; we can do this unconditionally because our digits in place 2 are always greater than those in places 0..1
  (
    x+
  |
    (?=
      .*(?!\18)\43       # \43 < \18
    |
      (?!.*(?!\40)\10)   # \40 <= \10
      .*(?=\18$)\43$     # \43 == \18
    )
  )
  (\27\33\33\37){2}\45$  # 2*(\27 + 2*\33 + \37) + \45
)

\22

|x\B|                    # handle inputs in the domain ^x{0,2}$

Regex (ECMAScript 2018), 861 bytes

This is a direct port of the 849 byte molecular lookahead version, using variable length lookbehind.

(?=(x(x*))(x)*(?=\1*$)\2+$)(?=(x(\2\3))+(x?(x*)))(?=\6(x(x*))(?=\8*$)\5\9*$)(?=.*(?=(?=\6*$)\6\7+$)(x*?)(?=\4*$)(x?(x*))(?=\11*$)((?=\5+$)\5\12*$|$\11))(?=.*(?=(?=\6*$)(?=\8*$)(?=\6\9+$)\8\7+$|$\6)(x*?)(?=\4*$)(x?(x*))(?=\15*$)((?=\5+$)\5\16*$|$\15))(?=.*(?=\14\14\11$)(x*?)(?=\4*$)(x?(x*))(?=\19*$)((?=\5+$)\5\20*$|$\19))(?=.*?(?=((?=\4*(x?(x*)))\23(x(x*))(?=\25*$)\5\26*$))(?<=(?=(?=.*(?=\25*$)(\25\26+$))(?=.*(?=(?=\23*$)\23\24+$)(x*?)(?=\4*$)(x?(x*))(?=\29*$)((?=\5+$)\5\30*$|$\29))(?=.*(?=(?=\23*$)(?=\25*$)(?=\23\26+$)\25\24+$|$\23)(x*?)(?=\4*$)(x?(x*))(?=\33*$)((?=\5+$)\5\34*$|$\33))(?=.*(?=\32\32\29$)(x*?)(?=\4*$)(x?(x*))(?=\37*$)((?=\5+$)\5\38*$|$\37))(?=.*(?=\28\28)(?=\4*(x*))(\5(x)|))(?=.*(?=\36\36\42)(?=\4*(x*))(\5(x)|))(?=(?=(.*)\15\15\19(?=\8*$)\8\9+$)\46(x+|(?=.*(?!\18)\43|(?!.*(?!\40)\10).*(?=\18$)\43$))(\27\33\33\37){2}\45$))^.*))\22|x\B|

Try it online!

This regex is on GitHub.

# Giving an input number N in the domain ^x*$, this regex returns floor(N / sqrt(2))
(?=
  (x(x*))                # \1 = will be the square root of the main number, rounded down; \2 = \1 - 1
  (x)*(?=\1*$)           # \3 = tool to round up instead of down
  \2+$
)

# Step 1: Calculate N*N in base ceil(sqrt(N))

(?=(x(\2\3))+(x?(x*)))   # \4 = \1 + \3 = ceil(sqrt(N)), the number base to work in; \5 = \4-1; \6 = N % \4; \7 = \6-1, or 0 if \6==0
(?=
  \6
  (x(x*))                # \8 = floor(N / \4); \9 = \8-1
  (?=\8*$)               # we can skip the test for divisibility by \5 because it's guaranteed that \5 <= \8
  \5\9*$
)
(?=
  .*
  (?=
    (?=\6*$)             # tail = \6 * \6
    \6\7+$
  )
  (x*?)(?=\4*$)          # \10 =       (\6 * \6) % \4, the base-\4 digit in place 0 of the result for N*N
  (x?(x*))               # \11 = floor((\6 * \6) / \4); \12 = \11-1, or 0 if \11==0
  (?=\11*$)
  (
    (?=\5+$)
    \5\12*$
  |
    $\11                 # must make a special case for \11==0, because \5 is nonzero
  )
)
(?=
  .*
  (?=
    (?=\6*$)             # tail = \6 * \8; must do symmetric multiplication, because \6 is occasionally 1 larger than \8
    (?=\8*$)
    (?=\6\9+$)
      \8\7+$
  |
    $\6                  # must make a special case for \6==0, because \8 might not be 0
  )
  (x*?)(?=\4*$)          # \14 =       (\6 * \8) % \4
  (x?(x*))               # \15 = floor((\6 * \8) / \4); \16 = \15-1, or 0 if \15==0
  (?=\15*$)
  (
    (?=\5+$)
    \5\16*$
  |
    $\15                 # must make a special case for \15==0, because \5 is nonzero
  )
)
(?=
  .*(?=\14\14\11$)       # tail =       2 * \14 + \11
  (x*?)(?=\4*$)          # \18 =       (2 * \14 + \11) % \4, the base-\4 digit in place 1 of the result for N*N
  (x?(x*))               # \19 = floor((2 * \14 + \11) / \4); \20 = \19-1, or 0 if \19==0
  (?=\19*$)
  (
    (?=\5+$)
    \5\20*$
  |
    $\19                 # must make a special case for \19==0, because \5 is nonzero
  )
)                              # {\8*\8 + 2*\15 + \19} = the base-\4 digit in place 2 of the result for N*N, which is allowed to exceed \4 and will always do so;
                # Note that it will be equal to N iff N is a perfect square, because of the choice of number base.

# Step 2: Find the largest M such that 2*M*M is not greater than N*N

# Step 2a: Calculate M*M in base \4
(?=
  .*?                    # Determine value of M with backtracking, starting with largest values first
  (?=
    (                    # \22 =       M
      (?=\4*(x?(x*)))\23 # \23 =       M % \4; \24 = \23-1, or 0 if \23==0
      (x(x*))            # \25 = floor(M / \4); \26 = \25-1
      (?=\25*$)          # we can skip the test for divisibility by \5, but I'm not sure why; TODO: figure out why this is
      \5\26*$
    )
  )
  (?<=                   # emulate molecular lookahead for the above expressions
    (?=
      (?=
        .*
        (?=\25*$)
        (\25\26+$)       # \27 = \25 * \25
      )
      (?=
        .*
        (?=
          (?=\23*$)      # tail = \23 * \23
          \23\24+$
        )
        (x*?)(?=\4*$)    # \28 =       (\23 * \23) % \4, the base-\4 digit in place 0 of the result for M*M
        (x?(x*))         # \29 = floor((\23 * \23) / \4); \30 = \29-1, or 0 if \29==0
        (?=\29*$)
        (
          (?=\5+$)
          \5\30*$
        |
          $\29           # must make a special case for \29==0, because \5 is nonzero
        )
      )
      (?=
        .*
        (?=
          (?=\23*$)      # tail = \23 * \25; must do symmetric multiplication, because \23 is occasionally 1 larger than \25
          (?=\25*$)
          (?=\23\26+$)
            \25\24+$
        |
          $\23           # must make a special case for \23==0, because \25 might not be 0
        )
        (x*?)(?=\4*$)    # \32 =       (\23 * \25) % \4
        (x?(x*))         # \33 = floor((\23 * \25) / \4); \34 = \33-1, or 0 if \33==0
        (?=\33*$)
        (
          (?=\5+$)
          \5\34*$
        |
          $\33           # must make a special case for \33==0, because \5 is nonzero
        )
      )
      (?=
        .*(?=\32\32\29$) # tail =       2 * \32 + \29
        (x*?)(?=\4*$)    # \36 =       (2 * \32 + \29) % \4, the base-\4 digit in place 1 of the result for M*M
        (x?(x*))         # \37 = floor((2 * \32 + \29) / \4); \38 = \37-1, or 0 if \37==0
        (?=\37*$)
        (
          (?=\5+$)
          \5\38*$
        |
          $\37           # must make a special case for \37==0, because \5 is nonzero
        )
      )                  # {\27 + 2*\33 + \37} = the base-\4 digit in place 2 of the result for M*M, which is allowed to exceed \4 and will always do so

      # Step 2b: Calculate 2*M*M in base \4
      (?=
        .*
        (?=\28\28)       # tail =       2*\28
        (?=\4*(x*))      # \40 =       (2*\28) % \4, the base-\4 digit in place 0 of the result for 2*M*M
        (\5(x)|)         # \42 = floor((2*\28) / \4) == +1 carry if {2*\28} does not fit in a base \4 digit
      )
      (?=
        .*
        (?=\36\36\42)    # tail =       2*\36 + \42
        (?=\4*(x*))      # \43 =       (2*\36 + \42) % \4, the base-\4 digit in place 1 of the result for 2*M*M
        (\5(x)|)         # \45 = floor((2*\36 + \42) / \4) == +1 carry if {2*\36 + \42} does not fit in a base \4 digit
      )                  # 2*(\27 + 2*\33 + \37) + \45 = the base-\4 digit in place 2 of the result for 2*M*M, which is allowed to exceed \4 and will always do so

      # Step 2c: Require that 2*M*M <= N*N

      (?=
        (?=
          (.*)           # \46
          \15\15\19
          (?=\8*$)       # tail = \8 * \8
          \8\9+$
        )
        \46              # tail = {\8*\8 + 2*\15 + \19}; we can do this unconditionally because our digits in place 2 are always greater than those in places 0..1
        (
          x+
        |
          (?=
            .*(?!\18)\43     # \43 < \18
          |
            (?!.*(?!\40)\10) # \40 <= \10
            .*(?=\18$)\43$   # \43 == \18
          )
        )
        (\27\33\33\37){2}\45$  # 2*(\27 + 2*\33 + \37) + \45
      )
    )
    ^.*                  # emulate molecular lookahead
  )
)
\22
|x\B|                    # handle inputs in the domain ^x{0,2}$

Regex (ECMAScript)

I have not yet ported this algorithm to basic ECMAScript. One way to do it would be to use \$k=\lceil\sqrt[\uproot{1}3]N\rceil\$ as the number base, and calculate:

$$N^2=(A k^2+B k+C)^2=A^2 k^4 + 2 A B k^3 + (2 A C + B^2)k^2 + 2 B C k + C^2$$

Another way would be to stick with \$k=\lceil\sqrt N\rceil\$, capture \$M\$ encoded into two or more backrefs, and emulate the existing calculations within the smaller available space. I'm not sure which way would be more concise. Either way, I expect the regex would roughly double in length.

Deadcode

Posted 2020-01-24T06:03:21.767

Reputation: 3 022

2I never thought of regex as a programming language but I guess it is one? For sure not a Turing complete one though... – findusl – 2020-01-24T08:08:42.160

12Did you post this challenge just so you could post this solution?! – Shaggy – 2020-01-24T21:39:05.440

1

@Shaggy I wouldn't have had the idea otherwise. Explained in the original sandbox post.

– Deadcode – 2020-01-25T06:32:56.580

2

@findusl It's certainly not Turing complete. Its power rests somewhere below primitive recursive, but exactly where hasn't really been pinned down. With unlimited scratch space it would be exactly primitive recursive; it's the extra limit of having to work within the input's space that changes this.

– Deadcode – 2020-01-25T06:34:31.000

15

Scratch 3.0, 7 blocks/62 bytes

Scratch Blocks

Try it online Scratch!

As SB Syntax:

when gf clicked
ask()and wait
say(round((answer)/([sqrt v]of(2

It's always fun to usual visual languages! At least I have built-ins this time.

Lyxal

Posted 2020-01-24T06:03:21.767

Reputation: 5 253

17Am I the only one who read the SB Synthax initially as "when girlfriend clicked, ask and wait"? ;) – Kevin Cruijssen – 2020-01-24T09:15:40.120

1+1, I'm always a sucker for animated cats – 640KB – 2020-01-28T12:53:27.390

1@KevinCruijssen I read it like that as well - one could also ask whether it is the girlfriend who clicks, or if it is the girlfriend who gets clicked. – Bjonnfesk – 2020-01-31T02:56:27.573

14

Python 3, 19 17 bytes

A different python answer

lambda x:x//2**.5

-2 bytes thanks to @Mukundan

try it online

RGS

Posted 2020-01-24T06:03:21.767

Reputation: 5 047

5Ooh, I like this method of rounding. Was scared for a moment there because I thought I wouldn't be able to accept this answer (output ends in .0), but I never said the output had to be in integer form, just that it had to be rounded to an integer. :) – Deadcode – 2020-01-24T07:37:10.257

@Deadcode thanks for your feedback :) – RGS – 2020-01-24T07:55:58.667

2Save 2 byte by doing truediv when dividing by sqrt of 2 instead of after it like lambda x:x//2**.5 – Mukundan – 2020-01-24T11:11:53.167

@Mukundan of course!!! Well pointed out :) – RGS – 2020-01-24T11:13:53.887

Do we care that this only works for inputs of up to about $10**16$, even though Python 3 allows for much larger integers? – paw88789 – 2020-01-25T15:30:12.603

@paw88789 it probably has to do with the fact that when we are dividing, we are no longer dealing with integers. No? – RGS – 2020-01-25T16:15:37.163

1@RGS true. I wasn't sure from the original problem statement whether it mattered that one didn't necessarily get the correct values for these larger inputs. – paw88789 – 2020-01-25T16:18:46.660

@paw88789 machine precision can only get you so far :) – RGS – 2020-01-25T16:21:27.600

@RGS I think one could program it to be exact for all Python integer values. But it would be a much longer program (at least by my reckoning). – paw88789 – 2020-01-25T16:24:57.947

12

JavaScript (ES6), 12 bytes

i=>i/2**.5|0

Uses a binary or to truncate the result

Try it online!

Niphram

Posted 2020-01-24T06:03:21.767

Reputation: 121

10

8087 FPU machine code, 11 bytes

Unassembled listing:

D9 E8   FLD1                    ; load a 1 constant (need to make a 2)
D8 C0   FADD ST, ST(0)          ; ST = 1+1 = 2 
D9 FA   FSQRT                   ; ST = SQRT(2) 
DE F9   FDIVP ST(1), ST         ; ST = N / ST 
DF 1F   FISTP QWORD PTR [BX]    ; *BX = ROUND(ST)
C3      RET                     ; return to caller

Input in ST0, as a 80-bit extended precision value, output to QWORD PTR [BX].

Floating point operations done in x87 math coprocessor hardware with 80-bit extended precision. Correctly calculates values of N up to 13043817825332782211, after which the result will exceed \$2^{63}-1\$ (overflowing a 64-bit signed integer return variable).

Example test program with I/O:

enter image description here

(Test program now with 64 bit I/O routines thx to suggestions from @PeterCordes)

Thanks to @PeterCordes for the suggestion take input in ST(0), saving 2 bytes.

640KB

Posted 2020-01-24T06:03:21.767

Reputation: 7 149

heh, x87 has a bunch of constants build in, including pi and log and ln(2), and log2() of e and 10, but not sqrt 2. :/ push 2 / fild wouldn't help either. Suggestion: custom calling convention: input in ST0, return in ST0. Then you just use fdivp after setting up the constant.

– Peter Cordes – 2020-01-25T19:10:29.107

Or for this integer-by-reference convention, use fidvr. Oh, but there's no m64int form of that, only 16 and 32! So that only works for int32_t. Now I see why you had to use fild to handle a qword integer. I don't think we can beat that with SSE2 in 64-bit mode; divsd is at least 4 bytes, and if you need an addressing mode it's more.

– Peter Cordes – 2020-01-25T19:17:17.117

1@PeterCordes, sure that would make sense to just do i/o using ST0 (especially since the stated platform is "8087 FPU"). Would cut 4 bytes and possibly increase the highest number of N by a little bit too (at least until the result is lte than $2^{63}-1$, whatever that is). Also the opcode DE F9 (FDIV) is actually FDIVP ST(1), ST so that's already good there. – 640KB – 2020-01-26T01:32:59.950

Oh wait, this relies on the caller to do the rounding to nearest integer. That's not allowed. We need frndint, or fistp to an output pointer. Input can still be an integer FP value in ST0 though.

– Peter Cordes – 2020-01-26T01:44:31.627

i.e. void halfshift(uint64_t *out_ds_bx, long double in_st0); would be a valid and legal custom calling convention. – Peter Cordes – 2020-01-26T01:48:13.380

@PeterCordes good point! I've reverted that part of the change so it once again returns to uint64_t *out_ds_bx. Thanks! – 640KB – 2020-01-26T01:54:52.757

1

If you want it: How to display a 64 bit number in decimal in assembly 8086 for output, using only 8086 instructions. Or in 16-bit mode on an emulator like DOSBox, you can use div r32 (32-bit regs in 16-bit mode). Then simply adapt Print 64 bit number stored in EDX:EAX to standard out. Input is easier, e.g. (x << 3) + (x<<1) + new_digit with carry propagation across 2 or 4 limbs. Or use hex; that's still trivial for large values and you can even use SSSE3 in real mode :P

– Peter Cordes – 2020-01-26T02:20:45.483

@PeterCordes I have some routines for 32 bit to ascii, and just never needed to extend them to 64. I do like this routine since it's very clean (and took no time to adapt for signed!). And yes, just need to wrap up the inverse and the cycle will be complete! Thanks for the links! – 640KB – 2020-01-26T16:10:16.353

@PeterCordes I like your algorithm for input, though trickier than it seems on the surface because you're also doing carry propagation on the two bitshifted copies of x as well as the later addition. Here's what I came up with https://godbolt.org/z/yqVp3- (still needs to be adapted to allow for negative decimal inputs, but that's not the interesting part). Thx yet again for the pro tips!

– 640KB – 2020-01-26T21:05:30.017

Yes, saving the x<<1 somewhere while doing the <<3 is what I had in mind. But multi-precision shifts are relatively easy and cheap (vs. extended-precision mul) with add same,same -> adc same,same, or by 3 bits at a time with 386 shld/.../shl starting from the top. That's why I broke down the usual total = total*10 + c - '0' that way, instead of the usual x *5 *2 for a single-register total, with lea reg, [reg + reg*4] and lea reg, [new_digit + reg*2] if 32/64-bit addressing modes are available. (My SO answer)

– Peter Cordes – 2020-01-26T21:41:14.323

@PeterCordes Yeah, it was more that at first glance I didn't realize that I had to make a temp copy of all four words to do the bitshifts (or add -> adc) separately. Though mine ended up being more like ((y=x+x)<<2)+y+new_digit. I did change the RCL's to ADD/ADC after I posted that scratchpad link. Anyway, everything's working great for both input and output of 64 bit values in ASCII on x86-16! – 640KB – 2020-01-27T00:59:23.397

8

Java 8, 18 bytes

n->n/=Math.sqrt(2)

Limited to a maximum of \$9{,}223{,}372{,}036{,}854{,}775{,}807\$ (signed 64-bit integer).

Try it online.

Explanation:

n->                // Method with long as both parameter and return-type
  n/=              //  Divide the input by:
     Math.sqrt(2)  //   The square-root of 2

// The `/=` sets the divided result back to `n`, which implicitly casts the resulting double
// back to long. This saves bytes in comparison to `n->(long)(n/Math.sqrt(2))`

Java 9, 76 74 bytes

n->n.divide(n.valueOf(2).sqrt(new java.math.MathContext(n.precision())),4)

-2 bytes thanks to @OlivierGrégoire.

Arbitrary I/O and precision.

Try it online.

Explanation:

n->               // Method with BigDecimal as both parameter and return-type
  n.divide(       //  Divide the input by:
    n.valueOf(2)  //   Push a BigDecimal with value 2
     .sqrt(       //   Take the square-root of that
           new java.math.MathContext(n.precision())),
                  //   with the same precision as the input
    4)            //  With rounding mode HALF_UP

Kevin Cruijssen

Posted 2020-01-24T06:03:21.767

Reputation: 67 575

Use n.precision() instead of (n+"").length() to save two bytes. Also, just for the sake of clarifying the language and the API, the Java 9 solution goes the extra mile since BigDecimal is not part of the language but of the API, and the challenge speaks only about language. – Olivier Grégoire – 2020-01-26T11:21:13.720

@OlivierGrégoire Thanks for -2! And didn't knew that about the API. I figured all internal imports that are available in Java were fine, but external not. – Kevin Cruijssen – 2020-01-26T16:12:37.757

They are fine! No worries: it was just informative :-) – Olivier Grégoire – 2020-01-26T19:14:18.953

7

05AB1E, 3 bytes

2t÷

Try it online!

-1 byte thanks to @Grimmy

Yet another port of my Keg answer for the sake of completion.

Explained

2t÷
2t  # Push the square root of two
  ÷ # Integer division

Still no ketchup.

Lyxal

Posted 2020-01-24T06:03:21.767

Reputation: 5 253

You can save a byte by using the built-in ÷ instead of . – Grimmy – 2020-01-24T16:21:07.353

6

Mathematica, 17 14 13 bytes / 12 7 characters

⌊#/√2⌋&

Try it online

-3 bytes because Mathematica accepts the char √, which I copied from this MathGolf answer.

-1 byte, -5 characters, as per @Mark S. suggestion, by using ⌊⌋.

For just one more byte (but 5 more characters) I can always round to the nearest integer with

Round[#/√2]&

RGS

Posted 2020-01-24T06:03:21.767

Reputation: 5 047

1Nice, a second arbitrary-precision answer :) And first answer that rounds to the nearest. – Deadcode – 2020-01-24T07:21:59.617

1@Deadcode It doesn't round to the nearest anymore, but ⌊#/√2⌋& would save 1 byte and 5 characters. – Mark S. – 2020-01-25T01:23:30.723

1Hey, that's fine with me :) Go ahead and drop that byte... I didn't mean to confine you to sticking with one rounding method. :) – Deadcode – 2020-01-25T06:49:44.870

6

Jelly, 15 bytes

³²:2_²:Ẹ¡:2+µƬṪ

Try it online!

An arbitrary precision Jelly answer that uses the Newton-Raphson method to find the correct answer. Uses only integer arithmetic operations so the intermediate values are all Python big ints rather than getting cast as floats which would lose precision. The integer result equates to the floor of what would be the floating point answer.

A full program that takes a (possibly negative) integer as its argument and returns an integer.

Now correctly handles inputs of 0 and 1; previously threw an error because of division of 0 by 0 being impermissible for integers.

Useful comment from @PeterCordes about efficiency of this method and some detail on Python’s big integer implementation:

Newton-Raphson converges quickly, like twice as many correct bits per iteration, given a decent first estimate. e.g. one step refines a 12-bit-precision rsqrtps(x) FP result into nearly 24-bit. (In this case apparently the original input is close enough). You only pay Python interpreter overhead per operation, not per limb (aka chunk) of a very long number; extended-precision division is not cheap but it is implemented in C on chunks of 2^30 stored in an array of 32-bit integers. (I forget if Python uses 64-bit on 64-bit machines.)

Explanation

            µƬ   | Do the following as a monad until no new values seen, collecting up the intermediate values:
³                | - Original argument to program
 ²               | - Squared
  :2             | - Integer divide by 2
    _²           | - Subtract current estimate squared
      Ẹ¡         | - If non-zero:
        :        |   - Integer divide by current estimate
         :2      | - Integer divide by 2
           +     | - Add to current estimate
              Ṫ  | Finally, take the tail of the list of estimates

Note Ẹ¡ is literally repeat the number of times indicated by applying the any function to current value, but it is effectively used here to mean if non-zero.

A much shorter answer that is only accurate to float precision is:

Jelly, 4 bytes

2½:@

Try it online!

Nick Kennedy

Posted 2020-01-24T06:03:21.767

Reputation: 11 829

1Wow, it's incredible how fast the arbitrary precision version is. I wouldn't have guessed Python could be that fast let alone Jelly. – Deadcode – 2020-01-24T08:44:02.007

Out of curiosity: what is the current estimate in the very first iteration? Is this the input itself, or 0, or something else? I wonder if I can somehow port this approach into a language that only uses integers, like BrainF*ck or Whitespace. :) Another question: "until no new values seen": can this include any previous collected intermediate values, or only the most recent one (in the second case, "until the current estimate no longer changes" would be a valid synonym)? – Kevin Cruijssen – 2020-01-24T09:13:00.780

@KevinCruijssen the original input, which works fine. Until no new values seen is technically correct, though for this particular problem I’m not sure whether the alternative would ever lead to oscillation between two or more values without checking. – Nick Kennedy – 2020-01-24T13:37:13.793

2

@Deadcode: Newton-Raphson converges quickly, like twice as many correct bits per iteration, given a decent first estimate. e.g. one step refines a 12-bit-precision rsqrtps(x) FP result into nearly 24-bit. (In this case apparently the original input is close enough). You only pay Python interpreter overhead per operation, not per limb (aka chunk) of a very long number; extended-precision division is not cheap but it is implemented in C on chunks of 2^30 stored in an array of 32-bit integers. (I forget if Python uses 64-bit on 64-bit machines.)

– Peter Cordes – 2020-01-26T02:37:10.820

@PeterCordes I hope you don’t mind, but I thought your comment was interesting enough to incorporate verbatim into my answer. Hope that’s ok. – Nick Kennedy – 2020-01-26T23:13:03.807

Could you please update the explanation for the part that correctly handles inputs of 0 and 1? (BTW I was going to ask you how much the size would increase for correctly handling 0 and 1... I thought it would've been 3 bytes at least. 2 is quite nice.) – Deadcode – 2020-01-26T23:41:57.310

1@Deadcode done. – Nick Kennedy – 2020-01-27T00:07:15.347

@NickKennedy: that's great, happy to contribute that way to your answer. :) BTW, it seems CPython doesn't take advantage of native 64-bit being available, always using uint32_t chunks to hold base 2^30 limbs. https://rushter.com/blog/python-integer-implementation/. (With a special fast path for most operations for single-limb integers. (But not all operations: Why are bitwise operators slower than multiplication/division/modulo?).

– Peter Cordes – 2020-01-27T02:12:59.360

6

Japt, 3 bytes

z2q

Try it

z is the floor division method and q is the nth-root method, defaulting to square root when it's not passed an argument.

Shaggy

Posted 2020-01-24T06:03:21.767

Reputation: 24 623

5

dc, 5 bytes

d*2/v

Try it online!

Takes input and leaves output on the stack.

dc automatically uses arbitrary-precision integers, and supports a precision of 0 decimal places by default, thus automatically "rounding". So taking the square-root of 2 will yield 1. Instead, this solution squares the input, by duplicating it and * multiplying both the items at the top of the stack, / dividing it by 2 (reverse-polish) and takes the v square root of that.

user41805

Posted 2020-01-24T06:03:21.767

Reputation: 16 320

3

APL (Dyalog Extended), 5 bytesSBCS

Full program. Prompts stdin for zero or more numbers.

⌈⎕÷√2

Try it online!

ceiling of

 console input

÷ divided by

 the square root of

2 two

Adám

Posted 2020-01-24T06:03:21.767

Reputation: 37 779

3

Pyth, 6 bytes

The division auto-casts the number to a decimal!? (In seriousness, is there a square root function in Pyth?)

/Q@2 2

Try it online!

Explanation

  @2   2 to the power of
     2 1/2 (effectively calculates math.sqrt(2))
/Q     Divide the (evaluated) input by that number

user85052

Posted 2020-01-24T06:03:21.767

Reputation:

3

wx, 3 bytes

It's W, with just one instruction added: square root. Turns out that this is very useful! (P.S. the built-in was added before the challenge.)

2Q/

Explanation

 2Q  % Find the square root of 2
a  / % Divide the input by it
     % If one operand is an integer,
     % the program will automatically
     % try to trunctuate to an integer

user85052

Posted 2020-01-24T06:03:21.767

Reputation:

3

PHP, 17 bytes

<?=$argn/2**.5|0;

Try it online!

Uses @Niphram's truncate method (which in PHP also has the ability to convert the float to an int)

I know it's trendy to say PHP is to be hated, but I kinda came to like its oddities, and it gives me a chance to add an original answer

EDIT: saved 4 bytes using <?= php tag (no need to echo)

EDIT2: basically it's just a port of @Niphram's answer now

Kaddath

Posted 2020-01-24T06:03:21.767

Reputation: 449

@640KB Ok it's noted, fixed it. Still a bit new to golfing; Thanks – Kaddath – 2020-01-27T08:25:47.917

I should have started with welcome to CGCC! The rule of thumb is that a submission doesn't have to work on all common configurations of platform but it does have to work on one. The reason omission of an opening tag can be permitted would be if your script could run using the -r command line option (php -r "echo 'hi world';"). Unless specified otherwise the Default I/O rules govern what's allowed.

– 640KB – 2020-01-27T15:04:21.900

Oh, and don't let people get you down about PHP. It is used on almost 80% of all websites utilizing server-side scripting, so it can't be that bad. :)

– 640KB – 2020-01-27T15:06:20.843

3

C (gcc), 23 \$\cdots\$ 53 50 bytes

typedef unsigned long long L;L f(L x){x/=sqrt(2);}

Try it online!

Saved 6 bytes thanks to a'_'!!!
Added 38 bytes to fix type error kindly pointed out by S.S. Anne.
Saved 3 bytes thanks to rtpax!!!

Noodle9

Posted 2020-01-24T06:03:21.767

Reputation: 2 776

118 bytes – None – 2020-01-24T16:36:28.040

@a` Thanks so much - always wanted to try that trick! :-) – Noodle9 – 2020-01-24T16:40:30.010

1Breaks the rule: "You are required to use, at minimum, the largest fixed-size integer type offered by your language, and if an unsigned variant of this is available, you must use it." – S.S. Anne – 2020-01-24T21:33:56.437

@S.S.Anne Fixed that - thanks! :-) – Noodle9 – 2020-01-24T23:07:36.017

It would actually be fewer bytes to use unsigned long without the #import. Also the printf in the footer should use %lu rather than %d. – Deadcode – 2020-01-25T06:21:51.897

@Deadcode From your challenge rules I assumed unsigned long long would be needed – Noodle9 – 2020-01-25T07:50:51.347

Well, I suppose it depends on what range of gcc versions/platforms you're targeting. I'm not sure at what point long became 64 bits, and how standard that is among gcc builds. – Deadcode – 2020-01-25T08:12:15.243

2@Deadcode Exactly, so in such circumstances you use unsigned long long to cover all possibilities (including future possibilities) and clearly state you want the biggest. Or simply use uint64_t which uses less bytes including the #import. – Noodle9 – 2020-01-25T10:38:54.310

@Noodle9: GNU C on 64-bit targets defines an __int128 type. You can use unsigned __int128 twice which is probably shorter than #include to uint64_t. C++ might even get away with auto for the return type. Err no, that would be double. – Peter Cordes – 2020-01-25T19:20:35.090

Also, if you want to write in actual C, not some silly abuse of how GCC compiles with optimization disabled, take a pointer arg and do *x/=sqrt(2) to avoid return. – Peter Cordes – 2020-01-25T19:21:58.150

Hmm, __int128 is wide enough for the precision of double division. Or __uint128_t is also a pre-defined builtin type with no headers. So __uint128_t f(__uint128_t x){x/=sqrt(2);} actually works, 41 bytes (or 48 bytes with a return) https://tio.run/##S9ZNT07@/z8@vjQzr8TQyCK@RCFNA5lXoVldlFpSWpSnUKFvW1xYVKJhpGld@z83MTNPQ7O6oAioME1DSTUnp1QBRMTkKekoaJTmFWem56WmKOTk56WDCc00DUMDTVxSlkZGxsbmRgbGZhamJubmphYG5pogWwA, or 43 with *x

– Peter Cordes – 2020-01-25T19:27:58.683

@Deadcode, Noodle9: On TIO (which is x86-64) unsigned long is the largest possible unsigned integer type. The challenge doesn't seem to require the code to be portable, so I would say that it's valid. – S.S. Anne – 2020-01-25T20:28:46.290

@S.S.Anne To quote your quote of the challenge: "You are required to use, at minimum, the largest fixed-size integer type offered by your language/" I'd say that's not saying largest available on TIO, but requires the code to be portable, – Noodle9 – 2020-01-25T21:29:17.100

@Noodle9 Well, unsigned long is the largest possible integer type on x86-64. It's open to interpretation; we'll see what Deadcode says. And if so, you might have to use uintmax_t in your answer. – S.S. Anne – 2020-01-25T22:01:27.517

I like that you and @S.S.Anne have golf-optimized for different circumstances... yours is more portable, while using __int128 is targeted at the 64-bit platforms only. I think you should both edit the language name in your answer to reflect this. – Deadcode – 2020-01-26T01:23:43.800

@Deadcode This actually isn't "more portable", per se. #import is a GNU extension, which should be replaced with #include in production code. – S.S. Anne – 2020-01-26T01:44:21.823

2@S.S.Anne I mean portable to different gcc versions/platforms. The language name is "C (gcc)", after all. – Deadcode – 2020-01-26T02:02:29.063

1

You can get 50 bytes by typedef-ing instead of including

– rtpax – 2020-01-27T16:27:11.783

@rtpax Thanks - that's a great idea! :-) – Noodle9 – 2020-01-27T17:48:53.597

3

C (gcc), Precision limited by built-in types, 42 36 bytes

__int128 f(__int128 n){n/=sqrtl(2);}

Try it online!

Floor for the most part but the last output is ceiling.

Uses GCC's __int128 type: shorter in text length than unsigned long, can represent every value in unsigned long, and determined to not be a builtin type. Stay tuned for 6-8 weeks to get arbitrary precision.

-6 bytes thanks to Peter Cordes!

S.S. Anne

Posted 2020-01-24T06:03:21.767

Reputation: 1 161

2I wouldn't really consider __uint128_t to be a built-in type, considering that you can't use integer literals of that size nor print them without a custom function. (There's also the fact that the 128-bitness isn't taken advantage of, precise-wise.) I would accept a limited-precision answer using unsigned 64-bit integers. – Deadcode – 2020-01-24T23:15:02.603

1@Deadcode this is inadvertently a size optimization -- unsigned long long is longer text-wise. – S.S. Anne – 2020-01-25T02:21:52.973

I see! Nice optimization then. FWIW, in gcc and clang you'd only need unsigned long. In MSVC you would indeed need unsigned long long or an #include, however it also has unsigned __int64. – Deadcode – 2020-01-25T06:17:00.930

@Deadcode Those are all still longer than __uint128_t. – S.S. Anne – 2020-01-25T18:22:20.693

2@Deadcode: even __int128 is large enough to hold every input for which this function produces a correct result (limited by 80-bit long double if we're compiling for x86-64 System V with an ABI where long double is the x87 type, unlike on Windows where long double = double). There may be ABIs where long double is a float128, possibly POWER? But anyway, can you use a signed type if it can handle every value your function works precisely for? – Peter Cordes – 2020-01-25T20:22:49.687

@PeterCordes I would say so, based on the previous comment. That's a good idea. – S.S. Anne – 2020-01-25T20:23:52.843

Just for the record, __uint128_t and [unsigned] __int128 are only defined by GNU C compilers when compiling for 64-bit targets. Is there a 128 bit integer in gcc?. (i.e. x86-64 but not with -m32)

– Peter Cordes – 2020-01-25T20:25:54.440

I only mention it because the question of portability (e.g. to MSVC) came up, and in case future readers were curious about __uint128_t for non-golf reasons. (And shameless self-promotion of my canonical answer on SO about compiler support for GNU C __int128) – Peter Cordes – 2020-01-25T20:33:51.153

__int128 isn't unsigned as per the challenge. To quote your quote of the challenge: "Breaks the rule: "You are required to use, at minimum, the largest fixed-size integer type offered by your language, and if an unsigned variant of this is available, you must use it." Emphasis yours. – Noodle9 – 2020-01-25T21:32:59.303

That's got nothing to do with whether the type is signed or unsigned.The quote isn't about whether or not a given type fits inside another type. It straight out says that if you have unsigned integral types you must use them. – Noodle9 – 2020-01-25T22:11:21.550

2@Noodle9 This is compatible with the intent of the rules I set forth, which are that you must use an equivalent precision to {what is offered by your largest fixed-size integer, unsigned if that variant exists}... and since __int128/__uint128 isn't a full-fledged builtin, as explained above, and also given that the max precision for this class of answer is an interaction between the floating point and the integer type, __int128 is still offering the maximum precision that unsigned long long would provide. I'd like to rephrase the rules to reflect this; suggestions would be welcome. – Deadcode – 2020-01-26T01:23:45.450

@Deadcode Then simply say that you must use an integral type that can hold all of the values that the largest builtin fixed-size integer type (unsigned if that variant exists} offered by your language can. – Noodle9 – 2020-01-26T22:27:15.037

2

Keg, 6 bytes

21½Ë/ℤ

Try it online!

This defines the function f as:

  • Taking a single parameter, then
  • Calculating the square root of 2 by raising it to the power of 0.5, then
  • Dividing the parameter by root 2, then
  • Casting the result to an integer (truncating / flooring the result) and returning it.

The footer is to define the test cases in a nice way.

Explained in a usual way

21½Ë/ℤ
2   # Push 2 to the stack
 1½ # Push 1 and halve it to get 0.5
   Ë    # Push 2 ** 0.5 (x ** 1/2 = sqrt(x))
    /ℤ  # Divide and cast to integer (floor) 

Sorry, we're all out of ketchup. You'll have to squeeze your own.

Lyxal

Posted 2020-01-24T06:03:21.767

Reputation: 5 253

What does that last comment mean? – S.S. Anne – 2020-01-25T20:19:48.683

@S.S.Anne, it's a reference to how the author asked for an explanation here

– Lyxal – 2020-01-25T21:29:30.360

2

Python 3, 22 21 bytes

lambda x:int(x/2**.5)

Try it online!

-1 byte thanks to @RGS. Thanks for reminding me that implicit decimals exist

Just a port of my Keg answer. Nothing special here.

Lyxal

Posted 2020-01-24T06:03:21.767

Reputation: 5 253

Save 1 byte by writing .5 instead of 0.5, no? – RGS – 2020-01-24T07:27:42.150

c.f. this Python 3 answer (19 bytes, rounds down): https://codegolf.stackexchange.com/a/198435/75323

– RGS – 2020-01-24T07:56:31.853

2

Haskell, 20 bytes

f n=round$n/(sqrt 2)

Try it online

RGS

Posted 2020-01-24T06:03:21.767

Reputation: 5 047

This doesn't match the requirements. The question says to use at least,the largest fixed size (unsigned) integer type. That type happens to be Word64 (or Word on a 64-bit system). The current answer can't even accept integers as input, only floating point values. It also gets the incorrect answer due to precision loss even when you allow a Double as input with Word ouput. Try it online!

– Potato44 – 2020-01-27T08:10:53.077

Whoops, my last comment comment uses a number too big for a 64 bit Word, but here is one demonstarting the accuracy problem properly Try it online!

– Potato44 – 2020-01-27T08:27:40.103

@Potato44 ty for your feedback! Since you have to import Data.Word, doesn't it mean that I can get away without having to support it? – RGS – 2020-01-27T08:49:41.910

Word is part of the prelude, I just had Data.Word imported because I was using Word64, but forgot to remove the import.

Even if it was not the case that Word was in the prelude, my interpretation is you would still have to import it as it is part of the standard library. But @Deadcode would be better at ruling on that.

Also you can write functions that accept Word64 without importing Data.Word if you make them polymorphic enough. – Potato44 – 2020-01-27T08:58:23.287

@Potato44 in any case I can mark my answer as non-competing. Thanks for teaching me something – RGS – 2020-01-27T09:04:18.507

2

MathGolf, 4 bytes

2√/i

Try it online.

Explanation:

2√    # Take the square-root of 2
  /   # Divide the (implicit) input-integer by this
   i  # Cast it to an integer, truncating any decimal values
      # (after which the entire stack joined together is output implicitly as result)

Kevin Cruijssen

Posted 2020-01-24T06:03:21.767

Reputation: 67 575

1I copied your √ character to use in my Mathematica answer. TIO counts that character as 3 bytes, so I should do the same, right? If so, why would you get to count it as 1? I'm new to this so an explanation would be great ^^ – RGS – 2020-01-24T08:54:42.030

4

Hi @RGS, welcome to CGCC! :) The language I use (MathGolf), has just like most other golfing languages (i.e. 05AB1E, Jelly, Charcoal, etc.) a custom codepage (which I usually link in the bytes part of the title). These codepages will contain 256 characters which are encoded as 1 byte each. That's why the is 1 byte in my answer, but 3 bytes in Mathematica, which uses UTF-8 encoding by default (I think, most languages use UTF-8, but I never used Mathematica, so I'm not 100% sure what the default codepage is).

– Kevin Cruijssen – 2020-01-24T08:58:21.483

3@RGS Mathgolf, like many golfing languages, uses a SBCS (Single Byte Code Set), so all 256 characters used in the language count as one byte. Mathematica presumably uses UTF-8, where that character is three bytes – Jo King – 2020-01-24T08:58:24.487

2

@RGS Here also an example in a comment of an 05AB1E (legacy) answer of mine, where the creator of the 05AB1E language explains how the three hexadecimal bytes using 05AB1E encoding can be verified with the --osabie flag, after someone asked a similar question as yours. :)

– Kevin Cruijssen – 2020-01-24T09:01:32.927

1KevinCruijssen, @JoKing thanks :) – RGS – 2020-01-24T09:05:44.800

@KevinCruijssen say I wanted to create a golfing lang. Of course I'd want to define as many one-char functions as possible. I'd just have to list those 256 and say "this is my base encoding, all these are worth one byte"? – RGS – 2020-01-24T14:31:04.910

2

@RGS Tbh, I'm not sure, but I think you'd have to prove each of them can be stored in a single byte on local disk using your encoding. Although I never created a language, so I honestly don't know. Usually those who create a golfing language add a small section on their github README page to explain how to encode it in a single byte each. I.e. the Usage/Compiling section of MathGolf or the Execution section of 05AB1E.

– Kevin Cruijssen – 2020-01-24T14:38:08.313

@KevinCruijssen thanks for the links – RGS – 2020-01-24T14:55:43.043

2

TI-BASIC, 5 bytes

int(Ans√(2⁻¹

Built-ins are great.
Input is a number in Ans.
Output is what is specified in the challenge.

Explanation:

       √(2⁻¹   ;get the square root of 1/2
    Ans        ;get the input (Ans)
               ;implicit multiplication
int(           ;truncate
               ;implicit print of Ans

Note: TI-BASIC is a tokenized language. Character count does not equal byte count.

Tau

Posted 2020-01-24T06:03:21.767

Reputation: 1 935

Which TI calculator is this for? On TI-85, it's int Ans√2⁻¹, which is still 5 bytes. On TI-89 and TI-92, it's ans(1), not Ans. Edit: Ah, TI-83. – Deadcode – 2020-01-24T11:00:24.747

@Deadcode the general consensus, as far as I am aware, is that submissions are for the TI-83 and TI-84 series of calculators (correct me if i'm wrong). Specific versions are specified in the title of the submission when needed. – Tau – 2020-01-24T11:04:36.553

2

CJam, 9 bytes

CJam has mQ, but unfortunately it trunctuates to an integer ... Another port of Lyxal's answer.

q~2 .5#/i

Try it online!

Explanation

q~        e# Take input & evaluate
  2       e# Take 2 to the power of ...
    .5#   e# ... 0.5 (equal to square root)
       /  e# Divide the input by it
        i e# Convert to integer

user85052

Posted 2020-01-24T06:03:21.767

Reputation:

2

Whitespace, 122 103 bytes

[S S T  T   N
_Push_-1][S S S N
_Push_0][S N
S _Dupe_0][T    N
T   T   _Read_STDIN_as_integer][T   T   T   _Retrieve_input][S N
S _Dupe_input][N
T   S T N
_If_0_Jump_to_Label_ZERO][N
S S N
_Create_Label_LOOP][S N
T   _Swap_top_two][S S S T  N
_Push_1][T  S S S _Add][S N
T   _Swap_top_two][S N
S _Dupe_input][S N
S _Dupe_input][T    S S N
_Multiply][S T  S S T   S N
_Copy_0-based_2nd_n][S N
S _Dupe_n][T    S S N
_Multiply][S S S T  S N
_Push_2][T  S S N
_Multiply][S N
T   _Swap_top_two][T    S S T   _Subtract][N
T   T   N
_If_neg_Jump_to_Label_LOOP][S N
T   _Swap_top_two][N
S S T   N
_Create_Label_ZERO][T   N
S T _Print_as_integer]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Output is rounded up.

Inspired by the following mentioned in @Deadcode's Regex answer:

For input \$N\$, we want to calculate \$M=\left\lfloor\frac{N}{\sqrt2}\right\rfloor\$. So we want the largest \$M\$ such that \$2M^2<N^2\$.

EDIT: My program now implements \$2M^2\leq N^2\$ instead to save 19 bytes (\$\lt\$ vs \$\leq\$ is irrelevant, otherwise \$\sqrt{2}\$ would be rational). Although I see @Deadcode edited his Regex answer and he's actually using \$\leq\$ as well.

Explanation in pseudo-code:

Integer n = -1
Integer input = STDIN as integer
Start LOOP:
  n = n + 1
  If(n*n*2 - input*input < 0):
    Go to next iteration of LOOP
  Print n
  (exit program with error since no exit is defined)

Example program flow (input 4):

Command  Explanation                  Stack         Heap     STDIN  STDOUT  STDERR

SSTTN    Push -1                      [-1]
SSSN     Push 0                       [-1,0]
SNS      Duplicate 0                  [-1,0,0]
TNTT     Read STDIN as integer        [-1,0]        [{0:4}]  4
TTT      Retrieve from heap #0        [-1,4]        [{0:4}]
SNS      Duplicate 4                  [-1,4,4]      [{0:4}]
NTSTN    If 0: Jump to Label ZERO     [-1,4,4]      [{0:4}]
         (^ workaround for input=0, since it would otherwise output -1)
NSSSN    Create Label LOOP            [-1,4]        [{0:4}]
SNT       Swap top two                [4,-1]        [{0:4}]
SSSTN     Push 1                      [4,-1,1]      [{0:4}]
TSSS      Add top two: -1+1           [4,0]         [{0:4}]
SNT       Swap top two                [0,4]         [{0:4}]
SNS       Duplicate 4                 [0,4,4]       [{0:4}]
SNS       Duplicate 4                 [0,4,4,4]     [{0:4}]
TSSN      Multiply top two: 4*4       [0,4,16]      [{0:4}]
STSSTSN   Copy 0-based 2nd            [0,4,16,0]    [{0:4}]
SNS       Duplicate 0                 [0,4,16,0,0]  [{0:4}]
TSSN      Multiply top two: 0*0       [0,4,16,0]    [{0:4}]
SSSTSN    Push 2                      [0,4,16,0,2]  [{0:4}]
TSSN      Multiply top two: 0*2       [0,4,16,0]    [{0:4}]
SNT       Swap top two                [0,4,0,16]    [{0:4}]
TSST      Subtract top two: 0-16      [0,4,-16]     [{0:4}]
NTTN      If neg: Jump to label LOOP  [0,4]         [{0:4}]

SNT       Swap top two                [4,0]         [{0:4}]
SSSTN     Push 1                      [4,0,1]       [{0:4}]
TSSS      Add top two: 0+1            [4,1]         [{0:4}]
SNT       Swap top two                [1,4]         [{0:4}]
SNS       Duplicate 4                 [1,4,4]       [{0:4}]
SNS       Duplicate 4                 [1,4,4,4]     [{0:4}]
TSSN      Multiply top two: 4*4       [1,4,16]      [{0:4}]
STSSTSN   Copy 0-based 2nd            [1,4,16,1]    [{0:4}]
SNS       Duplicate 1                 [1,4,16,1,1]  [{0:4}]
TSSN      Multiply top two: 1*1       [1,4,16,1]    [{0:4}]
SSSTSN    Push 2                      [1,4,16,1,2]  [{0:4}]
TSSN      Multiply top two: 1*2       [1,4,16,2]    [{0:4}]
SNT       Swap top two                [1,4,2,16]    [{0:4}]
TSST      Subtract top two: 2-16      [1,4,-14]     [{0:4}]
NTTN      If neg: Jump to label LOOP  [1,4]         [{0:4}]

SNT       Swap top two                [4,1]         [{0:4}]
SSSTN     Push 1                      [4,1,1]       [{0:4}]
TSSS      Add top two: 1+1            [4,2]         [{0:4}]
SNT       Swap top two                [2,4]         [{0:4}]
SNS       Duplicate 4                 [2,4,4]       [{0:4}]
SNS       Duplicate 4                 [2,4,4,4]     [{0:4}]
TSSN      Multiply top two: 4*4       [2,4,16]      [{0:4}]
STSSTSN   Copy 0-based 2nd            [2,4,16,2]    [{0:4}]
SNS       Duplicate 2                 [2,4,16,2,2]  [{0:4}]
TSSN      Multiply top two: 2*2       [2,4,16,4]    [{0:4}]
SSSTSN    Push 2                      [2,4,16,4,2]  [{0:4}]
TSSN      Multiply top two: 4*2       [2,4,16,8]    [{0:4}]
SNT       Swap top two                [2,4,8,16]    [{0:4}]
TSST      Subtract top two: 8-16      [2,4,-8]      [{0:4}]
NTTN      If neg: Jump to label LOOP  [2,4]         [{0:4}]

SNT       Swap top two                [4,2]         [{0:4}]
SSSTN     Push 1                      [4,2,1]       [{0:4}]
TSSS      Add top two: 2+1            [4,3]         [{0:4}]
SNT       Swap top two                [3,4]         [{0:4}]
SNS       Duplicate 4                 [3,4,4]       [{0:4}]
SNS       Duplicate 4                 [3,4,4,4]     [{0:4}]
TSSN      Multiply top two: 4*4       [3,4,16]      [{0:4}]
STSSTSN   Copy 0-based 2nd            [3,4,16,3]    [{0:4}]
SNS       Duplicate 3                 [3,4,16,3,3]  [{0:4}]
TSSN      Multiply top two: 3*3       [3,4,16,9]    [{0:4}]
SSSTSN    Push 2                      [3,4,16,9,2]  [{0:4}]
TSSN      Multiply top two: 9*2       [3,4,16,18]   [{0:4}]
SNT       Swap top two                [3,4,18,16]   [{0:4}]
TSST      Subtract top two: 18-16     [3,4,2]       [{0:4}]
NTTN      If neg: Jump to label LOOP  [3,4]         [{0:4}]

SNT       Swap top two                [4,3]         [{0:4}]
NSSTN     Create Label ZERO           [4,3]         [{0:4}]
TNST      Print as integer to STDOUT  [4]           [{0:4}]         3
                                                                            error

Program stops with an error because no exit is defined.

Kevin Cruijssen

Posted 2020-01-24T06:03:21.767

Reputation: 67 575

1@Deadcode Primarily because I would have to do an $-1$ after we've found $N+1$. So where your answer outputs $N$, mine outputs $N+1$ (excluding edge case $0$). – Kevin Cruijssen – 2020-01-24T12:34:23.747

1@Deadcode Also, Whitespace only has labels and jumps to labels to create loops and if-statements. The only jumps available are: jump unconditional; jump if 0; and jump it negative. Jump if positive is unfortunately not available (not really necessary, since one could use $×-1$ and then use the jump if neg. as alternative). Because of this I currently check whether $(N+1)^2 - 2M^2 < 0$ is truthy. If it is: continue the loop; if not: print $N+1$. – Kevin Cruijssen – 2020-01-24T12:34:51.743

1Wow, very cool that the same (or very similar) algorithm is quite fitting in both regex and Whitespace. And ≤ vs. < is of course purely a golf optimization :) If it made a difference which you used, sqrt(2) would be rational. FWIW I mis-typed the LaTeX explanation – it really is ≤ in the regex. Oh, and if this is using the same algorithm as the regex, how come this rounds up and the regex rounds down? [Edit: Oops, rewrote this comment not realizing you'd already replied to it.] – Deadcode – 2020-01-24T12:35:19.677

@Deadcode Ah, of course, $<$ vs $\leq$ is irrelevant, otherwise $\sqrt{2}$ would have been rational. Edited my answer. $<$ certainly saves bytes in my answer though, since I'd otherwise have to add a Duplicate, Jump if 0, and additional label which discards the duplicate before continuing with the loop (what I had in my initial 122 byter). – Kevin Cruijssen – 2020-01-24T12:53:07.123

2

PowerShell, 67 bytes

param([uint64]$n)($n/[math]::Sqrt(2)).ToString("G17")-replace'\..*'

Try it online!

.NET (and thus, by extension, PowerShell) doesn't have a BigDecimal, so we're limited to Double or Decimal. However, the [math]::Sqrt() function only works on Double, so there we're stuck. So far, so standard. We then specify precision with G17, which successfully round-trips to give us 17 digits of precision on our Double, so we can pass everything but the last three test cases. We finish that off with a simple truncation -replace.

AdmBorkBork

Posted 2020-01-24T06:03:21.767

Reputation: 41 581

2

JavaScript (Node.js) arbitrary-precision, 62 58 bytes

Thanks to Arnauld saving 4 bytes

(n,v=n*n/2n,m=x=>x-(y=v/x+x>>1n)>>1n?m(y):y)=>v<2n?v:m(1n)

Try it online!

This is sqrt(n*n/2) after golfing the iterative Newton method sqrt() from https://stackoverflow.com/a/53684036.

James

Posted 2020-01-24T06:03:21.767

Reputation: 491

2

Burlesque, 8 bytes

@2r@|/R_

Try it online!

@2   # Push 2.0
r@   # Sqrt it
|/   # Cast input to number, divide input by 2
R_   # Round to nearest

DeathIncarnate

Posted 2020-01-24T06:03:21.767

Reputation: 916

1

cQuents, 11 bytes

#|1:A_/2^.5

Try it online!

Explanation

#|1          output the first term
   :         mode: sequence
             each term equals:
    A        input
     _/            //
       2              2
        ^               **
         .5                .5

Stephen

Posted 2020-01-24T06:03:21.767

Reputation: 12 293

1

Charcoal, 46 bytes

≔⁰θ≔⁰ηF↨÷XN²¦²¦⁴«≔⁺×θ⁴ιθ≦⊗η¿›θ⊗η«≧⁻⊕⊗ηθ≦⊕η»»Iη

Try it online! Link is to verbose version of code. Performs an arbitrary-precision floored integer square root of n²/2 using the binary square root algorithm as demonstrated e.g. by Dr. Math. Explanation:

≔⁰θ≔⁰η

Set the accumulator and result to zero.

F↨÷XN²¦²¦⁴«

Loop over the base 4 digits of n²/2.

≔⁺×θ⁴ιθ

Multiply the accumulator by 4 and add the next digit.

≦⊗η

Double the result.

¿›θ⊗η«

If the accumulator is greater than double the doubled result, ...

≧⁻⊕⊗ηθ≦⊕η

... then subtract the incremented doubled result from the accumulator and increment the result.

»»Iη

Print the result once all of the digits have been processed.

Neil

Posted 2020-01-24T06:03:21.767

Reputation: 95 035

1

Pari/GP, 17 bytes

Another arbitrary-precision answer.

n->sqrtint(n^2\2)

Try it online!

alephalpha

Posted 2020-01-24T06:03:21.767

Reputation: 23 988

1

Haskell, 32 bytes

h n=last[x|x<-[0..n],2*x^2<=n^2]

This submission works for arbitrary precision integers, but is very slow because it checks every number \$x\$ below \$n\$ for whether it satisfies the equation \$ 2x^2\leq n^2\$, then takes the last one. Thus the runtime is exponential in the bit length of the input number.

Try it online!

Haskell, 64 bytes

g n|n<2=n|s<-g(n`div`4)*2=last$s+1:[s|(s+1)^2>n]
f n=g$n*n`div`2

This submission also works for arbitrary precision integer and is much faster (all test cases instantaneous). It is based on the digit-by-digit integer square root listed on Wikipedia.

Try it online!

Potato44

Posted 2020-01-24T06:03:21.767

Reputation: 2 835

1

Ruby, 20 bytes

->n{(n/2**0.5).to_i}

Try it online!

G B

Posted 2020-01-24T06:03:21.767

Reputation: 11 099

1

AWK, 19 17 bytes

1,$0=int($0/2^.5)

Try it online!

rootbeersoup

Posted 2020-01-24T06:03:21.767

Reputation: 111

1

Husk, 3 bytes

÷√2

Try it online!

Explanation

 √2  Find the square root of 2 (pretty straightforward).
÷  ⁰ Floor division with the input.
     Note that the numerator is the input, NOT the square root of 2.

user85052

Posted 2020-01-24T06:03:21.767

Reputation:

0

R, 19 bytes

function(i)i%/%2^.5

Try it online!

niko

Posted 2020-01-24T06:03:21.767

Reputation: 231