Length of a Sumac Sequence
Heavily based on this closed challenge from SE.
Description
A Sumac sequence starts with two non-zero integers $t_1$ and $t_2.$
The next term, $t_3 = t_1 - t_2$
More generally, $t_n = t_{n-2} - t_{n-1}$
The sequence ends when $t_n ≤ 0$. All values in the sequence must be positive.
Challenge
Given two integers $t_1$ and $t_2$, compute the Sumac sequence, and output it's length.
If there is a negative number in the input, remove everything after it, and compute the length.
You may take the input in any way (Array, two numbers, etc.)
Test Cases
(Sequence is included for clarification)
[t1,t2] Sequence n
------------------------------
[120,71] [120,71,49,22,27] 5
[101,42] [101,42,59] 3
[500,499] [500,499,1,498] 4
[387,1] [387,1,386] 3
[3,-128] [3] 1
[-2,3] [] 0
[3,2] [3,2,1,1] 4
Scoring
This is code-golf. Shortest answer in each language wins.
[Raku], 19 bytes {( …
4y ago
[Python 3], 49 47 44 35 bytes …
4y ago
[C (gcc)], 32 bytes …
4y ago
Japt `-N`, 9 bytes ¨T©Ò …
4y ago
[JavaScript (Node.js)], 27 25 …
4y ago
[Scala], 83 bytes x …
3y ago
BQN, 15 bytesSBCS ``` {𝕨(1 …
3y ago
[Jelly], 9 bytes Rȧ@Rп …
4y ago
[JavaScript (Node.js)], 31 byt …
4y ago
9 answers
Scala, 83 bytes
x=>x.init#::Stream.iterate(x)(x=>x++(x,x.tail).zipped.map(_-_))indexWhere(_.last<1)
Takes input as a list of two numbers. The fact that the length can be 0 makes this a bit longer.
x => //List(t1, t2) a.k.a. the second partial sequence
x.init //List(t1) a.k.a. the first partial sequence
#:: //prepended to
Stream //an infinite stream of partial sequences
.iterate(x) //starting with the second partial sequence
(x => //to which this function is repeatedly applied:
x ++ //Concatenate the previous sequence to the next values
(x, x.tail).zipped //Zip the previous sequence and its tail
.map(_-_)) //And subtract each i-1th element from the ith element
indexWhere //Find the index of the sequence where
(_.last<1) //The last element is not positive
0 comment threads
Raku, 19 bytes
{(|@_,*-*...0>*)-1}
{ } # Anonymous code block
... # Create a sequence
|@_ # Starting with the input
,*-* # With each element being the difference between the previous two
0>* # Until it is negative
( )-1 # And return the length of the list minus one
0 comment threads
Python 3, 49 47 44 35 bytes
a=lambda x,y:+(x>=0)and(1+a(y,x-y))
-3 bytes thanks to @Hakerh400
-9 bytes thanks to @Jo King
Python 2, 50 bytes
x,y=input()
a=0
while x>0:x,y,a=y,x-y,a+1
print(a)
An alternate solution I also came up with that I swear I should be able to make shorter, but can't think of it currently.
BQN, 15 bytesSBCS
{𝕨(1+⊢𝕊-)⟜𝕩⍟>0}
A block function that takes $t_1$ as the left argument 𝕨
and $t_2$ as the right argument 𝕩
. In BQN, 𝕊
indicates recursion on the current block function. Inside the function the idea is just to return 0 if 𝕨≤0
and otherwise advance the sequence by one, recurse, and add one to the resulting sequence length.
{𝕨(1+⊢𝕊-)⟜𝕩⍟>0}
0 # Default result of 0
𝕨 ⍟> # If 𝕨>0:
( )⟜𝕩 # Use 𝕩 as right arg (left is still 𝕨)
⊢ - # Right argument ⊢ and difference -
𝕊 # Recurse
1+ # Add one
The unrelated 0s for sequence length and minimum 𝕨
are combined by making 0 the right argument and using Repeat (⍟
). With 0 repetitions, Repeat will return the right argument 0, and with 1 repetition, it will call the operand function, which immediately replaces 0 with 𝕩
using After (𝕩
is a number, so it acts as a constant function).
0 comment threads
Jelly, 9 bytes
Rȧ_@Rп@L
Takes $t_1$ on the left and $t_2$ on the right. R}ȧ_@RпL
works given the arguments in the opposite order.
R Ascending range from 1 to t_1 (truthy if positive),
ȧ and:
п collecting intermediate results, loop while
R positive
@ on the reversed arguments:
_ subtract
@ the first from the second.
L Return the length of the conjunction.
¿
and family, given a dyad, replace the right argument with the previous left argument on each successive iteration. This is incredibly bothersome for some tasks, but perfect for working with this exact kind of sequence.
1 comment thread