32
\$\begingroup\$

We are all familiar with the Fibonacci sequence:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765

However, instead of, f(n) = f(n-1) + f(n-2) we'll be taking digital sum of the previous 2 entries.


The sequence should still start with 0, 1, after that the differences are rapidly apparent. This list is 0-indexed, you may use 1-indexed as well, state which you used.

f(0) = 0
f(1) = 1
f(2) = 1 # 0 + 1
f(3) = 2 # 1 + 1
f(4) = 3 # 1 + 2
f(5) = 5 # 2 + 3
f(6) = 8 # 3 + 5
f(7) = 13 # 8 + 5
f(8) = 12 # 8 + 1 + 3
f(9) = 7 # 1 + 3 + 1 + 2
f(10) = 10 # 1 + 2 + 7
f(11) = 8 # 7 + 1 + 0
f(12) = 9 # 1 + 0 + 8
f(13) = 17 # 8 + 9
f(14) = 17 # 9 + 1 + 7
f(15) = 16 # 1 + 7 + 1 + 7
f(16) = 15 # 1 + 7 + 1 + 6
f(17) = 13 # 1 + 6 + 1 + 5
f(18) = 10 # 1 + 5 + 1 + 3
f(19) = 5 # 1 + 3 + 1 + 0
f(20) = 6 # 1 + 0 + 5
f(21) = 11 # 5 + 6
f(22) = 8 # 6 + 1 + 1
f(23) = 10 # 1 + 1 + 8
f(24) = 9 # 8 + 1 + 0
f(25) = 10 # 1 + 0 + 9
f(26) = 10 # 9 + 1 + 0
f(27) = 2 # 1 + 0 + 1 + 0
(After this point it repeats at the 3rd term, 0-indexed)

Note: I didn't notice the repetition until I posted the challenge itself, and here I was thinking it'd be impossible to write another novel Fibonacci challenge.


Your task is, given a number n, output the nth digit of this sequence.

First 3 digits: [0,1,1],

24-digit repeated pattern: [2,3,5,8,13,12,7,10,8,9,17,17,16,15,13,10,5,6,11,8,10,9,10,10]

Hint: You may be able to exploit this repetition to your advantage.


This is , lowest byte-count is the winner.


BONUS: If you use the repetition in your answer, I will award the lowest byte-count answer that takes advantage of the repetition in the sequence a bounty of 100 points. This should be submitted as part of your original answer, after your original answer. See this post as an example of what I am talking about: https://codegolf.stackexchange.com/a/108972/59376

To qualify for this bonus your code must run in constant time (O(1)) with an explanation.

Bonus Winner: Dennis https://codegolf.stackexchange.com/a/108967/59376 < Dennis won.

Most Unique Implementation: https://codegolf.stackexchange.com/a/108970/59376
(Also will receive 100 points, finalized after correct answer is chosen)

asked Feb 2, 2017 at 19:28
\$\endgroup\$
7
  • 2
    \$\begingroup\$ Can we use 1-based indexing or does it have to be 0-based? \$\endgroup\$ Commented Feb 2, 2017 at 20:16
  • 1
    \$\begingroup\$ @BusinessCat yeah, sure, screw it. \$\endgroup\$ Commented Feb 2, 2017 at 21:10
  • 1
    \$\begingroup\$ How do you define takes advantage of the repetition? Does it have to be hardcoded or I just add a %24 to a "normal" solution? \$\endgroup\$ Commented Feb 2, 2017 at 21:33
  • 1
    \$\begingroup\$ @Dennis I define taking advantage of the repetition to mean O(1). Your code should be running in constant time, if it is truly exploiting the repetition. \$\endgroup\$ Commented Feb 2, 2017 at 21:39
  • 1
    \$\begingroup\$ @Dennis technically %24 on the input would make it upper bounded at 27 iterations; while, not interesting, it definitely counts. \$\endgroup\$ Commented Feb 2, 2017 at 21:44

31 Answers 31

1
2
28
+100
\$\begingroup\$

JavaScript (ES6), 45 bytes

f=(n,x=0,y=1)=>n?f(n-1,y,(x%9||x)+(y%9||y)):x
<input type=number min=0 oninput=o.textContent=f(this.value)><pre id=o>

x and y can't both be 9, since that would require the previous number to be 0, so their digital sum can't exceed 17. This means that the digital root for numbers greater than 9 is the same as the remainder modulo 9.

answered Feb 2, 2017 at 20:12
\$\endgroup\$
1
  • 6
    \$\begingroup\$ This, this also will get a bounty equivalent to the repetition leader... This is an awesome mathematical insight. \$\endgroup\$ Commented Feb 2, 2017 at 21:19
13
\$\begingroup\$

Python 2, 53 bytes

f=lambda n:n>1and sum(map(int,`f(n-1)`+`f(n-2)`))or n

Recursive function. The base cases of n=0 and n=1 yield n, larger numbers calculate the value by calling f(n-1) and f(n-2) converting each to a string, concatenating the two strings, converting each character to an integer using a map with the int function, and then sums the resulting list.


Using the modulo-24 information I can currently get a 56 byte non-recursive unnamed function:

lambda n:int(('011'+'2358dc7a89hhgfda56b8a9aa'*n)[n],18)
answered Feb 2, 2017 at 20:18
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Yes! So much +1! A repetition answer :). I've added a bonus section in your honor sir, you're now the leader in a 100 point bounty contest! \$\endgroup\$ Commented Feb 2, 2017 at 21:15
11
\$\begingroup\$

JavaScript (ES6), 34 bytes

f=n=>n<2?n:~-f(--n)%9+~-f(--n)%9+2

May freeze your browser for inputs above 27 or so, but it does work for all input values. This can be verified with a simple cache:

c=[];f=n=>n<2?n:c[n]=c[n]||~-f(--n)%9+~-f(--n)%9+2
<input type=number value=0 min=0 step=1 oninput="O.value=f(this.value)"> <input id=O value=0 disabled>

As pointed out in Neil's brilliant answer, the output can never exceed 17, so the digital sum of any output above 9 is equal to n%9. This also works with outputs below 9; we can make it work for 9 as well by subtracting 1 with ~- before the modulus, then adding back in 1 after.


The best I could do with hardcoding is 50 bytes:

n=>"0x"+"7880136ba5867ffedb834968"[n%24]-(n<3)*9+2
answered Feb 2, 2017 at 20:40
\$\endgroup\$
7
\$\begingroup\$

Oasis, 5 bytes

Code:

ScS+T

Try it online!

Expanded version:

ScS+10

Explanation:

ScS+ = a(n)
 0 = a(0)
 1 = a(1)
S # Sum of digits on a(n-1)
 c # Compute a(n-2)
 S # Sum of digits
 + # Add together
answered Feb 2, 2017 at 22:27
\$\endgroup\$
1
  • \$\begingroup\$ Oh man... I'm going to start learning Oasis too. \$\endgroup\$ Commented Feb 8, 2017 at 16:34
6
\$\begingroup\$

Jelly, 8 bytes

;DFS
ç¡1

Try it online!

How it works

ç¡1 Main link. No arguments. Implicit left argument: 0
 1 Set the right argument to 1.
ç¡ Repeatedly execute the helper link n times – where n is an integer read from
 STDIN – updating the left argument with the return value and the right
 argument with the previous value of the left argument. Yield the last result.
;DFS Helper link. Arguments: a, b
; Concatenate; yield [a, b].
 D Decimal; convert both a and b to their base-10 digit arrays.
 F Flatten the result.
 S Compute the sum of the digits.

Alternate solution, 19 bytes, constant time

;DFS
95ç23С8ịμṠ>?2

Try it online!

How it works

95ç23С8ịμṠ>?2 Main link. Argument: n
9 Set the return value to 9
 5 Yield 10.
 ç23С Execute the helper link 23 times, with initial left argument 10
 and initial right argument 9, updating the arguments as before.
 Yield all intermediate results, returning
 [10,10,2,3,5,8,13,12,7,10,8,9,17,17,16,15,13,10,5,6,11,8,10,9].
 8ị Extract the element at index n. Indexing is 1-based and modular.
 μ Combine all links to the left into a chain.
 >?2 If n > 2, execute the chain.
 Ṡ Else, yield the sign if n.
answered Feb 2, 2017 at 19:56
\$\endgroup\$
1
  • 1
    \$\begingroup\$ +1 for the chuzpe of "let's just calculate the whole repeated section in constant time" :D \$\endgroup\$ Commented Feb 3, 2017 at 14:26
4
\$\begingroup\$

JavaScript (ES6), (削除) 52 46 (削除ここまで) 45 bytes

_=$=>$<2?$:eval([..._(--$)+[_(--$)]].join`+`)

Usage

_=$=>$<2?$:eval([..._(--$)+[_(--$)]].join`+`)
_(7)

Output

13

Explanation

This function checks if the input is smaller than 2, and if so, it returns the input. Otherwise, it creates an array of two values that are appended to each other as strings. Those two values are the result of calling the function with input - 1 and input - 2.

The ... operator splits this string into an array of characters, which then is converted to a string again, but now with +es between values. This string is then interpreted as code, so the sum is calculated, which is then returned.

This is a double-recursive algorithm, which makes it quite inefficient. It needs 2n-2 function calls for input n. As such, here's a longer but faster solution. Thanks to ETHproductions for coming up with it.

f=(,ドルp=1,c=0)=>$?f($-1,c,eval([...p+[c]].join`+`)):c
answered Feb 2, 2017 at 19:37
\$\endgroup\$
6
  • \$\begingroup\$ This doesn't work for big values like 27, it freezes the browser (at least it does for me) \$\endgroup\$ Commented Feb 2, 2017 at 19:40
  • \$\begingroup\$ It takes some time, but it will get there... eventually. I'll look into it, but performance isn't important for this challenge... \$\endgroup\$ Commented Feb 2, 2017 at 19:44
  • \$\begingroup\$ Well, jesus, it's not that computationally intense, your program should work for values beyond 27... But if it works for 1-28, that technically proves it works for higher. \$\endgroup\$ Commented Feb 2, 2017 at 19:45
  • 1
    \$\begingroup\$ @KritixiLithos It's the recursion that's the problem. Computing the nth number in the sequence requires roughly 2^(n-2) function calls, which builds up pretty rapidly. \$\endgroup\$ Commented Feb 2, 2017 at 19:54
  • \$\begingroup\$ You can save a byte with [..._(--$)+[_(--$)]] :-) \$\endgroup\$ Commented Feb 2, 2017 at 19:55
4
\$\begingroup\$

05AB1E, 8 bytes

XÎF‚¤sSO

Try it online!

Explanation

XÎ # push 1,0,input
 F # input_no times do:
 ‚ # pair the top 2 elements of the stack
 ¤ # push a copy of the 2nd element to the stack
 s # swap the pair to the top of the stack
 S # convert to list of digits
 O # sum
answered Feb 2, 2017 at 20:44
\$\endgroup\$
4
\$\begingroup\$

Perl 6, (削除) 41 (削除ここまで) 37 bytes

{(0,1,{[+] |$^a.comb,|$^b.comb}...*)[$_]}

Try it

{(0,1,*.comb.sum+*.comb.sum...*)[$_]}

Try it

{ # bare block lambda with implicit parameter 「$_」
 (
 0, 1, # first two values
 # WhateverCode lambda with two parameters ( the two 「*」 )
 *.comb.sum # digital sum of first parameter
 +
 *.comb.sum # digital sum of second parameter
 ... # keep using that code object to generate new values until:
 * # never stop
 )[ $_ ] # index into the sequence
}
answered Feb 3, 2017 at 2:38
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can write the inner lambda as *.comb.sum+*.comb.sum. \$\endgroup\$ Commented Feb 3, 2017 at 11:31
  • 1
    \$\begingroup\$ You can write (*~*).comb.sum instead of *.comb.sum+*.comb.sum. \$\endgroup\$ Commented Sep 16, 2022 at 19:30
3
\$\begingroup\$

CJam, (削除) 22 (削除ここまで) 20 bytes

Saved 2 bytes thanks to Martin Ender

ri2,{(_(jAb\jAb+:+}j

Straightforward recursive algorithm, nothing fancy. 0-indexed.

Try it online! or test for 0-50 (actually runs pretty fast).

Explanation

ri Read an integer from input
 2, Push the array [0 1]
 { }j Recursive block, let's call it j(n), using the input as n and [0 1] as base cases
 ( Decrement (n-1)
 _( Duplicate and decrement again (n-2)
 jAb Get the list digits of j(n-2)
 \ Swap the top two elements
 jAb Get the list of digits of j(n-1)
 + Concatenate the lists of digits
 :+ Sum the digits

CJam, 42 bytes

Solution using the repetition. Similar algorithm to Jonathan Allan's solution.

ri_2,1+"[2358DC7A89HHGFDA56B8A9AA]"S*~@*+=

Try it online!

answered Feb 2, 2017 at 19:51
\$\endgroup\$
0
2
\$\begingroup\$

MATL, 15 bytes

lOi:"yyhFYAss]&

Try it online!

lO % Push 1, then 0. So the next generated terms will be 1, 1, 2,... 
i % Input n
:" % Repeat that many times
 yy % Duplicate top two elements in the stack
 h % Concatenate into length-2 horizontal vector
 FYA % Convert to decimal digits. Gives a 2-row matrix
 ss % Sum of all matrix entries
] % End
& % Specify that next function (display) will take only 1 input
 % Implicit display
answered Feb 2, 2017 at 19:56
\$\endgroup\$
2
\$\begingroup\$

Python 2, (削除) 54 (削除ここまで) 46 bytes

f=lambda n:n>2and~-f(n-1)%9+~-f(n-2)%9+2or n>0

Heavily inspired by @ETHproductions' ES6 answer.

Try it online!

answered Feb 2, 2017 at 20:33
\$\endgroup\$
2
\$\begingroup\$

C, 96 bytes

or 61 bytes counting escape codes as 1 byte each

0 indexed. Similar to some of the other answers I am indexing a lookup table of values but I have compressed it into 4 byte chunks. I didn’t bother investigating the mod 24 version because I didn’t think it was as interesting since the others have done so already but let’s face it, C isn’t going to win anyway.

#define a(n) n<3?!!n:2+(15&"\x1\x36\xba\x58\x67\xff\xed\xb8\x34\x96\x87\x88"[(n-3)/2%12]>>n%2*4)

explanation:

#define a(n) // using a preprocessor macro is shorter than defining a function
 n<3?!!n: // when n is less than 3 !!n will give the series 0,1,1,1..., otherwise..
 (n-3)/2%12 // condition the input to correctly index the string...
 "\x1\x36\xba\x58\x67\xff\xed\xb8\x34\x96\x87\x88" // which has the repeating part of the series encoded into 4 bits each number
 // these are encoded 2 less than what we want as all numbers in the series after the third are 2 <= a(n>2) <= 17 which conforms to 0 <= a(n>2) - 2 <= 15
 >>n%2*4 // ensure the data is in the lower 4 bits by shifting it down, n%2 will give either 0 or 1, which is then multiplied by 4
 15& // mask those bits off
 2+ // finally, add 2 to correct the numbers pulled from the string

Try it online!

answered Feb 3, 2017 at 6:51
\$\endgroup\$
1
  • \$\begingroup\$ I do count the escape codes as 1 byte each! Great job \$\endgroup\$ Commented Feb 10, 2017 at 11:16
2
\$\begingroup\$

Japt, (削除) 27 (削除ここまで) 25 bytes

U<2?U:~-ß ́U %9+~-ß ́U %9+2

Try it online!

Saved 2 bytes thanks to ETHproductions.

answered Feb 3, 2017 at 10:44
\$\endgroup\$
1
  • \$\begingroup\$ Hey, thanks for using Japt :-) You can use ´ in place of -- to save two bytes. \$\endgroup\$ Commented Feb 3, 2017 at 14:58
2
\$\begingroup\$

Haskell, 54 bytes

a!b=sum$read.pure<$>([a,b]>>=show)
g=0:scanl(!)1g
(g!!)

Try it online! Usage: (g!!) 12

answered Feb 3, 2017 at 23:12
\$\endgroup\$
2
\$\begingroup\$

Mathematica, 49 bytes

If[#<2,#,Tr[Join@@IntegerDigits[#0/@{#-1,#-2}]]]&

Straightforward recursive definition. Gets pretty slow after a while.

Mathematica, (削除) 79 (削除ここまで) 71 bytes

If[#<3,Sign@#,(9@@LetterNumber@"JJBCEHMLGJHIQQPOMJEFKHJ")[[#~Mod~24]]]&

Hardcoding the periodic pattern. Lightning fast and satisfyingly abusive to Mathematica :) Thanks to JungHwan Min for saving 8 bytes!

answered Feb 2, 2017 at 20:21
\$\endgroup\$
2
  • \$\begingroup\$ For your second code LetterNumber@"JJBCEHMLGJHIQQPOMJEFKHJ" is 8 bytes shorter than 43626804920391712116157158790~IntegerDigits~18. \$\endgroup\$ Commented Feb 9, 2017 at 15:48
  • \$\begingroup\$ you're right! One of these days I'm going to remember LetterNumber.... \$\endgroup\$ Commented Feb 9, 2017 at 18:11
1
\$\begingroup\$

Python 2, 56 bytes

Simple iterative solution.

a,b=0,1
exec'a,b=b,(a%9or a)+(b%9or b);'*input()
print a

Try it online!

Using (a%9or a)+(b%9or b) actually turned out to be shorter than sum(map(int(`a`+`b`)))!

answered Feb 2, 2017 at 20:06
\$\endgroup\$
1
  • \$\begingroup\$ I think you meansum(map(int,a+b)) (can't figure out how to use ` in comments) \$\endgroup\$ Commented Feb 8, 2017 at 20:55
1
\$\begingroup\$

PowerShell, 79 bytes

$b,$c=0,1;for($a=$args[0];$a;$a--){$z=[char[]]"$b$c"-join'+'|iex;$b=$c;$c=$z}$b

Try it online!

Lengthy boring iterative solution that does direct digit-sum calculations each for loop. At the end of the loop, the number we want is in $b, so that's left on the pipeline and output is implicit. Note that if the input is 0, then the loop won't enter since the conditional is false, so $b remains 0.

answered Feb 2, 2017 at 20:20
\$\endgroup\$
1
\$\begingroup\$

Batch, 85 bytes

@set/ax=0,y=1
@for /l %%i in (1,1,%1)do @set/az=x-x/10*9+y-y/10*9,x=y,y=z
@echo %x%

I was wondering how I was going to port my JavaScript answer to batch but the clue was in @Dennis's Python solution.

answered Feb 2, 2017 at 20:56
\$\endgroup\$
1
\$\begingroup\$

Pyth, 20 bytes

J,01VQ=+JssjRT>2J)@J

A program that takes input of a zero-indexed integer and prints the result.

Test suite (First part for formatting)

How it works

[Explanation coming later]

answered Feb 2, 2017 at 22:26
\$\endgroup\$
1
\$\begingroup\$

Ruby, 58 bytes

->n{n<3?n<=>0:"9aa2358dc7a89hhgfda56b8a"[n%24].to_i(18)}

The simple hardcoded solution.

answered Feb 3, 2017 at 9:41
\$\endgroup\$
1
\$\begingroup\$

stacked, 40 bytes

{!2:>[:$digitsflatmap sum\last,円]n*last}

This lambda is equivalent to the following lambda:

{n : 2:>[:$digitsflatmap sum\last,円]n*last}

Try it online!

answered Feb 5, 2017 at 15:47
\$\endgroup\$
1
\$\begingroup\$

Octave, 148 bytes

function f = fib(n)
 if (n <= 1)
 f = n;
 else
 f = sum(int2str((fib(n - 1)))-48) + sum(int2str((fib(n - 2)))-48);
 endif
endfunction
answered Feb 6, 2017 at 0:58
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to ppcg! Nice first post! \$\endgroup\$ Commented Feb 6, 2017 at 1:31
1
\$\begingroup\$

Haskell, 151 bytes

import Numeric
import Data.Char
s i=foldr(\c i->i+digitToInt c)0$showInt i""
d a b=a:d b(s a+s b)
f 0=0
f 1=1
f 2=1
f i=d 2 3!!fromIntegral(mod(i-3)24)

Invoke the function with f 123456789012345678901234567890123456789012345678, for example.

The code works also with very big indices. Because of the implemented modulo 24 functionality it is very fast.

The uncompressed code:

-- FibonacciDigital
-- Gerhard
-- 13 February 2017
module FibonacciDigital () where
import Numeric
import Data.Char
-- sum of digits
digitSum :: Int -> Int 
digitSum i = foldr (\c i -> i + digitToInt c) 0 $ showInt i ""
-- fibonacci digital sequence function with arbitrary starting values
fibonacciDigitals :: Int -> Int -> [Int]
fibonacciDigitals a b = a : fibonacciDigitals b (digitSum a + digitSum b)
-- index -> fibonacci digital value
f :: Integer -> Int 
f 0 = 0 
f 1 = 1 
f 2 = 1 
f i = fibonacciDigitals 2 3 !! fromIntegral (mod (i-3) 24) 
-- End
answered Feb 13, 2017 at 3:27
\$\endgroup\$
1
\$\begingroup\$

Vyxal 2, 7 bytes

≬"Ṡ∑k≈Ḟ

Try it Online!

answered Sep 16, 2022 at 17:52
\$\endgroup\$
1
\$\begingroup\$

J-uby, 24 bytes

(:digits|:sum)**:++[0,1]

Uses the ** operator which is absent in the latest version of J-uby; I've restored it in the header on ATO.

Attempt This Online!

answered Mar 21, 2024 at 16:20
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -MList::Util=sum -p, 53 bytes

($,円$b)=($b|0,sum($b=~/./g,$\=~/./g)||1);$_--&&redo}{

Try it online!

answered Mar 21, 2024 at 20:14
\$\endgroup\$
3
  • \$\begingroup\$ Nice, I've had a little play, but I keep generating the wrong answer so I need to have a look at this later again! I think you can save the |0 using $- though! \$\endgroup\$ Commented Mar 22, 2024 at 9:33
  • \$\begingroup\$ Oh, noticed another few bytes too if you combine $\ and $b ($-) into a string and split them both into chars: Try it online! \$\endgroup\$ Commented Mar 22, 2024 at 13:22
  • \$\begingroup\$ 2 more bytes if you require 1-indexing instead and use while$_--: Try it online! \$\endgroup\$ Commented Mar 22, 2024 at 13:33
0
\$\begingroup\$

R, 90 bytes

A horribly long solution, but it's better than the 108 I originally had. I suspect that there is a lot better way to do this, but I can't see it at the moment.

function(n,x=0:1){repeat`if`(n,{x=c(x,sum(scan(t=gsub('',' ',x))))[-1];n=n-1},break);x[1]}

This is an unnamed function that uses gsub and scan(t= to split the numbers in the vector into digits. The sum of these is added to the vector while the first item is dropped. repeat is used to step through the sequence n times and the result is the first item of the vector.

answered Feb 3, 2017 at 0:51
\$\endgroup\$
0
\$\begingroup\$

PHP, 80 Bytes

for($r=[0,1];$i<$argn;)$r[]=array_sum(str_split($r[$i].$r[++$i]));echo$r[$argn];

Online Version

answered Apr 29, 2017 at 13:09
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 67 bytes

r=IntegerDigits;f@0=0;f@1=1;f[x_]:=f@x=Tr@r@f[x-1]+Tr@r@f[x-2];f@#&
Riker
7,9084 gold badges39 silver badges73 bronze badges
answered May 19, 2017 at 2:28
\$\endgroup\$
0
\$\begingroup\$

Fig, \8ドル\log_{256}(96)\approx\$ 6.585 bytes

Gr2'+SxS

Try it online!

Beats Jelly for once.

Gr2'+SxS
G # Generate an infinite list using the initial terms...
 r2 # [0, 1]
 ' # And the generating function...
 Sx # Digit sum of first number
 S # Digit sum of second number
 + # Add the sums
answered Sep 16, 2022 at 14:15
\$\endgroup\$
1
2

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.