The Written Digits Sequence

Here's a reasonably trivial sequence which is not in the Online Encyclopedia of Integer Sequences.

Start with an empty sequence then define each term as the number of characters required to write out, in English, all of the digits of the sequence so far without spaces.*

For reference the number of characters of all of the (base ten) digits in English are:

zero   one    two    three  four   five   six    seven  eight  nine
4      3      3      5      4      4      3      5      5      4

(Which is the start of both A52360 and A5589.)

This makes the first entry $$\a(0) = 0\$$ since there are zero digits present in the empty sequence.

This makes the second entry $$\a(1) = 4\$$ as it takes four characters to write "zero", the only digit present so far.

This makes the third entry $$\a(2) = 8\$$ as it takes four more characters to write the "four" for a total of eight to write "zerofour".

This makes the fourth entry $$\a(3) = 13\$$ as it takes five more characters to write "eight" for a total of thirteen to write "zerofoureight".

This makes the fifth entry $$\a(4) = 21\$$ as it takes eight more characters to write "onethree" for a total of twenty-one to write "zerofoureightonethree".

...and so on. Here are the first 100 entries:

0, 4, 8, 13, 21, 27, 35, 44, 52, 59, 67, 75, 84, 93, 102, 112, 121, 130, 142, 152, 162, 171, 182, 193, 205, 216, 225, 235, 247, 259, 270, 282, 293, 305, 318, 331, 344, 357, 371, 384, 398, 412, 422, 432, 444, 456, 467, 479, 492, 503, 516, 526, 536, 548, 561, 571, 583, 597, 610, 620, 630, 642, 652, 662, 671, 682, 693, 705, 718, 731, 744, 757, 771, 784, 798, 812, 823, 836, 849, 862, 873, 888, 903, 916, 926, 936, 948, 961, 971, 983, 997, 1010, 1024, 1038, 1055, 1070, 1086, 1101, 1114, 1127

* We could define it for other languages and/or other bases or with spaces of course

The challenge

Given $$\n\$$ output, in as few bytes of code as possible, any of:

• The first $$\n\$$ terms of the sequence (should work for non-negative integers)
• The value of $$\a(n)\$$ (should work for non-negative integers)
• The $$\n\$$th term of the sequence (should work for positive integers - i.e. value of $$\a(n-1)\$$)

This is so the shortest answer in bytes wins for each language, and the shortest answer in bytes wins. Don't let golfing languages stop you from entering in your favourite language be it a practical one or an esoteric one!

• By the first option, do you mean that 1) 1 should output  and 0 should output [] or 2) 0 should output  (as in my former answer)? – Erik the Outgolfer Oct 22 '18 at 18:01
• @EriktheOutgolfer I mean (1) as it should return the first n terms. That is, the options are "output the sequence up to but not including a(n)", "output a(n)", or "output a(n-1)". – Jonathan Allan Oct 22 '18 at 18:06
• So, a(x) = a(x-1) + f(a(x-1)) where f(x) is the amount of characters needed to write x? – FireCubez Oct 23 '18 at 12:40
• @FireCubez yes, if a(0)=0 and f(x) is non-space characters to write the digits of x – Jonathan Allan Oct 23 '18 at 13:19

Perl 6, 45 bytes

{({[+] @_.join.uninames>>.comb X-6}...*)[$_]} Try it online! No need for fancy moduloing when you can get the name of the digit directly! Anonymous code block that returns the nth value of the sequence, or you can pass in a range to get a list of values Explanation: {( )[$_]}  # Index input into:
{                               }...*        # An infinite sequence
# Where each element is
[+]   # The sum of
@_.join  # All previous elements joined together
.uninames  # The unicode names for each character
# These are names in the form "DIGIT ONE"
>>.comb  # Split each to lists of characters
X-6  # Subtract 6 from each
• @JonathanAllan Ah, I had assumed you had allowed an infinite sequence as a return, sorry. I'll fix this – Jo King Oct 22 '18 at 22:50
• Nice, that's good :) – Jonathan Allan Oct 22 '18 at 22:53
• Nice! » is one byte, right? Also, [+] might be cuter and hint at how binary ops can become reducers but sum is also three bytes and in keeping with the rest of the solution which might not be the shortest but sure is the most elegant golf imo. – raiph Oct 29 '18 at 20:44
• @raiph » is two bytes so it's interchangable. – Jo King Oct 29 '18 at 20:53
• Maybe this is cheating but doesn't Rakudo handle Latin1 source code correctly? If so, note that say '»'.encode('latin1').bytes displays 1. :) – raiph Oct 29 '18 at 21:31

JavaScript (ES6), 696861 58 bytes

Returns $$\a(n)\$$.

f=(n,s=0)=>n?f(n-1,[...s+''].map(d=>s+=(d+10)%23%3+3)|s):s

Try it online!

How?

A digit $$\d\$$ is converted to a number $$\n\$$ of letters with:

$$n=(((d \times 100 + 10) \bmod 23) \bmod 3)+3$$

d | *100 | +10 | MOD 23 | MOD 3 | +3 | word
---+------+-----+--------+-------+----+-------
0 |    0 |  10 |   10   |   1   |  4 | zero
1 |  100 | 110 |   18   |   0   |  3 | one
2 |  200 | 210 |    3   |   0   |  3 | two
3 |  300 | 310 |   11   |   2   |  5 | three
4 |  400 | 410 |   19   |   1   |  4 | four
5 |  500 | 510 |    4   |   1   |  4 | five
6 |  600 | 610 |   12   |   0   |  3 | six
7 |  700 | 710 |   20   |   2   |  5 | seven
8 |  800 | 810 |    5   |   2   |  5 | eight
9 |  900 | 910 |   13   |   1   |  4 | nine

Because the number is split into digit characters, we can process $$\d\times 100+10\$$ by just adding $$\10\$$ (as a string concatenation).

Stax, 14 13 bytes

┴♥7[╘⌂←─üTJ‼√

Run and debug it

The key insight here is that digit d requires ((4 - 2 * d) // 3) % 3 + 3 letters to spell. (That's python integer division, and python-style non-negative modulus)

Pip, 21 bytes

Lai+:$+4335443554@^Pi Takes input $$\n\$$ as a command-line argument and outputs the first $$\n\$$ terms. Try it online! Explanation Lai+:$+4335443554@^Pi
a is 1st cmdline arg; i is 0 (implicit)
La                     Loop (a) times:
Pi   Print i
^     Split it into a list of characters (i.e. digits)
4335443554@      Use each digit to index into this number, giving the length of the
name of the digit (0 -> 4, 1 -> 3, etc.)

Try it online!

05AB1E, 15 14 bytes

ÎFD•16\|/•sSèOO

Try it online!

Explanation

Î                # initialize stack with 0 and input
F               # input times do:
D              # duplicate the current number
sSè     # and use one copy to index into
•Qb₁ñ•        # 433544355
OO   # sum digits and sum the stack

APL (Dyalog Unicode), 29 28 bytes

{{⍵++/3+3|⌊3÷⍨4-2×⍎¨⍕⍵}⍣⍵⊢0}

Try it online!

Dfn. Prints $$\f(input)\$$

Thanks to the guys @The APL Orchard for helping with this one:

@ngn for 2 bytes; @H.PWiz for 3 4 bytes.

Now using @recursive's formula.

How:

{{⍵++/3+3|⌊3÷⍨4-2×⍎¨⍕⍵}⍣⍵⊢0} ⍝ Main fn

{                     }⍣⍵⊢0 ⍝ Starting with 0, repeat (⍣) the inner fn input times
3+3|⌊3÷⍨4-2×⍎¨⍕⍵      ⍝ @recursive's formula
⍵++/                       ⍝ Sum with the input.

Python 2, 61 bytes

n=0
exec"for c inn:n+=(4-2*int(c))/3%3+3\n"*input()
print n

Try it online!

Python 2, 63 bytes

f=lambda n:n and f(n-1)+sum((4-2*int(c))/3%3+3for c inf(n-1))

Try it online!

A recursive function version. It takes exponential time to run because it has two recursive calls to f(n-1).

• Nice! I'm curious if the expression-finding script you've mentioned using before finds this expression (or maybe an even shorter one?) – Lynn Oct 24 '18 at 11:12
• @Lynn I had run the script but didn't find a better one. 13 chars is too much for a full search, and didn't find anything at most 9 chars long. When I cut off the +3 and limited it to arithmetic operators (no bitwise) and numbers <=4, I found this solution but nothing shorter or even the same length except equivalents. – xnor Oct 24 '18 at 22:54

Python 2, 71 bytes

f=lambda n,k=0:n and f(n-1,k+sum(632179420>>3*int(d)&7for d ink))or k

Try it online!

• f=lambda n,k=0:n and f(n-1,k+sum(632179420>>3*int(d)&7for d ink))or k is the same count but avoids outputting an enclosing list. – Jonathan Allan Oct 22 '18 at 20:53
• Looks like recursive's algorithm from their staxx answer would save 2 bytes. I do like this though! – Jonathan Allan Oct 22 '18 at 21:18

MathGolf, 17 bytes

0\{_▒♀*♂+L%3%3+Σ+

Try it online!

This uses Arnauld's method. Outputs the nth element of the sequence.. If the empty string is okay for a(0), then we could remove the 0\ at the beginning.

Explanation:

0\                 Setup 0 as the counter
{                Loop input times
_▒              Duplicate counter and split to list of digits
♀*            Multiply each element by 100
L%        Modulo by 23
3%      Modulo by 3
Σ   Sum list
+  And add to counter

Pyth, 21 bytes

u+Gs@L+L3jC\᯻3jGTQ0

Try it online here.

u+Gs@L+L3jC\᯻3jGTQ0   Implicit: Q=eval(input()), T=10

u                Q0   Starting at 0, repeat the following Q times, with current value as G:
C\᯻           Get character code 7163
j   3          Convert the above to base 3, yields [1, 0, 0, 2, 1, 1, 0, 2, 2]
+L3               Add 3 to each to generate digit length dictionary
jGT       Get digits of G (convert to base 10)
@L                  Lookup each value in the above in the dictionary, modular indexing
s                    Take the sum
+G                     Add G to the above
• very likely isn't a single byte in Pyth's codepage. (I think it uses UTF-8, in which case it's 3 bytes, and j7163 3 has the same length; but tio.run says Pyth has a SBCS. Mysterious!) – Lynn Oct 24 '18 at 11:10
• @Lynn You're absolutely right, I'd forgotten about the byte count, my bad. I'll leave the code as is for now and update the byte count – Sok Oct 24 '18 at 12:39

Ruby, 54 bytes

->n{s=0;n.times{s+=s.digits.sum{|d|4+392[d]-70[d]}};s}

Try it online!

Java (JDK), 95 bytes

n->{int l=0;while(n-->0)l+=(""+l).chars().map(x->"4335443554".charAt(x-48)-48).sum();return l;}

Try it online!

JavaScript (Node.js), 82 bytes

f=(a,b=1,s=4)=>a?b<a?f(a,++b,s+=[...s+''].reduce((q,w)=>+'4335443554'[w]+q,0)):s:0

Try it online!

Jelly, 13 bytes

ṃ“vẋç’ḃ5¤S+Ɗ¡

Try it online!

0-indexed.

Full program; takes input from STDIN.

Red, 99 95 bytes

func[n][d:"4335443554"s: 0 repeat i n[print s foreach c form s[s: s - 48 + do d/(-47 + do c)]]]

Try it online!

Just a straightforward solution.

J, 37 bytes

(+1#.|(3+3|23|10+100*]),.&.":)@]^:[&0

Try it online!

Uses Arnauld's method

Explanation:

The argument is n

^:    - apply the verb on the left hand site
[   - n times
&0 - to a starting value 0
(                             )@]     - calculate for the current value of the argument
,.&.":        - convert to string and then each char to digit
(3+3|23|10+100*])              - map each digit to its word length
|                               - a filler for the fork
1#.                                - sum the lengths
+                                   - add them to the current value

Edited after 1st comment.

Prints all terms

Scala, 76 bytes

def^(n:Int)=(1 to n).scanLeft(0)((y,_)=>y+(y+"").map(x=>(x*9+1)%13%3+3).sum)

Try it online!

Prints nth term

Scala, 72 bytes

def^(n:Int)=Stream.iterate(0)(x=>x+(x+"").map(x=>(x*9+1)%13%3+3).sum)(n)

Scala, 69 bytes

def^(n:Int)=(0/:(1 to n))((y,_)=>y+(y+"").map(x=>(x*9+1)%13%3+3).sum)

Scala, 67 bytes

def s(b:Int):Stream[Int]=b#::s(b+(b+"").map(x=>(x*9+1)%13%3+3).sum)

Scala, 67 bytes

val s:Stream[Int]=0#::s.map(x=>x+(x+"").map(x=>(x*9+1)%13%3+3).sum)

Try it online!

• I don't know Scala, but I think this is neither a program or a function but rather a snippet (i.e. it runs on the REPL once n is defined). If you know Scala it's probably easy to fix. Also note that there is a tips for golfing in Scala question which may help. Lastly it's nice to post a link to an online interpreter, TIO has Scala and is used by a lot of PPCG members. – Jonathan Allan Oct 24 '18 at 17:40
• @JonathanAllan, thank you, it was very helpful. – Dr Y Wit Oct 24 '18 at 20:48