Given a sequence of three integers, determine if the sequence is arithmetic (of the form [a, a+d, a+2*d]) or geometric (of the form [a, a*r, a*r^2]) by outputting a fourth term that completes it (a+3*d for arithmetic, a*r^3 for geometric).
Examples:
[1, 2, 3] -> 4 (This is an arithmetic sequence with a difference of 1)
[2, 4, 8] -> 16 (This is a geometric sequence with a ratio 2)
[20, 15, 10] -> 5 (arithmetic sequence, d=-5)
[6, 6, 6] -> 6 (arithmetic with d=0 OR geometric with r=1)
[3, -9, 27] -> -81 (geometric with r=-3)
- The input is guaranteed to be a valid arithmetic and/or geometric sequence (so you won't have to handle something like
[10, 4, 99]) - None of the inputted terms will be
0(both[2, 0, 0]and[1, 0, -1]would not be given) - For geometric sequences, the ratio between terms is guaranteed to be an integer (ie.
[4, 6, 9]would be an invalid input, as the ratio would be 1.5) - If a sequence could be either arithmetic or geometric, you may output either term that completes it
- You may take input as a 3-term array (or whatever equivalent) or as three separate inputs
- This is code golf, so aim for the lowest byte count possible!
-
1\$\begingroup\$ I think I'll remove any test cases involving 0 (as a term). Someone on the sandbox mentioned [1, 0, 0] \$\endgroup\$nyxbird– nyxbird2024年01月22日 22:37:40 +00:00Commented Jan 22, 2024 at 22:37
-
\$\begingroup\$ Regarding "If a sequence could be either arithmetic or geometric", this happens if and only if the three terms are equal, which corresponds to either (a = 0, d = 0, r = anything) or (a != 0, d = 0, r = 1). \$\endgroup\$Stef– Stef2024年01月23日 16:02:41 +00:00Commented Jan 23, 2024 at 16:02
21 Answers 21
Python, 34 bytes
-1 thanks to @Arnauld
lambda a,b,c:c+(c-b)**2/(b-a or 1)
How?
Uses the fact that the increments form a geometric sequence in either case. (This avoids the longish (in Python) ternary operator.)
Indeed: \$c+\frac{(c-b)^2}{b-a} = \begin{cases} c+(c-b)=2c-b & \text{if }c-b=b-a \\ c+(c-b)\times \frac c b = \frac{c^2} b & \text{if } \frac c b = \frac b a \end{cases}\$
-
1\$\begingroup\$ i accidentally downvoted can you edit so i can change it \$\endgroup\$pacman256– pacman2562024年01月23日 00:06:29 +00:00Commented Jan 23, 2024 at 0:06
-
2\$\begingroup\$ Would it be OK to use
/instead of//? Returning integers as floats is fine. \$\endgroup\$Arnauld– Arnauld2024年01月23日 05:28:40 +00:00Commented Jan 23, 2024 at 5:28 -
\$\begingroup\$ With "ternary operator" it's only 2 bytes longer:
lambda a,b,c:(c*b/a,c+b-a)[c-b==b-a](unfortunately cannot compressc-b==b-aintoc-2*b+abecause that can take values other than 0 or 1) \$\endgroup\$Stef– Stef2024年01月23日 17:07:32 +00:00Commented Jan 23, 2024 at 17:07 -
\$\begingroup\$ @Stef you could use
c*a<b*b, though, couldn't you? \$\endgroup\$Albert.Lang– Albert.Lang2024年01月24日 05:20:36 +00:00Commented Jan 24, 2024 at 5:20
Raku (Perl 6), 13 bytes
A block taking a sequence of length 3 as a single argument. This task is a perfect match for Raku's sequence operator.
{($_...*)[3]}
Python 3, 24 bytes
lambda a,b,c:c*(a+c)/b-b
Note that this fails when \$ a=0 \$ or \$ b=0 \$, but that seems to be OK for this challenge :). We can verify its correctness:
- For an arithmetic sequence \$ b-a = c-b \implies 2b = a+c \$, the formula rightfully produces \$ 2c-b \$: $$ \frac{c*(a+c)}{b}-b = \frac{c*2b}{b}-b = 2c-b $$
- Likewise, for a geometric sequence \$ b/a = c/b \implies a = b^2/c \$, the formula rightfully produces \$ c^2/b \$: $$ \frac{c*(a+c)}{b}-b = \frac{c*(b^2/c+c)}{b}-b = \frac{b^2+c^2}{b}-b = b+\frac{c^2}{b}-b = \frac{c^2}{b} $$
-
1\$\begingroup\$ Since \$ 2b = a + c \$ and \$ b^2 = ac \$ respectively, you can just say \$ \frac { c ( a + c) } b - b = \frac { 2bc } b - b = 2c - b \$ and \$ \frac { c (a + c) } b - b = \frac { b^2 + c^2 } b - b = b + \frac { c^2 } b - b = \frac { c^2 } b \$. \$\endgroup\$Neil– Neil2024年01月25日 14:56:14 +00:00Commented Jan 25, 2024 at 14:56
JavaScript (ES6), 28 bytes
(a,b,c)=>c-2*b+a?c*c/b:2*c-b
Commented
(a, b, c) => // given the 3 integers,
c - 2 * b + a ? // if the sequence is not arithmetic:
c * c / b // assume it's geometric and return the next geometric term
: // else:
2 * c - b // return the next arithmetic term
R, 28 bytes
\(a,b,c)c+(c-b)^2/(b-a+!b-a)
Port of @loopy walt's Python answer.
R, 33 bytes
\(a,b,c)`if`(c-b-b+a,c*c/b,c+c-b)
Straightforward approach.
Google Sheets, 34 bytes
=IF(A3/A2=A2/A1,A3*A2/A1,A3+A2-A1)
The formula assumes the sequence is in A1:A3.
Awk, 33 bytes
1,0ドル=1ドル-2*2ドル+3ドル?2ドル*3ドル/1ドル:2ドル+3ドル-1ドル
You could remove the 1, at the start if you assume that the output will not be 0, saving 2 bytes.
Jelly, 11 bytes
×ばつ÷Ɲ$}E?UḢ
A monadic link taking a list of three integers and returning an integer.
Explanation
I | Increments (differences between consecutive list members)
E? | If all equal then:
+ U | - Add the increments to the reversed input list
$} U | Else, following as a monad applied to the reversed input list:
×ばつ | - Multiply by:
÷Ɲ | - The result of dividing each pair of neighbouring list members
Ḣ | Head
-
1\$\begingroup\$ Updated with attribution since there are now two Jelly answers. Always best to link regardless in my opinion. \$\endgroup\$Jonathan Allan– Jonathan Allan2024年01月23日 17:40:05 +00:00Commented Jan 23, 2024 at 17:40
Alice, 29 bytes
3&/O
?+\M@/!]!?-R.n$n?[?-.*~:
-4 bytes thanks to Nitrodon!
Uses loopy walt's solution, go upvote them!
3&/M\ Read 3 arguments a b c on the stack
!]! Pop and write c then b on the tape
?-R Push b on the stack and calculate b-a
.n$n if b-a is 0, replace with 1
?[? Push b and c on the stack
-.* Calculate (c-b)^2
~: Calculate (c-b)*(c-b)/(b-a or 1)
?+ Pop c and calculate c+(c-b)*(c-b)/(b-a or 1)
\O@ Output the result
-
1
APL+WIN, (削除) 43 (削除ここまで) 38 bytes
Prompts for integers
↑(=/ ̈a b)/(×ばつ↑a←2÷/v),(↑v+↑b←2-/v←⌽⎕)
Jelly, 9 bytes
Uses the trick described by loopy walt in their excellent Python answer although the implementation is somewhat different.
IQ2÷\@/+Ṫ
A monadic Link that accepts a triple of integers, [a, b, c], that is either arithmetic or geometric and yields the next integer in the series, d.
How?
IQ2÷\@/+Ṫ - Link: list of integers, [a, b, c]
I - forward differences -> [b-a, c-b]
Q - deduplicate
-> if arithmetic: L=[b-a] (potentially [0])
else: L=[b-a, c-b] (with no zeros)
/ - reduce L by:
@ - with swapped arguments:
\ - last two links as a dyad - f(x, y):
2 - square -> x^2
÷ - divide -> x^2/y
-> if arithmetic: Z=b-a (only one item so reduce does not perform f)
else: Z=(c-b)^2/(b-a)
+ - add {[a, b, c]} (vectorises) -> [a+Z,b+Z,c+Z]
Ṫ - tail -> c+Z (= d)
-> if arithmetic: d=c+(b-a)
else: d=c+(c-b)^2/(b-a)
Desmos, 19 bytes
f(a,b,c)=c(a+c)/b-b
Port of dingledooper's Python 3 solution, so make sure to upvote that one too!
Vyxal, 6 bytes
+∇/*0-
Port of dingledooper's clever formula, go look at that for an explanation of why this works.
# input c, a, b
+ # c+a
∇ # rotate stack to b, c, c+a
/ # c/b
* # (c+a) * c/b
0 # last input (b)
- # (c+a) * c/b - b
This uses four necessary operations (+/-*) and two stack-manipulation operations (0∇). I'm fairly sure that a solution with only one stack-manipulation op is impossible but I'd love to be proven wrong.
-
\$\begingroup\$ Your explanation is incorrect. It's
c/bnotb/c(e.g.(c+a) * b/c - bfor the first test case would be(3+1) * 2/3 - 2 = 2⁄3instead of(3+1) * 3/2 - 2 = 4). Your code and TIO are fine. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2024年01月25日 09:34:19 +00:00Commented Jan 25, 2024 at 9:34
MathGolf, 6 bytes
+╠*k;,
Port of dingledooper's Python 3 answer, so make sure to upvote that answer as well!
I/O as floats, and inputs are in the order \$c,a,b\$.
Explanation:
+ # Add the first two (implicit) inputs together: c+a
╠ # Divide it by the third (implicit) input: (c+a)/b
* # Multiply it by the first (implicit) input: (c+a)/b*c
k; # Push the second input, and discard it
, # Subtract it by the third (implicit) input: (c+a)/b*c-b
# (after which the entire stack is output implicitly as result)
The k;, could also be ?-Þ for the same byte-count: Try it online.
? # Triple-swap the top three values: a,(c+a)/b,b
- # Subtract the top two: a,(c+a)/b-b
Þ # Only keep the top value of the stack: (c+a)/b-b
# (after which the entire stack is output implicitly as result)
Retina 0.8.2, 65 bytes
.+
$*
¶1+¶
$'$&
1(?=1*¶1+¶(1+))
1ドル
(?=1+¶(1+)¶)1円
1
(1+)¶1円¶1+
1
Try it online! Takes input on separate lines but link is to test suite that splits on non-digits for convenience. Limited to positive integers due to use of unary arithmetic. Explanation: Uses @dingledooper's formula.
.+
$*
Convert to unary.
¶1+¶
$'$&
Add c to a.
1(?=1*¶1+¶(1+))
1ドル
Multiply a+c by c.
(?=1+¶(1+)¶)1円
1
Divide that by b.
(1+)¶1円¶1+
Subtract b and remove b and c.
1
Convert to decimal.
Charcoal, 16 bytes
×ばつ+θζζηη
Try it online! Link is to verbose version of code. Explanation: Trivial implementation of @dingledooper's formula.
35 bytes to validate the input:
NθNηNζ¿=⊗η+θζI−+ζηθ¿∧θ=×ばつζηθ
Try it online! Link is to verbose version of code. Works with edge cases such as 0 0 0, 1 0 0, 1 0 -1. Doesn't output anything if the input is not an arithmetic or geometric sequence.
Notes for both solutions:
- 6 bytes (
NθNηNζ) could be saved by requiring the input to be in JSON format. - Floating-point arithmetic could be used by replacing
÷with∕.