title: Implement the Polygamma function

text:
# Question
Title: Implement the Polygamma function
The Polygamma function of order \\$m\\$, \\$\psi^{(m)}(z)\\$, is the \\$(m + 1)\\$th derivative of the logarithm of the gamma function, which is also the \\$m\\$th derivative of the digamma function. Your task is to take an integer \\$m\\$ and a positive real number \\$z\\$ and output \\$\psi^{(m)}(z)\\$

## Definitions

For those unfamiliar with the functions above (Gamma, Digamma and Polygamma), here are a few different definitions for each:

### \\$\Gamma(z)\\$

* The gamma function is an extension of the factorial (\\$x! = 1\cdot2\cdot3\cdots(x-1)\cdot(x)\\$) to real numbers
* \\$\Gamma(z) = \int\_{0}^{\infty}x^{z-1}e^{-x}dx\\$
* \\$\Gamma(n) = (n - 1)! \\:,\\:\\: n \in \mathbb{N}\\$
* \\$\Gamma(n+1) = n\Gamma(n) \\:,\\:\\: n \in \mathbb{N}\\$

### \\$\psi(z)\\$

* The digamma function is the logarithmic derivative of the gamma function
* \\$\psi(z) = \frac{d}{dz}\ln(\Gamma(z))\\$
* \\$\psi(z) = \frac{\Gamma'(z)}{\Gamma(z)}\\$
* \\$\psi(z + 1) = \psi(z) + \frac{1}{z}\\$

### \\$\psi^{(m)}(z)\\$

* The polygamma function of order \\$m\\$ is the \\$m\\$th derivative of the digamma function
* \\$\psi^{(m)}(z) = \frac{d^m}{dz^m}\psi(z)\\$
* \\$\psi^{(m)}(z) = \frac{d^{m+1}}{dz^{m+1}}\ln(\Gamma(z))\\$
* \\$\psi^{(m)}(z+1)= \psi^{(m)}(z) + (-1)^m\frac{m!}{z^{m+1}}\\$

## Task

You are to take two inputs, a natural number \\$m\\$ and a positive real number \\$z\\$, and output \\$\psi^{(m)}(z)\\$. The inputs and outputs will always fit within the number bounds of your language, but your algorithm must work *theoretically* for any and all inputs.

As the output is usually going to be a real number, rather than an integer, the output should be correct to at least 10 significant figures. Trailing zeros may be omitted for exact values. For example, if the output is an integer, trailing decimal `0`s are not required, but are allowed if you want.

This is so the shortest code in bytes wins.

## Test cases

Results may differ due to floating point inaccuracies, Python's scipy library was used to generate the values. Values are rounded to 15d.p., unless otherwise stated.

```
 m,                  z -> ψ⁽ᵐ⁾(z)
17,                  2 -> 1357763223.715975761413574
 5,                 40 -> 0.0000002493894351
 9,           53.59375 -> 0.00000000001201026493
35,                  9 -> 469354.958166260155849
46,                  5 -> -7745723758939047727202304.000000000000000
 7, 1.2222222222222222 -> 1021.084176496877490
28,               6.25 -> -2567975.924144014250487
 2,               7.85 -> -0.018426049840992

```

This table has the values of \\$\psi^{(m)}(z)\\$ for \\$0 \le m \le 9\\$ and \\$1 \le z \le 20\\$:

```

+---+------------------------+---------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+
|   |           1            |          2          |         3          |         4          |         5          |         6          |         7          |         8          |         9          |         10         |         11         |         12         |         13         |         14         |         15         |         16         |         17         |         18         |         19         |         20         |
+---+------------------------+---------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+
| 0 |   -0.577215664901533   |  0.422784335098467  | 0.922784335098467  | 1.256117668431800  | 1.506117668431800  | 1.706117668431800  | 1.872784335098467  | 2.015641477955610  | 2.140641477955610  | 2.251752589066721  | 2.351752589066721  | 2.442661679975812  | 2.525995013309145  | 2.602918090232222  | 2.674346661660794  | 2.741013328327460  | 2.803513328327460  | 2.862336857739225  | 2.917892413294781  | 2.970523992242149  |
| 1 |   1.644934066848227    |  0.644934066848227  | 0.394934066848226  | 0.283822955737115  | 0.221322955737115  | 0.181322955737115  | 0.153545177959338  | 0.133137014694031  | 0.117512014694031  | 0.105166335681686  | 0.095166335681686  | 0.086901872871768  | 0.079957428427324  | 0.074040268664010  | 0.068938227847684  | 0.064493783403239  | 0.060587533403239  | 0.057127325790783  | 0.054040906037696  | 0.051270822935203  |
| 2 |   -2.404113806319188   |  -0.404113806319189 | -0.154113806319189 | -0.080039732245115 | -0.048789732245114 | -0.032789732245115 | -0.023530472985855 | -0.017699569195768 | -0.013793319195768 | -0.011049834970802 | -0.009049834970802 | -0.007547205368999 | -0.006389797961592 | -0.005479465690312 | -0.004750602716552 | -0.004158010123959 | -0.003669728873959 | -0.003262645625435 | -0.002919710097314 | -0.002628122402315 |
| 3 |   6.493939402266829    |  0.493939402266829  | 0.118939402266829  | 0.044865328192755  | 0.021427828192755  | 0.011827828192755  | 0.007198198563125  | 0.004699239795945  | 0.003234396045945  | 0.002319901304290  | 0.001719901304290  | 0.001310093231071  | 0.001020741379219  | 0.000810664701232  | 0.000654479778283  | 0.000535961259764  | 0.000444408525389  | 0.000372570305061  | 0.000315414383708  | 0.000269374221340  |
| 4 |  -24.886266123440890   |  -0.886266123440879 | -0.136266123440878 | -0.037500691342113 | -0.014063191342113 | -0.006383191342113 | -0.003296771589026 | -0.001868795150638 | -0.001136373275638 | -0.000729931168235 | -0.000489931168235 | -0.000340910050701 | -0.000244459433417 | -0.000179820455575 | -0.000135196191875 | -0.000103591253604 | -0.000080703070010 | -0.000063799959344 | -0.000051098643488 | -0.000041405977726 |
| 5 |  122.081167438133861   |  2.081167438133896  | 0.206167438133897  | 0.041558384635954  | 0.012261509635954  | 0.004581509635954  | 0.002009493175049  | 0.000989510004771  | 0.000531746332896  | 0.000305945162117  | 0.000185945162117  | 0.000118208290511  | 0.000078020533309  | 0.000053159387985  | 0.000037222150950  | 0.000026687171526  | 0.000019534614153  | 0.000014563111016  | 0.000011034967722  | 0.000008484266206  |
| 6 |  -726.011479714984489  |  -6.011479714984437 | -0.386479714984435 | -0.057261607988551 | -0.013316295488551 | -0.004100295488551 | -0.001528279027645 | -0.000654007738836 | -0.000310684984930 | -0.000160150871077 | -0.000088150871077 | -0.000051203486564 | -0.000031109607963 | -0.000019635233198 | -0.000012804988755 | -0.000008590996985 | -0.000005908787970 | -0.000004154139804 | -0.000002978092040 | -0.000002172607350 |
| 7 |  5060.549875237640663  |  20.549875237639476 | 0.862375237639470  | 0.094199654649073  | 0.017295357774073  | 0.004392957774073  | 0.001392271903016  | 0.000518000614207  | 0.000217593204539  | 0.000100511115987  | 0.000050111115987  | 0.000026599144024  | 0.000014877714841  | 0.000008699205352  | 0.000005284083130  | 0.000003317553637  | 0.000002144087193  | 0.000001421585007  | 0.000000964233099  | 0.000000667475582  |
| 8 | -40400.978398747647589 | -80.978398747634884 | -2.228398747634885 | -0.179930526327158 | -0.026121932577158 | -0.005478092577158 | -0.001477178082416 | -0.000478010895205 | -0.000177603485537 | -0.000073530517936 | -0.000033210517936 | -0.000016110901963 | -0.000008296615840 | -0.000004494456155 | -0.000002542957742 | -0.000001494142013 | -0.000000907408791 | -0.000000567407762 | -0.000000364140247 | -0.000000239189714 |
| 9 | 363240.911422382690944 | 360.911422382626938 | 6.536422382626807  | 0.391017718703625  | 0.044948382766125  | 0.007789470766125  | 0.001788099024012  | 0.000503455497598  | 0.000165497161722  | 0.000061424194120  | 0.000025136194120  | 0.000011145599233  | 0.000005284884641  | 0.000002652620244  | 0.000001398085550  | 0.000000768796112  | 0.000000438758675  | 0.000000258758130  | 0.000000157124373  | 0.000000097937278  |
+---+------------------------+---------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+

```

# Answer
# JavaScript (ES7),  ~~68 66 61~~  59 bytes

Expects `(m)(z)`.

```
(m,n=m)=>g=z=>n?-n--*g(z):eval("for(k=5e6;k--;)n-=z++**~m")

```

Try it online!

This is based on the following series representation (from Wikipedia):

$$\psi^{(m)}(z)=(-1)^{m+1}m!\sum\_{k=0}^{\infty}\dfrac{1}{(z+k)^{m+1}}$$

### Commented

```
(m, n = m) =>                // outer function taking m and saving a copy in n
g = z =>                     // inner recursive function taking z
  n ?                        // if n is not equal to 0:
    -n--                     //   yield -n to invert the sign; decrement n afterwards
    * g(z)                   //   multiply by the result of a recursive call
  :                          // else:
    eval(                    //   evaluate as JS code:
      "for(k = 5e6; k--;)" + //     repeat 5 million times:
        "n -= z++ ** ~m"     //       subtract z ** -(m+1) from n; increment z
    )                        //   end of eval(), which returns the final value of n

```
> 16 votes

# Answer
# Mathematica, 9 bytes

```
PolyGamma

```

Of course Mathematica has a builtin for this
> 11 votes

# Answer
# Mathematica, 32 bytes (30 characters)

Without any `Gamma` related builtin, uses Bubbler's formula

```
Sum[#!/(-#2-x)^(#+1),{x,0,∞}]&

```

Try it online!

# Mathematica, 29 bytes

Without `PolyGamma[z]` or `PolyGamma[n, z]`

```
Log@Gamma@x~D~{x,#+1}/.x->#2&

```

Try it online!

# Mathematica, 27 bytes

With `PolyGamma[z]` (this is the equivalent of the digamma function, or \\$\large\psi^0(z)\\$)

```
PolyGamma@x~D~{x,#}/.x->#2&

```

Try it online!

A few Mathematica programs that don't use the builtin `PolyGamma[n, z]`.
> 9 votes

# Answer
# , 8 bytes

```
psigamma

```

Try it online!

Takes inputs `z,m` (test harness stolen from Dominic's answer).

R has a builtin as part of its Special Functions of Mathematics including various forms of the gamma function.
> 8 votes

# Answer
# 05AB1E, ~~16~~ 15 bytes

```
₄nÝ+I±mOI!IÉ·<P

```

-1 byte thanks to *@ovs*.

First input is \\$z\\$, second input is \\$m\\$.

Try it online or verify all test cases.

**Explanation:**

Uses the same algorithm as in *@Arnauld*'s JavaScript answer, so make sure to upvote him.
Or to be more precise, it uses the algorithm:

$$\psi^{(m)}(z)=(m\text{%}2\times2-1)\times m!\times\sum\_{k=0}^{1000^2}{(z+k)^{\sim m}}$$

```
₄         # Push 1000
 n        # Square it to 1000000
  Ý       # Pop and push a list in the range [0,1000000]
   +      # Add the first (implicit) input-integer `z` to each value
    I     # Push the second input `m`
     ±    # Take it's bitwise-NOT: -m-1
      m   # Take each value to the power this `-m-1`
       O  # Sum all values in the list together
I!        # Push the second input `m` again, and take its factorial
IÉ        # Push the second input `m` again, and check if it's odd
          # (1 if truthy; 0 if falsey)
  ·       # Double that
   <      # And decrease it by 1
P         # And finally take the product of all three values on the stack
          # (after which it is output implicitly as result)

```

NOTE: If there are any very minor inaccuracies in the decimals, the `₄n` (\\$1\text{,}000\text{,}000\\$) could be replaced with `žm` (\\$9\text{,}876\text{,}543\text{,}210\\$), although it would be too slow to run on TIO in that case.
> 7 votes

# Answer
# APL (Dyalog Unicode) 18.0, 20 bytes

```
+/!⍤⊣÷(-(⍳!9)+⊢)*1+⊣

```

Try it online!

-2 bytes thanks to Adám and ngn.

---

# APL (Dyalog Unicode), 22 bytes

```
{+/(!⍺)÷(-⍵+⍳1e6)*1+⍺}

```

Try it online!

Left argument is \\$m\\$, right arg is \\$z\\$.

Uses a slight modification of the formula used by other answers:

$$ \begin{aligned} \psi^{(m)}(z)&=(-1)^{m+1}m!\sum\_{k=0}^{\infty}\dfrac{1}{(z+k)^{m+1}} \\ &\approx\sum\_{k=0}^{10^6-1}\dfrac{m!}{(-z-k)^{m+1}} \end{aligned} $$

### How it works

```
{+/(!⍺)÷(-⍵+⍳1e6)*1+⍺}  ⍝ ⍺←m, ⍵←z
         -⍵+⍳1e6        ⍝ vector of -(z+0..999999)
        (       )*1+⍺   ⍝ raise each to the power of 1+m
 +/(!⍺)÷                ⍝ divide m! by each of above and sum them

```
> 6 votes

# Answer
# Octave / MATLAB, 4 bytes

```
@psi

```

Try it online!
> 5 votes

# Answer
# , ~~52~~ ~~51~~ ~~45~~ 44 bytes

*Edit: -1+1 bytes thanks to Giuseppe, who also pointed out that there is already a built-in  function, `psigamma`, that solves the task for only 8 bytes*

*Edit2: ...and -6 more bytes thanks to Robin Ryder*

```
function(m,z)gamma(M<-m+1)*sum((-z:-1e4)^-M)

```

Try it online!

Uses the same formula as Arnauld's answer.
Series representations like this are very well-suited to  as a natively-vectorized language.

Change the `1e4` to higher values (up to `9e9` without increasing the byte count) for progressively higher-accuracy and slower runtime.
> 4 votes

# Answer
# Python 3, 38 bytes

```
from scipy.special import*
f=polygamma

```

Try it online!
> 2 votes

# Answer
# Java, ~~168~~ ~~148~~ 102 bytes

```
(m,z)->{double p=1-m%2*2,f=0;long i=m;for(;i>0;)p*=i--;for(;i<1e7;)f-=p*Math.pow(z+i++,~m);return f;};

```

## Explanation

I used the same algorithm as in @Arnauld's JavaScript answer. Please vote his answer up.

For convenience, here the auto-formatted version:

```
(m, z) -> {
      double p = 1 - m % 2 * 2, f = 0;
      long i = m;
      for (; i > 0; ) p *= i--;
      for (; i < 1e7; ) f -= p * Math.pow(z + i++, ~m);
      return f;
    };

```

So typical Java code: quite verbose. At least my version.

Edit: could save 20 bytes thanks to @user

Edit: saved even more bytes thanks to @ceilingcat

Try it online
> 2 votes

# Answer
# Pyth, 24 bytes

```
**^_1JhhQ*FhQsm^+deQ_JCG

```

Try it online! (link points to slightly different code that sums `1e5` terms instead of `1.56e62` terms to make code runnable and avoid overflow errors)

## Explanation

Uses the same algorithm as in @Arnauld's JavaScript answer, so make sure to upvote him.

```
**^_1JhhQ*FhQsm^+deQ_JCG
     JhhQ                  : Set J to first input + 1
  ^_1J                     : -1 ^ J
 *       *FhQ              : times factorial of first input
*            s             : times sum of
              m            : mapping
               ^+deQ_J     :   F(d): (d + (second input)) ^ -J
                      CG   : on range(1.56e62)

```
> 1 votes

# Answer
# Scala, 68 bytes

*Saved 3 bytes and fixed my answer thanks to Arnauld*

Uses the algorithm from Arnauld's answer

```
m=>z=>(0 to 1<<20 map(z+_ pow ~m)sum)*(m%2*2-1)*(1.0/:(1 to m))(_*_)

```

Try it online!
> 1 votes

---
Tags: code-golf, math, number
---


title: Let's Decrypt It!

text:
# Question
Title: Let's Decrypt It!
# Note

This is the decryption challenge. The encryption challenge can be found here.

# Challenge

The challenge is to decrypt a given string, using the rules as specified below. The string will only contain **lowercase alphabets**, **digits**, and/or **blank spaces**. If you want to know how the input string has been encrypted, refer to this challenge!

# Equivalent of a Character

Now, firstly you would need to know how to find the "equivalent" of each character.

If the character is a consonant, this is the way of finding it's equivalent:

```
1) List all the consonants in alphabetical order
    b c d f g h j k l m n p q r s t v w x y z
2) Get the position of the consonant you are finding the equivalent of.
3) The equivalent is the consonant at that position when starting from the end.

```

eg: 'h' and 't' are equivalents of each other because 'h', 't' are in the 6th position from start and end respectively.

The same procedure is followed to find the equivalent of vowels/digits. You list all the vowels or the digits (starting from 0) in order and find the equivalent.

Given below is the list of the equivalents of all the characters:

```
b <-> z
c <-> y
d <-> x
f <-> w
g <-> v
h <-> t
j <-> s
k <-> r
l <-> q
m <-> p
n <-> n

a <-> u
e <-> o
i <-> i

0 <-> 9
1 <-> 8
2 <-> 7
3 <-> 6
4 <-> 5

```

# Rules of Decrypting

1. You start with two empty strings, let's call them `s1` and `s2`. We will be moving from left to right of the input string. At the beginning, we would be considering the first empty string, i.e, `s1`. We will be switching between the two strings whenever we encounter a vowel.
2. We take the equivalent of the current character of the input string, or a blank space if it is a blank space. Let's call this character `c`. `c` is now appended to the **right of** `s1` (if we are considering `s1` currently) or to the **left of** `s2` (if we are considering `s2` currently).
3. If that character was a vowel, switch to the other string now (`s1 <-> s2`).
4. Repeat step 2 (and 3 for vowels) for every character in the input string.
5. Concatenate `s1` and `s2` and the result is the decrypted string.

Now let me decrypt a string for you.

```
String = "htioj ixej uy "
Initially, s1 = s2 = ""
Current: s1
Moving left to right
"h" -> "t" (s1 = "t")
"t" -> "h" (s1 = "th")
"i" -> "i" (s1 = "thi")
Vowel encountered. Switching to s2 now.
"o" -> "e" (s2 = "e")
Vowel encountered. Switching to s1 now.
"j" -> "s" (s1 = "this")
" " -> " " (s1 = "this ")
"i" -> "i" (s1 = "this i")
Vowel encountered. Switching to s2 now.
"x" -> "d" (s2 = "de") [Note that when dealing with s2, we append to the left]
"e" -> "o" (s2 = "ode")
Vowel encountered. Switching to s1 now.
"j" -> "s" (s1 = "this is"
" " -> " " (s1 = "this is ")
"u" -> "a" (s1 = "this is a")
Vowel encountered. Switching to s2 now.
"y" -> "c" (s2 = "code")
" " -> " " (s2 = " code")
Now, append s1 and s2 to get:
"this is a code"

Output -> "this is a code"

```

# Examples

```
"wqcjmc" -> "flyspy"
"toek" -> "hero"
"toyike" -> "heroic"
"uo" -> "ae"
"uoz" -> "abe"
"htoo jmuy" -> "the space"
"uh68v8x " -> "a d1g13t"
"fo78i d" -> "we xi12"
"htioj ixej uy " -> "this is a code"
"jea ceeac hnx8x vni kokhj jiuth xoqqc xohmcky" -> "so you really decrypted this string d1dnt you"

```

You may also choose to use uppercase alphabets instead of lowercase.

# Scoring

This is , so the shortest code wins!

# Answer
# Jelly, 29 bytes

```
ØḄ,ØẹØDṭ,U$F€yµe€ØẹŻœṗµ;ṚU$m2

```

A full program which prints the decoded text.

**Try it online!**

### How?

```
ØḄ,ØẹØDṭ,U$F€yµe€ØẹŻœṗµ;ṚU$m2 - Main Link: list, S
ØḄ                            - consonant characters
   Øẹ                         - vowel characters
  ,                           - pair
     ØD                       - digit characters
       ṭ                      - tack -> ["bcd...","aeiou","012..."]
          $                   - last two links as a monad:
         U                    -   upend -> ["...dcb","uoiea","...210"]
        ,                     -   pair -> [["bcd...","aeiou","012..."],["...dcb","uoiea","...210"]]
           F€                 - flatten each -> ["bcd...aeiou012...","...dcbuoiea...210"]
             y                - translate S using that map
              µ               - new monadic chain (i.e. f(A=that))
                 Øẹ           - vowel characters
               e€             - (for c in A) exists in (vowels)?
                   Ż          - prepend a zero
                    œṗ        - partition (A) before truthy elements (of that)
                      µ       - new monadic chain (i.e. f(that))
                                  ...e.g.: f(["thi","e","s i","do","s a","c "])
                          $   - last two links as a monad:
                        Ṛ     -   reverse    ["c ","s a","do","s i","e","thi"]
                         U    -   upend      [" c","a s","od","i s","e","iht"]
                       ;      - concatenate  ["thi","e","s i","do","s a","c "," c","a s","od","i s","e","iht"]
                           m2 - mod-2 slice  ["thi",    "s i",     "s a",    ," c",      "od",      "e"      ]
                              - implicit, smashing print -> this is a code

```
> 5 votes

# Answer
# JavaScript (ES6),  ~~112 110~~  109 bytes

Expects an array of characters.

```
s=>s.map(c=>(C="bzcydxfwgvhtjskrlqmpnn  aueoii",c=C[j=C.search(c)^1]||9-c,+s?b=c+b:a+=c,s^=j>23),a=b='')&&a+b

```

Try it online!

### How?

We look for the index of each character `c` in the following lookup string:

```
 0         1         2
 012345678901234567890123456789
"bzcydxfwgvhtjskrlqmpnn  aueoii"

```

If the character is not found, it must be a digit which is replaced with `9-c`. Otherwise, we get the position of the counterpart character by inverting the least significant bit of the index.

For instance: `j``12``13``s`

The new character is either appended to `a` or prepended to `b`.

We switch between `a` and `b` whenever the index is greater than 23 -- i.e. `c` is a vowel.
> 4 votes

# Answer
# Python, ~~226, 160~~ 146 bytes

Try it Online

I am fairly new to python and wanted to try this challenge. I know a lot of this can be improved using lambda or simplified code. I am showing my code so I can get feedback.

Thanks to @Arnauld for helping me learn new ways to code. Now at 160 bytes

More inputs and refinements. Now at 146.

```
def k(y):
x='aueoiibzcydxfwgvhtjskrlqmpnn0918273645  '
s=1
b=['']*2
for i in y:n=x.find(i);b[s]+=x[n+1-2*(n%2)];s^=n<6
print(b[1]+b[0][::-1])

```

Old Code:

```
def k(y):
 x='aueoiibzcydxfwgvhtjskrlqmpnn0918273645  '
 s=1
 b=c=''
 def a(t):
  m=n+1 if n%2==0 else n-1;t+=x[m];return t
 for i in y:
  n=x.find(i)
  if s:
   b=a(b)
  else:
   c=a(c)
  if n<=5:s=not s
 b+=c[::-1]
 print(b)

k('wqcjmc')
k('toek')
k('toyike')
k('uo')
k('uoz')
k('htoo jmuy')
k('uh68v8x ')
k('fo78i d')
k('htioj ixej uy ')
k('jea ceeac hnx8x vni kokhj jiuth xoqqc xohmcky')

```

Tested all the sample items and got the correct response.

```
"wqcjmc" -> "flyspy"
"toek" -> "hero"
"toyike" -> "heroic"
"uo" -> "ae"
"uoz" -> "abe"
"htoo jmuy" -> "the space"
"uh68v8x " -> "a d1g13t"
"fo78i d" -> "we xi12"
"htioj ixej uy " -> "this is a code"
"jea ceeac hnx8x vni kokhj jiuth xoqqc xohmcky" -> "so you really decrypted this string d1dnt you"

```
> 4 votes

# Answer
# Retina 0.8.2, ~~89~~ ~~83~~ ~~80~~ 71 bytes

```
[aeiou]|$
$&¶
+`(¶.+)¶(.*)$
$2$1
O$^r`.\G

T`¶b-df-hj-maed\oup-tv-z_`Ro

```

Try it online! Link includes test cases. This turned out to be easier than encoding, as demonstrated by the fact that I was able to code it in Retina 0.8.2 rather than requiring Retina 1. Explanation:

```
[aeiou]|$
$&¶

```

Split the input on substrings ending on vowels. An extra split is forced at the end of the string so that there are at least two lines.

```
+`(¶.+)¶(.*)$
$2$1

```

Join alternate lines together, so that the first line is the concatenation of all the odd lines and the second line is the concatenation of all the even lines.

```
r`.\G

```

Matching only the characters on the last (second) line...

```
O$^`

```

.. reverse the matches, thus reversing the second line only.

```
T`¶b-df-hj-maed\oup-tv-z_`Ro

```

Join the two lines together and decode the letters. The `Ro` causes the string to transliterate to its reverse. The middle consonant `n` and vowel `i` map to themselves so don't need to be listed. The  maps to the special `_` thus deleting it. The first and last 10 consonants and the first and last two vowels then surround the digits. (The `o` is normally special so it has to be quoted here.)
> 2 votes

# Answer
# C (gcc), ~~144~~ ~~143~~ 140 bytes

-1 -3 bytes thanks to ceilingcat

```
k,v,p,a;f(char*s,char*o){for(k=p=0,v=strlen(s);a=*s++;p^=1065233>>a-97&1)o[p?--v:k++]=a<33?a:a<58?105-a:"uzyxowvtisrqpnemlkjhagfdcb"[a-97];}

```

Try it online!
> 2 votes

# Answer
# , 190 bytes

```
function(i,`/`=strsplit){a=el(" 01234aeibcdfghjklmnpqrstvwxyziou98765 "/"")
names(a)=rev(a)
j=k=""
for(l in a[el(i/"")]){if(T)j=c(j,l)else k=c(l,k)
if(grepl(l,"aeiou"))T=!T}
cat(j,k,sep="")}

```

Try it online!

Note to self: learn a new, non-, language to golf text-based challenges...

Commented:

```
decrypt=function(i,
`/`=strsplit){                  # use infix '/' as alias to strsplit function
 a=el(" 01234aeibcdfghjklmnpqrstvwxyziou98765 "/"")
                                # a=vector of characters with equivalents at reverse index
 names(a)=rev(a)                # name characters by equivalent
 j=k=""                         # initialize j,k as empty strings
 for(l in a[el(i/"")]){         # for each input letter (split using /), find its equivalent l
  if(T)j=c(j,l)else k=c(l,k)    #  if T=1 (initial value) append l to j, otherwise put it at start of k
  if(grepl(l,"aeiou"))T=!T}     #  if it was a vowel, T=not T
 cat(j,k,sep="")}               # finally, output j,k

```
> 2 votes

# Answer
# 05AB1E, ~~27~~ 26 bytes

```
žMIå0šÅ¡ι€S`R«žNÂ‡žMÂ‡žhÂ‡

```

I/O as a list of characters.

Try it online or verify all test cases (with the I/O joined to pretty-print).

**Explanation:**

```
žM             # Push the vowels "aeiou"
  Iå           # Check for each character in the input-list if it's in the vowel string
               #  i.e. ["h","t","i","o","j"," ","i","x","e","j"," ","u","y"," "]
               #   → [0,0,1,1,0,0,0,1,0]
    0š         # Prepend a leading 0
               #  → [0,0,0,1,1,0,0,0,1,0]
      Å¡       # Split the (implicit) input-string on the truthy values
               #  → [["h","t","i"],["o"],["j"," ","i"],["x","e"],["j"," ","u"],["y"," "]]
        ι      # Uninterleave the list of lists
               #  → [[["h","t","i"],["j"," ","i"],["j"," ","u"]],[["o"],["x","e"],["y"," "]]]
         €S    # Convert each inner list of lists to a flattened list of characters
               #  → [["h","t","i","j"," ","i","j"," ","u"],["o","x","e","y"," "]]
           `   # Push both lists of characters separated to the stack
               #  → ["h","t","i","j"," ","i","j"," ","u"] and ["o","x","e","y"," "]
            R  # Reverse the second string
               #  → ["h","t","i","j"," ","i","j"," ","u"] and [" ","y","e","x","o"]
             « # Merge the two lists together
               #  → ["h","t","i","j"," ","i","j"," ","u"," ","y","e","x","o"]
žN             # Push the consonants "bcdfghjklmnpqrstvwxyz"
  Â            # Bifurcate it; short for Duplicate & Reverse copy
   ‡           # Transliterate the "bcdfghjklmnpqrstvwxyz" to "zyxwvtsrqpnmlkjhgfdcb"
               #  → ["t","h","i","s"," ","i","s"," ","u"," ","c","e","d","o"]
žMÂ‡           # Do the same for the vowels "aeiou"
               #  → ["t","h","i","s"," ","i","s"," ","a"," ","c","o","d","e"]
žhÂ‡           # And the digits "0123456789"
               #  → ["t","h","i","s"," ","i","s"," ","a"," ","c","o","d","e"]
               # (after which the result is output implicitly)

```
> 0 votes

# Answer
# Perl 5 `-F`, 110 bytes

```
map{push@{$o[$i]},y/0-9a-z/9876543210uzyxowvtisrqpnemlkjhagfdcb/r;$i^=/[aeiou]/}@F;say@{$o[0]},reverse@{$o[1]}

```

Try it online!
> 0 votes

---
Tags: code-golf, string, encryption
---


title: Simple Race KoTH

text:
# Question
Title: Simple Race KoTH
> This challenge has officially ended. Further submissions will not be competitive (but are still welcome!). View the scores here

In this challenge, submissions ("bots") should be Javascript functions which try to win as many races as possible. In each race, bots will have a limited amount of energy which should be used to travel as quickly as possible over a distance of 100 units.

## Mechanics

Each game will consist of a number of races, which are made up of a number of turns. In each turn, bots will choose a nonnegative distance to travel forward. The amount of energy consumed is equal to the square of the distance traveled (and bots will only travel as far as their energy level allows if they return a longer distance).

At the beginning of each race, bots' positions are reset to 0. Once one or more bots reach a distance of 100 units, the race will end. Note that if a bot returns a distance which would place it further than 100 units from the start, it will only move as far as it needs in order to win. At the beginning of all races, bots will receive 100 energy in addition to any remaining from the last race. They will also receive a bonus of 1 energy for every unit they traveled in the previous race.

## Points

At the end of each race, all bots will receive one point for every ten units they have traveled when the game ends (including fractions of a point). At the end of a game, the bot with the most points wins.

Because it's likely bots will be optimized for a certain number of races, there will be 5 categories in which all bots will compete: 250 races, 750 races, 2500 races, 7500 races, and 25000 races. A bot's overall score will be the sum of their average score **per race** in each of these categories, making the highest possible score 50.

## Input/output

Bots will receive the following arguments: `dist` (the distance they have traveled in the current race), `energy` (the amount of energy they have), `bots` (an array of the distances of all other bots as of the end of the last turn, shuffled at the end of each race), and `storage`, which is by default an empty object and can be used to store information between races.

## Example bot

Follower will try to keep ahead of the average bot, by the average amount moved per turn.

```
{
    "Follower": function(dist, energy, bots, storage) {
        storage.turns = storage.turns || 0;

        if (Math.max(...bots))
            storage.avg = ((storage.avg || 0) * storage.turns++ + bots.reduce((a, b, i) => a + (b - storage.last[i]), 0) / bots.length) / storage.turns;

        storage.last = bots;

        return (bots.reduce((a, b) => a + b, 0) / bots.length + (storage.avg || 1)) - dist;
    }
}

```

## Controller

```
// Each bot should be placed in this object

var bot_data = {
    "Follower": function(dist, energy, bots, storage) {
        storage.turns = storage.turns || 0;

        if (Math.max(...bots))
            storage.avg = ((storage.avg || 0) * storage.turns++ + bots.reduce((a, b, i) => a + (b - storage.last[i]), 0) / bots.length) / storage.turns;

        storage.last = bots;

        return (bots.reduce((a, b) => a + b, 0) / bots.length + (storage.avg || 1)) - dist;
    }
};

var games = 0;
var records = {};

// races: Number of races
// log: Array of bot names to log information about, or null for no logging
//   Per-turn logging will only happen in games with less than 10 races
//   Per-race logging will only happen in games with less than 100 races
// bold: Whether to use bold text when logging information

var run_game = function(races, log = [], bold = true) {
    var perf_now = performance.now();

    var bots = [];

    games++;

    for (let bot in bot_data)
        bots.push({
            name: bot,
            run: bot_data[bot]
        });

    var uids = new Array(bots.length);

    for (let i = 0; i < uids.length; i++)
        uids[i] = i;

    var race = 0;
    var turn = 0;

    for (let r = 0; r < races; r++) {
        race++;

        for (let j, i = 0; i < uids.length; i++) {
            j = Math.random() * (i + 1) | 0;
            [uids[i], uids[j]][uids[j], uids[i]];
        }

        for (let b, i = 0; i < bots.length; i++) {
            b = bots[i];

            bots[i] = {
                name: b.name,
                run: b.run,

                uid: uids[i],
                dist: 0,
                energy: (b.energy || 0) + 100,
                points: b.points || 0,

                storage: b.storage || {},

                next: 0,
                inactive: 0
            };
        }

        turn = 0;

        while ((bots.every(b => b.dist < 100) && bots.some(b => b.energy > 0 && b.inactive < 3))) {
            turn++;

            for (let b, i = 0; i < bots.length; i++) {
                b = bots[i];

                try {
                    b.next = b.run(
                        b.dist, b.energy,
                        bots.filter(o => o.uid != b.uid).map(o => o.dist),
                        b.storage
                    );

                    if (log && log.includes(b.name) && races < 10)
                        console.log("[" + race + ":" + turn + "] " + b.name + "(" + (Math.round(b.dist * 1000) / 1000) + "," + (Math.round(b.energy * 1000) / 1000) + "):", b.next);
                } catch(e) {
                    if (log && races < 10)
                        console.warn("[" + race + ":" + turn + "] " + b.name + ":\n" + (e.stack || e.message));

                    b.next = 0;
                }

                b.next = Number(b.next);

                if (Number.isNaN(b.next))
                    b.next = 0;

                b.next = Math.max(Math.min(b.next, 100 - b.dist, Math.sqrt(b.energy)), 0);

                if (!b.next)
                    b.inactive++;
            }

            for (let b, i = 0; i < bots.length; i++) {
                b = bots[i];

                b.dist += b.next;
                b.energy = Math.max(b.energy - b.next ** 2, 0);
            }
        }

        for (let b, i = 0; i < bots.length; i++) {
            b = bots[i];

            b.energy = b.energy + b.dist;
            b.points += b.dist / 10;
        }

        if (log && races < 100)
            console.log(
                (bold ? "%c" : "") + "Race " + race + ":\n" +
                (bold ? "%c" : "") + bots.map(b => b).sort((a, b) => b.dist - a.dist).map(
                    b => b.name.slice(0, 16) + " ".repeat(20 - Math.min(b.name.length, 16)) + (Math.round(b.dist * 1000) / 10000)
                ).join("\n"), ...(bold ? ["font-weight: bold;", ""] : [])
            );
    }

    for (let i = 0; i < bots.length; i++)
        records[bots[i].name] = (records[bots[i].name] || 0) + bots[i].points / races;

    if (log)
        console.log(
            (bold ? "%c" : "") + "Average Points/Race (" + races + " races, " + (Math.ceil((performance.now() - perf_now) * 1000) / 1000) + "ms):\n" +
            (bold ? "%c" : "") + bots.sort((a, b) => b.points - a.points).map(
                b => b.name.slice(0, 16) + " ".repeat(20 - Math.min(b.name.length, 16)) + (Math.round((b.points / races) * 10000) / 10000)
            ).join("\n"), ...(bold ? ["font-weight: bold;", ""] : [])
        );
};

// Print and clear records for average scores

var print_records = function(bold = true) {
    console.log(
        (bold ? "%c" : "") + "Sum of Average Points/Game:\n" +
        (bold ? "%c" : "") + Object.entries(records).sort((a, b) => b[1] - a[1]).map(
            b => b[0].slice(0, 16) + " ".repeat(20 - Math.min(b[0].length, 16)) + (Math.round(b[1] * 10000) / 10000)
        ).join("\n"), ...(bold ? ["font-weight: bold;", ""] : [])
    );
};

var clear_records = function() {
    records = {};
};

// Default race categories

run_game(250);
run_game(750);
run_game(2500);
run_game(7500);
run_game(25000);

print_records();

```

## Rules

* If no bots have moved for three turns in a row, a race will end (scores will still be counted)
* If a bot errors, it will lose a turn (i.e., not move)
* Bots may not tamper with the controller or other bots, or be otherwise malicious
* Bots should run in a reasonable amount of time
* Bots must be deterministic; **no randomness** unless it's seeded by the bot's arguments

**Chat:** https://chat.stackexchange.com/rooms/112222/simple-race-koth

~~**Bots due by:** Friday, September 4th, 12:00 UTC (08:00 EDT)~~

# Answer
# Compensator

A derivative from "SubOptimal", Compensator does not explicitly cater for the "Horde/Burst" strategy, rather it naturally compensates via the knowledge that if it was not first, then it may not have used all its energy in the previous turn and so it may have more energy than expected. To capitalise on this over supply of energy, this bot will use half of the excess energy to try and force a quicker race, but keeping the other half in reserve to try and stretch out the effect of the energy surplus over multiple races.

It does seem to perform slightly better than its sibling (SubOptimal), and as the time of this submission, ekes slightly ahead of all other bots.

```
{
    "Compensator": function(dist, energy, bots, storage) {
        if ( dist == 0)
        {
          if (storage.targetStartingEnergy == undefined)
          {
            storage.targetStartingEnergy = energy;
            storage.nominalStartingEnergy = energy + 100;
          }
          else
          {
            if (energy <= storage.nominalStartingEnergy)
            {
              storage.targetStartingEnergy = energy;
            }
            else
            {
              storage.targetStartingEnergy = ((energy - storage.nominalStartingEnergy) * 0.5) +  storage.nominalStartingEnergy;
            }
          }

          if (storage.raceNumber == undefined)
          {
            storage.raceNumber = 1;
          }
          else
          {
            storage.raceNumber++;
          }

          storage.energyConsumptionRate = storage.targetStartingEnergy / 100;
        }

        let step = 0;

        if (storage.raceNumber == 1)
        {
          step = 1;
        }
        else
        {
          step = storage.energyConsumptionRate;
        }

        return step;
    }
}

```
> 3 votes

# Answer
# Rate control

```
{
    "Rate control": function(distanceTravelled, energyLeft, _, s) {
        if (distanceTravelled === 0) {
            for (let i = 100; i > 0; --i) {
                if (10000 / i > energyLeft) {
                    s.travelSpeed = 100 / (i + 1);
                    break;
                }
            }
        }

        return s.travelSpeed;
    }
}

```

Each round uses up all of its energy to reach the finish line. Strictly better than "Slow and steady" as this entry will only ever use 1 or more energy per turn while also making sure to always make it to the end. Unoptimized, but still fairly fast.
> 6 votes

# Answer
# Slow and steady

```
{
    "Slow and steady": function() {
        return 1;
    }
}

```

Baseline bot while I try to figure out what to do with this challenge. Doesn't adapt at all so it might start consistently losing if some sort of meta develops.
> 4 votes

# Answer
## Robin Hood

```
{
    "Robin Hood": function(dist, energy, bots, storage) {
        if (!dist)
            storage.move = [
                [100, 1],
                [200, Math.sqrt(192 / 49) - 0.00695],
                [10000 / 49, (100 / 49)]
            ].sort((a, b) => Math.abs(a[0] - energy) - Math.abs(b[0] - energy))[0][1];

        return storage.move;
    }
}

```

This bot will do one of three things in a race:

* **Move one unit per turn:** This is done in the first race of each game to ensure it has the full 200 energy it needs
* **Move slightly slower than two units per turn:** This is done every other turn and saves just enough energy to allow it to...
* **Move slightly faster than two units per turn:** This lets it finish one turn faster than the current competitors, and just barely undercuts a few of the previous winners (though Rate control is ahead by a hundredth of a point as of posting)
> 3 votes

# Answer
# precomputed

```
{
    "precomputed": function(dist, energy, bots, storage) {
        if (dist === 0) {
            let movements = Array.from(new Array(100), _=>1)

            const totalEnergyConsumed = () => movements.reduce((a,c)=>a+c**2,0)
            let currentIndex = 0

            while(totalEnergyConsumed() < energy) {
                movements[currentIndex] += movements[currentIndex + 1]
                movements.splice(currentIndex + 1, 1)
                if (++currentIndex >= movements.length - 1) {
                    currentIndex = 0
                }
            }

            currentIndex = movements.length
            while(totalEnergyConsumed() > energy) {
                if(movements[currentIndex] > 1) {
                    movements[currentIndex]--
                    movements.push(1)
                } else {
                    currentIndex--
                }
            }

            storage.movements = {}
            movements.reduce((a,c)=>{storage.movements[a]=c;return a+c}, 0)
        }
        return storage.movements[dist]
    }
}

```

starts the race by calculating the full path to the end in order to move almost the same speed for the whole race, while still using all the energy available
> 3 votes

# Answer
# Ninety

```
{
    "Ninety": function(dist, energy, bots, storage) {
        if (dist === 0) {
            for (let i = 90; i > 0; --i) {
                if (8100 / i > (energy - 10)) {
                    storage.travelSpeed = 90 / (i + 1);
                    break;
                }
            }
        }
        if (dist >= 89) {
            return 1;
        }

        return storage.travelSpeed;
    }
}

```

Aims to get 9 points per round. I'm not sure how well it does, but it's less likely to lose points to bots finishing faster than it (as compared to Rate Control, which this is forked from).
> 3 votes

# Answer
## I love Randomness

```
{
    "I love Randomness": function(dist, energy, bots, storage) {
        storage.rand = Math.abs(dist ^ energy ^ storage.rand) + 1;
        return Math.abs(dist ^ energy ^ storage.rand) + 1;
    }
}

```
> 3 votes

# Answer
## Pulse

```
"Pulse": function(dist, energy, bots, storage) {
    storage.round = storage.round ? storage.round+1 : 1;
    if(storage.round%500==0) return Math.max([...bots])+50
    return Math.floor(Math.sqrt(energy/100))
}

```

Each step using only 1% of the energy. Every 500 turns, takes the distance of the first place in this moment, and adds 50 pass it.
> 3 votes

# Answer
# Jack in the Box

Saves up its energy until it can beat the game in 40 moves, bringing the number of average moves per game down.

```
{
    "Jack in the Box": function(dist, energy, bots, storage) {
        if (!dist) {
            if (energy >= 250) {
                storage.speed = energy / 100
            } else {
                storage.speed = .5
            }
        }
        return storage.speed
    }
}

```

# Simpleton

Simpleton just wants to win :(

```
{
    "Simpleton": function(dist, energy, bots, storage) {
        return energy / (100 - dist)
    }
}

```

# Steady

Steady tries to go the same amount every turn, but doesn't like having extra energy.

```
{
    "Steady": function(dist, energy, bots, storage) {
        storage.turns = storage.turns || 0
        storage.totalTurns = storage.totalTurns || 0
        storage.games = storage.games || 0
        storage.totalEnergyGained = storage.totalEnergyGained || 0
        storage.previousEnergy = storage.previousEnergy || 0
        if (!dist) {
            if (storage.games == 0) {
                storage.speed = 1
            } else {
                storage.totalTurns += storage.turns
                storage.turns = 0
                storage.speed = Math.sqrt(storage.totalEnergyGained / storage.totalTurns) + storage.previousEnergy / storage.totalTurns
            }
            storage.totalEnergyGained += energy - storage.previousEnergy
            storage.games++
        }
        storage.turns++;
        storage.previousEnergy = Math.max(energy - Math.max(Math.min(storage.speed, 100 - dist, Math.sqrt(energy)), 0) ** 2, 0)
        return storage.speed;
    }
}

```
> 3 votes

# Answer
# Suboptimal

The optimal solution where there is no means to affect other racers is to use all your energy to ensure that you finish first to both gain the most energy next round and to deny energy for your opponents. To this can be achieved by, spending 1.0 energy per turn on the first race and then 2.0 per turn for subsequent races (due to the extra 100 energy given for winning at 100 distance)

This can be achieved by calculating the bot's energy / the distance to travel at the start of a race, storing this value and then returning this value each turn of the race.

Now, that we know the optimal solution sans opponent effects, we need to consider the actions that opponents can perform that can affect others. In this game, the only real effect is the ability to force the end of the current race by being the winner. Since bots are allowed to hoard and accumulate energy, they can decide to minimise energy consumption and maximise energy production, sacrificing the chance to gain many points for any particular race and instead spending the accumulated points in one race to dominate the other bots and win that race. While this strategy does not yield high points overall, it does impact bots that are expecting the races to finish after 100 turns. The average turn count of a race is thus reduced. So to compensate for this effect, a sub-optimal solution is derived from the optimal solution by adding a factor that emulates the effect of bots that use this "hoard-burst" strategy.

This factor is not able to computed unless the bot incorporates all other bot strategies and then performing an analysis to determine the factor. This is not really in the spirit of KoTH challenges and may be not allowed. So for this bot, a simple empirical analysis was performed to determine the factor at time of submission and adding in a scalar based on number of submissions that will increase the factor as more submissions on the assumption that later bots may be more interfering.

Ultimately the formula is:

distance\_per\_turn = starting\_energy / (( race\_distance + hoard\_burst\_factor) * (1.0 + (number\_of\_bots - number\_of\_bots\_at\_submission) * 0.1))

```
{
    "Suboptimal": function(dist, energy, bots, storage) {
        if ( dist == 0)
        {
          storage.energyConsumptionRate = energy / ((100 + 10) * ( 1.0 + (bots.length - 26) * 0.1 ));
        }

        return storage.energyConsumptionRate;
    },
}

```
> 3 votes

# Answer
## Collector

```
{
    "Collector": function(dist, energy, bots, storage) {
        if (!dist) {
            if ("turns" in storage) {
                storage.avg = ((storage.avg * Math.max(storage.races++, 0)) + storage.turns) / Math.max(storage.races, 1);
            } else {
                storage.avg = 100;
                storage.races = -1;
            }

            storage.turns = 0;

            storage.move = (energy >= 10000 / (storage.avg | 0)) ? (100 / (storage.avg | 0)) : 0.5;
        }

        storage.turns++;

        return storage.move;
    }
}

```

Collector will default to moving at a rate of 0.5 units/turn. This is optimal for gathering energy. If it predicts at the beginning of a race that it can tie or beat the average with the energy it has, then it will try to do so.

Currently loses to Rate control, but might be able to better adapt to new strategies.
> 2 votes

# Answer
## Greedy/Greedier

```
{
    "Greedy": function(dist, energy, bots, storage) {
        return energy > 100 ? 2 : 1;
    },
    "Greedier": function(dist, energy, bots, storage) {
        return dist + energy > 100 ? 2 : 1;
    },
}

```

Greedy will move 2 units/turn if it has at more than 100 energy otherwise 1 unit/turn. Greedier will move 2 units/turn if it thinks it will probably have enough energy to each the end otherwise 1 unit/turn. These were the simplest ways I could think of of using any bonus energy the bot might have.
> 2 votes

# Answer
## (New) Accelerate

```
{
    "Accelerate": function(dist, energy, bots, storage) {
        return dist * 0.21 + 0.001;
    },
}

```

Calm down, I'm just experimenting with extremely simple bots.

This bot is very easy to understand. It initially runs at speed 0.001 and accelerates quadratically.
> 2 votes

# Answer
# Calculated Sprinter

Calculated Sprinter tries to run the full lap as quickly as he can with his current fuel left. Not smart enough to plan for future races, is just happy to be here for the run.

```
{
    "Calculated Sprinter": function(dist, energy, bots, storage){
        var remaining = 100-dist;
        var energyLeftPerUnit = energy/remaining;
        return Math.sqrt(energyLeftPerUnit)
    }
}

```
> 2 votes

# Answer
# Surprise/Timing

```
"Timing": function(dist, energy, bots, storage) {
  storage.turns = storage.turns || 0;
  storage.games = storage.games || 0;
  storage.turns++;
  if(dist == 0) {
      storage.games++;
      estimated_game_length = Math.ceil( storage.turns / storage.games)+2;
      desired_speed = 100 / estimated_game_length;
      max_speed = Math.sqrt( energy / estimated_game_length);
      storage.speed = Math.min(desired_speed, max_speed);
  }
  if(storage.games < 3)
      return storage.games;
  return storage.speed;
},
"Surprise": function(dist, energy, bots, storage) {
  storage.turns = storage.turns || 0;
  storage.games = storage.games || 0;
  storage.turns++;
  if(dist == 0) {
      storage.games++;
      estimated_game_length = Math.ceil( storage.turns / storage.games);
      desired_speed = 100 / (estimated_game_length - 3);
      max_speed = Math.sqrt( energy / estimated_game_length);
    if(desired_speed <= max_speed) {
      storage.speed = desired_speed;
    }
    else {
      storage.speed = Math.min(2, max_speed);
    }
  }
  if(storage.games < 3)
       return storage.games;
  return storage.speed;
}

```

Calculate a fixed speed based on how long games are generally lasting. Timing then tries to hit the mark, while Surprise tries to beat it.

While running tests with both of these, it became apparent that we probably need rules about collusion in this KotH, minimal though the interactions are. Surprise could make Timing do much better by sacrificing its own score to make the race length shorter, and could help it even more by only doing so at fixed intervals that Timing knows about.

I'm not pulling these shenanigans now because I assume they're not in the spirit.
> 2 votes

# Answer
## Fast and not steady

```
{
    "Fast and not steady": function() {
        return 99999999;
    }
}

```
> 1 votes

# Answer
## Mimic

```
{
    "Mimic": function(dist, energy, bots, storage) {
        if (!dist) {
            storage.last = bots;
            storage.rand = energy ** 3;

            return energy / (100 - dist);
        }

        storage.rand = Math.abs(dist ^ dist ** 2 ^ energy ^ energy ** 3 ^ energy ** 5 ^ bots.reduce((s, b) => s + b, 0) ^ storage.rand * (2 ** 31)) / (2 ** 31);

        var result = bots.map((b, i) => b - storage.last[i])[storage.rand * bots.length | 0]; // Fix RNG

        storage.last = bots;

        return Math.max(Math.min(result, Math.sqrt(energy / ((100 - dist) / 4))), Math.sqrt(energy / ((100 - dist))));
    }
}

```

Creates a list of every other bot's (effective) move in the last turn, and picks a pseudorandom one using a better version of HighlyRadioactive's PRNG. It ensures these values are within a certain range (which happens about half the time), so it doesn't do anything stupid.
> 1 votes

# Answer
## Faster than Slow

```
{
    "Faster than Slow": function() {
        return 2;
    }
}

```

If you think this is a bad bot, then no.

`Faster than Slow 48.951`
> 1 votes

# Answer
**Whole**

Whole doesn't like fractional distances and will always move a distance that is an integer.

<pre><code>    "Whole": function(dist, energy, bots, storage) {
        if (dist == 0) {
            if (energy < 110) {
                storage.lambda = function(distance) {return 100 - distance - 1;}
                storage.step = 1
            }
            else {
                storage.lambda = function(distance) {return 200 - distance - 2;}
                storage.step = 2
            }
        }
        let expEnergyPast = storage.lambda(dist);
        if (expEnergyPast + (storage.step + 1) ** 2 <= energy) {
            return storage.step + 1;
        }
        return storage.step;
    }

```
</code></pre>
> 1 votes

# Answer
**Fourty-Nine**

Fourty-Nine did take a look at Winner & Winner2 and recognized that 49 turns to win is better than 48 turns to win. But Fourty-Nine wants to win according to your rules. So Fourty-Nine doesn't sacrifice its averange distance to win many races. But it will never go faster than 49 turns to win.

```
    "fourty-nine": function(dist, energy, bots, storage) {
        if (dist == 0) {
            if (energy < 110) {
                storage.step = 1
            }
            else if(energy < 10000.0/49){
                storage.step = 2
            }
            else {
                storage.step = 100.0/49
            }
        }
        return storage.step;
    },

```
> 1 votes

# Answer
# Predictor

```
{
    "Predictor": function(dist, energy, bots, storage) {
        if (!dist)
            if (energy == 100)
                storage.move = 1;
            else
                storage.move = (energy >= 10000 / (50 - bots.length * 0.25 | 0)) ? (100 / (50 - bots.length * 0.25 | 0)) : 1.3;

        return storage.move;
    }
}

```

Predictor assumes that the more bots are added, the faster it needs to go to win. It collects energy over time, then sprints toward the finish line in a manner similar to Collector or Jack in the box.
> 1 votes

# Answer
## DECISION3M8

Improvement on **UWUTM8** that works kind of differently

Tries to predict when someone is speeding and tries to use more energy to gain more points

```
"DECISION3M8": function(dist, energy, bots, storage) {
    const checkpointPer = 5;
    if (storage.turn == undefined) {
        storage.turn = 0;
    } else {
        storage.turn = storage.turn + 1;
    }

    if (dist === 0) {
        if (storage.round == undefined) {
            storage.round = 0;
        }
        storage.round = storage.round + 1;
        storage.turn = 0;
        storage.maxAtPreviouscheckpoint = 0;
        storage.predictedTurnsLeft = 100;
        storage.travelSpeed = Math.sqrt(energy / 50);

        if (energy == 100) {
            return 1;
        }
    } else if (storage.turn % checkpointPer == 0) {
        let maxAtCurrentTurn = Math.max( ...bots );
        let speederCheck = maxAtCurrentTurn / (storage.turn / checkpointPer) - storage.maxAtPreviouscheckpoint / ((storage.turn / checkpointPer) - 1);
        let speedOfSpeederPerTurn = maxAtCurrentTurn / storage.turn;
        if ((Math.abs(speederCheck) < 0.01) && (maxAtCurrentTurn > dist)) {
            //console.log(speederCheck);
            storage.predictedTurnsLeft = Math.ceil(100 / speedOfSpeederPerTurn) - (100 - storage.turn);
            storage.travelSpeed = Math.sqrt(energy / (storage.turn - speedOfSpeederPerTurn));
            //console.log(storage.predictedTurnsLeft);
        }
    }

    return storage.travelSpeed;
}

```
> 1 votes

# Answer
**Winner**

Winner doesn't care about your rules. Winner plays by its own rules.

Winner tries to win ( = end at distance 100) in as many races as possible.

<pre><code>"Winner": function(dist, energy, bots, storage) {
        if (dist == 0) {
            if (energy < 10000.0/49) {
                storage.step= 0.5;
            }
            else {
                storage.step = 100.0/49;
            }
        }
        return storage.step;
    },
"Winner2": function(dist, energy, bots, storage) {
        if (dist == 0) {
            if (energy < 10000.0/48) {
                storage.step= 0.5;
            }
            else {
                storage.step = 100.0/48;
            }
        }
        return storage.step;
    },

```
</code></pre>
> 0 votes

# Answer
## UWUTM8

Just like many bots i tries to finish as fast as it can by using as mutch energy as it can. It also doesn't try to finish at all at specific marks but tries to reach 9 point mark

```
"UWUTM8": function(dist, energy, bots, storage) {
    if (dist === 0) {
        if (storage.round == undefined) {
            storage.round = 0;
        }
        storage.round = storage.round + 1;
        if (storage.round % 2500 == 0 || storage.round == 250 || storage.round == 750) {
            storage.travelSpeed = Math.sqrt(energy / 90)
        } else {
            storage.travelSpeed = Math.sqrt(energy / 100)
        }
    }

    return storage.travelSpeed;
}

```
> 0 votes

---
Tags: king-of-the-hill, javascript
---


title: Curve Stitching

text:
# Question
Title: Curve Stitching
Curve stitching is the process of "stitching" together multiple straight lines in order to create a curve, like so:

For an explanation of curve stitching, visit this website.

We will be drawing our curve in the top left of the screen, as shown in the image above.

Given an integer `n` (via STDIN or a function parameter), being the number of lines to draw, and an integer `p` pixels, being the interval between the starting points, draw a straight line curve.

Horizontal/vertical lines are necessary, and should be part of the line count.

---

### Example Outputs:

n = 25, p = 15

n = 20, p = 20

---

This is a challenge, so **shortest code wins**.

# Answer
## Mathematica, ~~55~~ ~~51~~ ~~50~~ ~~47~~ ~~64~~ 68 bytes

```
f=Graphics[Line@Table[#2{{i-1,#+1},{0,i+1}},{i,#}],ImageSize->#*#2]&

```

Defines a function which yields the image as specified when called like

```
f[25,15]

```

Yielding

**Edit**: Had to add some characters to make sure that the second parameter was actually interpreted as pixels.

**Edit**: four more bytes to plot the horizontal lines.
> 6 votes

# Answer
# Python - 74

Since the question doesn't specify units, axes scaling etc. I'm coming up with the following minimum solution:

```
import pylab
n,p=input()
for i in range(n):pylab.plot([0,i*p],[(i-n)*p,0])

```
> 6 votes

# Answer
# Bash+Imagemagick+xview, 124 bytes

```
for((;i<$1;));{
s+=" -draw 'line $[i*$2],0 0,$[($1-i++)*$2]'"
}
eval convert -size $[$1*$2]x$[$1*$2] xc:$s png:-|xview stdin

```

### Output for `./curvestitch.sh 25 15`:
> 4 votes

# Answer
# APL (dzaima/APL), 26 bytes

```
{P5.G.ln↓⍉↑⍵×⍺∘-@3⍳¨⍺1 1⍺}

```

-2 bytes from Adam using *magic*

Requires `⎕IO←0`. (0-indexing)

## Explanation

```
{P5.G.ln↓⍉↑⍵×⍺∘-@3⍳¨⍺1 1⍺}
 P5.G.ln                   Create lines using the following sets of four points:
                    ⍺1 1⍺  Array [n,1,1,n]
                  ⍳¨       generate range 0..n for each
                           [0..n,0,0,0..n]
                @3         to the third element,
             ⍺∘-           subtract it from n.(reversing the last range)
                           [0..n,0,0,n..0]
           ⍵×              scale all items by p
          ↑                mix , creating columns of coordinates.
        ↓⍉                 transpose, and convert to lists of two points

```

## APL (dzaima/APL), 28 bytes

```
{P5.G.ln↓⍉↑(⍵×⍳⍺)⍬⍬(⍵×⍺-⍳⍺)}

```

Anonymous function which takes n and p as left and right arguments, and displays the pattern, given an adequately sized canvas.

Full Program here.

Made with a lot of advice and golfing from dzaima.

### Test Cases

`25, 15`

`20, 20`

`6,72`

## Java + `Processing`, 62 bytes

The original function I made for this question.

```
void c(int n,int p){for(int i=1;i<n;)line(p*i,0,0,p*(n-i++));}

```
> 4 votes

# Answer
## Basic 7.0, Commodore 128, ~~60~~ 58 bytes

```
0inputn,p:gR1:s=n*p:do:dR1,s,0to0,n:s=s-p:n=n+p:loOwHs>=0

```

Watch a video of it running:

Unfortunately, INPUT command hasn't an abbreviation :(
> 4 votes

# Answer
# Perl, ~~121~~ 130 bytes

The input is via `STDIN`. The values are comma separated.

**EDIT:** We have new rules. I'm not sure why, but the first two pixels are invisible and I had to add an offset...

```
use Tk;<>=~/,/;$c=tkinit->Canvas(-width=>$w=$`*$'-$',-height=>$w)->pack;$c->createLine(2,2+$_*$',2+$w-$_*$',2)for 0..~-$`;MainLoop

```

Here are some tests:

**25x15:**

**6x72:**
> 3 votes

# Answer
# BBC Basic, 58 ascii characters, tokenised filesize 49

```
INPUTn,p:p*=2FORi=1TOn:MOVEi*p-p,974DRAW0,974-(n-i)*p:NEXT

```

Download emulator at http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

`p*=2` is needed because in the default mode BBC Basic maps a logical square of 2x2 to a single physical pixel.

BBC Basic has the origin at the bottom left corner of the screen, with y coorinates going up. On my machine the default window has an upper y coordinate of 974 (yours may be different.) 7 characters could be saved if it was permitted to plot in the bottom left corner of the screen. Adding `MODE16` after the first `:` will resize the window so that the upper y coordinate is guaranteed to be 799.
> 3 votes

# Answer
# Java 8, 143 bytes

```
import java.awt.*;n->p->new Frame(){{add(new Panel(){public void paint(Graphics g){for(int m=0;m<n;)g.drawLine(0,m*p,n*p-++m*p,0);}});show();}}

```

**Output for \\$n=25, p=15\\$:**

**Output for \\$n=5, p=50\\$:**

**Explanation:**

```
import java.awt.*;            // Required import for almost everything
n->p->                        // Method with two integer parameters & Frame return-type
  new Frame(){                //  Create the Frame
   {                          //   In an inner code-block:
     add(new Panel(){         //    Add a Panel we can draw on:
       public void paint(Graphics g){
                              //     Overwrite its paint method:
         for(int m=0;m<n;)    //      Loop `m` in the range [0,n):
           g.drawLine(        //       Draw a line:
             0,m*p,           //        Starting at x=0, y=m*p
             n*p-++m*p,0);}});//        to x=n*p-(m+1)*p, y=0
     show();}};               //    And afterwards show the Frame

```
> 3 votes

# Answer
# Html + JavaScript 155 ~~157 183~~

Edit: learnig what stuff I can cut without functionality loss
Edit 2: as suggested by @Optimizer

```
<canvas id='c'/><script>
p=prompt,s=p(l=p(t=c.getContext("2d")));for(c.width=c.height=y=s*l,x=0;l--;x-=s)t.moveTo(0,y-=s),t.lineTo(-x,0);t.stroke()
</script>

```

Fiddle First input *number of lines*, second input *pixel interval*

Ungolfed Fiddle
> 1 votes

# Answer
# , 100 bytes

```
function(n,p,P=p*n*1.08){bmp(,P,P)
par(mar=!1:4)
plot.new()
segments((1:n-1)/n,1,0,1:n/n)
dev.off()}

```

Saves output to bitmap file 'Rplot001.bmp'.
There are some 'wasted' pixels at the top & on the left (so the curve is in the top left corner but not touching the edge). This seems to be within the spec, but could be removed for +13 bytes.

Commented code:

```
curve_stitch=
function(n,p,                   # n = number of lines, p = pixels between starting points
 P=p*n*1.08){                   # P = pixel dimensions of final plot.
                                # (R expands axes by 4% at each end by default, so to
                                # ensure that the curve itself is p*n pixels, we need
                                # to expand the output by +8%
 bmp(,P,P)                      # open bitmap output to default filename, with dimensions PxP
 par(mar=!1:4)                  # remove margins by setting all to zero
 plot.new()                     # define new plot (default data range from 0 to 1)
 segments((1:n-1)/n,1,0,1:n/n)  # plot lines within range from 0 to 1
 dev.off()                      # close bitmap output to save file
 }

```

Sample output:

```
curve_stitch(10,10)

```

```
curve_stitch(5,50)

```
> 1 votes

---
Tags: code-golf, graphical-output
---


title: What's my PPCG ID?

text:
# Question
Title: What's my PPCG ID?
# Challenge

Given the name of a PPCG member, output their PPCG ID number. If the user does not exist, you may report an error or return any non-positive number. If there are multiple members with this name, you may choose to output only one ID or all of them.

# Test Cases

```
"musicman523" -> 69054
"Dennis" -> 12012
"xnor" -> 20260
"Leaky Nun" -> 48934
"fəˈnɛtɪk" -> 64505
"Jörg Hülsermann" -> 59107
"Community" -> -1
"Any user that does not exist" -> 0
"Alex" -> 69198 (this is one possible result)
"Leaky N" -> 0
"Jorge" -> 3716

```

# Answer
> 30 votes
# Stack Exchange Data Explorer, ~~56~~ ~~54~~ ~~53~~ ~~51~~ 46 bytes

*-1 byte thanks to Hyper Neutrino. -5 bytes thanks to Giacomo Garabello.*

```
SELECT ID FROM USERS WHERE##S##=DISPLAYNAME--S

```

Try it online!

Not sure if this is completely valid but... Input must be surrounded in single quotes `'`.

Also, I still don't get why SQL programmers like to shout but it's apparently good practise so... `SELECT` EVERYTHING `FROM` EVERYTHING `WHERE` EVERYTHING `LIKE` EVERYTHING!

## Explanation

LET ME EXPLAIN.

```
SELECT ID FROM USERS WHERE##S##=DISPLAYNAME--S

                                           --S  -- DECLARE AN INPUT PARAMETER NAMED S
SELECT                                          -- FIND...
       ID                                       -- ID OF THE USERS...
          FROM USERS                            -- IN THE TABLE USERS...
                     WHERE                      -- THAT SATISFIES THE CONDITION...
                          ##S##=DISPLAYNAME     -- S EQUALS THE USERS' DISPLAY NAME

```

# Answer
> 5 votes
# Python 3 \+ requests, 196 bytes

Thanks @Wondercricket for -6 bytes!

```
from requests import*
x=lambda s:all([print(a['user_id'])if s==a['display_name']else''for a in get('http://api.stackexchange.com/users?inname=%s&site=codegolf'%utils.quote(s)).json()['items']])and d

```

Uses Stack Exchange API. Fixed the `Leaky N` and `Jorge` errors.

If there are multiple users with the same name, it prints all of them, which is allowed.

# Answer
> 5 votes
# Python 2 \+ requests, 187 bytes

```
from requests import*
def f(x):t=get("http://api.stackexchange.com/users?inname="+utils.quote(x)+"&site=codegolf").json()["items"];print[k['user_id']for k in t if k['display_name']==x][0]

```

Returns the user ID if a single user exists, the first user which matches the requirements if more exist, and reports an error otherwise.

# Answer
> 5 votes
# JavaScript, ~~155~~ ~~149~~ ~~142~~ 135 bytes

```
i=>fetch("//api.stackexchange.com/users?site=codegolf&inname="+i).then(r=>r.json()).then(r=>r.items.find(u=>u.display_name==i).user_id)

```

```
f=i=>fetch("//api.stackexchange.com/users?site=codegolf&inname="+i).then(r=>r.json()).then(r=>r.items.find(u=>u.display_name==i).user_id)
```

```
<input onchange="f(this.value).then(console.log)"><br>Fill input and press Enter
```

# Answer
> 3 votes
# Python 2 \+ requests, 173 bytes

```
lambda s:[i['user_id']for i in get('http://api.stackexchange.com/users?inname=%s&site=codegolf'%utils.quote(s)).json()['items']if i['display_name']==s]
from requests import*

```

## Sample run

```
>>> f=\
... lambda s:[i['user_id']for i in get('http://api.stackexchange.com/users?inname=%s&site=codegolf'%utils.quote(s)).json()['items']if i['display_name']==s]
>>> from requests import*
>>>
>>> tests = ['musicman523', 'Dennis', 'xnor', 'Leaky Nun', 'Community', 'Any user that does not exist', 'Alex', 'Leaky N', 'Jorge']
>>> for i in tests: print '%-30r -> %s'%(i, f(i))
...
'musicman523'                  -> [69054]
'Dennis'                       -> [12012, 13891, 14912, 24937]
'xnor'                         -> [20260]
'Leaky Nun'                    -> [48934]
'Community'                    -> [-1]
'Any user that does not exist' -> []
'Alex'                         -> [21536, 69198, 11192]
'Leaky N'                      -> []
'Jorge'                        -> [3716]

```

Fun fact: the result is sorted by reputation, highest first.

# Answer
> 3 votes
# JavaScript, ~~128~~ 119 bytes

-9 bytes thanks to Rogem.

```
n=>fetch("198.252.206.16/users?site=codegolf&inname="+n).then(r=>r.text()).then(t=>t.match(`\\/([^\\/]*)\\/`+n+`"`)[1])

```

# Answer
> 1 votes
# APL (Dyalog Unicode), 169 bytes

```
a←⍞
y←(⎕JSON((⎕SE.SALT.New'HttpCommand').Get'https://api.stackexchange.com/users?site=codegolf&inname=',('\s+'⎕R'\%20')a).Data).items
{a≡1⊃y.display_name:y.user_id ⋄ 0}1

```

This took forever to figure out, lol.

Thanks to @Adám for saving me a lot of time, and a lot of bytes on the HTTP request.

## Explanation

```
a←⍞                                 ⍝ Store string input
y←        ('\s+'⎕R'\%20')a          ⍝ Convert spaces to '%20' for query
  (⎕JSON((⎕SE.SALT.New'HttpCommand').Get'https://api.stackexchange.com/users?site=codegolf&inname=',).Data).items
                                    ⍝ Get and parse JSON from API call using ⎕SE (session namespace)
 a≡⊃y.display_name                  ⍝ Is the input equal to the unwrapped user id?
                                    ⍝ (display name comes as an array of strings)
{                  :y.user_id ⋄ 0}  ⍝ If so, print the user id
                                    ⍝ Else print zero
                                    ⍝ Call function with placeholder arg 1

```

# Answer
> 0 votes
# JavaScript (ES6) + HTML, ~~154~~ ~~152~~ ~~151~~ ~~202~~ ~~179~~ ~~161~~ 145 bytes

Sacrificed a few bytes to handle special characters.

Needs to be run under the `api.stackexchange.com` domain. Returns a Promise containing the ID or Throws an error in the Promise if the username can't be found.

```
s=>fetch(`/users?site=codegolf&inname=`+s).then(r=>r.json()).then(j=>j.items.find(i=>(o.innerHTML=i.display_name,o.innerText==s)).user_id)

<a id=o

```

Note: This solution was developed independently of Uriel's and its comments; if Uriel decides to use the `find` method, I'm happy to roll back to my longer, recursive version.

---
Tags: code-golf, internet, stack-exchange-api
---


title: Build a Faulty XKCD Browser

text:
# Question
Title: Build a Faulty XKCD Browser
## Challenge

Given the number of an XKCD comic, output the title text of that comic (the mouseover text).

However, the program must throw an error when given the numbers `859` or `404`.

## Rules

The number given will always be an existing comic (except `404`).

Your program must not throw an error for any other numbers than `859` or `404`.

For reference, comic `404` does not exist and `859` is:

```
Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;"''{<<[' this mouseover text."

```

Url shorteners are disallowed. You may use the internet to get the title text.

## Examples

```
Input > Output
1642 > "That last LinkedIn request set a new record for the most energetic physical event ever observed. Maybe we should respond." "Nah."
1385 > ::PLOOOOSH:: Looks like you won't be making it to Vinland today, Leaf Erikson.
1275 > If replacing all the '3's doesn't fix your code, remove the 4s, too, with 'ceiling(pi) / floor(pi) * pi * r^floor(pi)'. Mmm, floor pie.
1706 > Plus, now I know that I have risk factors for elbow dysplasia, heartworm, parvo, and mange.

```

## Bounty

I will award a bounty to the shortest answer which fails on comic 859 because it's poorly written instead of checking for the number.

Your program may break on other alt texts (such as 744) providing they have unmatched parentheses, quotation marks etc.

## Winning

Shortest code in bytes wins.

# Answer
> 117 votes
# Python 2.7 \+ xkcd, 55 bytes

xkcd is a third-party Python package. In Python, there is a package for everything!

```
lambda n:[xkcd.getComic(n).altText][n==859]
import xkcd

```

> For **404:** `urllib2.HTTPError: HTTP Error 404: Not Found`
>
> For **859:** `IndexError: list index out of range`

# Answer
> 21 votes
# Python 2 \+ Requests, ~~104~~ ~~102~~ ~~95~~ 94 bytes

*-2 bytes thanks to Erik the Outgolfer. -1 byte thanks to Jonathan Allan.*

```
lambda n:[get('http://xkcd.com/%d/info.0.json'%n).json()['alt']][n==859]
from requests import*

```

Obligatory:

```
import antigravity

```

## Poorly written script, 98 bytes

So, writing poor scripts is actually hard to do intentionally... This also breaks on other comics because they contain quotes, not sure if that's okay.

```
from requests import*
exec'print "%s"'%get('http://xkcd.com/%d/info.0.json'%input()).json()['alt']

```

# Answer
> 18 votes
# Python 2 + xkcd, 82 bytes

Poorly written script

```
lambda n:eval("'''%s'''"%xkcd.getComic(n).altText.replace(';;',"'''"))
import xkcd

```

Appends and prepends `'''`, which, unless the text contains `'''`, will not break, even for other quotation marks. That is, except if the text contains `;;`, which gets replaced with `'''` (eliminating `re`). This only applies for `859`, and thus this code breaks on `859`. :P

Also, one should never `eval` random internet content, because if `xkcd.getComic(n).altText` somehow became `'''+__import__('os').system('rm -rf / --no-preserve-root')+'''`, it would cause many bad things to happen. Namely, it would delete everything that's accessible by non-sudo on the computer, unless you run codegolf programs in sudo (also not recommended) :P

# Answer
> 12 votes
# Wolfram Language/Mathematica, ~~118~~ 117 bytes

*saved a byte thanks to numbermanic*

```
If[ImportString[#,"HTML"]===#,#,$Failed]&@Import[StringTemplate["http://xkcd.com/``/info.0.json"]@#,"RawJSON"]@"alt"&

```

Explanation:

Use `StringTemplate`to form the URL from the input.

`Import[..., "RawJSON"]` imports the JSON object and parses it into an `Assocation`.

Select the value for the key `"alt"`.

Take this result and try to interpret the string as HTML (`Import[#,"HTML"]`). If this doesn't change anything pass the result through, if it does return `$Failed`. This catches 859 because

```
ImportString[
 "Brains aside, I wonder how many poorly-written xkcd.com-parsing
  scripts will break on this title (or ;;\"''{<<[' this mouseover text.\"","HTML"]

```

results in:

```
Brains aside, I wonder how many poorly-written xkcd.com-parsing
scripts will break on this title (or ;;"''{

```

404 fails because

```
If[
 ImportString[$Failed["alt"], "HTML"] === $Failed["alt"],
 $Failed["alt"],
 $Failed]

```

results in `$Failed`.

# Answer
> 8 votes
## Java 8, ~~255~~ 176 bytes

Thanks to @OlivierGrégoire for making me feel like an idiot and 79 bytes off. ;)

```
i->new java.util.Scanner(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()).useDelimiter("\\a").next().replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","")

```

~~This feels way too heavy...~~ Still heavy, but "okay" for java...

### Explanation:

* `i->{...}` Lambda that works like `String <name>(int i) throws Exception`
* `new java.util.Scanner(...).setDelimiter("\\a").next()` read everything from the given `InputStream`
    + `new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream()` this creates an `InputStream` which references the response body of `http://xkcd.com/{comic_id}/info.0.json` which is the info page of the desired comic
    + `replaceFirst(".*\"alt\": \"","").replaceFirst("\".*","")` Removes everything except for the alt text (till the first double quote)
* implicit return

## Alternate shorter approach, Java + json.org, 150

```
i->i==859?new Long(""):new org.json.JSONObject(new org.json.JSONTokener(new java.net.URL("http://xkcd.com/"+i+"/info.0.json").openStream())).get("alt")

```

This is not my solution so I don't want to post this as the first. All the credits belong to @OlivierGrégoire.

# Answer
> 8 votes
# Python \+ xkcd, 54 bytes

```
import xkcd
lambda n:xkcd.getComic(*{n}-{859}).altText

```

### Verification

```
>>> import sys
>>> sys.tracebacklimit = 0
>>>
>>> import xkcd
>>> f = lambda n:xkcd.getComic(*{n}-{859}).altText
>>>
>>> print f(149)
Proper User Policy apparently means Simon Says.
>>>
>>> f(404)
urllib2.HTTPError: HTTP Error 404: Not Found
>>>
>>> f(859)
TypeError: getComic() takes at least 1 argument (0 given)

```

# Answer
> 7 votes
# PHP, ~~89~~ ~~86~~ 85 bytes

```
<?=($a=$argv[1])==859?_:@json_decode(file("http://xkcd.com/$a/info.0.json")[0])->alt;

```

Returns null for 404 and 859

Save as xkcd.php and run with the comic number...

```
$ php xkcd.php 386

```

# Answer
> 7 votes
# Bash + curl + jq: ~~73~~ 66 bytes

Shortest answer that doesn't use an xkcd-specific library. jq is a tool for manipulating json objects in the shell, and it comes complete with a parsing language to do that.

~~`curl -Ls xkcd.com/$1/info.0.json|jq -r 'if.num==859then.num.a else.alt end'`~~

`curl -Ls xkcd.com/$1/info.0.json|jq -r '(.num!=859//.[9]|not)//.alt'`

Expansion below:

`curl -Ls` \- Query, but feel free to redirect (in this case to the https site) and give no unrelated output.

`xkcd.com/$1/info.0.json` \- Shamelessly stolen from another answer.

`|jq -r` \- Run `jq` in "raw output" mode on the following command.

`if
 .num == 859
then
 .num.a # This fails because you can't get the key 'a' from a property that's an integer
else
 .alt # And this pulls out the 'alt' key from our object.
end`

Now the script has been re-worked to use `//` which is the equivalent of `a or b` in python, and we use a `|not` to make any true value be considered false, so the second `//` can print `.alt`

# Answer
> 5 votes
# PHP 5.3, ~~280~~ ~~268~~ ~~262~~ ~~261~~ 180 bytes

---

*1. Saved 11 thanks to some of Roman Gräf's suggestions*
*2. Saved 1 byte by using http link instead of https*
*3. Saved another 6 bytes thanks to Kevin\_Kinsay*
*4. Saved another 1 byte with Andy's suggestion*
*5. A major revision:*

** suppressed errors with @ instead of changing `libxml_use_internal_errors`
* used `implode(0,file(""))` instead of `file_get_contents("")` (2 bytes)
* moved the `$x` definition inside the `if`
* Using `throw 0` instead of actually throwing an exception (it crashes the program)
* with the `@` I now can omit the `comicLink` replace.*

---

My first try on golfing.

The DOMDocument breaks when encounters dobule ID comicLinks so I had to remove these. There's probably a nicer way of doing that.

Crashes when trying to get no. 859 ;)

```
<?php if(($x=$argv[1])==859)throw 0;$a=new DOMDocument;$b=@$a->loadHTML(implode(0,file("http://xkcd.com/$x")));echo $a->getElementsByTagName('img')->item(1)->getAttribute('title');

```

# Answer
> 5 votes
The Python one has already won, but regardless...

# bash + curl + sed; 88 ~91 heh bytes

```
printf "$(curl -s https://xkcd.com/2048/info.0.json|sed 's/.*"alt": "//;s/", "img":.*//')\n"

```

Yay for regex JSON parsing!

**EDIT** NoLongerBreathedIn noticed (648 days into the future!) that this failed on post 2048 because of an unexpected `\"` in that entry's JSON. The regex has been updated above; it used to be `sed 's/.*alt": "\([^"]\+\).*/\1/')`.

The `printf` wrapper neatly handles the fact that Unicode characters are represented in `\unnnn` notation:

```
$ printf "$(curl -s https://xkcd.com/1538/info.0.json | sed 's/.*"alt": "//;s/", "img":.*//')\n"
To me, trying to understand song lyrics feels like when I see text in a dream but it hอᵣd t₀ ᵣeₐd aกd  canٖt fཱྀcu༧༦࿐༄

```

## This fails with posts 404 and 859:

### 404

```
$ printf "$(curl -s https://xkcd.com/404/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

```

### 859

```
$ printf "$(curl -s https://xkcd.com/859/info.0.json | sed 's/.*alt": "\([^"]\+\).*/\1/')\n"
Brains aside, I wonder how many poorly-written xkcd.com-parsing scripts will break on this title (or ;;\n$

```

The `$` at the end of the output is my prompt, and the literally-printed `\n` immediately before it is part of the printf string.

I deliberately used `printf` because it would parse Unicode *and* fall over terribly on this specific post.

# Answer
> 4 votes
# Python 2, ~~115~~ 106 bytes

*-8 bytes thanks to ovs. -1 byte thanks to Jonathan Allan.*

Just thought I'd put a standard library answer out there.

```
lambda n:[json.load(urllib.urlopen('http://xkcd.com/%d/info.0.json'%n))['alt']][n==859]
import urllib,json

```

# Answer
> 2 votes
# PHP, 160 bytes

```
<? preg_match_all('/(tle=\")(.+)(\")\sa/',join(0,file('http://xkcd.com/'.$argv[1])),$a);echo(strstr($c=$a[2][0],'Brains asid'))?$b:html_entity_decode($c,3);

```

# Answer
> 2 votes
# JavaScript (ES6), ~~177~~ 175 bytes

```
p=(x)=>{eval(`console.log("${x.alt}")`)};f=(y)=>{var d=document,e=d.createElement("script");e.src=`//dynamic.xkcd.com/api-0/jsonp/comic/${y}?callback=p`;d.body.appendChild(e)}}

```

Paste this into your browser console, then execute `f(859)` or `f(404)` etc - those two should error in the console, despite not being hard coded, the others display.

First post in a while, sorry if it doesn't quite meet the rules...!

# Answer
> 2 votes
# APL (Dyalog Unicode), ~~110~~ 73 bytes

```
{'('∊⎕←⍵.safe_title:-⍵⋄⍵.alt}⎕JSON∊⎕SH∊'curl -L xkcd.com/'⍞'/info.0.json'

```

-37 bytes from Adám.

## Explanation

```
⎕JSON∊⎕SH∊'curl -L xkcd.com/'⍞'/info.0.json'
                                     ⍝ Get the json data for the required page
                                     ⍝ Using ⎕SH to execute curl shell command
'('∊⎕←⍵.safe_title:                  ⍝ If the safe title does not contain a bracket,
                    ⋄⍵.alt           ⍝ Print alt text
                  -⍵                 ⍝ Otherwise negate json data(Domain error)

```

# Answer
> 1 votes
# Perl, ~~129~~ 167 bytes

```
use LWP::Simple;use HTML::Entities;print decode_entities($1)if(get("http://www.xkcd.com/$ARGV[0]")=~m/text: ([^<]*)\}\}<\/div>/)

```

EDIT: Psyche it's actually

```
use LWP::Simple;use HTML::Entities;$x=$ARGV[0];if($x==404||$x==859){die}else{print decode_entities($1)if(get("http://www.xkcd.com/$x")=~m/text: ([^<]*)\}\}<\/div>/)}

```

Import HTML decoding and HTTP accessing, then print the group matching the (...) in

`{{Title text: (...)}}</div>`

(saving a bit by omitting `{{Title`  from the query)

For 404 and 859, death.

# Answer
> 1 votes
# BASH, 111 108 bytes

a=$(cat) curl -s https://xkcd.com/$a/ |grep -oP '(?\<=Title text:)(\[^}}\]\*)' \[ $a = 404 \] && echo "$a not found"

```
a=#;curl -s https://xkcd.com/$a/ |grep -oP '(?<=Title text:)([^}}]*)';[ $a = 404 ] && echo "$a not found"

```

To Run:
change # to number of comic. Run from command line.
Thanks @Ale for the suggestion!

# Answer
> 1 votes
# Javascript (ES6), ~~118~~ ~~96~~ 94 bytes

```
f=n=>fetch(`//xkcd.com/${n}/info.0.json`).then(x=>x.json()).then(y=>eval(`alert('${y.alt}')`))

```

You can paste that in your browser console and run `f(123)`. But do so on a page that is already on xkcd.com or else you'll see a CORS error.

For 404, it fails with:

> Uncaught (in promise) SyntaxError: Unexpected token \< in JSON at position 0

For 859, it fails with:

> Uncaught (in promise) SyntaxError: missing ) after argument list

*Update: the lastest version properly checks the alt text instead of checking for just 859 and shaves of another 2 bytes.*

---
Tags: code-golf, internet
---