title: Tips for Golfing in T-SQL

text:
# Question
Title: Tips for Golfing in T-SQL
What general tips do you have for golfing in T-SQL? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to T-SQL. Please post one tip per answer.

Thanks to Marcog for the original idea. :)

# Answer
My general bag of tricks::

* `@` is a valid variable in t-sql.
* T-sql 2012 added `iif` a VB style case statement. This is almost always shorter than an equivalent `if` `else`.
* `\` is a useful way to initialize a number as 0 in a money type. You can convert a value to to a float by adding `e`. e.g. `4e` or `\k` which will set k to the value 0.00 money.
* `rCTE` seem to be the best way to create a number table of less than a 100 entries. Even shorter than using spt\_values. If you need more than a 100, cross join and add them.
* `+=` and other compound operators were added in 2008. Use them it saves a few characters.
* Literals are usually a good enough delimiter for aliasing purposes. You rarely need a space or a `;`.
* Use ANSI SQL joins if you need them. `Select*from A,B where condition` is shorter than `select*from A join b on condition`
* If you can be assured that the your while loop will do the first iteration it's best to rewrite it as a do-while style `goto` loop.
* `STR()` is the shortest function to turn an int into a string. If you are doing more than one conversion or may need to concat numerous different datatypes consider the `concat` function. E.g. `'hello'+str(@)` is shorter than `concat('hello',@)`, but `hello+str(@)+str(@a)` is longer than `concat('hello',@,@a)`

For example These two are semantically equivalent.

```
while @<100begin/*code*/set @+=1 end
s:/*code*/set @+=1if @<100goto s

```

You can use `Values` to create a table or subquery. This will only really be a benefit if you need a few constant rows.
> 20 votes

# Answer
**Code compression using SQL**

SQL is wordy,scores high, and as much as we love'em, `SELECT FROM WHERE` cost 23 bytes with every use. You can compress these and other repeated words or entire code snippets. Doing this will decrease the marginal cost of repeated code to 1 byte!\*

**How this works:**

* A variable is declared and assigned compressed SQL code
* A table modifies the variable. Each row deflates the variable.
* The modified variable is executed.

**The problem:**

The upfront cost is close to 100 bytes and each row in the replacement table costs another 6 bytes. This kind of logic won't be very effective unless you're working with a lot of code which you can't trim down or the challenge is compression-based.

**Here's an example**

The challenge is to get the last 10 multiples of 2,3, and 5 leading up to n. Let's say this (**343 bytes golfed**) is the best solution I could come up with:

```
WITH x AS(
    SELECT 99 n
UNION ALL
    SELECT n-1
    FROM x
    WHERE n>1
)
SELECT w.n,t.n,f.n
FROM
    (SELECT n, ROW_NUMBER()OVER(ORDER BY n DESC)r
     FROM x WHERE n%2=0
    )w
,
    (SELECT n, ROW_NUMBER()OVER(ORDER BY n DESC)r
     FROM x WHERE n%3=0
    )t
,   (SELECT n, ROW_NUMBER()OVER(ORDER BY n DESC)r
     FROM x WHERE n%5=0
    )f
WHERE w.r=t.r AND w.r=f.r AND w.r<11
ORDER BY 1

```

**Example after code is compressed**

This executes the same code as above, is ~**302 bytes golfed**.

```
DECLARE @a CHAR(999)='
WITH x AS(!99n UNION ALL !n-1 @x#n>1)
!w.n,t.n,f.n@$2=0)w,$3=0)t,$5=0)f
#w.r=t.r AND w.r=f.r AND w.r<11^1'

SELECT @a=REPLACE(@a,LEFT(i,1),SUBSTRING(i,2,99))
FROM(VALUES
  ('$(!n,ROW_NUMBER()OVER(^n DESC)r@x#n%'),
  ('! SELECT '),
  ('@ FROM '),
  ('# WHERE '),
  ('^ ORDER BY ')
)x(i)

EXEC(@a)

```
> 5 votes

# Answer
Here's a funny one. This will convert the values in a column into a single tuple.

EDIT: Thank you for the comments. It seems like the shortest way of rolling up without the XML tags is:

```
SELECT (SELECT column1+''
FROM table
ORDER BY column1
FOR XML PATH(''))

```

Note: if XML is a valid output you can omit the outer select and parens. Also the `column1+''`, only works for strings. For number types it's best to do `column1+0`
> 4 votes

# Answer
It is possible to use some **bitwise** operators in T-SQL.

I don't have a concrete example, but I believe it is a good-to-know fact when golfing in T-SQL.
> 3 votes

# Answer
## Print instead of Select

It's as simple as that! So here's a T-SQL / Python polyglot:

```
print'Hello, World!'

```

**Try it online**
> 3 votes

# Answer
Scientific notation is a shorter method to express very large and very small numbers, e.g. `select 1000000000` = `select 1E9` and `select 0.000001` = `select 1E-6`.
> 3 votes

# Answer
# Use GZIP compression for very long strings!

So I knew that SQL 2016 added a `COMPRESS` function (and a `DECOMPRESS` function), which (finally) brings the ability to GZIP a string or binary.

The problem is that it isn't immediately clear how to take advantage of this for golfing; `COMPRESS` can take a string but returns a `VARBINARY`, which is shorter in *bytes* (when stored in a SQL `VARBINARY` field), but is *longer* in characters (raw hex).

I've played with this before, but I finally was able to put together a working version, based on this old answer on SO. That post doesn't use the new GZIP functions, but it does convert a `VARBINARY` to a Base-64 encoded string. We just needed to insert the new functions into the right place, and golf it up a bit.

Here is the code you can use to convert your very long string to the Base-64 encoded compressed string:

```
DECLARE @s VARCHAR(MAX)='Your really long string goes right here'
SELECT CONVERT(VARCHAR(MAX),(SELECT CONVERT(VARBINARY(MAX),COMPRESS(@s))
       FOR XML PATH(''),BINARY BASE64))

```

Take the output, and use it in your code in place of the original long string, along with:

```
--To use your compressed string and return the original:
DECLARE @e VARCHAR(MAX)='H4sIAAAAAAAEAIvMLy1SKEpNzMmpVMjJz0tXKC4pygRS6fmpxQpFmekZJQoZqUWpAGGwW5YnAAAA'
SELECT CAST(DECOMPRESS(CAST(@e as XML).value('.','varbinary(max)'))AS varchar(max))

```

So instead of your original code (**1471 bytes**)

```
SELECT'Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we can not dedicate — we can not consecrate — we can not hallow — this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us — that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion — that we here highly resolve that these dead shall not have died in vain — that this nation, under God, shall have a new birth of freedom — and that government of the people, by the people, for the people, shall not perish from the earth.'

```

you would have this (**1034 bytes**):

```
SELECT CAST(DECOMPRESS(CAST('H4sIAAAAAAAEAGVUW47bMAy8Cg/g5hD9aLFA0a8C/aYt2hZWEVNJjpGT5LodinE2i/0JIouPmeFQP3QrVCctQpwDVblKpptwqcSLkt3O3FbBeSy6LWujWUtbSTO1NVaaNLeYJbeBmLLslLlFzYNdTBKvEihm+hVHKe029CZBQpy44aYpighdil60RsvDmRtxSnQGEAasqUiPlX8bpxP91p126TeSF168PtNiYTTFa0y0cxmoSQWwhfZVDL8XPsBpAZLb40hVX9B+QgganCkp6kgOW5ET/fXmZ2mmwdF45NaSfJujpEA6ezfg6PErX8FDz2KEj9pIvUBJ63/E92xoBO3xP3Oi8iBxSTyJKY9ArQJSSiAltFhp8IuFEuBXL/TClc7RhmaXJ3prhJFxarq4KHNsvb6RtikcOkHhuuoGLkH7nE/0fcOIu9SJy4LAKrnKYKGmUdb2Qe3++hXSVpnKl+8rpoxh3t1HC9yVw4n+wA9jMVYwwGC4D3xBGOIY89rKtiwJwzINhkPfow0cAagzY8aj4sZMfFG1n90IKnEIZoEgrfDUvOmuBXT3COulaMM0kCieEdgNUOQsZ9gYEB4K8e0BYNwgbHNm2KBik4LCHgmhbxSigz1mYKPcane/Uxyo9D0bDN8oL0vS5/zYlC3DF7Gu+Ay872gQp9U7mDCzb2jPWN0ZaGJKwOJZx3QD9SvD6uEA4l2feHrvnv9lS93ojeu7ScHAAVFGme3tQOr94eGiZwuHSVeFduKDM70avwscZAtd++er+sqrp068VTf5C63D4HBdRfWtvwxcsYq2Ns8a96dvnTxMD7JYH0093+dQxcFU897DhLgO0V+RK0gdlbopj+cCzoRGPxX+89Se5u/dGPtzOIO5SAD5e3drL7LAfiXDyM13HE+d6CWZY26fjr7ZH+cPgFhJzPspK+FpbuvpP9RXxXK3BQAA'as XML).value('.','varbinary(max)'))AS varchar(max))

```

See this answer which saved me nearly 200 bytes.

I haven't done the math, but clearly due to the overhead this is only going to be effective for extremely long strings. There are probably other places this can't be used; I've already discovered you have to `SELECT` it, you can't `PRINT` it, otherwise you get:

```
Xml data type methods are not allowed in expressions in this context.

```

**EDIT**: Shorter version of the decompress code, courtesy of @digscoop:

Save 10 bytes by changing the outer `CAST` to an implicit conversion using `CONCAT`:

```
SELECT CONCAT('',DECOMPRESS(CAST('encoded_string_here'as XML).value('.','varbinary(max)')))

```

You can also declare a variable of type `XML` instead of `VARCHAR(MAX)`, and save on the inner `CAST`:

```
DECLARE @ XML='encoded_string_here'
SELECT CONCAT('',DECOMPRESS(@.value('.','varbinary(max)')))

```

This is *slightly* longer by itself, but if you need it in a variable for other reasons, then it might help.
> 3 votes

# Answer
Michael B mentioned using a recursive CTE for a number table, but didn't show an example. Here is a MS-SQL version we worked out in this other thread:

```
--ungolfed
WITH t AS (
    SELECT 1 n
    UNION ALL
    SELECT n + 1
    FROM t
    WHERE n < 99)
SELECT n FROM t

--golfed
WITH t AS(SELECT 1n UNION ALL SELECT n+1FROM t WHERE n<99)SELECT n FROM t

```

Note that you can change the *starting value* (`1 n`), the *interval* (`n + 1`) and the *ending value* (`n < 99`).

If you need more than 100 rows, though, you will need to add `option (maxrecursion 0)`:

```
WITH t AS(SELECT 0n UNION ALL SELECT n+1FROM t WHERE n<9999)
SELECT n FROM t option(maxrecursion 0)

```

or join the rCTE to itself:

```
WITH t AS(SELECT 0n UNION ALL SELECT n+1FROM t WHERE n<99)
SELECT 100*z.n+t.n FROM t,t z

```

Although this last one isn't guaranteed to return in numeric order without an `ORDER BY 1`
> 2 votes

# Answer
A few thoughts about creating and using tables for challenges:

**1. SQL input can be taken via a pre-existing table**

Code Golf Input/Output Methods:

> SQLs may take input from a named table

Creating and populating this table with input values doesn't count toward your byte total, you can just assume it is already there.

This means your calculations can output via simple SELECT from the input table:

```
SELECT 2*SQRT(a)FROM t

```

**2. If possible, don't actually create a table at all**

Instead of (69 bytes):

```
CREATE TABLE t(b INT)
INSERT t VALUES(7),(14),(21),(99)
SELECT b FROM t

```

Just do (43 bytes):

```
SELECT b FROM(VALUES(7),(14),(21),(99))t(b)

```

**3. If possible, create the table with a SELECT INTO**

Instead of (39 bytes):

```
CREATE TABLE t(p INT)
INSERT t VALUES(2)

```

Do this (17 bytes):

```
SELECT 2 p INTO t

```

**4: Consider mashing multiple columns together**

Here are two variations that return the same output:

```
SELECT a,b FROM
(VALUES('W','Bob'),('X','Sam'),('Y','Darla'),('Z','Elizabeth'))t(a,b)

SELECT LEFT(a,1),SUBSTRING(a,2,99)FROM
(VALUES('WBob'),('XSam'),('YDarla'),('ZElizabeth'))t(a)

```

After some testing, the top version (multiple columns) seems shorter with *7 or fewer rows*, the bottom version (due to the LEFT and SUBSTRING) is shorter with *8 or more rows*. Your mileage may vary, depending on your exact data.

**5: Use REPLACE and EXEC for very long sequences of text**

In the vein of comfortablydrei's excellent answer, if you have **15 or more values**, use `REPLACE` on a symbol to get rid of the repeated `'),('` separators between elements:

114 characters:

```
SELECT a FROM(VALUES('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H')
,('I'),('J'),('K'),('L'),('M'),('N'),('O'))t(a)

```

112 characters:

```
DECLARE @ CHAR(999)=REPLACE('SELECT a FROM(VALUES(''
 A-B-C-D-E-F-G-H-I-J-K-L-M-N-O''))t(a)','-','''),(''')EXEC(@)

```

If you're *already* using dynamic SQL for other reasons (or have multiple replaces), then the threshold where this is worth it is much lower.

**6: Use a SELECT with named columns instead of a bunch of variables**

Inspired by jmlt's excellent answer here, re-use strings via a SELECT:

```
SELECT a+b+a+b+d+b+b+a+a+d+a+c+a+c+d+c+c+a+a
FROM(SELECT'Hare 'a,'Krishna 'b,'Rama 'c,'
'd)t

```

returns

```
Hare Krishna Hare Krishna
Krishna Krishna Hare Hare
Hare Rama Hare Rama
Rama Rama Hare Hare

```

(For MS SQL I changed the `\t` to an in-line return, and changed `CONCAT()` to `+` to save bytes).
> 1 votes

# Answer
**Tag your code for T-SQL syntax highlighting**

Instead of just:

```
CREATE TABLE t(b INT)
INSERT t VALUES(7),(14),(21),(99)
SELECT b FROM t

```

Include a language tag like this:

```
<!-- language: lang-sql -->

    CREATE TABLE t(b INT)
    INSERT t VALUES(7),(14),(21),(99)
    SELECT b FROM t

```

and the result will be:

```
CREATE TABLE t(b INT)
INSERT t VALUES(7),(14),(21),(99)
SELECT b FROM t

```
> 1 votes

# Answer
**Take advantage of new features/functions in MS SQL 2016 and SQL 2017**

If you don't have local copies to work with, you can play online with the StackExchange Data Explorer (SQL 2016) or with dbfiddle.uk (SQL 2016 or SQL "vNext").

**STRING\_SPLIT** (SQL 2016 and later)

```
SELECT *
FROM STRING_SPLIT('one,two,three,four,five',',')

```

If you need to alias the table or refer to the column name:

```
SELECT t.value
FROM STRING_SPLIT('one,two,three,four,five',',')t

```

**TRIM** (SQL 2017 or later)

Shorter than `RTRIM()` and certainly shorter than `LTRIM(RTRIM())`.

Also has an option to remove other characters or sets of characters from either the beginning or the end:

```
SELECT TRIM('sq,0' FROM 'SQL Server 2000')

```

returns `L Server 2`

**TRANSLATE** (SQL 2017 or later)

`TRANSLATE` allows you to replace multiple characters in one step, rather than a bunch of nested `REPLACE` statements. But don't celebrate *too* much, it only replaces individual single characters with different single characters.

```
SELECT TRANSLATE('2*[3+4]/{7-2}', '[]{}', '()()');

```

Each character in the second string is replaced by the *corresponding* character in the 3rd string.

Looks like we could eliminate a bunch of characters with something like `REPLACE(TRANSLATE('source string','ABCD','XXXX'),'X','')`

---

Some more interesting ones as well, like `CONCAT_WS` and `STRING_AGG` that are probably worth a look as well.
> 1 votes

# Answer
Holy cow, I have discovered the wonder of **`PARSENAME`** (SQL 2012 or higher).

The function was built to isolate the parts of an object name like `servername.dbname.dbo.tablename`, but it works for *any* dot-separated values. Just remember it counts from the *right*, not the left:

```
SELECT PARSENAME('a.b.c.d',1),      -- d
       PARSENAME('a.b.c.d',2),      -- c
       PARSENAME('a.b.c.d',3),      -- b
       PARSENAME('a.b.c.d',4)       -- a

```

If you have less than 4 dot-separated values, it will return `NULL` for the remainder (but it *still counts right to left*):

```
SELECT PARSENAME('a.b',1),      -- b
       PARSENAME('a.b',2),      -- a
       PARSENAME('a.b',3),      -- NULL
       PARSENAME('a.b',4)       -- NULL

```

Here's where the magic comes in, though: combine it with `STRING_SPLIT` (2016 or higher) to make *in-memory multi-column tables!!*

Old and busted:

```
SELECT a,b,c FROM
(VALUES('Bob','W','Smith'),
       ('Sam','X','Johnson'),
       ('Darla','Y','Anderson'),
       ('Elizabeth','Z','Turner'))t(a,b,c)

```

New hotness:

```
SELECT PARSENAME(value,3)a,PARSENAME(value,2)b,PARSENAME(value,1)c
FROM string_split('Bob.W.Smith-Sam.X.Johnson-Darla.Y.Anderson-Elizabeth.Z.Turner','-')

```

Clearly your actual savings depend on the size and contents of the table, and how exactly you are using it.

Note that if your fields are constant-width, you're probably better off using `LEFT` and `RIGHT` to separate them instead of `PARSENAME` (not only because the function names are shorter, but also because you can eliminate the separators entirely).
> 1 votes

# Answer
A couple more unrelated tricks I saw and wanted to preserve:

1. **Use `GO #` to repeat a block a specific number of times**.

Saw this clever trick on Paul's excellent answer.

```
PRINT'**********'
GO 10

```

This would, of course, reset any counter variables in the block, so you'd have to weigh this against a `WHILE` loop or a `x: ... GOTO x` loop.

2. **`SELECT TOP ... FROM systypes`**

From the same question as Paul's above, Anuj Tripathi used the following trick:

```
SELECT TOP 10 REPLICATE('*',10) FROM systypes

```

or, as suggested by pinkfloydx33 in the comments:

```
SELECT TOP 10'**********'FROM systypes

```

Note this doesn't rely on any of the actual *contents* of `systypes`, just that the system view exists (which it does in every MS SQL database), and contains at least 10 rows (it looks to contain 34, for most recent versions of SQL). I couldn't find any system views with shorter names (that didn't require a `sys.` prefix), so this may be ideal.
> 1 votes

# Answer
See this question on dba.stackexchange for some interesting ideas for adding a number column to a STRING\_SPLIT result.

Given a string like `'one,two,three,four,five'`, we want to get something like:

```
value   n
------ ---
one     1
two     2
three   3
four    4
five    5

```
1. Per Joe Obbish's answer, use `ROW_NUMBER()` and order by `NULL` or a constant:

```
SELECT value, ROW_NUMBER() OVER(ORDER BY (SELECT 1))n
FROM STRING_SPLIT('one,two,three,four,five',',')

```
2. Per Paul White's answer, use a `SEQUENCE`:

```
CREATE SEQUENCE s START WITH 1
SELECT value, NEXT VALUE FOR s
FROM STRING_SPLIT('one,two,three,four,five', ',')

```

Sequences are interesting persistent objects; you can define the data type, the min and max value, the interval, and whether it wraps around to the beginning:

```
    CREATE SEQUENCE s TINYINT;     --Starts at 0
    CREATE SEQUENCE s MINVALUE 1;  --Shorter than START WITH
    SELECT NEXT VALUE FOR s        --Retrieves the next value from the sequence
    ALTER SEQUENCE s RESTART;      --Restarts a sequence to its original start value

```
3. Per Biju jose's answer, you can use the `IDENTITY()` *function* (which is *not* the same as the `IDENTITY` *property* in conjunction with an INSERT:

```
SELECT value v,IDENTITY(INT) AS n
INTO t
FROM STRING_SPLIT('one,two,three,four,five',',')

SELECT * FROM t

```

Note that the last two parameters in `IDENTITY(INT,1,1)` are optional, and will default to 1 if excluded.
> 1 votes

# Answer
Just discovered that you can **use numerals for a single-character `REPLACE` to eliminate quotes**:

```
--44 bytes
PRINT REPLACE('Baby Shark******','*',' doo')

--42 bytes
PRINT REPLACE('Baby Shark000000',0,' doo')

```

This is because `REPLACE` does an implicit conversion to string.

Both produce the same output:

```
Baby Shark doo doo doo doo doo doo

```
> 1 votes

# Answer
_ and # are valid aliases. I use them with CROSS APPLY to make it appear the columns it returns are part of the FROM clause e.g.

```
SELECT TOP 10 number, n2
FROM master.dbo.spt_values v
CROSS APPLY (SELECT number*2 n2) _

```

I like this when the only purpose of the CROSS APPLY is to compute an expression.

For that matter, using APPLY for computing sub-expressions is a neat way to make your code DRY-er (and shorter). From what I've seen in execution plans, there is no added cost to this approach. The compiler figures out you're just computing something and treats it like any other expression.
> 0 votes

---
Tags: code-golf, tips, sql
---


title: Crossing sequences

text:
# Question
Title: Crossing sequences
# Crossing Sequences

Given a list of positive integers `A`, call it an *increasing sequence* if each element is greater than or equal to the previous one; and call it a *decreasing sequence* if each element is less than or equal to the previous one.

Some increasing sequences:

```
[1,2,4,7]
[3,4,4,5]
[2,2,2]
[]

```

Some decreasing sequences:

```
[7,4,2,1]
[5,4,4,3]
[2,2,2]
[]

```

A *crossing sequence* is a list that can be decomposed into two disjoint subsequences, one an increasing sequence and the other a decreasing sequence.

For example, the list:

```
[3,5,2,4,1]

```

is a crossing sequence, since it can be decomposed into:

```
[3,    4  ]
[  5,2,  1]

```

where `[3,4]` is the increasing subsequence and `[5,2,1]` is the decreasing subsequence. We'll call such a pair of (increasing,decreasing) subsequences a *decomposition* of the crossing sequence.

The list:

```
[4,5,2,1,3]

```

is not a crossing sequence; there is no way to decompose it into an increasing and decreasing subsequence.

Your task is to write a program/function taking as input a list of positive integers; and if it is a crossing sequence, return the two lists in one of its decompositions; or some consistent "falsey" value if the list is not a crossing sequence.

This is ; shortest program/function in each language is the winner.

## Rules:

* Input is flexible.
* The usual loopholes are forbidden.
* If there are multiple valid ways to decompose the input, you may output one or all of them.
* Output formatting for the decomposition is flexible; but it must be unambiguous regarding the distinction between the two subsequences.
* You may use any consistent output value to indicate that the input is not a crossing sequence; so long as it is unambiguous compared to the output for any crossing sequence. You should specify the falsey value in your answer.

## Test Cases:

Using `False` to indicate non-crossing sequences:

```
[3, 5, 2, 4, 1] => [3, 4], [5, 2, 1]
[3, 5, 2, 4, 4, 1, 1] => [3, 4, 4], [5, 2, 1, 1]

[7, 9, 8, 8, 6, 11] => [7, 8, 8, 11], [9, 6]
[7, 9, 8, 8, 6, 11] => [7, 9, 11], [8, 8, 6] # also valid
[7, 9, 8, 8, 6, 11] => [7, 8, 11], [9, 8, 6] # also valid

[7, 8, 9, 10, 20, 30] => [7, 8, 9, 20, 30], [10]
[7, 8, 9, 10, 20, 30] => [8, 9, 10, 20, 30], [7] # this is also valid

[5, 5, 5] => [5, 5, 5], []

[4, 5, 2, 1, 3] => False
[3, 4, 3, 4, 5, 2, 4] => False

```

# Answer
# Brachylog, 17 bytes

```
;Ṣzpᵐz{ℕˢ}ᵐ≤₁ʰ≥₁ᵗ

```

Try it online!

There's probably considerable room to golf this.
> 1 votes

# Answer
# 05AB1E, ~~15~~ ~~14~~ 13 bytes

```
2.Œ.ΔćRšεü@}W

```

Try it online or validate all test cases.

Explanation:

```
2.Œ                    # all partitions of the input in 2 subsequences
   .Δ                  # find the first partition such that the following gives 1
     ćRš               # reverse the first subsequence
        ε  }           # map each subsequence to
         ü@            # pairwise greater-than
            W          # minimum (1 if all 1s, 0 otherwise)

```
> 1 votes

# Answer
# Jelly, 12 bytes

```
ŒPżṚ$ṢNÞƭ€ƑƇ

```

Try it online!
> 1 votes

# Answer
# JavaScript (ES6),  ~~110 105~~  104 bytes

Returns either `[[decreasing], [increasing]]` or \\$1\\$ if there's no solution.

```
f=(a,n,b=[[],[]])=>a.some((v,i)=>[...x=b[i=n>>i&1]].pop()*(x.push(v),i-=!i)>v*i)?n>>a.length||f(a,-~n):b

```

Try it online!

## How?

We try all values of a bitmask \\$n\\$ between \\$0\\$ and \\$2^L\\$, where \\$L\\$ is the length of the input array.

At each iteration, we split the original array into two subsequences \\$b\[0\]\\$ (decreasing) and \\$b\[1\]\\$ (increasing), using each bit \\$i\\$ of \\$n\\$ to know where each value goes.

When a new value is added to a subsequence, we simultaneously make sure that it's not invalid by comparing it with the last value, popped from a copy of the subsequence. The direction of the inequality is always the same, but the operands are multiplied by either \\$1\\$ (if \\$i=1\\$) or \\$-1\\$ (if \\$i=0\\$):

```
[...x = b[i = n >> i & 1]].pop() * (x.push(v), i -= !i) > v * i

```

We stop and return \\$b\\$ as soon as all values are passing, i.e. `some()` is falsy.
> 1 votes

# Answer
## Haskell, 84 bytes

```
(([],[])#)
(d,i)#(a:b)=(#b)=<<[(d++[a],i)|all(a<=)d]++[(d,i++[a])|all(a>=)i]
p#_=[p]

```

Returns a list of all valid `(decreasing,increasing)` pairs or the empty list if there's no such pair.

Try it online!
> 1 votes

# Answer
# Python 3, ~~109~~ 107 bytes

```
def f(l,i=[],d=[]):
 if l:s,*r=l;i and s<i[-1]or f(r,i+[s],d);d and s>d[-1]or f(r,i,d+[s])
 else:print(i,d)

```

Try it online!

The function prints all possible decompositions to the standard output. If there are no possible decompositions, nothing is printed.

Thanks to @Sriotchilism O'Zaic for improvement suggestions.
> 1 votes

# Answer
# Python 2, 147 bytes

```
def f(a):
 for i in range(2**len(a)):
	x=[];y=[]
	for c in a:[x,y][i&1]+=[c];i/=2
	if x==sorted(x)and y[::-1]==sorted(y[::-1]):return x,y
 return 0

```

Try it online!
> 0 votes

---
Tags: code-golf, sequence, array
---


title: Who was president of the USA?

text:
# Question
Title: Who was president of the USA?
# Challenge

Write a program that takes as input a day from April 30, 1789 to August 21, 2019 and returns as output who was president of the USA that day.

# Notes

For the list of US presidents, the format of their names, and the period of their presidency, see below:

```
April 30, 1789 - March 4, 1797          George Washington
March 4, 1797 - March 4, 1801           John Adams
March 4, 1801 - March 4, 1809           Thomas Jefferson
March 4, 1809 - March 4, 1817           James Madison
March 4, 1817 - March 4, 1825           James Monroe
March 4, 1825 - March 4, 1829           John Quincy Adams
March 4, 1829 - March 4, 1837           Andrew Jackson
March 4, 1837 - March 4, 1841           Martin Van Buren
March 4, 1841 - April 4, 1841           William Henry Harrison
April 4, 1841 - March 4, 1845           John Tyler
March 4, 1845 - March 4, 1849           James K. Polk
March 4, 1849 - July 9, 1850            Zachary Taylor
July 9, 1850 - March 4, 1853            Millard Fillmore
March 4, 1853 - March 4, 1857           Franklin Pierce
March 4, 1857 - March 4, 1861           James Buchanan
March 4, 1861 - April 15, 1865          Abraham Lincoln
April 15, 1865 - March 4, 1869          Andrew Johnson
March 4, 1869 - March 4, 1877           Ulysses S. Grant
March 4, 1877 - March 4, 1881           Rutherford B. Hayes
March 4, 1881 - September 19, 1881      James A. Garfield
September 19, 1881 - March 4, 1885      Chester A. Arthur
March 4, 1885 - March 4, 1889           Grover Cleveland
March 4, 1889 - March 4, 1893           Benjamin Harrison
March 4, 1893 - March 4, 1897           Grover Cleveland
March 4, 1897 - September 14, 1901      William McKinley
September 14, 1901 - March 4, 1909      Theodore Roosevelt
March 4, 1909 - March 4, 1913           William Howard Taft
March 4, 1913 - March 4, 1921           Woodrow Wilson
March 4, 1921 - August 2, 1923          Warren G. Harding
August 2, 1923 - March 4, 1929          Calvin Coolidge
March 4, 1929 - March 4, 1933           Herbert Hoover
March 4, 1933 - April 12, 1945          Franklin D. Roosevelt
April 12, 1945 - January 20, 1953       Harry S. Truman
January 20, 1953 - January 20, 1961     Dwight D. Eisenhower
January 20, 1961 - November 22, 1963    John F. Kennedy
November 22, 1963 - January 20, 1969    Lyndon B. Johnson
January 20, 1969 - August 9, 1974       Richard Nixon
August 9, 1974 - January 20, 1977       Gerald Ford
January 20, 1977 - January 20, 1981     Jimmy Carter
January 20, 1981 - January 20, 1989     Ronald Reagan
January 20, 1989 - January 20, 1993     George H. W. Bush
January 20, 1993 - January 20, 2001     Bill Clinton
January 20, 2001 - January 20, 2009     George W. Bush
January 20, 2009 - January 20, 2017     Barack Obama
January 20, 2017 - Incumbent            Donald Trump

```

A presidency is intended as first day included and last day excluded. For example, "March 4, 1861 - April 15, 1865; Abraham Lincoln" means that Lincoln was president from March 4, 1861 to April **14**, 1865.

This is code-golf, the shortest program in each language wins.

# Example

Input: "February 7, 1865" Output: "Abraham Lincoln"

# Answer
> 27 votes
# PHP, 936 bytes

```
for($a=explode('-',gzinflate(base64_decode('dVTRbtswDPwV/YANKXZq+zFJ1wRts3VZtgB7Y2Mm1ipLAO0089+PtNIuHbAnAzySd+RRNkVZ6XxSJUsMdES1g66x/tgHn5iiKnSms+Q+NF7Nami7xJTajLFtE1ro1D0eDkidZJe6itnQYqfWUNsYNsV1OHgKyNHJ9G/rryfr98M7wyT2mfma8KzuYf8SG2Wx0Rqot179AK/mJ0JB8qhpZ52z0KoVehrUCoguEhjP38i2g0OS2PRK1kOqnoJ7kXAk/wn7BrjJFgYXJH2qdaHLZM0UQLW6428bSCaZZmPFHYF/cSzsySLtR+B68PmJG3oQNTdR7eyZoGG1jzx8cCMw1bnJ3wdntVH+TdT03Q1dx62+pWrJZD0jRaTYnPoG6RBY2DzlwQeUPZbmin/GRUAHi66OUGXKZNFg1yMJOKO+OcmgZdzLksIrIwuHr+jAj0VRxhz9L2h50KsFV9n/ii4n9GbNev9gvcMhMZUWDXJIGGrepNqE0EldL1j10dBwlqVv4SCgiWS7EGoKZ8VJo4hqcrkCloVeLWURVPMtC5RpPtxkAe6VhS9CcLY+ogCRaIX0jNQzkQzA8ewfU2/TD/pyccoksoFB/NjSqRVvKz4GY6rk9myPTS9Vn2yHvgnnsSs7L+h4h3epekDvsZZd3GTGTEzyOPg6ePHw3fyKzZeajZWDrNVn+3sMFzlPVPKrJXB8jmy9BIvY37btoBb8TkbWMrJugpfUDcJxlFrGxpd3v0rVLuUr7RqGqjjFnNfPZlovf4OJ1ua64C2b47HRHIifqvryDC1w1EQtfwA=')));$d=$a[+$i++];)date(Ymd,strtotime($argn))>$d?$m=$a[$i++]:die($m);echo'Donald Trump';

```

Try it online!

---

Tests: Try it online!

The code for tests is the same logic but a little bit different to replace the `die(...)` with `return...` so I can loop over tests.

---

I have created a string having start date of presidency minus 1 day in format of `YYYYMMDD` and name of president in it, separated by `-`. Example: `17890429-George Washington-17970303-John Adams-18010303-Thomas Jefferson-...`

This string is compressed using gzdeflate and also the compressed output is converted to base-64 so all characters are printable ASCII and I can post them here or use them in TIO.

In the script, the string is split by `-` and looped over. For each loop iteration:

* `$d` is set to current iteration value (which is the president's start date -1 day) and the loop variable (`$i`) is increased by one.
* If input date is larger than `$d`, then `$m` is set to next iteration value (which is the president name for `$d`) and the loop variable (`$i`) is increased by one again. This allows the loop to get president names but jump over them in iterations.
* If input date is not larger than `$d`, then that means the previous iteration was the correct president, so `$m` is printed using `die` function, this will stop the whole program after printing the name.

At the end, if the loop is finished (which means no `die` was called), the last president's name is printed, since we know non of previous presidents have got a match (so basically anything after `January 19, 2017`) prints last president's name, even if it is `January 1, 3999`.

# Answer
> 15 votes
# Bash, 1229 1124 bytes

-103 bytes with @GammaFunction's excellent comments, removing a couple of unproductive substitutions (Adams), and refactoring the code to use the date offset from the previous date rather than the absolute date for each presidency.

```
M=(. Ja F Mar Ap May Jun Jul Au S O N D)
A=40000
B=80000
s=son
a=James
c=Andrew
d=William
e=Harri$s
f=Franklin
g=George
h=Grover#Cleveland
i=Roosevelt
j=John
k=#W.#Bush
X="304:$g#Washington
$A:$j#Adams
$B:Thomas#Jeffer$s
$B:$a#Madi$s
$B:$a#Monroe
$A:$j#Quincy#Adams
$B:$c#Jack$s
$A:Martin#Van#Buren
100:$d#Henry#$e
39900:$j#Tyler
$A:$a#K.#Polk
10405:Zachary#Taylor
29595:Millard#Fillmore
$A:$f#Pierce
$A:$a#Buchanan
40111:Abraham#Lincoln
39889:$c#$j$s
$B:Ulysses#S.#Grant
$A:Rutherford#B.#Hayes
615:$a#A.#Garfield
39385:Chester#A.#Arthur
$A:$h
$A:Benjamin#$e
$A:$h
40610:$d#McKinley
79390:Theodore#$i
$A:$d#Howard#Taft
$B:Woodrow#Wilson
20598:Warren#G.#Harding
59402:Calvin#Coolidge
$A:Herbert#Hoover
120108:$f#D.#$i
79708:Harry#S.#Truman
$B:Dwight#D.#Eisenhower
21002:$j#F.#Kennedy
58998:Lyndon#B.#$j$s
50789:Richard#Nixon
29211:Gerald#Ford
$A:Jimmy#Carter
$B:Ronald#Reagan
$A:$g#H.$k
$B:Bill#Clinton
$B:$g$k
$B:Barack#Obama"
T=($1)
D=0${T[1]%,}
for((;;)){ [[ $T =~ ${M[++i]} ]]&&break;}
N=0$i
S=$[${T[2]}-1797]${N: -2}${D: -2}
for z in $X;{ O=$[O+${z%:*}];[ $S -lt $O ]&&z=${z//#/ }&&echo ${z#*:}&&exit;}
echo Donald Trump

```

Try it online!

A lot of manual compression :)

# Answer
> 13 votes
# T-SQL, ~~1169 981 979~~ 977 bytes

Holy cow, I figured out string compression in SQL (available in SQL 2016 and above):

```
SELECT TOP 1 STUFF(value,1,8,'')
FROM d,STRING_SPLIT(
    CAST(DECOMPRESS(CAST('H4sIAAAAAAAEAHVT23LaMBD9FX1AxiMZg+1HIAWGhDaltMz0bYMXrEaWOmsc6r/vrpw27kOHB8ZnL+fs2VWqTa6NKe+DB1epA3XNz7tU61LABRCcXtSnZ2hAQCPgGgNdUB0Tteja+s6U5STmWufU0ll/DZ7BohzlbpJRehG77Ae+PcIFJD+PKra2aXq1BLoiCZjpQhdrJEldBaoYm8XGe3uqgSr10f6KdLOJMal57H0VvFokahtq3w6RSCffapWoB/Qeq57xaVR9f7OX+qruE/XBtujrcIvE2VRnxmyAqFdfkuhKVDmZaP6tCPwLTypl+xBafEV35WhaSnSD9Ix0VZsQXmOzdMJTmCW4Vy5ZhuBsdUHBjaQfmQS9WieK6SrrLxwxkeYYQkXhpo7WDaPo2J8/nYWG+9/EgQOchZt3w2WHGkMVCMeyijIfl+1OD9Y77CUQadYkOnl1kg+ePS6KSLRA/wMa1iw+2CihKKb/KxH+Ylljy6tT80TN6Vp3NES4ZAsNtoKvgc4WndTkUdi+u9ZIZ96uLG4DPbYcm0UJX13ftlzHO1iz6TLNTFaTzX1FeHtfczGLLPNngpqHfLT+FJzg0/ydfdHx0XiI8L+LfLJIJxRc61wXO/ZKvF3xf8N2ciCLer6DnF3PpvcuyHDZ9L39Q6KegnsR1OiMUbm5Q++QBmi8O/TcZeTrJMrc8eGzmm/AN9zxVXBguKk/4/JrHPLTgVcYPnc8bK/mFTRinBkNvAuegqgfLucNhOqNVEdNhzo00Kotns9IMZAPFxO7v7XN+SSy9O/bh7bmS+WX/hut0W9jPwQAAA=='as XML).value('.','varbinary(max)'))AS varchar(max)),',')
WHERE LEFT(value,8)<i

```

Doesn't save *quite* as much as I hoped it might, probably due to the amount of code it takes to convert/deconvert.

Here is the original version, which is equivalent to the code that runs after the encoded string is decompressed (1169 bytes):

```
SELECT TOP 1 SUBSTRING(value,9,99)
FROM d,STRING_SPLIT(
    '20170119Donald Trump,20090119Barack Obama,20010119George W. Bush,19930119Bill Clinton,19890119George H. W. Bush,19810119Ronald Reagan,19770119Jimmy Carter,19740808Gerald Ford,19690119Richard Nixon,19631121Lyndon B. Johnson,19610119John F. Kennedy,19530119Dwight D. Eisenhower,19450411Harry S. Truman,19330303Franklin D. Roosevelt,19290303Herbert Hoover,19230801Calvin Coolidge,19210303Warren G. Harding,19130303Woodrow Wilson,19090303William Howard Taft,19010913Theodore Roosevelt,18970303William McKinley,18930303Grover Cleveland,18890303Benjamin Harrison,18850303Grover Cleveland,18810918Chester A. Arthur,18810303James A. Garfield,18770303Rutherford B. Hayes,18690303Ulysses S. Grant,18650414Andrew Johnson,18610303Abraham Lincoln,18570303James Buchanan,18530303Franklin Pierce,18500708Millard Fillmore,18490303Zachary Taylor,18450303James K. Polk,18410403John Tyler,18410303William Henry Harrison,18370303Martin Van Buren,18290303Andrew Jackson,18250303John Quincy Adams,18170303James Monroe,18090303James Madison,18010303Thomas Jefferson,17970303John Adams,17890429George Washington',',')
WHERE LEFT(value,8)<i

```

Line breaks are for readability only.

Input is taken from pre-existing table \\$d\\$ with `INT` field \\$i\\$, per our IO rules. Input date is formatted as an 8-digit number `YYYYMMDD`.

A few tricks I used to save bytes:

* I sorted the presidents *descending* so I didn't have to add an `ORDER BY` to the code
* I subtracted 1 in the "start" date of each term, so I could use `<` instead of `<=`
* String-split is *much* shorter than a big list of `VALUES()` would be, even though I have to then break the string apart with `SUBSTRING` and `LEFT`.
* **EDIT**: Saved 2 bytes by changing `SUBSTRING()` to `STUFF()`

# Using Base64-encoded compressed strings in SQL

(Added to SQL Tips thread)

So Microsoft added a `COMPRESS` and a `DECOMPRESS` function back in SQL 2016, which handles the GZIP; the problem is that it returns a `VARBINARY`, which although shorter in *bytes* (when stored in a SQL `VARBINARY` field), is *longer* when displayed in characters (raw hex), which makes it unsuitable for golfing.

Converting to Base64 is clearly the answer, but finding a short, simple implementation was a challenge. I based my version off of this old answer on SO, which gives us most of what we need, although it doesn't use the new GZIP functions. I just had to insert the new functions into the right place, and golf it down a bit.

To use this method in your own code:

```
--Run this to generate your compressed string:
DECLARE @s VARCHAR(MAX)='Your really long string goes right here'
SELECT CONVERT(VARCHAR(MAX),(SELECT CONVERT(VARBINARY(MAX),COMPRESS(@s))FOR XML PATH(''),BINARY BASE64))

--Use your compressed string and the following code to get back to the original:
DECLARE @e VARCHAR(MAX)='H4sIAAAAAAAEAIvMLy1SKEpNzMmpVMjJz0tXKC4pygRS6fmpxQpFmekZJQoZqUWpAGGwW5YnAAAA'
SELECT CAST(DECOMPRESS(CAST(@e as XML).value('.','varbinary(max)'))AS varchar(max))

```

That's ~~75~~ 73 extra bytes of code to decompress an encoded string, so clearly only use this for very long strings.

**EDIT**: Saved 2 bytes in the decompress code with `CAST` instead of `CONVERT`.

# Answer
> 12 votes
# Excel, ~~1243~~ ~~1206~~ 1180 bytes

*-37 bytes by subtracting from all the dates*
*-26 bytes by by fiddling with the subtraction values*

```
=CHOOSE(MATCH(A1-65^4,{39805,119679,159679,239679,319679,399679,439679,519679,559679,559779,599679,639679,650084,679679,719679,759679,799790,839679,919679,959679,960294,999679,1039679,1079679,1119679,1160289,1239679,1279679,1359679,1380177,1439679,1479679,1599787,1679495,1759495,1780497,1839495,1890184,1919495,1959495,2039495,2079495,2159495,2239495,2319495}),"George Washington","John Adams","Thomas Jefferson","James Madison","James Monroe","John Quincy Adams","Andrew Jackson","Martin Van Buren","William Henry Harrison","John Tyler","James K. Polk","Zachary Taylor","Millard Fillmore","Franklin Pierce","James Buchanan","Abraham Lincoln","Andrew Johnson","Ulysses S. Grant","Rutherford B. Hayes","James A. Garfield","Chester A. Arthur","Grover Cleveland","Benjamin Harrison","Grover Cleveland","William McKinley","Theodore Roosevelt","William Howard Taft","Woodrow Wilson","Warren G. Harding","Calvin Coolidge","Herbert Hoover","Franklin D. Roosevelt","Harry S. Truman","Dwight D. Eisenhower","John F. Kennedy","Lyndon B. Johnson","Richard Nixon","Gerald Ford","Jimmy Carter","Ronald Reagan","George H. W. Bush","Bill Clinton","George W. Bush","Barack Obama","Donald Trump")

```

Input is in cell `A1` with the format `YYYYMMDD` since Excel doesn't like dates before 1900.

I don't know of a compression method for the dates or names that wouldn't add more bytes. The "subtract \[value\] from all the dates" method could apply to anybody's solution.

---

I found a 1102 bytes solution in Google Sheets using the same principle. Excel doesn't have the `Split` function so it's not translatable.

```
=Index(Split("George Washington,John Adams,Thomas Jefferson,James Madison,James Monroe,John Quincy Adams,Andrew Jackson,Martin Van Buren,William Henry Harrison,John Tyler,James K. Polk,Zachary Taylor,Millard Fillmore,Franklin Pierce,James Buchanan,Abraham Lincoln,Andrew Johnson,Ulysses S. Grant,Rutherford B. Hayes,James A. Garfield,Chester A. Arthur,Grover Cleveland,Benjamin Harrison,Grover Cleveland,William McKinley,Theodore Roosevelt,William Howard Taft,Woodrow Wilson,Warren G. Harding,Calvin Coolidge,Herbert Hoover,Franklin D. Roosevelt,Harry S. Truman,Dwight D. Eisenhower,John F. Kennedy,Lyndon B. Johnson,Richard Nixon,Gerald Ford,Jimmy Carter,Ronald Reagan,George H. W. Bush,Bill Clinton,George W. Bush,Barack Obama,Donald Trump",","),Match(A4-65^4,{39805,119679,159679,239679,319679,399679,439679,519679,559679,559779,599679,639679,650084,679679,719679,759679,799790,839679,919679,959679,960294,999679,1039679,1079679,1119679,1160289,1239679,1279679,1359679,1380177,1439679,1479679,1599787,1679495,1759495,1780497,1839495,1890184,1919495,1959495,2039495,2079495,2159495,2239495,2319495}))

```

# Answer
> 9 votes
# 05AB1E, ~~587~~ ~~584~~ 568 bytes

```
.•6}©ß þz∊‘Îнúj7a>º ·,$_+šüÑßu?PδIëàá©ā.ǝ/¬j«Ížr‹þVwô¨"¶&ˆ₃ǝαh^¼ì∞öîNÊÌ.ÚáýиÇ÷©Mèé…—¾…тŒ¹/ÈÂÓŒš/«ª³PÉÇJúΓÁ¦';X·₅ï»/„q<ƶÚÙÊtÔιuš2βƒ¼ï\~ö…3ihD·¢ðΘmζ8É9Ïγ=^$¨Ä₆ËÂÊPv5+}þ¯ÑX4hÖdÀÒuàнº₁›ǝΘ³P@¥ùnðT“É)ó_“:Èx³«äƒæ¤∞Wgþ¶š}ô|ićcÁ‘.·ƒp>Z¬Aéγê‰ù‰¥Ó₃#/›pÐT¹Â¹J3—ΛΓkÙ»(áÌ›₃z@ìqW›Â"™raÒ›₂%ïx{
_Ωb≠¹₁Ä¾ÊÌ›}çºô|ôëKÝǝÚï,‚£=A©áāY∊~"KøVóΓyΛJÚΘ·ˆUΩ₂TнîëнÐQнĆ!!¶%Ý₃ó¸ß0ûиî€AvÙ∍Õ
'«₂θSè‡H¿ÏLôǝāqaмÑIƶ%ŸSdUbåÐÉιδJ¯4₆>θçàƶñwC¨OVÀàczdRæs?5ʒP8“ƒÍÜðαŸÝf,ƒη,™`ÿeиäƵθC≠ýzX‡)и∞úø+þćÎÌвĆæŒ±ðí1•™„qz„K.‡„  ¡•gpöz&»XZ1rć¾{¦¯Û¿p~Θø•Ƶaв₄R«•e½òœu#ÈĆÔFƵ•Ƶ`вŽcƵ«•9…åœòFýLÂ]FÜÔĀ=Ƶ®5¿ùK»Ωм••Rwg•в««•1L₄Æ•+I‹Oè

```

Input is a concatenated date in the format `yyyyMMdd` (i.e. `20190821` for August 21, 2019).

-16 bytes thanks to *@Grimy*.

Try it online or verify a few more test cases.

**Explanation:**

We start by creating a list of the presidents in chronological order:

```
.•6}©...ðí1•            # Push compressed string "george washington  john adams  thomas jefferson  james madison  james monroe  john quincy adams  andrew jackson  martin van buren  william henry harrison  john tyler  james kz polk  zachary taylor  millard fillmore  franklin pierce  james buchanan  abraham lincoln  andrew johnson  ulysses sz grant  rutherford bz hayes  james az garfield  chester az arthur  grover cleveland  benjamin harrison  grover cleveland  william mcqinley  theodore roosevelt  william howard taft  woodrow wilson  warren gz harding  calvin coolidge  herbert hoover  franklin dz roosevelt  harry sz truman  dwight dz eisenhower  john fz kennedy  lyndon bz johnson  richard nixon  gerald ford  jimmy carter  ronald reagan  george hz wz bush  bill clinton  george wz bush  barack obama  donald trump"
™                       # Titlecase each word in the string
„qz„K.‡                 # Replace all lowercase "q" with "K" (for McKinley),
                        # and all lowercase "z" with "."
                        # (only lowercase letters and spaces can be compressed as string)
„  ¡                    # Split the string on "  " (two spaces)

```

Then we create a list of all dates as integers in the format `yyyyMMdd` (order is irrelevant for this list):

```
•gpöz&»XZ1rć¾{¦¯Û¿p~Θø• # Push compressed integer 57036763189461803778321913240836786322696217070172
  Ƶa                    # Push compressed integer 137
    в                   # Convert the large integer to base-137 as list:
                        #  [4,12,20,28,32,40,44,48,52,56,60,64,72,80,84,88,92,96,100,112,116,124,132,136]
     ₄R                 # Push 1000, and reverse it to "0001"
       «                # And concat it to each item:
                        #  [40001,120001,200001,280001,320001,400001,440001,480001,520001,560001,600001,640001,720001,800001,840001,880001,920001,960001,1000001,1120001,1160001,1240001,1320001,1360001]
                        # (this is for all the March 4th dates)
•e½òœu#ÈĆÔFƵ•           # Push compressed integer 47362342587646909879438102
  Ƶ`                    # Push compressed integer 223
    в                   # Convert the large integer to base-223 as list:
                        #  [155,163,171,179,183,191,195,203,211,219,222]
     ŽcƵ                # Push compressed integer 9817
        «               # And concat it to each item:
                        #  [1559817,1639817,1719817,1799817,1839817,1919817,1959817,2039817,2119817,2199817,2229817]
                        # (this is for all the January 20th dates)
•1åŽ¨£ÆÊÂç-i∞YúΛÈ¾EW½Ω≠tW•
                        # Push compressed integer 42494608868313599134973321717434089414197466371857150907
  •Rwg•                 # Push compressed integer 1770507
       в                # Convert the large integer to base-1770507 as list:
                        #  [440101,530406,680112,840616,1040611,1260499,1480109,1660819,1770506]
                        # (these are the remaining dates; i.e. those who died earlier)
««                      # Merge the three lists together:
                        #  [40001,120001,200001,280001,320001,400001,440001,480001,520001,560001,600001,640001,720001,800001,840001,880001,920001,960001,1000001,1120001,1160001,1240001,1320001,1360001,1559817,1639817,1719817,1799817,1839817,1919817,1959817,2039817,2119817,2199817,2229817,440101,530406,680112,840616,1040611,1260499,1480109,1660819,1770506]
  •1L₄Æ•                # Push compressed integer 17970302
        +               # Add it to each item in the list:
                        #  [18010303,18090303,18170303,18250303,18290303,18370303,18410303,18450303,18490303,18530303,18570303,18610303,18690303,18770303,18810303,18850303,18890303,18930303,18970303,19090303,19130303,19210303,19290303,19330303,19530119,19610119,19690119,19770119,19810119,19890119,19930119,20010119,20090119,20170119,20200119,18410403,18500708,18650414,18810918,19010913,19230801,19450411,19631121,19740808]

```

Then we use the input to determine the output president-name based on the dates in the list:

```
I‹                      # Check for each value in the integer-list if the Input is smaller
                        # (1 if truthy; 0 if falsey)
  O                     # Sum these to get the amount of truthy values
   è                    # And use that to (0-based) index into the president-names list
                        # (after which the result is output implicitly)

```

See this 05AB1E tip of mine (sections *How to compress strings not part of the dictionary?*, *How to compress large integers?*, and *How to compress integer lists?*) to understand how all the compressed string, integers, and lists work.

# Answer
> 7 votes
# Jelly,  ~~431 428 427~~  426 bytes

```
“¡Ẹị’ḃ4ż“ƓĠƒƝƊ!ɓa(‘ḅ⁹
“FQIȥ’ḃ8Ėẋ/€<8ż¢F1,303yo119
“f×Ð<Mk7LqƇ%_¡¤cċ⁴ẏ’Do13’⁽¤.;Äż¢ḅȷ4<VSị“¡ṀÑṅyȮÇæjRṂ~ɠƥ⁺'Ḃġ"Ƈ~Ị'9ƒȮṃ$ḶPȯṅṡḊl¥JƊ€ẊḥSṣọwɦṡ5ėṂU #Fɲẓ÷iḄþ%~%ñçŒfƒƙɼ=ɓ⁼¡⁻Q`⁵¡ḍ36)żȥÑR\ḋ⁾ḶƤ0ÞṘḳ÷¦IṂ\}ƊĊÐḳŻƈɦ!zɠ⁺ƈṖṭW⁸ƥṛU|ḄØ^ẓfḂḣƈCȦ8ɱḤH⁵AKṢzȯỵƭḊ:TʠƬ/~ƝÑȥgṖ(ṁȯDƲṫỴftlBOȧ6Ụiṃıẉ_ƈvh5ṄUɓạẓDẠẸıṣƥ"bçȥ¿çOġQẹİẊẸs*⁶ż,Ḍg®ƲW×ɗ,ẏ¡Ḅ5M5)ṀạƈCṛʂẎŒƬwġ⁶NẠṆRƇsẊ<fŀȯ⁵øȤ\⁾.>ḋTṖĠUṇŻṬTṖræ_TçṡȤOʠƥðȦe]ƈ⁵cṆWƭƲ>`½n¿O¡ṭOþV¤ṡẊ²rdS€ė)ƘIÆ&ṙḞ¬5[pṁȥLṘVỴɠ»ḲṚƑ”.ẋṭƲ€KỴ¤

```

A full program accepting a string `YYYYMMDD` which prints the president's name.

**Try it online!** Or see (Kevin Cruijssen's) test-suite.

### How?

```
“¡Ẹị’ḃ4ż“...‘ḅ⁹ - Link 1, getNonStandardEndMonthDays: no arguments
“¡Ẹị’           - base 250 literal       = 106467
     ḃ4         - to bijective base 4    = [1,2,1,3,3,3,1,4,3]
        “...‘   - code-page indices      = [147,196,158,150,145,33,155,97,40]
       ż        - zip together           = [[1,147],[2,196],...,[3,40]]
              ⁹ - built-in literal       = 256
             ḅ  - from base (vectorises) = [403,708,414,918,913,801,411,1121,808]

“FQIȥ’ḃ8Ėẋ/€<8ż¢F1,303yo119 - Link 2, getEndMonthDays: no arguments
“FQIȥ’                      - base 250 literal    = 1114518671
      ḃ8                    - to bijective base 8 = [8,2,3,3,4,3,2,2,1,7]
        Ė                   - enumerate           = [[1,8],[2,2],[3,3],[4,3],[5,4],[6,3],[7,2],[8,2],[9,1],[10,7]]
           €                - for each:
          /                 -   reduce with:
         ẋ                  -     repeat          = [[1,1,1,1,1,1,1,1],[2,2],[3,3,3],[4,4,4],[5,5,5,5],[6,6,6],[7,7],[8,8],9,[10,10,10,10,10,10,10]]
            <8              - less than 8?        = [[1,1,1,1,1,1,1,1],[1,1],[1,1,1],[1,1,1],[1,1,1,1],[1,1,1],[1,1],[0,0],0,[0,0,0,0,0,0,0]]
               ¢            - call last Link (1)  = [403,708,414,918,913,801,411,1121,808]
              ż             - zip together        = [[[1,1,1,1,1,1,1,1],403],[[1,1],708],[[1,1,1],414],[[1,1,1],918],[[1,1,1,1],913],[[1,1,1],801],[[1,1],411],[[0,0],1121],[0,808],[0,0,0,0,0,0,0]]
                F           - flatten             = [1,1,1,1,1,1,1,1,403,1,1,708,1,1,1,414,1,1,1,918,1,1,1,1,913,1,1,1,801,1,1,411,0,0,1121,0,808,0,0,0,0,0,0,0]
                 1,303      - pair literal        = [1,303]
                      y     - translate           = [303,303,303,303,303,303,303,303,403,303,303,708,303,303,303,414,303,303,303,918,303,303,303,303,913,303,303,303,801,303,303,411,0,0,1121,0,808,0,0,0,0,0,0,0]
                        119 - literal             = 119
                     o      - logical OR          = [303,303,303,303,303,303,303,303,403,303,303,708,303,303,303,414,303,303,303,918,303,303,303,303,913,303,303,303,801,303,303,411,119,119,1121,119,808,119,119,119,119,119,119,119]

“...’Do13’⁽¤.;Äż¢ḅȷ4<VSị“...»ḲṚƑ”.ẋṭƲ€KỴ¤ - Main Link: list of characters, X
“...’                                     - base 250 literal    = 5999595155245555951555559593750993764595999
     D                                    - to base 10          = [5,9,9,9,5,9,5,1,5,5,2,4,5,5,5,5,9,5,1,5,5,5,5,5,9,5,9,3,7,5,0,9,9,3,7,6,4,5,9,5,9,9,9]
       13                                 - literal             = 13
      o                                   - logical OR          = [5,9,9,9,5,9,5,1,5,5,2,4,5,5,5,5,9,5,1,5,5,5,5,5,9,5,9,3,7,5,13,9,9,3,7,6,4,5,9,5,9,9,9]
         ’                                - decrement           = [4,8,8,8,4,8,4,0,4,4,1,3,4,4,4,4,8,4,0,4,4,4,4,4,8,4,8,2,6,4,12,8,8,2,6,5,3,4,8,4,8,8,8]
          ⁽¤.                             - literal             = 1797
             ;                            - concatenate         = [1797,4,8,8,8,4,8,4,0,4,4,1,3,4,4,4,4,8,4,0,4,4,4,4,4,8,4,8,2,6,4,12,8,8,2,6,5,3,4,8,4,8,8,8]
              Ä                           - cumulative sums     = [1797,1801,1809,1817,1825,1829,1837,1841,1841,1845,1849,1850,1853,1857,1861,1865,1869,1877,1881,1881,1885,1889,1893,1897,1901,1909,1913,1921,1923,1929,1933,1945,1953,1961,1963,1969,1974,1977,1981,1989,1993,2001,2009,2017]
                ¢                         - call last Link (2)  = [303,303,303,303,303,303,303,303,403,303,303,708,303,303,303,414,303,303,303,918,303,303,303,303,913,303,303,303,801,303,303,411,119,119,1121,119,808,119,119,119,119,119,119,119]
               ż                          - zip together        = [[1797,303],[1801,303],[1809,303],[1817,303],[1825,303],[1829,303],[1837,303],[1841,303],[1841,403],[1845,303],[1849,303],[1850,708],[1853,303],[1857,303],[1861,303],[1865,414],[1869,303],[1877,303],[1881,303],[1881,918],[1885,303],[1889,303],[1893,303],[1897,303],[1901,913],[1909,303],[1913,303],[1921,303],[1923,801],[1929,303],[1933,303],[1945,411],[1953,119],[1961,119],[1963,1121],[1969,119],[1974,808],[1977,119],[1981,119],[1989,119],[1993,119],[2001,119],[2009,119],[2017,119]]
                  ȷ4                      - literal 10^4        = 10000
                 ḅ                        - from base           = [17970303,18010303,18090303,18170303,18250303,18290303,18370303,18410303,18410403,18450303,18490303,18500708,18530303,18570303,18610303,18650414,18690303,18770303,18810303,18810918,18850303,18890303,18930303,18970303,19010913,19090303,19130303,19210303,19230801,19290303,19330303,19450411,19530119,19610119,19631121,19690119,19740808,19770119,19810119,19890119,19930119,20010119,20090119,20170119]
                     V                    - evaluate (X)        (i.e. X -> YYYYMMDD)
                    <                     - less than? (vectorises)
                      S                   - sum                 (a number between 0 and 44 inclusive)
                                        ¤ - nilad followed by link(s) as a nilad:
                        “...»             -   compression of dictionary words and strings
                             Ḳ            -   split at spaces
                                     €    -   for each (part):
                                    Ʋ     -     last four links as a monad:
                               Ƒ          -        invariant under?:
                              Ṛ           -          reverse (true for initials only)
                                ”.        -        literal = '.'
                                  ẋ       -        repeat
                                   ṭ      -        tack (the part - e.g. [['A'],'.'])
                                      K   -   join (back up) with spaces
                                       Ỵ  -   split at newline characters
                       ị                  - index into (that list) (1-indexed & modular)
                                          - implicit (smashing) print

```

# Answer
> 5 votes
# JavaScript (Node.js),  ~~855 851~~  803 bytes

```
d=>(g=i=>(p+=parseInt((a=(require('zlib').inflateRawSync(Buffer("ZVJtct0gDLwKB1A9dSaTtGfoKWSQDc+AXgS2S09f8T6cdPqDsc2utKuVv411jTC6FV4EzzO6eD53GG26vc0Wtp+3t9uhjkwn7+0dxnf6hPu5JHiJP8524mHcr7fPV3yDF+Z79XcL48em2ASy/yP+1dRCLAuZA4sPeamc4cI+G3SYClTPCYu50DyTlI5homISuvDli7Mw3cs+tpBte1RjdkKHuaBdOzuh1JDNjtlMm1CGI8QYMBlPWZrxKHLv2hvVFkkeAutgrhxX+INWSc1UbJEFkpajODPrM7EQzIJ5jSpxDSSWHtXTplUZM+Ak6FVOGZZjPu2pXJfdYitF+WUwizaqIFv1JDOrxDSovUbl0RKVgjIHig6sp1JJ+p3O5zeBRXjXCxtpp6giMFHWOvV1jvgf5RlFsr9CjtQ0eWKnQxlhLp1VP+Pio49dcdY7Zid8GMV6XwU0WLN0u+J0n2Ax7qpsmWNwC4FONJFUbdIdfEbmhi9K3WfrQVTZkibnjrD42jkUCmU10HfT1zQPZqWcyTWILTvOPapnohL6vpzJ4XefmQSjbkvzhEtIqRmrgWkj4dwBIVwwP/9HP5hj0N0VD5POrVGFXPmETwxF/y7DEyYEd2/UTV//Ag","base64"))+"").split`,`)[i],32))<new Date(d)/864e5?g(i+1):a[i+44].replace(/\b./g,c=>c.toUpperCase()))(p=0)

```

Try it online!

### How?

The compressed string contains a list of 89 values.

The first 44 values are the length of the president mandates expressed in number of days and encoded in base 32 (which is the base that compresses best).

The next 45 values are the president names in lower case. Title-case is applied afterwards (trick borrowed from @KevinCruijssen's answer).

# Answer
> 5 votes
# Jelly, 454 bytes

```
“¡#<Ḷ“¡D{“ß“®“c“ƒⱮ“¡“(Ȥ“u^“£“ɠn“ƒ⁺“¥“¢r“ƈ⁶“©“ƙm“¡B⁻“¤“Pẋ“ḣ¢“¡“¡ẓk“¡CẆ“¢“S¢“ėẋ“ṄỴ“t<“Œ“¦’ḃ2$¹<?€ȷ2F4ȷ4,8ȷ4ĖF¤yÄ<⁸TṪị“€`ɲ×ƥF7ȯẒ⁼ẈẎu⁻ɠṇẠẈƊ⁻QḲỌ ỊƭʠµḢƊCṾr⁻=ßạḌ`^ḌX§®tṭN£jx,ƈ=suĖɼ_ḍf9*ÆṙỊṪṄ Jʋ ȯṡẉ ỌẏⱮøÞ⁴xḤżḅñ£ṡṭʂMṚ¶ṇwıƲṁEnÄ`:®ƥʂ_xd⁶ŒĖṁƙƝg°ṂʠkṫhO5Ịḅḳ³'ø⁵aẏṄKḂẆZØ4JḌþḂ⁸⁸XlIVḤOḲØṢÐ!}?Ọ°ḲẆiḢAr`ġƘ⁸ḷ[¿T§ẓ⁵|ḍdɓ^ṭƲfỴĖġJw(Ȯ:⁺k=£ŀnṗ*'hẹḋŻZOLæØ²ẋ⁼ẏ&ı6ḣṗẈƥ¡:9D¢=G§⁴eỤ6wẈ6ṗw6⁺zOẉ}OṆƲdṃ'ıẠ£¤þ4¢1ȷfɓ.ṪpṀ⁴Ṡtṁ⁷ẇlŒ!ṠyaṪ66xvḍgġ¤goḍRẒ³żẎịṣ6ĿⱮ}ḲkƒiL²?Ḃ¿ḥƝ¤dėḤ½Ṗ,cRÐþɼ©ṢƈḅṬḊṬɠṅÞ»Ỵ¤

```

Try it online!

A monadic link taking as its argument the date in YYYYMMDD format and returning a string with the answer.

Test cases (borrowed from @KevinCruijssen’s 05AB1E answer).

# Answer
> 5 votes
# 05AB1E, ~~464~~ ~~444~~ ~~442~~ 418 bytes

*-15 or so bytes by stealing ideas from Kevin Cruijssen's answer*

*Crossed 444 is still 444 ):*

```
.•J@λ
A∞‚XÃUδ„«›Æx…ΔΣ¸ÃEÛö›³;Î!¦ǝzŽ`²œ∊ïøÞ‰Cf4₆и)Kuм¹5®‹м£Ž}мNPõüïí
^ā-Ç¨åˆ[Ü_5δ³ÂBмzIΣŠÒÅÆè"²0¢₆'$Ćùù»õJ´õý¢ºн³õ?ëØØ†Dǝç.r˜èÌ•ć¡`“ŒÕ‡¹„Ð±·Ž²¿É‰Þ³×‰ÞÌ¯„Ðëìncy±·¢Œžˆ–ÄîèÿíÈ£ÎÈœ„ÐÕÀ‰Þ kz™éÿ¥•¹êardœãÿ²ÀâÓ‰Þÿã³«Æ¢Œš•ÿ—§Î¶ÿæ©‰Þ–Öÿ×œ–Ö·Š¶‹r¯ŽÇÕÈœ¶‹r¯ŽíÈÿíÈ©Æ»äft–œrow¦‹¼‰ gz†èingãŸîÁÿ²Àÿ„Ð fz½¸ÿš••Öÿéï™»»É»‰ÖŠÿŒÕÕ¹ wzŒ›‰ŽµÍŒÕ wzŒ›‹²ÿ¹Ñÿ“™„qz„K.‡#•¥ü„¨%¨₃Ó8•3в4α£ðý•9ÕS&µç©•3в±žD*•¾¹iìzÓ.+,âšÜĀ‘ó₆x.»δ•žHв«9._.¥•U<¶•+I32β‹Oè

```

Try it online!

### Part 1: the names

There are two types of string compression in 05AB1E:

* Base-27 strings encode each letter in ~0.6 bytes (technically: log(27) / log(255)), but they can only contain `[a-z ]` (lowercase letters and spaces).
* Dictionary strings encode common English words (plus the preceding space) in 2 bytes, and all ASCII characters in 1 byte each (they're just passed through unmodified). They can also use the byte `ÿ`, to pop a value from the stack and embed it in the string.

We're going to use an optimal mix of both. Since switching from one encoding to the other incurs some overhead, this is more complex than picking the shortest encoding for each individual name. For example:

* The `ing` in `Harding Calvin` takes ~1.8 bytes in base-27 vs 3 bytes in a dictionary string. But `Hard` and `Calvin` are both in the dictionary, so we end up leaving `ing` uncompressed inside a dictionary string.
* The `Herb` in `Coolidge Herbert Hoover` takes ~3 bytes in base-27 vs only 2 in a dictionary string (since `herb` is in the dictionary). But neither `Coolidge` nor `Hoover` are in the dictionary, so we end up encoding `Herb` as base-27.

To get around the restriction that base-27 strings can only contain `[a-z ]`, we assign special meanings to some letters. Between them, the 44 presidents use up all 26 letters, but we can still play tricks:

* The only `j`s are in dictionary words (`James`, `Benjamin`, ...), so `j` is free for base-27 strings.
* The only `q` is in `Quincy`, so lowercase `q` is free
* The only `z` is in `Zachary`, so lowercase `z` is free
* The only `x` is in `Nixon`, so uppercase `X` is free (we don't actually make use of that)

With that said, let's look at the code.

```
.•J@λ
A∞‚XÃUδ„«›Æx…ΔΣ¸ÃEÛö›³;Î!¦ǝzŽ`²œ∊ïøÞ‰Cf4₆и)Kuм¹5®‹м£Ž}мNPõüïí
^ā-Ç¨åˆ[Ü_5δ³ÂBмzIΣŠÒÅÆè"²0¢₆'$Ćùù»õJ´õý¢ºн³õ?ëØØ†Dǝç.r˜èÌ•

# (The newlines are significant.) This is the base-27 string:
# "j trumpjack obamaj reaganj nixonj lyndon bzj dz roosevelt harry sz truman dwight dz eisenhowerjidge herbert hooverj mcqinley theodore rooseveltj garfieldjerford bzj ulysses szj buchananjmorejlk zacharyj buren"

ć    # extract the first character
 ¡   # split the rest on that character (a "j")
  `  # dump the list on the stack
# We now have " buren" at the top of the stack, and " trump" at the bottom.

“ŒÕ‡¹„Ð±·Ž²¿É‰Þ³×‰ÞÌ¯„Ðëìncy±·¢Œžˆ–ÄîèÿíÈ£ÎÈœ„ÐÕÀ‰Þ kz™éÿ¥•¹êardœãÿ²ÀâÓ‰Þÿã³«Æ¢Œš•ÿ—§Î¶ÿæ©‰Þ–Öÿ×œ–Ö·Š¶‹r¯ŽÇÕÈœ¶‹r¯ŽíÈÿíÈ©Æ»äft–œrow¦‹¼‰ gz†èingãŸîÁÿ²Àÿ„Ð fz½¸ÿš••Öÿéï™»»É»‰ÖŠÿŒÕÕ¹ wzŒ›‰ŽµÍŒÕ wzŒ›‹²ÿ¹Ñÿ“
# Dictionary string. All the values we just dumped on the stack are popped by `ÿ`s in this string. We end up with:
# "george washington john adams thomas jefferson james madison james monroe john quincy adams andrew jackson martin van buren william henry harrison john tyler james kz polk zachary taylor millard fillmore franklin pierce james buchanan abraham lincoln andrew johnson ulysses sz grant rutherford bz hayes james az garfield chester az arthur grover cleveland benjamin harrison grover cleveland william mcqinley theodore roosevelt william howard taft woodrow wilson warren gz harding calvin coolidge herbert hoover franklin dz roosevelt harry sz truman dwight dz eisenhower john fz kennedy lyndon bz johnson richard nixon gerald ford jimmy carter ronald reagan george hz wz bush bill clinton george wz bush barack obama donald trump"

™         # title case
 „qz      # literal "qz"
    „K.   # literal "K."
       ‡  # transliterate (replaces all "q" with "K" and all "z" with "."

# This takes care of two issues at once: title casing would leave McKinley with a lowercase k, and base-27 strings can't contain "."
# We now have a long string, with all the presidents' names in order. We need to split it into 45 strings (one per president).
# We could've used a special marker to delimit the presidents, but it turns out it's more efficient to count the words in each name:

#                  # split on spaces (yes i know i've been using # for comments, but there's no actual comment character in 05AB1E)
 •¥ü„¨%¨₃Ó8•3в     # compressed list 222221211212222221111222221212211111222202122
              4α   # vectorized absolute difference with 4: 222223233232222223333222223232233333222242322
                   # this is the list of the number of words in the presidents' names
                   # (note that "George H. W. Bush" is the only 4-word name, forcing us to use base-3 instead of base-2 for the compressed list, which costs 3 bytes)

£                  # split the list of words according to the list of wordcounts: [["George", "Washington"], ..., ["Donald", "Trump"]]
 ðý                # join each sub-list with spaces

```

We now have a list of the 45 full names in chronological order, so we're done with this part.

### Part 2: the dates

To make it easier to compare dates, we convert them to integers. This is done with a conversion from base-32, which gives 1024 * year + 32 * month + day (and doesn't care that the year "digit" is greater than 32).

We start with a list of the number of consecutive reelections (elections that don't change the president), in reverse chronological order:

```
•9ÕS&µç©•3в   # compressed list 111010111011020000011000000101110

```

Those first three 1s correspond to Obama, Bush and Clinton all being reelected once. The lone 2 corresponds to McKinley and Theodore Roosevelt both being reelected once (McKinley died in office and Theodore Roosevelt was his vice-president, so there was no other election inbetween their reelections). There should be a 4 in there for Franklin D. Roosevelt + Truman, but this is also the point where inauguration day changed from March 4 to January 20, so we handle this special case later.

```
±             # bitwise not (equivalently: add 1, then negate): [-2, -2, ..., -1]
 žD*          # multiply by 4096 [-8192, -8192, ..., -4096]

```

Remember that 1024 means a year, so 4096 means a full mandate. This is now a list of time deltas between newly elected presidents (still in reverse chronological order, which is why the numbers need to be negative).

Now, lets take care of the 9 presidents who didn't serve full mandates (4 died of natural causes, 4 assassinated, Nixon resigned):

```
•¾¹iìzÓ.+,âšÜĀ‘ó₆x.»δ•žHв   # compressed list [45088, 9317, 15270, 16548, 20475, 22484, 22410, 18666, 11155, 43819]

```

45088 is the time delta from March 4, 1797 (first introduction on a March 4) to April 4, 1841 (first death in office). The following numbers are time deltas between the 9 deaths/resignations. Finally, 43819 is the time delta from August 9, 1974 (Nixon's resignation) to January 20, 2017 (latest introduction on a January 20).

```
«             # merge the two lists of time deltas
 9._          # rotate left by 9 (the number of January 20 introductions)
    .¥        # undelta
      •U<¶•   # compressed integer 1979491, meaning March 4, 1933 (the last March 4 introduction)
           +  # add to each

```

We now have a list of all dates where the president changed. The order is a bit funky: it starts in 1933, then follows March 4 introductions backwards in time, then deaths/resignations forwards in time, then goes back along the January 20 introductions. However, order won't actually matter.

```
I             # get the input date
 32β          # convert from base 32, yielding an integer
    ‹         # vectorized compare with our list, yielding a list of 0/1 booleans
     O        # sum
      è       # use the sum to index into the list of presidents' names
              # implicit output

```

And we're done.

# Answer
> 3 votes
# SOGL, 475 bytes

```
⁵æ“DƧ▓«ļ¶↕Q∫<⅔∑+fQyΛ‼Bī:׀═&Sf',№═׀ΔΥκ\κΗδ=6oΡΠω«i℮ī K }½6YΨδ~░pTø№ŗ◄&Λθ▒“Æš“─{1α:C'⁰%+:"⅞“*c'⁰÷+dr"⅞“*b'«*e++>?al"t!■u↔R⅝Θνj╤←⁵κP׀λc⅜-Gc⁸׀!┐)└█5¦@T¬[@∫↕‛ρ℮↑δŗιf√³I2~Δ▓η¤⁴b¡νθ@36⅛Π└Ξ±Ƨ⅜⅓mwθ:∫^⌠≥-N\T‛V;r□τθ⁹;C{¾lΠƨUΒΡ║⁸Κ≤øΔ°?U┼S→iļ┐Kπzz∑Θ⅛%τ`ωΗ2D≡ψ_;OR⁴w≡1Z⅓ēυ%─ž′ιVJοUζķπd└≈³ΘΟ‚GR2┌═NΒθ↔T²νsσ□lQMæν÷¦Π±°≡═øΡTe¼ž⁰λ_►○³1≡№╚█λΜβΤ½<Π±Cļ¬└⁴┘čgr⁰⁄▲8|}⁸ē4№╤#√⅔d?÷≥}▼eī┼^ƧX‽>≥▼k ¹Wļm║⌠¦→┘C׀ψΠ¼⁽tΠ↔:φbεļ▓Β√⁷->→⅜O∑░=`ξε↕ņ⅛╚πBπσ§T׀ķīT:‽4;%≥═pP¶G→○▼φβjτ9v⁄6Υ◄⁹¤{τ/∑a⁰}┐⁵e¬č‘ūƧkiƧKiŗƧ, Θw←

```

Try it here!

Date logic could probably be improved a bit.

# Answer
> 3 votes
# PHP, 888 bytes

```
$_=0;$l=explode('|',gzinflate(substr($a=base64_decode('AAALMQW0C2oLagtqBbULagW1AB8FlgW1AewDyQW1BbUF3wWLC2oFtQDHBO4FtQW1BbUGdgqoBbULagNxB/kFtRFGCxgLagQMB14H6wN/BbULagW1C2oLagtqZVLtjtpADHyVfYK8Ax8FBEd7pWmR+s9kTXbLxq68CXSlffjaheNO6q8o6/HMeOw1svTojpBDpH5kqlsO5GYehlzbwANkt8XzGSVbDQbMbg8+fvhjEsZ729cpUlce3TPygje3he5i6D3IGMn9AHLzSZDqMaYUYXAbJCluAyJ3ViNqS0J5COwa98rpUn9CF0CRLZTEUvfaDuLdSr8DC9aVAF2SSrxGlA4f3fNJuwiozk4CQeVe1CInetpTOZP9nkrOiv/WuLUSjfUwjQHlzCoxb9RewfygnCkE5Bwx+boImEcUe5vJGCapa+GrPiwSXjEB+TpH+gWD+nqO+B/kLYp9t4uUsGjyyF6HcgfmbKjxPS6+2dgtnPWN2QvfnNaM96gCSG5tdsXrPusC0lWVF8wp+h7rBuWEMiqJOXiPbNl8UDKfxYJoZRo0ueUt9mE0zKeYkQLfbDe2plXjdkiEvtSXQp7JonpL9BBtX959jn9sZhRIui3Ns27jMBS30INQogOTFQ4IPRjs3z1uGndsdHc51LnOrVFFGvlZftZA9LrclxMMUJd3IjP9+y8='),90)));foreach(str_split(substr($a,0,90),2)as$i=>$d)(strtotime($argn)+5701449600)/86400<($_+=hexdec(bin2hex($d)))&&@die($l[$i-1]);echo end($l);

```

**TRY DEMO**

# Answer
> 2 votes
# Charcoal, 550 bytes

```
✂⊟Φ⪪”}¶⟲φε"1Ｉt↙θ｜&s1%⎚÷Ｘ2J¦T↶M↙@Ｐ≡,7gSＣ{WＴＢ¿μ;↗ＡEoU…⁹aⅉ:(↶Þ|‹Ｃρr]χＹ↨×⪪…✳μⅉⅈ²]⌈&ρτ“↖s∕↘yⅉ⊘K%QUi&Ｕρ⦃→↑^_tＺ}↙s⪪3#\UZ¶L↥ρ÷Qa.ρE⊞B↘¿⦃{RＣ⁴βLΦï←⁹″*²⌊∕~L‽∧＆;⁵⪪⪪◨sＦψ⊗=₂εωb5⎚∧¬Ii»Ｓ⟲Ｈ⧴⮌⁵↷≕≦-Ｌκ↗⦃″✂DcgSOE}PΣ℅ξ»u➙ïＡ⁼×◧⁴Gθkιbσ6�V→↓B⮌⦃]σ0↶L↷'Þ¡σ？αδ⪫4⁶M"‽Ｗ◨-n℅O≡o ⊙^fκ{~✳N⦄y⊟≦Ｋθ!«↘pB;fJ<ιU%Ｄ‴▶p|‹⌕ιＨpＩt‽7}u1~φνL▶⮌;ＮY✂Ｓ>ÞＳλ<«⦃¬k⦄Ｊ⦃◧‴}v≕﹪φＥβ<⁴↘la»�λ⁼.Xξ.th⊕jEχ>m4J'⁺▷αＺ↷|D$⸿Sz⪪←fＦωρ↓oⅉ⊙⁰vFQ0T⪫?GＥ▷｜℅±P；χ'|x>i↨E◧⁺4Ｍ↖‴№⟦Π～‹σ_▷⁵Ｎ？6ⅉ ｜x+\⁺“≡Ｃ⟦⁹⁸pC⊕Dïψ？◧⎇ςΠＨ&]▷≧β↓⧴J<(1←¦6‽GG✂¡58Ｇo…Qψ/§§c↷ZＱ\@ςr⁹}ＴＺ?«fPO)⧴\`↘℅⦄＆yθ%⪫iλ*fÀ-ⅈ↖→◨⬤Ｆ″‖↘→⁹Ｓ#″▶Φ∨¬w◧«℅ySq§mＣＩπF?sⅈＰ⍘↷≔f‽k↥ABＭX﹪”¶‹ιθχ

```

Try it online! Link is to verbose version of code. Takes input in ISO format. Explanation:

```
    ”...”       List of decremented dates and presidents
   ⪪     ¶      Split on newlines
  Φ       ‹ιθ   Keep those that precede the input
 ⊟              Take the last
✂            χ  Remove the date

```

# Answer
> 2 votes
# Stax, ~~550~~ ~~509~~ 502 bytes

```
ª╠TkªÑTs¬¢‼É▼╠→+╕s☼∩b°┴ò0J Öª◙%µ♪)Çb○Σ²╦àôä√P┼[╫»↓♪─y·:+x/ p~┤☺kèT┤╩☺♀◄╗*DX○e╩+ë%╫↔^║;◙/Θ╛B║K>▌GΣR╥♠╞N┬6dt♥h♪T⌠╥⌠ó←`±ΘÆM:\V►╢◘≥pe½╖→Ea}╚≤╠ΓÜ╗,πUF[╢▄¥¥▒t≥òK"=☺S╟▐ü%û▼98╕→→ñ`eB▌y↨\%Ç│╝û°6R┘K√â°◘RfçMñ♪3╦┤â╞╥┼«╧j/εⁿ○ó▀CäI3┘c▄}═%[C_%jgÿÉJÑS═g(┴`╦%êk9½é╔PT¶◄<║╕à¼╬≤`dεµc╨╔?Z=╧╥RDΓl.┘uFⁿ∟Juö♥,╠╛z¡ÇM7m☺╩?ïPª$πä♂ ╝Jò'æφ▬♠w►○ôr├=é┴╪ù#?∩E↓╣J∩╒░▒○LÑ∞¥╗å▐Ü└ä∙↨l♀╠├d┴Uÿ╩(╔♦)═╦¢αe£/bΦ╜%d$Öä¢M║╖q]¢╝8╨ÖBÿ┼÷{@0╕/#└â╪~V§πp<≡k♫á∩g4üÉà↔DR[√á√ü.îºV'X♥9↔øiè²≈τoæ┴0☻ó╪!‼⌡¼'↔ δ'X⌂■OpX¬E╡░├a"√4lB<└♣A╪º╕4íbz♠ìÿ°Γ═àÅ└5äº5æ2§ΩWª

```

Run and debug it also featuring Kevin Cruijssen's tests

This program executes correctly, but if you use the "Uncompress Literals" tool, it will corrupt the source code. It ends up putting two integer literals right next to each other, which makes one bigger literal. Of course, that doesn't do the same thing as the original program.

---
Tags: code-golf, string, kolmogorov-complexity, date
---


title: Numbers Decrease while Letters Increase

text:
# Question
Title: Numbers Decrease while Letters Increase
*Randomly inspired by Numbers Increase While Letters Decrease*

Given a list of mixed letters and integers (e.g., `['a', 2, 3, 'b']`) *increase* the letters by one position in the alphabet (wrapping at `z` to `a`) and *decrease* the numbers by 1. For the above example, the output should be `['b', 1, 2, 'c']`.

* The input can be a mixed-type list, a delimited string, a list of strings, etc.
* `z` wraps to `a`, but `1` goes to `0`, and `0` goes to `-1`, etc.
* The input will only ever be `[a-z]` and integers. You can choose capital letters `[A-Z]` as input if that's easier for you.
* The input is guaranteed non-empty.
* The input may contain only numbers or only letters.

Examples:

```
Input
Output

['a', 2, 3, 'b']
['b', 1, 2, 'c']

['a', 'b', 'z']
['b', 'c', 'a']

[-1, 0, 257, 'x']
[-2, -1, 256, 'y']

[0, 3, 1, 20382876]
[-1, 2, 0, 20382875]

```

### Rules and Clarifications

* Input and output can be given by any convenient method.
* You can print the result to STDOUT or return it as a function result.
* The output doesn't have to be the same format as the input (e.g., you could take input as a string and output as a list).
* Either a full program or a function are acceptable.
* If applicable, you can assume the input/output integers fit in your language's native `int` range.
* Standard loopholes are forbidden.
* This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

# Answer
> 6 votes
# 05AB1E, 5 bytes

```
<AAÀ‡

```

Try it online!

```
<          # decrement the numbers
 A         # constant "abcdefghijklmnopqrstuvwxyz"
  AÀ       # same, but rotated left ("bcd...yza")
    ‡      # transliterate

```

# Answer
> 5 votes
# Python 3, 59 bytes

```
lambda a:[i-1if''!=i*0else chr(97+(ord(i)+8)%26)for i in a]

```

Try it online!

*-1 byte thanks to Erik the Outgolfer*

# Answer
> 5 votes
# Perl 5 (-p), 17 bytes

```
y/a-z/b-za/or$_--

```

Try it online!

Bonus 19-byter:

```
$_>$_++?$_-=2:s/a//

```

TIO. This one features some cool tricks, but fails to beat the straightforward solution above.

# Answer
> 5 votes
# Ruby, 34 bytes

For each element, attempt to return the element -1. Strings cannot do this, so they error out and are picked up by the `rescue` clause, which instead calls `succ` on it to return the next letter in the alphabet. `succ` "rolls over" on `z` and returns `aa` though, so we simply take the first character in the returned string.

```
->a{a.map{|e|e-1rescue e.succ[0]}}

```

Try it online!

# Answer
> 3 votes
# JavaScript (Node.js), 55 bytes

```
a=>a.map(s=>1/s?s-1:B([(B(s)[0]+8)%26+97])+'',B=Buffer)

```

Try it online!

# Answer
> 3 votes
# Python 3, 182 130 118 bytes

*-51 bytes thanks to @AdmBorkBork and @Black Owl Kai, -1 byte thanks to @Black Owl Kai, -12 bytes by replacing `.append()` with `+=[]` and replacing `n+1` with `-~n`*

```
def a(x):
 b='abcdefghijklmnopqrstuvwxyz';c=[]
 for d in x:
  try:c+=[d-1]
  except:c+=[b[(-~b.find(d)%26)]]
 return c

```

Try it online!

I made this while the question was in the Sandbox but didn't see it posted until just now. :P

## Ungolfed

```
def a(x):
    b = 'abcdefghijklmnopqrstuvwxyz'
    c = []
    for d in x:
        try:
            c.append(d - 1)
        except:
            c.append(b[((b.find(d) + 1) % 26)])
    return c

```

## Explanation

For each element in the inputted list `x`, it tries to subtract 1 and add it to the eventual returned list. If an error occurs (because the element is a string), the letter's index in the alphabet is added by 1 and that mod 26 is taken. The mod 26 wraps an index of 26 back to 0.

# Answer
> 2 votes
# , 30 bytes

```
<: ::((26|>:)&.(_97+a.i.]))&.>

```

Try it online!

# Answer
> 2 votes
# Retina, ~~52~~ ~~50~~ ~~48~~ ~~58~~ ~~41~~ 37 bytes

```
T`zl`l
\b0
-
\d+
*
-_*
-$.0
_(_*)
$.1

```

-4 bytes thanks to *@FryAmTheEggman* (and for mentioning I had a bug: `1 → -1` instead of `1 → 0`).
+10 bytes to fix a bug with `1` and `0`.. Such an annoying edge case which screwed me over for quite a while.. But golfed it to 41 bytes now. (Now I'm curious about the \<40 bytes versions *@Neil* and *@CowsQuack* mentioned in the comments.. Thanks *@Neil* for the tip of converting the `0` to `-`, and dealing with the negative values first. Converting those right back from unary to integer helped a lot.)
Apparently I don't need the boundaries at this point, so -4 bytes.. \>.\>

I/O is comma-separated.

Try it online.

**Explanation:**

Transliterate all `"zabcdefghijklmnopqrstuvwxy(z)"` to `"abcdefghijklmnopqrstuvwxyz"`:

```
T`zl`l

```

Replace all standalone `0`s with a `-`:

```
\b0
-

```

Convert all numbers to unary, by replacing them with that amount of underscores:

```
\d+
*

```

For all negative values, with zero or more unary-lines behind it: keep the minus sign, and get the total length of this match (including the `-`), converted back to an integer:

```
-_*
-$.0

```

As for the positive integers: match a positive integer by matching a single unary-line, followed by zero or more unary-lines. And then replace them with the length of that capture group to remove that single unary-line and convert them back to integers simultaneously:

```
_(_*)
$.1

```

# Answer
> 2 votes
# Gema, 55 characters

```
<N>=@sub{$1;1}
z=a
<L>=@int-char{@add{@char-int{$1};1}}

```

Dirty solution. Wrapping around on letter increment is painfully long, so got a separate rule.

Input can be quite anything, just use some separators. (You can even omit separators between numbers and letters. With the price of 1 character for changing to `<L1>` you could omit separators between letters too.)

Sample run:

```
bash-5.0$ gema '<N>=@sub{$1;1};z=a;<L>=@int-char{@add{@char-int{$1};1}}' <<< "['a', 2, 3, 'b']"
['b', 1, 2, 'c']

```

Try it online!

### Gema, 66 characters

```
<N>=@sub{$1;1}
<L>=@cmpi{$1;z;@int-char{@add{@char-int{$1};1}};a;}

```

Clean solution. Half relatively efficient, then half pure pain.

Sample run:

```
bash-5.0$ gema '<N>=@sub{$1;1};<L>=@cmpi{$1;z;@int-char{@add{@char-int{$1};1}};a;}' <<< "['a', 2, 3, 'b']"
['b', 1, 2, 'c']

```

Try it online!

# Answer
> 2 votes
# , 77 ~~85~~ bytes

Thanks @Giuseppe for a whooping 8 bytes

```
function(l)Map(function(x)"if"(i<-match(x,L<-c(letters,"a"),0),L[i+1],x-1),l)

```

Try it online!

Takes the input as a list. After a big change by @Giuseppe, this makes use of `Map` to apply a function to the list. It makes use of `match` to test for a character. During the test the extended letter list and index are saved for the return.

# Answer
> 2 votes
# MathGolf, 14 bytes

```
▄\╧¿ò'z=¿Å'a)(

```

Try it online!

Takes letter as lowercase.

## Explanation

```
▄\╧              Is the element in the lowercase alphabet?
   ¿ò            If so:
     'z=           Is it equal to z?
        ¿Å         If so:
          'a         Push 'a'
            )      Else: Increment the string
             (   Else: Decrement the number

```

# Answer
> 1 votes
# dzaima/APL, ~~21~~ 20 bytes

```
{0::⍵-1⋄⎕l(⍳⊇1⌽⊣)⍵}¨

```

Try it online!

-1 thanks to ngn.

# Answer
> 1 votes
# PHP, 50 bytes

```
for(;''<$a=$argv[++$i];)echo$a<a?--$a:(++$a)[0],_;

```

Try it online!

Tests

Outputs letters/integers separated by `_` with a trailing separator.

In PHP you can increment letters directly, so I took advantage of it. But the `z` is incremented to `aa`, to convert it to `a`, the `(++$a)[0]` is used which only outputs the first character of the incremented value.

# Answer
> 1 votes
# Japt `-m`, ~~13~~ 12 bytes

-1 byte thanks to Shaggy

```
;¤?UÉ:Cg8+Uc

```

Try it

## Explanation:

```
;o ?UÉ:Cg8+Uc
-m              // Map U through the input:
 o              // Try to create a range [1...U]
   ?            //   If that creates a range (number):
    UÉ          //     Return U-1
      :         //   Else, return:
;      C        //     alphabet (a...z)
        g       //     Index:
         8+Uc   //       8 + char-code of U

```

**Note**: `;` turns `C` into the lowercase alphabet

# Answer
> 1 votes
# SNOBOL4 (CSNOBOL4), 103 bytes

```
	U =&UCASE 'A'
N	X =INPUT	:F(END)
	U X @P	:F(D)
	U POS(P) LEN(1) . OUTPUT	:(N)
D	OUTPUT =X - 1	:(N)
END

```

Try it online!

# Answer
> 1 votes
## Haskell, ~~52~~ 51 bytes

```
map q
q"z"="a"
q x|x>"`"=succ<$>x|1<2=show$read x-1

```

As Haskell doesn't allow lists of mixed types, letters and numbers are taken and returned as strings.

Try it online!

Check for every list element: if the string is `"z"`, return `"a"`; if the first character of the string is \> `'`'` (i.e. a letter, not a digit), return the successor of the char(s) in the string; else it must be number, so convert to an integer, subtract 1 and turn into a string again.

Edit: -1 byte thanks to @cole.

# Answer
> 1 votes
# Jelly, 13 bytes

```
®i‘ị®µ’e?€Øa©

```

Try it online!

Clever fix by Jonathan Allan.

Note: This is not a full program, the footer over TIO makes it possible to input using a command-line argument to test the function.

# Answer
> 1 votes
# K (oK), 27 bytes

```
{$[9+@x;`c$97+26!8+x;x-1]}'

```

Try it online!

-8 thanks to ngn and dzaima :)

# Answer
> 1 votes
# C++17 (gcc), 120 bytes

```
#define O int operator()
struct V{O(char&c){c++-90?:c=65;}O(int&i){--i;}};int f(auto&l){for(auto&x:l)std::visit(V{},x);}

```

Here `f` is the required function; `l` is both the input and output parameter, and it is expected to be a container of objects which are compatible with `std::variant<char, int>` or vice versa.

Try it online!

# Answer
> 0 votes
# Runic Enchantments, 36 bytes

```
\$ka'~?*3({':+1\
R';$ >i::0Sqn=?/1-$

```

Try it online!

General process is to read input, prepend with a 0 (coercion to string), convert back to a number (single char will always return -1), compare with input. If same, it must be a numerical value, subtract 1 and print. If not same, it must be a char, subtract 1, compare with `{`. If less than, print, otherwise replace it with `a` and print.

Repeat until program performs a stack underflow.

Output is separated by `;` in order to save 1 byte (and has a trailing one). Input is space-separated.

# Answer
> 0 votes
# Stax, 17 bytes

```
àºÇ╝'♫d▬♣ΩÜEƒ6╩╬ó

```

Run and debug it

This feels like it should be possible to do shorter, but I can't resist the opportunity to use a new stax feature from the last release.

Treating the entire input as a string:

1. Regex replace runs of digits with `eval(match) - 1`. This is the new feature, as the regex block replacement is not a string, but an integer.
2. Regex replace runs of letters by ring-translating them around the lower-case alphabet.

# Answer
> 0 votes
# Python 3, 66 bytes

```
lambda X:[x-1if type(x)==int else chr(97+(ord(x)+8)%26)for x in X]

```

Edit:

I didn't see the solution of Jitse until now. The trick of if''!=i\*0 is awesome!

# Answer
> 0 votes
# C (gcc), ~~93~~ 86 bytes

```
f(int**s){for(char**p=s,*z;z=*p++;)64&*z?*z=*z-'z'?++*z:97:sprintf(z,"%d",atoi(z)-1);}

```

Try it online!

The input is a `NULL`-terminated array of `'\0'`-terminated strings, e.g. `{"a", "b", "c", "17", NULL}`.

-7 bytes thanks to @ceilingcat

# Answer
> 0 votes
# C#, 148 bytes

```
(object[] o)=>{var l=new List<object>();foreach(var h in o){try{l.Add((int)h-1);}catch{var c=((char)h+1);if(c>122){c=97;}l.Add((char)c);}}return l;}

```

Repl.it link

Ungolfed:

```
var inputList = new object[] {'a', 2, 'z', 6};
var outputList = new List<object>();
foreach (var currentItem in inputList)
{
    try
    {
        outputList.Add((int)currentItem-1);
    }
    catch
    {
        var currentItemPlusOne = ((char)currentItem + 1);
        if (currentItemPlusOne > 122)
        {
            currentItemPlusOne = 97;
        }
        outputList.Add((char)currentItemPlusOne);
    }
}

```

# Answer
> 0 votes
# Charcoal, 16 bytes

```
ＷＳ⟦⎇№βι§β⊕⌕βιＩ⊖ι

```

Try it online! Link is to verbose version of code. Takes input on STDIN, each line being either a single lowercase letter or an integer, and outputs on separate lines on STDOUT. Explanation:

```
ＷＳ

```

Repeatedly input from STDIN until an empty line is reached.

Make this expression output on its own line.

```
⎇№βι

```

Is this a substring of the predefined lowercase alphabet?

```
§β⊕⌕βι

```

If so then print the next letter cyclically indexed.

```
Ｉ⊖ι

```

Otherwise decrement the value and cast back to string for implicit print.

# Answer
> 0 votes
# Zsh, 47 bytes

```
a=({a..z} a)
for i
<<<${a[$a[(i)$i]+1]:-$[--i]}

```

Try it online!

```
a=({a..z} a)                  # append extra 'a' to the end to handle 'z' case
for i                         # for i in "$@" arguments
<<<${a[$a[(i)$i]+1]:-$[--i]}
       $a[(i)$i]              # first (i)ndex of $i in list (if not found, set to after last index)
      [         +1]           # increment
   ${a[           ]        }  # value in array at index. if lookup fails, empty string
   ${              :-$[--i]}  # if empty, decrement $i and substitute instead
<<<                           # print to stdout

```

# Answer
> 0 votes
# Perl 6, 31 bytes

```
*>>.&{(try $_-1)||chr ord ++$_}

```

Try it online!

Anonymous Whatever lambda that maps each element to the list and attempts to subtract one from it, otherwise incrementing it and taking the first character in the case that `z` wraps over to `aa`.

# Answer
> 0 votes
# T-SQL 2012, 61 bytes

Capital letters needed in input.

Using table variable as input.

```
SELECT iif(x<'a',left(x-1,9),char((ascii(x)-64)%26+65))FROM @

```

**Try it online**

# Answer
> 0 votes
# SimpleTemplate, 80 bytes

This was written on a language I've made.

Due to limitations in the compiler, I can't reduce it any more.

```
{@eachargv}{@if_ is matches"@\d+@"}{@incby-1_}{@echol_}{@else}{@inc_}{@echol_.0}

```

And now, ungolfed:

```
{@each argv as value}
    {@if value is matches "@\d+@"}
        {@inc by -1 value}
    {@else}
        {@inc by 1 value}
    {@/}
    {@echo value, "\n"}
{@/}

```

And the explanation:

* `{@each argv as value}` \- loops through all values in `argv`. (`argv` contains all the arguments passed).
If the `as <var>` isn't present, the default `_` variable is assumed.
* `{@if value is matches "@\d+@"}` \- checks that `value` matches with the regular expression `"@\d+@"`.
* `{@inc by -1 value}` \- increments the value by -1 (basically, a decrement).
* `{@echo value, "\n"}` and `{@echol_}` \- `echol` outputs the values passed and appends a line at the end.
* `{@else}` \- self-explanatory
* `{@inc by 1 value}` \- increments the value by 1. If the `by <value>` is missing, it is assumed to be 1.
* `{@echo value.0, "\n"}` and `{@echol_.0}` \- `echol` outputs the values passed and appends a line at the end.
This is required because of the challenge rules: `z wraps to a`.
When an `@inc` is used on a string, it increments the chars and, once it hits `z`, it wraps to `aa`.
Outputting the first character satisfies the challenge, at the cost of 7 bytes.
* `{@/}` \- closes the `{@else}` above (optional).
* `{@/}` \- closes the `{@each}` above (optional).

You can try this on: http://sandbox.onlinephpfunctions.com/code/7533641a0aa1fc8bf4699a9c758690de186b052f

Each passed argument to `render()` will be a new value that is considered.

# Answer
> -1 votes
## Perl, 64 bytes

```
foreach (@ARGV){$_=~m/[a-zA-Z]/?++$_:--$_;print substr $_,0,1;}

```

---
Tags: code-golf, integer, alphabet
---


# Question
Title: Fastest algorithm to output array containing all integers in range excluding duplicate digits
Input is a single integer in ascending digit order.

## The **only** valid inputs are:

`12`
`123`
`1234`
`12345`
`123456`
`1234567`
`12345678`
`123456789`

## The **only** valid output is an array (set; list) of `length` equal to the factorial of input:

Input - Factorial of input - Output array `length`

`12` -\> `1*2` -\> `2`
`123` -\> `1*2*3` -\> `6`
`1234` -\> `1*2*3*4` -\> `24`
`12345` -\> `1*2*3*4*5` -\> `120`
`123456` -\> `1*2*3*4*5*6` -\> `720`
`1234567` -\> `1*2*3*4*5*6*7` -\> `5040`
`12345678` -\> `1*2*3*4*5*6*7*8` -\> `40320`
`123456789` -\> `1*2*3*4*5*6*7*8*9` -\> `362880`

The output array is all integers of input length in lexicographical order.

For example, given input `123` -\> factorial of input is `1*2*3=6` -\> for each of the six array elements output the input integer and the five remaining integers of the array in lexicographic order -\> `[123,132,213,231,312,321]`. Notice that the last element is always the input integer in reverse order.

## Test Cases

```
Input  Output
`12` ->  `[12,21]` // valid output, ascending numeric order
`12` ->  `[12.0,21.0]` // invalid output, output must be rounded to integer
`123` -> `[123,132,213,231,312,321]` // valid output
`123` -> `[123,132,213,222,231,312,321]` // invalid output: `222` are duplicate digits
`123` -> `[123,142,213,231,213,321]` // invalid output: `142` outside range `1-3`
`123456789` -> `[987654321,...,123456789]` // valid output, descending numeric order
`123456789` -> `[987654321,...,123456798]` // invalid output, `123456798` is greater than the minimum required integer in resulting array `123456789`

```

## Rules

* Do **not** use standard library functions for permutations or combinatorics.
* If the algorithm produces an integer greater or less than input minimum or maximum **only** the integers in the specified range must be output. (Technically, if input is `12345` we could generate all integers to `21` or `12`, though for input `12345` the only valid output **must** be within the range `12345` through `54321`).
* Output must be an array (set; list) of integers, **not** strings.
* The integers output must **not** be hardcoded.
* The output integers must **not** include duplicate digits (more than one of the same digit at that array index).

## Winning criteria

## Hardware, OS

Where submissions will be run

```
~$ lscpu
Architecture:          i686
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                2
On-line CPU(s) list:   0,1
Thread(s) per core:    1
Core(s) per socket:    2
Socket(s):             1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 37
Model name:            Intel(R) Pentium(R) CPU        P6200  @ 2.13GHz
Stepping:              5
CPU MHz:               2133.000
CPU max MHz:           2133.0000
CPU min MHz:           933.0000
BogoMIPS:              4256.26
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              3072K

~$ free -m
              total        used        free      shared  buff/cache   available
Mem:           3769        1193         802         961        1772        1219
Swap:             0           0           0

~$ uname -r
4.8.0-36-lowlatency

```

Kindly explain the algorithm within the body of the answer.

For languages used other than JavaScript (which will test at Chromium 70) will take the time to install the language and test the code for the time taken to output the requirement, as there is no way (that have found) to provide uniform results as to time for every possible language used to derive output (see this comment).

# Answer
# Haskell, 6.9 s

```
f [] [x] = [[x]]
f [] [x,y] = [[x,y],[y,x]]
f l (x:r) = map (x:) (f [] $ l++r) ++ f (l++[x]) r
f _ [] = []

g :: Int -> [Int]
g = map read . f [] . show

```

Try it online! `g` is the main function which converts the input to a string and the result to a list of integers. `f` recursively performs the shuffling.

The algorithm works as follows: Given `123`, we need to generate `[123,132,213,231,312,321]`. This can be done in parts by taking the first digit `1`, recursively computing the list for the remaining digits `23 -> [23,32]` and adding `1` to the front again: `[123,132]`. Then we do the same with `2` and the remaining digits `13` to get `[213,231]` and with `3` and `12` to get `[312,321]`. Finally, the three lists are concatenated.

This works in the same way for larger numbers. `f` handles two lists, the first one (`l`) contains all digits left from the current digit, the second one (`x:r`) has the current digit `x` at the first position, followed by the remaining digits `r`. We recursively call `f` with all but the current digit (that is `l` and `r` concatenated) `(f [] $ l++r)` and add the current digit `x` to the front of each element in the resulting list: `map (x:)`. We then finished processing `x` and add it to the end of the `l` list and recursively call `f (l++[x]) r` to handle the next digit.

---

The largest test case `g 123456789` takes ~6.9s on OPs machine:

```
real 0m6.877s user 0m4.439s sys 0m0.056s

```

(~0.1s on my own machine)
> 5 votes

# Answer
# JavaScript 0.185 Seconds

```
function fact(x) {

  x+=""
  var rL=1,rI=0,i=0
  if(x.length <2)return [x]
  for(i;i<x.length;i++)rL*=(i+1);
  var r = new Array(rL);
  function loop(p, s) {
    var l = s.length, i=0;
    if (l === 2) {
      r[rI++] = (p + s)*1;
      r[rI++] = (p + s.charAt(1) + s.charAt(0)) * 1;
      return;
    }
    while (i < l) {
      loop(p + s.charAt(i), s.substr(0,i) + s.substr(++i));
    }
  }
  loop("",x)
  return r;
}

```

This function creates an array r of length "factorial of input length". It then has a recursive loop of with parameters for prefix and suffix (p and s). It starts the loop with an empty prefix and a suffix of the input. It then checks the base case of suffix length equal to 2 and if reached adds those results. If it's not a base case then loop through the suffix characters, take a character at index and add it to prefix, remove that character from the suffix, and loops those as a new prefix and suffix. This will continue until input length factorial results are added to array r.
> 2 votes

# Answer
**Common Lisp SBCL 0.157 seconds**

```
(defun num-permutations (list)
  (cond ((null list) nil)
        ((null (cdr list)) (list list))
        (t (loop for element in list
             append (mapcar (lambda (l) (cons element l))
                            (num-permutations (remove element list)))))))

```

here is the run with 1-9

```
CL-USER> (time (num-permutations '(1 2 3 4 5 6 7 8 9)))
Evaluation took:
  0.157 seconds of real time
  0.156455 seconds of total run time (0.140332 user, 0.016123 system)
  [ Run times consist of 0.081 seconds GC time, and 0.076 seconds non-GC time. ]
  99.36% CPU
  468,738,490 processor cycles
  165,083,680 bytes consed

```
> 1 votes

# Answer
## C# (31 ms)

```
    static int[] Foo(int perm) {
        int n = perm.ToString().Length, fact = n;
        int[] pow10 = new int[n];
        pow10[n - 1] = 1;
        for (int k = n - 2; k >= 0; k--) {
            pow10[k] = 10 * pow10[k + 1];
            fact *= k + 1;
        }

        int[] rv = new int[fact];
        rv[0] = perm;
        int z = 1, i = n - 1, pi = perm/pow10[i]%10;
        while (true) {
            int pidec = perm/pow10[i-1]%10;
            if (pidec > pi) {
                if (--i == 0) return rv;
                pi = pidec;
            }
            else {
                int j = n - 1;
                while (perm/pow10[j]%10 < pidec) j--;

                perm += (perm/pow10[i-1]%10 - perm/pow10[j]%10) * (pow10[j] - pow10[i-1]);
                for (j = n - 1; i < j; i++, j--)
                    perm += (perm/pow10[i]%10 - perm/pow10[j]%10) * (pow10[j] - pow10[i]);

                rv[z++] = perm;
                i = n - 1;
                pi = perm/pow10[i]%10;
            }
        }
    }

```

Online demo

The algorithm is the standard one.
> 1 votes

# Answer
# C++

```
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <chrono>
#include <cstring>

#include <emmintrin.h>
#include <smmintrin.h>

unsigned char bsr(unsigned long* index, unsigned long long mask)
{
    if (!mask) return 0;
    *index = 63 - __builtin_clzll(mask);
    return 1;
}

std::vector<uint32_t> findPermulations(uint32_t input)
{
    std::string tmp = std::to_string(input);
    size_t size = std::distance(tmp.begin(), tmp.end());
    uint8_t* perm = (uint8_t*)_mm_malloc(32, 64);
    memcpy(perm, tmp.data(), size);
    memset(perm + size, 0, 64 - size);
    for (size_t i = 0; i < size; i++) {
        perm[i] -= '0'; // Convert char to uint8_t
    }

    size_t fact = 1;
    for (size_t i = 0; i < size; i++) {
        fact *= perm[i];
    }

    std::vector<uint32_t> results;
    results.reserve(fact);
    results.push_back(input);

    for (size_t i = 1; i < fact; i++)
    {
        uint8_t k;
        __m128i mask = _mm_cmplt_epi8(_mm_load_si128((__m128i*)perm), _mm_loadu_si128((__m128i*)(perm + 1)));
        unsigned long index = 0;
        if (!bsr(&index, _mm_extract_epi64(mask, 1))) {
            if (!bsr(&index, _mm_extract_epi64(mask, 0))) k = size - 1;
            else k = index / 8;
        }
        else k = (index / 8) + 8;

        uint8_t l = 8;
        mask = _mm_cmplt_epi8(_mm_set1_epi8(perm[k]), _mm_load_si128((__m128i*)perm));
        if (!bsr(&index, _mm_extract_epi64(mask, 1))) {
            bsr(&index, _mm_extract_epi64(mask, 0));
            l = 0;
        }

        l += index / 8;

        std::swap(perm[k], perm[l]);
        std::reverse(perm + k + 1, perm + size);

        uint32_t result = 0;
        for (size_t i = 0; i < size; i++) {
            result *= 10;
            result += perm[i];
        }

        results.push_back(result);
    }
    _mm_free(perm);
    return results;
}

int main()
{
    std::cout << "Press any key to begin...\n";
    std::cin.get();
    auto start = std::chrono::high_resolution_clock::now();
    auto perms = findPermulations(123456789);
    auto end = std::chrono::high_resolution_clock::now();
    std::cout << "Completed in " << std::chrono::duration<double, std::milli>(end - start).count() << "ms\n";
    return 0;
}

```

Regular algorithm. If `std::reverse` count counts as a library permutation function, replace with:

```
void reverse(uint8_t* first, uint8_t* last){
    while ((first != last) && (first != --last)) {
        std::iter_swap(first++, last);
    }
}

```

Swaps don't really count as permutations, put you could change them anyway.

Compile with clang 6.0: `clang++-6.0 find.cpp -O3 -mssse3` `./a.out`
> 0 votes

---
Tags: math, number, combinatorics, fastest-code
---


title: The Knight's estate

text:
# Question
Title: The Knight's estate
And then the King said: *You fought bravely, Knight, and your deed will not be forgotten for centuries. For your valor I grant you this castle and the lands around it. Things rush me, and I can not take you to the castle. Therefore, I will give you the way from this place to the castle. Now go and come back after the deadline.* \- as it is written in the Green Book of Years.

In addition, it is known from the Green Book of Years that the lands with which the castle was granted were in the shape of a circle. The king was very wise and, in order to avoid unnecessary proceedings regarding the right to land, always granted only areas of land on the map that have a convex shape.

Recently, historians have had information about where the castle was located and where this historical conversation took place. They want to know how much land did the Knight get on the assumption that the road to the castle was perfectly straight.

## Explanation

The following figure shows in light gray the territory originally granted to the knight, and in dark gray, the one that came to him as a result of the king giving him the way.

## Input

The first line of the input contains two floating-point numbers: xk and yk \- the coordinates of the place where the dialogue took place. The second line contains three floating-point numbers: xc, yc and rc \- the coordinates of the castle and the radius of the circle that bounds the land granted with it.

## Output

Print one floating-point number - the area of the land obtained by the Knight, with an accuracy of at least three characters after the decimal point.

## Tests

### Input Output

`2 5` `5.69646`
`2 1 1`

---

`3 9` `80.7130`
`2 3 5`

---

`1 3` `3.141`
`1 2 1`

**Note:** A triangle may not include the entire semicircle if it is too close to the center, as in the test I have given.

# Answer
> 7 votes
# Wolfram Language (Mathematica), 51 bytes

```
Area@ConvexHullMesh[CirclePoints[##2,7!]~Append~#]&

```

Try it online!

```
                    CirclePoints[##2,7!]            (* generate 5040 points on the perimeter of the circle *)
                                        ~Append~#   (* append the point at the end of the way, *)
Area@ConvexHullMesh[                             ]& (* and find the area of the convex hull of those points *)

```

# Answer
> 6 votes
# JavaScript (ES7), 76 bytes

Port of Jitse's answer.

```
with(Math)f=(X,Y,x,y,r,h=hypot(X-x,Y-y))=>r*(r*(PI-acos(r/h))+(h*h-r*r)**.5)

```

Try it online!

# Answer
> 5 votes
# Python 3, 107 bytes

```
from math import*
def f(X,Y,x,y,r):d=hypot(X-x,Y-y);return(r>d)*pi*r*r or(pi-acos(r/d))*r*r+(d*d-r*r)**.5*r

```

Try it online!

*-3 bytes thanks to Arnauld*

*-4 bytes thanks to squid*

*-5 bytes thanks to Greg Martin*

### Explanation

First, we calculate the traveled distance between both coordinates using the Pythagorean theorem. Let's call it `d`.

Then, we construct a rectangular triangle between coordinate 1, coordinate 2 and the point on the circle where it meets with the straight line. Using the Pythaogrean theorem again, the area of this triangle is given by $$\frac{1}{2}\times\sqrt{d^2-r^2}\times r$$ where `d` is the distance between the coordinates and `r` is the radius of the circle. Since we have two of those triangles, this area is resembled in the code by `(d*d-r*r)**.5*r`

Next, we need to calculate the remaining area of the circle. A circle's area is given by $$ a = \pi\times r^2$$ However, part of the circle is already taken into account. The angular fraction of the circle that is already described by the triangles is given as $$\cos^{-1}(r/d)$$ so that the remaining area in the circle can be described by `(pi-acos(r/d))*r*r`.

And then some code juggle to make it as short as possible.

### Except...

when the traveled distance lies within the circle. Then just return the circle area.

# Answer
> 4 votes
# Jelly, 33 bytes

```
½÷@ÆAØP_×²}
I²SḢ_²}½×ʋ+çɗṛ²×ØPʋ>?

```

Try it online!

Port of @jitse’s Python answer so be sure to upvote that one! A full program taking as its arguments `[[xk, xc], [yk, yx]]` and `r`.

# Answer
> 3 votes
# Python 3, 96 bytes

```
from math import*
def f(X,Y,x,y,r):t=max(hypot(X-x,Y-y)**2/r/r-1,0)**.5;return(t-atan(t)+pi)*r*r

```

Try it online!

In Python 3.8, the solution can be further improved using assignment expressions:

# Python 3.8 (pre-release), 91 bytes

```
lambda X,Y,x,y,r:((t:=max(hypot(X-x,Y-y)**2/r/r-1,0)**.5)-atan(t)+pi)*r*r
from math import*

```

Try it online!

*-2 bytes thanks to @Jitse*

This solution is based on a bit more math manipulation of the formula. Let \\$\theta\\$ be the size of common angle of each triangle and its corresponding sector. The area of each triangle equals to \\$\frac{1}{2}\times r\tan{\theta}\times r\\$ and the area of the common sector of the triangles and the circle equals to \\$\theta\times r\times r\\$. Hence, the total area $$S=\tan{\theta}\cdot r^2 +\pi r^2-\theta r^2=(\pi+\tan{\theta}-\theta)r^2$$

We define \\$t\\$ to be $$t=\tan{\theta}=\frac{\sqrt{d^2-r^2}}{r}=\sqrt{\frac{d^2}{r^2}-1}$$ Here, \\$d\\$ is the distance between the two given coordinate pairs. Then we have $$S=(\pi+t-\arctan{t})r^2$$

# Answer
> 1 votes
# C (clang), ~~111~~ ~~103~~ 93 bytes

```
float f(X,x,r)_Complex X,x,r;{X=cabs(X-x)/r;return(4*atan(1)-atan(X=csqrt(X*X-1))+X)*r*r;}

```

Try it online!

It's 90 bytes for the code, but +3 bytes because we need to pass `-lm` to the compiler.

Thanks to @ceilingcat for shaving off 12 bytes, and the brilliant use of `csqrt()` inspired me to take the coordinates as complex numbers, to shave off another 10 bytes.

---
Tags: code-golf, geometry
---