Your Task:
Write a program or function to check if a number that is inputted is a Fibonacci number. A Fibonacci number is a number contained in the Fibonacci sequence.
The Fibonacci Sequence is defined as:
F(n) = F(n - 1) + F(n - 2)
With the seeds being F(0) = 0
and F(1) = 1
.
Input:
A non-negative integer between 0 and 1,000,000,000 that may or may not be a Fibonacci number.
Output:
A truthy/falsy value indicating whether or not the input is a Fibonacci number.
Examples:
0-->truthy
1-->truthy
2-->truthy
12-->falsy
Scoring:
This is code-golf, lowest byte count wins.
-
8\$\begingroup\$ The programming language I'm using only supports numbers up to 9999 (Geometry Dash). Is it okay if I assume that it does support numbers up to 1000000, theoretically? \$\endgroup\$MilkyWay90– MilkyWay902019年01月26日 17:51:28 +00:00Commented Jan 26, 2019 at 17:51
71 Answers 71
Neim, 2 bytes
fi
Explanation:
f Push an infinite fibonacci list
i Is the input in that list?
Works the same as my It's Hip to be Square answer, but uses a different infinite list: f
, for fibonacci.
-
1\$\begingroup\$ Wow! Impressive score. \$\endgroup\$Gryphon– Gryphon2017年06月14日 17:01:21 +00:00Commented Jun 14, 2017 at 17:01
-
2\$\begingroup\$ That's great, but not 2 bytes. In UTF-8 it's represented as "66 F0 9D 95 9A" \$\endgroup\$sm4rk0– sm4rk02017年06月16日 14:05:30 +00:00Commented Jun 16, 2017 at 14:05
-
12\$\begingroup\$ @sm4rk0 That's great, but you're wrong. Neim uses a custom codepage, so the byte representation of this is
66 D5
\$\endgroup\$Okx– Okx2017年06月16日 15:06:26 +00:00Commented Jun 16, 2017 at 15:06 -
\$\begingroup\$ Doesn't this loop forever if the input is not in the list? If so, does that count as falsey? \$\endgroup\$Enrico Borba– Enrico Borba2017年06月16日 15:09:28 +00:00Commented Jun 16, 2017 at 15:09
-
\$\begingroup\$ @EnricoBorba Neim knows that the nth element in this infinite list will always be equal to or less than the n+1th element in the list. Therefore, it can catch itself and it will not run forever. Have you tried the program it? :P \$\endgroup\$Okx– Okx2017年06月16日 15:12:21 +00:00Commented Jun 16, 2017 at 15:12
Regex (ECMAScript), (削除) 392 (削除ここまで) (削除) 358 (削除ここまで) (削除) 328 (削除ここまで) (削除) 224 (削除ここまで) (削除) 206 (削除ここまで) (削除) 165 (削除ここまで) (削除) 164 (削除ここまで) (削除) 162 (削除ここまで) 161 bytes
-1 byte by using ECMAScript non-participating capture group behavior
-2 bytes by by calculating \$F_{2n+3}\$ differently
-1 byte by moving around a remainder
The techniques that need to come into play to match Fibonacci numbers with an ECMAScript regex (in unary) are a far cry from how it's best done in most other regex flavors. The lack of forward/nested backreferences or recursion means that it is impossible to directly count or keep a running total of anything. The lack of lookbehind makes it often a challenge even to have enough space to work in.
Many problems must be approached from an entirely different perspective, and seem unsolvable until the arrival of some key insight. It forces you to cast a much wider net in finding which mathematical properties of the numbers you're working with might be able to be used to make a particular problem solvable.
In March 2014, this is what happened for Fibonacci numbers. Looking at the Wikipedia page, I initially couldn't figure out a way, though one particular property seemed tantalizingly close. Then the mathematician teukon outlined a method that made it quite clear it would be possible to do, using that property along with another one. He was reluctant to actually construct the regex. His reaction when I went ahead and did it:
You're crazy! ... I thought you might do this.
As with my other ECMAScript unary math regex posts, I'll give a warning: I highly recommend learning how to solve unary mathematical problems in ECMAScript regex. It's been a fascinating journey for me, and I don't want to spoil it for anybody who might potentially want to try it themselves, especially those with an interest in number theory. See that post for a list of consecutively spoiler-tagged recommended problems to solve one by one.
So do not read any further if you don't want some unary regex magic spoiled for you. If you do want to take a shot at figuring out this magic yourself, I highly recommend starting by solving some problems in ECMAScript regex as outlined in that post linked above.
The challenge I initially faced: A positive integer x is a Fibonacci number if and only if 5x2 + 4 and/or 5x2 - 4 is a perfect square. But there is no room to calculate this in a regex. The only space we have to work in is the number itself. We don't even have enough room to multiply by 5 or take the square, let alone both.
teukon's idea on how to solve it (originally posted here):
The regex is presented with a string of the form
^x*$
, let z be its length. Check whether or not z is one of the first few Fibonacci numbers by hand (up to 21 should do). If it is not:
- Read a couple of numbers, a Use forward look-aheads to build a2, ab, and b2.
- Assert that either 5a2 + 4 or 5a2 - 4 is a perfect square (so a must be Fn-1 for some n).
- Assert that either 5b2 + 4 or 5b2 - 4 is a perfect square (so b must be Fn).
- Check that z = F2n+3 or z = F2n+4 by using the earlier built a2, ab, and b2, and the identities:
- F2n-1 = Fn2 + Fn-12
- F2n = (2Fn-1 + Fn)Fn
In brief: these identities allow us to reduce the problem of checking that a given number is Fibonacci to checking that a pair of much smaller numbers are Fibonacci. A little algebra will show that for large enough n (n = 3 should do), F2n+3 > Fn + 5Fn2 + 4 so there should always be enough space.
And here is a mockup of the algorithm in C which I wrote as a test before implementing it in regex. My final golfed regex is rather different. There turned out to be no need to find both \$a\$ and \$b\$, because \$b\$ is the Lucas number \$L_n\$, which along with \$F_n\$ can be used to derive \$F_{2n+2}\$ and \$F_{2n+3}\$ as needed:
- \${L_n}^2 = 5{F_n}^2±4\$
- \$L_{2n} = ({5{F_n}^2 + {L_n}^2}) / 2 = 5{F_n}^2±2 = {L_n}^2∓2\$
- \$F_{2n} = L_n F_n\$
- \$F_{2n+1} = ({L_{2n} + F_{2n}})/2\$
- \$F_{2n+2} = F_{2n} + F_{2n+1}\$
- \$F_{2n+3} = F_{2n+1} + F_{2n+2}\$
So with no further ado, here is the regex:
^(?=(x*).*(?=x{4}(x{5}(1円{5}))(?=2円*$)3円+$)(|x{4})(?=xx(x*)5円)4円(x(x*))(?=(6円*)7円+$)(?=6円*$8円)6円*(?=x1円7円+$)(x*)(9円x?)|)(9円10円(5円10円)12円?|xx?x?|x{5}|x{8}|x{21})$
And the pretty-printed, commented version:
^ # tail = N = input number
(?=
(x*) # 1円+1 = potential number for which 5*(1円+1)^2 ± 4 is a
# perfect square; this is true iff 1円+1 is a Fibonacci number,
# which we shall call F_n. Outside the surrounding lookahead
# block, 1円+1 is guaranteed to be the largest number for which
# this is true such that 1円 + 5*(1円+1)^2 + 4 <= N.
.*
(?= # tail = (1円+1) * (1円+1) * 5 + 4
x{4}
( # 2円 = (1円+1) * 5
x{5}
(1円{5}) # 3円 = 1円 * 5
)
(?=2円*$)
3円+$
)
(|x{4}) # 4円 = parity - determined by whether the index of Fibonacci
# number 1円+1 is odd or even;
(?=
xx # tail = arithmetic mean of (1円+1) * (1円+1) * 5 and 6円 * 6円
# = ((F_n * F_n * 5) + (L_n * L_n)) / 2 = L_{2n}
(x*)5円 # 5円 = floor(tail / 2) = floor(L_{2n} / 2)
)
4円
# require that the current tail is a perfect square
(x(x*)) # 6円 = potential square root, which will be the square root
# after the following two lookaheads; 7円 = 6円-1
(?=(6円*)7円+$) # 8円 = must be zero for 6円 to be a valid square root
(?=6円*$8円)
# 6円 is now the Lucas number L_n corresponding to the Fibonacci number F_n.
6円*
(?=x1円7円+$) # tail = F_{2n} = L_n * F_n = 6円 * (1円+1), where 6円 is larger
(x*)(9円x?) # 9円 = floor(tail / 2);
# 10円 = ceil(tail / 2); the remainder tail % 2 will always be
# the same as the remainder discarded by 5,円 because
# F_{2n} is odd iff L_{2n} is odd, thus this ceil()
# can complement the floor() of 5円 when adding 5円 + 10円
| # Allow everything above to be skipped, resulting in all
# capture groups being unset.
)
(
# Note that if the above was skipped using the empty alternative in the lookahead,
# the following will evaluate to 0. This relies on ECMAScript NPCG behavior.
9円10円(5円10円) # 12円 = F_{2n+1} = (L_{2n} + F_{2n})/2 = 5円 + 10円;
# head = F_{2n+2} = F_{2n} + F_{2n+1}
# = 9円+10円 + 12円
12円? # head = F_{2n+3} = F_{2n+2} + F_{2n+1} (optionally)
# = head + 12円
|
xx?x?|x{5}|x{8}|x{21} # The Fibonacci numbers 1, 2, 3, 5, 8, 21 cannot be handled
# by our main algorithm, so match them here; note, as it so
# happens the main algorithm does match 13, so that doesn't
# need to be handled here.
)$
The multiplication algorithm is not explained in those comments, but is briefly explained in a paragraph of my abundant numbers regex post.
I was maintaining six different versions of the Fibonacci regex: four that ratchet from shortest length to fastest speed and use the algorithm explained above, and two others that use a different, much faster but much more lengthy algorithm, which as I found can actually return the Fibonacci index as a match (explaining that algorithm here is beyond the scope of this post, but it's explained in the original discussion Gist). I don't think I would maintain that many very-similar versions of a regex again, because at the time I was doing all my testing in PCRE and Perl, but my regex engine is fast enough that concerns of speed are not as important anymore (and if a particular construct is causing a bottleneck, I can add an optimization for it) – though I'd probably again maintain one fastest version and one shortest version, if the difference in speed were big enough.
The "return the Fibonacci index minus 1 as a match" version (not heavily golfed):
All of the versions are on github with the full commit history of golf optimizations:
regex for matching Fibonacci numbers - short, speed 0.txt (the shortest but slowest one, as in this post)
regex for matching Fibonacci numbers - short, speed 1.txt
regex for matching Fibonacci numbers - short, speed 2.txt
regex for matching Fibonacci numbers - short, speed 3.txt
regex for matching Fibonacci numbers - fastest.txt
regex for matching Fibonacci numbers - return index.txt
-
1\$\begingroup\$ Amazing! At first, I didn't even know that regular expressions could do math! \$\endgroup\$Eric Xue– Eric Xue2022年07月19日 17:11:37 +00:00Commented Jul 19, 2022 at 17:11
JavaScript (ES6), 34 bytes
f=(n,x=0,y=1)=>x<n?f(n,y,x+y):x==n
Recursively generates the Fibonacci sequence until it finds an item greater than or equal to the input, then returns item == input.
-
\$\begingroup\$ NB: naive recursive calculation of the Fibonacci sequence is O(Fib(n)) - approximately O(1.6 ^ n) \$\endgroup\$Alnitak– Alnitak2017年06月16日 08:47:27 +00:00Commented Jun 16, 2017 at 8:47
Retina, 23 bytes
^$|^(^1|(?>2円?)(1円))*1$
Input in unary, outputs 0
or 1
.
Explanation
The Fibonacci sequence is a good candidate for a solution with forward references, i.e. a "backreference" that refers either to a surrounding group or one that appears later in the regex (in this case, we're actually using both of those). When matching numbers like this, we need to figure out a recursive expression for the difference between sequence elements. E.g. to match triangular numbers, we usually match the previous segment plus one. To match square numbers (whose differences are the odd numbers), we match the previous segment plus two.
Since we obtain the Fibonacci numbers by adding the second-to-last element to the last one, the differences between them are also just the Fibonacci numbers. So we need to match each segment as the sum of the previous two. The core of the regex is this:
( # This is group 1 which is repeated 0 or more times. On each
# iteration it matches one Fibonacci number.
^1 # On the first iteration, we simply match 1 as the base case.
| # Afterwards, the ^ can no longer match so the second alternative
# is used.
(?>2円?) # If possible, match group 2. This ends up being the Fibonacci
# number before the last. The reason we need to make this optional
# is that this group isn't defined yet on the second iteration.
# The reason we wrap it in an atomic group is to prevent backtracking:
# if group 2 exists, we *have* to include it in the match, otherwise
# we would allow smaller increments.
(1円) # Finally, match the previous Fibonacci number and store it in
# group 2 so that it becomes the second-to-last Fibonacci number
# in the next iteration.
)*
Now this ends up adding the Fibonacci numbers starting at 1, i.e. 1, 1, 2, 3, 5, .... Those add up to 1, 2, 4, 7, 12, .... I.e. they are one less than the Fibonacci numbers, so we add a 1
at the end. The only case this doesn't cover is zero, so we have the ^$
alternative at the beginning to cover that.
-
4\$\begingroup\$ Very elegant! I'd just like to point out, for completeness's sake, that it can be shortened to 20 bytes in PCRE using a possessive quantifier:
^$|^(^1|2円?+(1円))*1$
\$\endgroup\$Deadcode– Deadcode2019年01月21日 19:47:51 +00:00Commented Jan 21, 2019 at 19:47 -
1\$\begingroup\$ @Deadcode I do miss those a lot in .NET ;) \$\endgroup\$Martin Ender– Martin Ender2019年01月21日 22:30:21 +00:00Commented Jan 21, 2019 at 22:30
-
\$\begingroup\$ Save 1 byte by removing the unnecessary second
^
. \$\endgroup\$Neil– Neil2019年02月08日 01:08:17 +00:00Commented Feb 8, 2019 at 1:08 -
\$\begingroup\$ @Neil That doesn't work because then it would match the
1
at the end of every non-Fibonacci number by doing zero iterations of the loop. \$\endgroup\$Deadcode– Deadcode2021年03月20日 23:30:08 +00:00Commented Mar 20, 2021 at 23:30 -
\$\begingroup\$ Ah, yes, and the fix for that ends up costing that byte. Oh well. \$\endgroup\$Neil– Neil2021年03月21日 00:46:17 +00:00Commented Mar 21, 2021 at 0:46
-
1\$\begingroup\$ Being Python should it not work, given enough resources, for arbitrarily large inputs? \$\endgroup\$Jonathan Allan– Jonathan Allan2017年06月14日 17:49:09 +00:00Commented Jun 14, 2017 at 17:49
-
2\$\begingroup\$ I always had the impression we could use whatever algorithm we wanted as long, as it works in practice if the calculations fits in the data type and in theory given infinite precision. Sure, using only
int
would set the bar higher (still not arbitrarily large), but we also don't force C answers to use 64-bit integers (or 128-bit with gcc). At any rate, being allowed to use the same algorithm in one language but not another seems nonsensical. \$\endgroup\$Dennis– Dennis2017年06月15日 04:34:38 +00:00Commented Jun 15, 2017 at 4:34 -
\$\begingroup\$ The algorithmic view does make sense (I had always thought it was the input domain that dictated the "fit in data type" criteria). The only thing to watch for is the grey area between what is the idea of the algorithm and its implementation. Here one could check if either of the integers are square without casting to floats. I guess that an internal cast as a side-effect is acceptable so long as it is part of a legitimate, working algorithm (...and I'm pretty sure an algorithm that relied on the cast would not be acceptable). \$\endgroup\$Jonathan Allan– Jonathan Allan2017年06月15日 05:03:17 +00:00Commented Jun 15, 2017 at 5:03
-
\$\begingroup\$ @JonathanAllan Since the maximum value to handle is 1e9, I dont think arbitrarily large inputs would be a problem. \$\endgroup\$JAD– JAD2017年06月16日 13:24:40 +00:00Commented Jun 16, 2017 at 13:24
-
1\$\begingroup\$ @JarkoDubbeldam yes, that detail was actually changed after my comment was made. \$\endgroup\$Jonathan Allan– Jonathan Allan2017年06月16日 13:28:05 +00:00Commented Jun 16, 2017 at 13:28
Python 2, (削除) 48 (削除ここまで) 44 bytes
f=lambda n,a=0,b=1:n>a and f(n,b,a+b)or n==a
Thanks to Jonathan Allan for saving 4 bytes
-
\$\begingroup\$ This can be 47 bytes, if truthy values can be
False
and falsy valuesTrue
: TIO! \$\endgroup\$Mr. Xcoder– Mr. Xcoder2017年06月14日 17:20:45 +00:00Commented Jun 14, 2017 at 17:20 -
\$\begingroup\$ Could also use
n-a
in place ofn==a
and have -1 and 0 as your return values. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2017年06月14日 18:06:26 +00:00Commented Jun 14, 2017 at 18:06 -
\$\begingroup\$ @carusocomputing I had that in my edit history, but it doesn't work, because for larger test values, you might have
-101
or some other result instead of-1
. \$\endgroup\$mbomb007– mbomb0072017年06月14日 21:47:16 +00:00Commented Jun 14, 2017 at 21:47 -
\$\begingroup\$ @Mr.Xcoder do you really think that saving 1 byte is worth everybody's sanity? \$\endgroup\$frarugi87– frarugi872017年06月16日 14:23:17 +00:00Commented Jun 16, 2017 at 14:23
-
1\$\begingroup\$ @frarugi87 Saving a byte is always worth it \$\endgroup\$Mr. Xcoder– Mr. Xcoder2017年06月16日 14:25:10 +00:00Commented Jun 16, 2017 at 14:25
05AB1E, (削除) 8 (削除ここまで) 7 bytes
>ÅF1å1m
Explanation:
>ÅF # Generate Fibbonacci numbers up to n+1
1å # 0 if original isn't in the list, 1 if it is
1m # 0**0 = 1 if input was 0 (hotfix for 0).
# or 0**n if not fibb / 1**n if it is a fibb.
-1 thanks to Jonathan Allan for the 0-not-a-fibonacci-number workaround.
-
\$\begingroup\$ Actually, won't be updating to 6 bytes. Can't believe there's NO way to append a 0 to a list in under 3 bytes. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2017年06月14日 17:24:26 +00:00Commented Jun 14, 2017 at 17:24
-
\$\begingroup\$ @JonathanAllan the "generate fibbonacci function" in 05AB1E doesn't contain 0. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2017年06月14日 18:56:03 +00:00Commented Jun 14, 2017 at 18:56
-
\$\begingroup\$ @JonathanAllan I understand now, nice idea. Took me a minute to figure out what was actually happening there. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2017年06月14日 19:04:32 +00:00Commented Jun 14, 2017 at 19:04
-
\$\begingroup\$ Isn't it enough to generate upto
n
(saving a byte) asÅF
is inclusive and¹å
would result in0
either way forn=0
? \$\endgroup\$Emigna– Emigna2017年06月15日 10:19:26 +00:00Commented Jun 15, 2017 at 10:19 -
\$\begingroup\$ 0AF = []. 1AF = [1,1]. So apparently not. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2017年06月15日 13:26:26 +00:00Commented Jun 15, 2017 at 13:26
-
\$\begingroup\$
{(0,1,*+*...^*>$_).tail==$_}
was what I was going to initially post. I may have gotten around to Set operators eventually. \$\endgroup\$Brad Gilbert b2gills– Brad Gilbert b2gills2017年06月14日 17:36:15 +00:00Commented Jun 14, 2017 at 17:36
Seriously, 3 bytes
,fu
Returns the index +1 in the list of Fibonacci numbers if truthy, otherwise returns falsy.
Explanation:
,fu
, read input
f 0-indexed index of that number in the fibonacci sequence (-1 if not in the sequence)
u increment. (Makes the -1 value falsy and the 0-value truthy)
-
14\$\begingroup\$ Seriously rude ^^ \$\endgroup\$Jonathan Allan– Jonathan Allan2017年06月14日 18:01:44 +00:00Commented Jun 14, 2017 at 18:01
Jelly, (削除) 8 7 (削除ここまで) 6 bytes
-r‘ÆḞċ
How?
-r‘ÆḞċ - Link: non negative number, n
- - literal -1 = -1
r - inclusive range = [-1,0,1,2,3,4,5,...,n]
‘ - increment n = [ 0,1,2,3,4,5,6,...,n+1]
ÆḞ - Fibonacci = [ 0,1,1,2,3,5,8,...,fib(n+1)]
ċ - count occurrences of n (1 if n is a Fibonacci number, 0 otherwise)
Notes:
- the increment,
‘
, is needed so this works for 2 and 3, since they are the 3rd and 4th Fibonacci numbers - beyond 3 all Fibonacci numbers are greater than their index. - the
-
is needed (rather than just‘R
) so this works for 0 since 0 is the 0th Fibonacci number;
-
\$\begingroup\$ Umm, this looks too much like my answer... \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年06月14日 17:20:56 +00:00Commented Jun 14, 2017 at 17:20
-
\$\begingroup\$ Oh, I golfed mine down to yours, except mine works for
3
:) \$\endgroup\$Jonathan Allan– Jonathan Allan2017年06月14日 17:22:04 +00:00Commented Jun 14, 2017 at 17:22 -
\$\begingroup\$ Oh whoops...Fibonacci is weird. (btw deleted my answer then if u say so) \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年06月14日 17:26:11 +00:00Commented Jun 14, 2017 at 17:26
-
\$\begingroup\$ Are you sure about that last note? When I run the Fibonacci atom on a list starting from 0, 0 is included in the output. \$\endgroup\$Christian Legge– Christian Legge2017年06月14日 18:08:47 +00:00Commented Jun 14, 2017 at 18:08
-
1\$\begingroup\$ It doesn't appear to be relevant based on the wording of the challenge, but if you use the count atom with 1 as your argument on the list of Fibonacci numbers the result is 2 (not 1). \$\endgroup\$FryAmTheEggman– FryAmTheEggman2017年06月14日 18:55:51 +00:00Commented Jun 14, 2017 at 18:55
ZX81 BASIC (削除) 180 (削除ここまで) (削除) 151 (削除ここまで) (削除) 100 (削除ここまで) ~94 tokenized BASIC bytes
With thanks to Moggy on the SinclairZXWorld forums, here is a much neater solution that saves more bytes.
1 INPUT I
2 FOR F=NOT PI TO VAL "1E9"
3 LET R=INT (VAL ".5"+(((SQR VAL "5"+SGN PI)/VAL "2")**I)/SQR VAL "5")
4 IF R>=I THEN PRINT F=R
5 IF R<I THEN NEXT F
This will output 1 if a Fibonacci number is entered, or zero if not. Although this saves bytes, it's much slower than the old solutions below. For speed (but more BASIC bytes) remove the VAL
wrappers around the string literal numbers. Here is the old(er) solutions with some explanations:
1 INPUT A$
2 LET A=SGN PI
3 LET B=A
4 LET F=VAL A$
5 IF F>SGN PI THEN FOR I=NOT PI TO VAL "1E9"
6 LET C=A+B
7 LET A=B
8 LET B=C
9 IF B>=F THEN GOTO CODE "£"
10 IF F THEN NEXT I
12 PRINT STR$(SGN PI*(B=F OR F<=SGN PI)) AND F>=NOT PI;"0" AND F<NOT PI
The amendments above saves further BASIC bytes to condensing the IF
statements into a single PRINT
in line 12; other bytes were saved by using the VAL
keyword and, and using GOTO CODE "£"
, which in the ZX81 character set is 12. Strings save more bytes over numbers as all numeric values are stored as floats so therefore take more space on the VAR stack.
-
\$\begingroup\$ Actually, I could save another 6 tokenized BASIC bytes by removing line 6 altogether and changing line 5 to
5 IF R<F THEN NEXT I
- my bad! \$\endgroup\$Shaun Bebbers– Shaun Bebbers2019年02月04日 23:56:00 +00:00Commented Feb 4, 2019 at 23:56
C#, 109 bytes
bool f(int n){int[]i=new[]{0,1,0};while(i[0]<n||i[1]<n){i[i[2]%2]=i[0]+i[1];i[2]++;}return n==i[0]||n==i[1];}
Definitely could be improved, but I didn't have time.
-
\$\begingroup\$ Welcome to PPCG! \$\endgroup\$Martin Ender– Martin Ender2017年06月14日 19:36:16 +00:00Commented Jun 14, 2017 at 19:36
-
1\$\begingroup\$ I wrote my own answer only to realize that it was the same as yours. You can use lambda expressions and simple variables to get this:
n=>{int a=0,b=1,c=0;while(a<n&b<n)if(++c%2>0)a=a+b;else b=a+b;return a==n|b==n;}
(just 80 bytes). Try it online! \$\endgroup\$Charlie– Charlie2017年06月14日 20:08:31 +00:00Commented Jun 14, 2017 at 20:08 -
1\$\begingroup\$ @CarlosAlejo Save a further 2 bytes on that with
a+=b
instead ofa=a+b
andb+=a
instead ofb=a+b
. \$\endgroup\$TheLethalCoder– TheLethalCoder2017年06月15日 08:18:19 +00:00Commented Jun 15, 2017 at 8:18 -
\$\begingroup\$ -1 bytes: replace
int[]i
withvar i
\$\endgroup\$Eric Xue– Eric Xue2022年07月19日 17:15:38 +00:00Commented Jul 19, 2022 at 17:15
><>, (削除) 21 (削除ここまで) 19+3 = (削除) 24 (削除ここまで) 22 bytes
i1\{=n;
?!\:@+:{:}(
Input is expected to be on the stack at program start, so +3 bytes for the -v
flag.
This works by generating Fibonacci numbers until they are greater than or equal to the input number, then checking the last generated number for equality with the input. Outputs 1
if it was a Fibonacci number, 0
otherwise.
To ensure that 0
is handled correctly, the seed is -1 1
- the first number generated will be 0
rather than 1
.
Thanks to @cole for pointing out that i
can be used to push -1
onto the stack when STDIN is empty. Very clever!
Previous version:
01-1\{=n;
}(?!\:@+:{:
-
\$\begingroup\$ Now I feel stupid for wasting bytes continuously checking each generated number along the way. Nicely done! \$\endgroup\$Emigna– Emigna2017年06月16日 08:56:19 +00:00Commented Jun 16, 2017 at 8:56
-
1
-
\$\begingroup\$ @cole of course, using
i
as-1
when there is no input to STDIN, I'd not considered that. Nicely done! \$\endgroup\$Sok– Sok2018年01月21日 22:54:36 +00:00Commented Jan 21, 2018 at 22:54
Mathematica, 37 bytes
!Fibonacci@n~Table~{n,0,#+1}~FreeQ~#&
-4 bytes from @ngenisis
-
\$\begingroup\$
Fibonacci[0]
gives0
, so you can save4
bytes by including0
in theTable
range. You can save another byte using infix notation forTable
:!Fibonacci@n~Table~{n,0,#+1}~FreeQ~#&
\$\endgroup\$user61980– user619802017年06月14日 18:55:11 +00:00Commented Jun 14, 2017 at 18:55
MATL (16 bytes)
2^5*4-t8+hX^tk=s
Not the golfiest solution, but wanted to use the direct method of checking if "5*x^2+/-4" is a perfect square.
Explanation:
2^5* % 5 times the input squared
4- % push the above minus 4
t8+ % push the above plus 8 (+4 overall)
hX^ % concatenate them into an array and then take the sqrt().
tk % push a copy of the array that is rounded using floor().
= % test if the sqrt's were already integers
s % sum the results, returns 0 if neither was a perfect square.
Note:
In the "0" case it returns "2" because both 4 and -4 are perfect squares, same with 1 which produces "1 1". Consider any non-zero output as "truthy", and 0 as "falsy".
PHP, 44 bytes
for(;0>$s=$x-$argn;)$x=+$y+$y=$x?:1;echo!$s;
PHP, 58 bytes
for($x=0,$y=1;$x<$argn;$x=$y,$y=$t)$t=$x+$y;echo$x==$argn;
-
2\$\begingroup\$ Golfed more:
for(;0>$s=$x-$argn;)$x=+$y+$y=$x?:1;echo!$s;
. \$\endgroup\$user63956– user639562017年06月15日 03:43:57 +00:00Commented Jun 15, 2017 at 3:43 -
\$\begingroup\$ @user63956 Thank You for the learning effort with the chaining variables assignment \$\endgroup\$Jörg Hülsermann– Jörg Hülsermann2017年06月15日 10:45:33 +00:00Commented Jun 15, 2017 at 10:45
C# (.NET Core), 51 bytes
bool f(int n,int a=0,int b=1)=>a<n?f(n,b,a+b):a==n;
-6 bytes thanks to @Oliver!
This solution uses a pretty straightforward recursive function.
- The variable
n
is the number to be tested. - The variables
a
andb
are the 2 most recent numbers in the sequence. - Checks if the first of the 2 most recent number is less than input. When this is the case, a recursive call is made to the next numbers in the series.
- Otherwise, check whether the first number is equal to input and return the result.
The TIO link demonstrates this working for 1134903170 which exceeds the maximum value required by the challenge.
-
-
\$\begingroup\$ Thanks! And nice tip :) \$\endgroup\$dana– dana2019年01月23日 00:22:08 +00:00Commented Jan 23, 2019 at 0:22
Alchemist, (削除) 205 (削除ここまで) 134 bytes
Big thanks to ASCII-only for rather clever merging of states, saving 71 bytes!!
_->In_x+c+u
u+b->u+a+d
u+0b->v
v+c->v+b+d
v+0c->w
w+a+x->w+y
w+0a+0x->Out_"1"
w+a+0x->Out_"0"
w+0a+x+y->w+2x
w+0a+0y+d->w+c
w+0d+0a->u
Try it online or verify in batch!
Ungolfed
# read input, initialize (c = 1)
_ -> In_x + c + s0
# a,d <- b
s0 + b -> s0 + a + d
s0 + 0b -> s1
# b,d <- c
s1 + c -> s1 + b + d
s1 + 0c -> s2
s2 + a + x -> s2 + y # y <- min(a,x)
s2 + 0a + 0x -> Out_"1" # if (a == x): was Fibonacci
s2 + a + 0x -> Out_"0" # if (a > x): stop (we exceeded target)
s2 + 0a + x + y -> s2 + 2x # if (a < x): x += a (since y = a) / restore x
s2 + 0a + 0y + d -> s2 + c # once that's done; c <- d
s2 + 0a + 0d->s0 # and finally loop
-
\$\begingroup\$ Wip: tio.run/##JcpBCsMgFATQvcfIdhCsB8i@qx5BjD/… \$\endgroup\$ASCII-only– ASCII-only2019年01月29日 11:21:42 +00:00Commented Jan 29, 2019 at 11:21
-
\$\begingroup\$ 139. you can remove some
0
checks for fewer bytes at the cost of nondeterminism \$\endgroup\$ASCII-only– ASCII-only2019年01月30日 06:16:33 +00:00Commented Jan 30, 2019 at 6:16 -
\$\begingroup\$ 129 \$\endgroup\$ASCII-only– ASCII-only2019年01月30日 06:22:48 +00:00Commented Jan 30, 2019 at 6:22
-
\$\begingroup\$ @ASCII-only: That's pretty nice! Fails for 0 though, but not adding the
b
-atom on initialization fixes it (and saves 2 bytes) :D Thanks \$\endgroup\$ბიმო– ბიმო2019年01月31日 15:16:51 +00:00Commented Jan 31, 2019 at 15:16
Java (JDK), 37 bytes
s->s.matches(".?|(\2円?+(\1円|^.))*..")
This works for numbers up to 1,836,311,903 (47th fibonacci number) included. Above that, the result is undefined (including a potential infinite loop).
Credits
- Thanks to Kevin Cruijssen and David Conrad for helping golfing :)
- Thanks to Kevin Cruijssen for porting the regex version, saving 12 bytes in the process!
-
1\$\begingroup\$ Nice approach. Btw, you can golf a byte by changing
n==0
ton<1
. In the question it states "A non-negative integer between 0 and 1,000,000,000". \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2017年06月15日 10:45:13 +00:00Commented Jun 15, 2017 at 10:45 -
1\$\begingroup\$ @KevinCruijssen I golfed not 1, but 5 bytes with that clause! :-P Thanks, I hadn't noticed it. \$\endgroup\$Olivier Grégoire– Olivier Grégoire2017年06月15日 11:12:26 +00:00Commented Jun 15, 2017 at 11:12
-
2\$\begingroup\$ You don't need a temp variable for the Fibonacci sequence. You can calculate successive pairs with
b+=a;a=b-a;
\$\endgroup\$David Conrad– David Conrad2017年06月16日 07:31:02 +00:00Commented Jun 16, 2017 at 7:31 -
1\$\begingroup\$ You're doing black magic, @DavidConrad! I'm telling you! Black magic! :) \$\endgroup\$Olivier Grégoire– Olivier Grégoire2017年06月16日 07:40:51 +00:00Commented Jun 16, 2017 at 7:40
-
1\$\begingroup\$ 37 bytes by taking input as unary and porting the Retina approach:
s->s.matches(".?|(\2円?+(\1円|^.))*..")
(Here an explanation of that regex.) \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2020年05月14日 16:29:08 +00:00Commented May 14, 2020 at 16:29
Vyxal r
, 4 bytes
ÞFce
Try it Online! - show all boolean results
Try it Online! - show only numbers returning truthy
Thanks to Steffan. This based on the alternative 5 byte answer below, removing the need for the $
.
Vyxal, 5 bytes
ÞF0pc
Try it Online! - show all boolean results
Try it Online! - show only numbers returning truthy
ÞF # All 1-indexed Fibonacci numbers as a LazyList.
0p # Prepend the list with 0
c # Is the input contained in the list?
Alternative 5 bytes:
ÞFc$e
Try it Online! - show all boolean results
Try it Online! - show only numbers returning truthy
ÞF # All 1-indexed Fibonacci numbers as a LazyList.
c # Is the input contained in the list?
$ # Swap above result with the input (this creates a copy of the input)
e # Exponentiate. For an input of zero this will yield 0**0 == 1; for other
# Fibonacci numbers, 1**{n>0} == 1; otherwise 0**{n>0} == 0.
The above two solutions work around the fact that there's no 0-indexed version of ÞF
. Alternatively using ∆F
requires a different workaround, but it can also be done in 5 bytes:
Þn∆Fc
Try it Online! - show all boolean results
Try it Online! - show only numbers returning truthy
Þn # All integers in an infinite list (0, 1, -1, 2, -2, ...)
∆F # nth Fibonacci number, 0-indexed
c # Contains - Check if one thing contains another
Using ʀ
(Inclusive range [0..input]) instead of Þn
wouldn't work, because the Fibonacci numbers \2ドル\$ and \3ドル\$ are not members of the lists \$[0,1,1]\$ and \$[0,1,1,2]\$ respectively. It would be necessary to use ›ʀ
(the range [0..input+1]), but for non-Fibonacci numbers that is exponentially slower than using Þn
(and Þn∆Fc
is in turn a bit slower than ÞFc$e
).
Note that Þn
includes negative numbers, and ∆F
on a negative number returns a negative Fibonacci number. However, Þn∆Fc
only returns truthy for nonnegative Fibonacci numbers, probably due to a bug in Vyxal.
Without using any Fibonacci builtins (7 bytes):
k≈(+dḞc
Try it Online! - show all boolean results
Try it Online! - show only numbers returning truthy
The is based on lyxal's answer to Fibonacci function or sequence.
k≈ # the list [0, 1]
(+d # lambda x, y: x + y
Ḟ # Create an infinite sequence based on the function and the initial list.
c # Does the list contain the input?
-
1\$\begingroup\$ 5-byte workaround, just use
v
:ʀv∆Fc
\$\endgroup\$naffetS– naffetS2022年07月09日 21:49:55 +00:00Commented Jul 9, 2022 at 21:49 -
\$\begingroup\$ @Steffan Interesting. That is a direct workaround to the bug using knowledge of its nature. I also found another 5 byte workaround (above). \$\endgroup\$Deadcode– Deadcode2022年07月09日 22:17:30 +00:00Commented Jul 9, 2022 at 22:17
-
1
Jelly, 5 bytes
ȷḶÆḞi
Returns 0 for non-Fibonacci numbers, and the 1-indexed position of the number in the Fibonacci sequence for Fibonacci numbers.
Explanation:
ȷḶÆḞi
ȷ The literal number 1000
Ḷ Range [0,1,...,999]
ÆḞ Get the ith Fib number; vectorizes [1,1,2,3,5,...,<1000th Fib number>]
i Get the first index of element in list, or 0 if not found
R, (削除) 43 (削除ここまで) 40 bytes
pryr::f(x%in%DescTools::Fibonacci(0:45))
pryr::f
creates a function:
function (x)
x %in% DescTools::Fibonacci(0:45)
Uses DescTools::Fibonacci
to create the first x+1
fibonacci numbers and checks for inclusion. x+1
because the third fibnum is 2, and that wouldn't be enough to check for inclusion of 3.
Luckily Desctools::Fibonacci(0)=0
, so that is a nice freebee.
-3 bytes thanks to MickyT
-
\$\begingroup\$
-1:x+1
will save you a byte, but0:45
will save you three and cover the required range \$\endgroup\$MickyT– MickyT2017年06月14日 20:39:53 +00:00Commented Jun 14, 2017 at 20:39 -
\$\begingroup\$ @MickyT Oh, I must've overlooked the required range specification. Thanks :) \$\endgroup\$JAD– JAD2017年06月14日 20:42:37 +00:00Commented Jun 14, 2017 at 20:42
-
\$\begingroup\$ An alternative approach, only 36 bytes:
pryr::f(any(!(5*n^2+c(-4,4))^.5%%1))
. \$\endgroup\$rturnbull– rturnbull2017年06月16日 08:12:26 +00:00Commented Jun 16, 2017 at 8:12 -
-
\$\begingroup\$ I'm not so familiar with code golf rules -- does allowing non-base packages make sense? I could write arbitrary R code into a package, install it, and run it the same way you have run the function from
pryr
. \$\endgroup\$mb7744– mb77442017年06月16日 12:58:07 +00:00Commented Jun 16, 2017 at 12:58
Haskell, 31 bytes
f=0:scanl(+)1f
(`elem`take 45f)
Try it online! This exploits the fact that the input will be in the range from 0 to 1,000,000,000, hence we need to check only the first 45 Fibonacci numbers. f=0:scanl(+)1f
generates an infinite list of Fibonacci numbers, take 45f
is the list of the first 45 Fibonacci numbers and elem
checks whether the input is in this list.
Unrestricted version: 36 bytes
f=0:scanl(+)1f
g n=n`elem`take(n+3)f
Try it online! For any n
, taking the first n+3
Fibonacci numbers will guarantee that n
will be in this list if it's a Fibonacci number.
Note that this approach is incredible inefficient for high numbers that are not Fibonacci numbers, because all n+3
Fibonacci numbers need to be computed.
Javascript (ES6 without the ** operator), 44 bytes
f=(x,c=x*(Math.sqrt(5)-1)/2%1)=>x*(c-c*c)<.5
Relies on the ratio between successive Fibonacci numbers approaching the golden ratio. The value of c is the fractional part of the input divided by the golden ratio - if the input is Fibonacci then this will be very close to 1 and the value of c-c2 will be very small.
Not as short as some of the other JS answers but runs in O(1) time.
Julia 0.4, 29 bytes
!m=in(0,sqrt(5*m*m+[4,-4])%1)
If this isn't how you do a Julia answer, let me know. I'm unsure of how input works on TIO.
-
1\$\begingroup\$ You'd have to make it a regular function (counting
!m=
) or a lambda (countingm->
). More importantly, this fails for 0 as is. \$\endgroup\$Dennis– Dennis2017年06月14日 18:55:49 +00:00Commented Jun 14, 2017 at 18:55
R, (削除) 32 (削除ここまで) 31 bytes
Takes input from stdin, returns TRUE
or FALSE
as appropriate.
any(!(5*scan()^2+-1:1*4)^.5%%1)
Common Lisp, (削除) 61 (削除ここまで) 54 bytes
(defun f(x)(do((a 0 b)(b 1(+ a b)))((>= a x)(= a x))))
The reduction in size with respect to the previous version:
(defun f(x)(do((a 0 b)(b 1 c)(c 1(+ b c)))((>= a x)(= a x))))
was triggered by the idea that to generate the sequence of the Fibonacci numbers only two variables are necessary, not three.
D, (削除) 98 (削除ここまで) (削除) 79 bytes (削除ここまで) 77 bytes
-19 bytes: changed square number algorithm (which also had the side effect of not needing import std;
) and realized the non-UFCS way was 1 byte shorter
golfed:
int p(real z){return z^^.5%1==0;}int f(int z){return p(5*z*z+4)||p(5*z*z-4);}
readable:
int p(real z){
return z^^.5%1==0
}
int f(int z){
return p(5*z*z+4)||p(5*z*z-4);
}
where f
is the function that tests if a number is a fibonacci number.
This uses the fact that a positive integer z is a Fibonacci number if and only if one of 5z^2 + 4 or 5z^2 − 4 is a perfect square.
wikipedia
Also real
instead of float
for one less byte, and returning an int
instead of bool
to save another byte (since ints are truthy if they're nonzero, and D implicitly casts expressions to the function's return value if possible, in this case casting a bool to an int).
There's probably some way to avoid having the extra function p
(used to check if a number is a perfect square) but I can't find it out.
edit: replaced z^^2 with z*z
-
\$\begingroup\$ if your
z^^2
meansz^2
you can doz*z
instead i think \$\endgroup\$okie– okie2022年09月28日 05:07:24 +00:00Commented Sep 28, 2022 at 5:07 -
\$\begingroup\$ Presumably just doing the check on both sides of the condition would be shorter than having a whole function? Something like
(5*z*z+4)^^.5%1==0||(5*z*z-4)^^.5%1==0
\$\endgroup\$Jo King– Jo King2023年01月20日 05:05:17 +00:00Commented Jan 20, 2023 at 5:05
Explore related questions
See similar questions with these tags.