# Coding Challenge #9: Recamán's sequence

## Coding Challenge #9

Hello! Welcome back to another challenge. I am still looking for people to help me out and make challenges as well! So if you’re interested, help me out!

As usual, same requirements:

• Has to be written in Lua 5.1 (the version roblox uses)
• The program has to be compatible with Roblox Studio, meaning you can’t use features vanilla Lua has but rbxlua disabled
• You can’t use httpservice to cheat the challenge

Recamán’s sequence is a sequence where the first term is 0 (meaning `R(0)` = 0), and each next term in the sequence is either the previous term minus the current index, if the result is negative, then the next term is the previous term plus the current index.

The first few terms of the sequence are: 0, 1, 3, 6, 2, 7, 13, 20, 12…

Write a function `R(n)`, that returns the n-th term in the sequence.

``````R(0) -- 0
R(1) -- 1
R(2) -- 3
R(3) -- 6

R(12) -- 18
R(20) -- 22
R(100) -- 152
``````

Goodluck! You can find a list of all the challenges here or a github version here.

More formally,

If you ever made an algorithm for a fabonacci sequence for example, making an algorithm for another sequence would become a piece of cake! What’s the answer? Recursion.
Technically, in order to calculate the value each time we would need to do this

``````local previous = R(n-1)
if previous - i > 0 then
return previous - i
else
return previous + i
end
``````

and with ternary magic we can do

``````local previous = R(n-1)
return previous - n > 0 and previous - n or previous + n
``````

Now, let’s say we called `R(3)`, the function will need to get the previous term, which is the 2nd term first in order to perform the calculations later. The 2nd term will need the 1st term, because any term requires the previous one. The 1st would require the starting term, the 0-th if you’d call it that, which is 0. We know the starting term so we can simply return it straight away (if n == 0 then return 0). Now we go up the ladder again, we hand off the 1st term 0, it finishes its calculation, we hand off the result of that to the 2nd term, and we hand off the result of that to the 3rd term, and we get out final result (which is 6). The poor computer has to go through this whole process! Imagine if we wanted to get the 100th term. This our function, very simple.

``````local function R(n)
if n == 0 then return 0 end
local r = R(n-1)
return r - n > 0 and r - n or r + n
end
``````

You can even do this with iteration, but in cases like these, recursion seems to be superior, because it’s easier to understand and read. But performance wise, iteration is better.

``````local function R(n)
if n == 0 then return 0 end
local r = R(n-1)
return r - n > 0 and r - n or r + n
end

local function R2(n)
local previous = 0
for i = 1, n do
previous = previous-i>0 and previous-i or previous+i
end
return previous
end

local start = tick()
for i = 1, 10000 do
R(i)
end
print(tick()-start) --8.298012

local start = tick()
for i = 1, 10000 do
R2(i)
end
print(tick()-start) --3.761421
``````

The Slightly Spooky Recamán Sequence - Numberphile - YouTube

6 Likes
``````local index = 0

function R(n)
index += 1

if n == 0 then print("0") end

if n > 0 then
print(n)
R( (n-1) - index )
else
R( (n-1) + index )
end
end

R(0)
``````
1 Like

Here’s my solution:

code
``````local function recaman(ind)
if ind == 0 then return 0 end

local prev = recaman(ind - 1)
if prev - ind <= 0 then
return prev + ind
else
return prev - ind
end
end
``````

Alternatively:

code
``````local cache = {0, 1, 3, 6, 2, 7, 1, 8, 16, 7, 17, 6, 18, 5, 19, 4, 20, 3, 21, 2, 22, 1, 23, 46, 22, 47, 21, 48, 20, 49, 19, 50, 18, 51, 17, 52, 16, 53, 15, 54, 14, 55, 13, 56, 12, 57, 11, 58, 10, 59, 9, 60, 8, 61, 7, 62, 6, 63, 5, 64, 4, 65, 3, 66, 2, 67, 1, 68, 136, 67, 137, 66, 138, 65, 139, 64, 140, 63, 141, 62, 142, 61, 143, 60, 144, 59, 145, 58, 146, 57, 147, 56, 148, 55, 149, 54, 150, 53, 151, 52, 152, 51, 153, 50, 154, 49, 155, 48, 156, 47, 157, 46, 158, 45, 159, 44, 160, 43, 161, 42, 162, 41, 163, 40, 164, 39, 165, 38, 166, 37, 167, 36, 168, 35, 169, 34, 170, 33, 171, 32, 172, 31, 173, 30, 174, 29, 175, 28, 176, 27, 177, 26, 178, 25, 179, 24, 180, 23, 181, 22, 182, 21, 183, 20, 184, 19, 185, 18, 186, 17, 187, 16, 188, 15, 189, 14, 190, 13, 191, 12, 192, 11, 193, 10, 194, 9, 195, 8, 196, 7, 197, 6, 198, 5, 199, 4, 200, 3, 201, 2, 202, 1, 203, 406, 202, 407, 201, 408, 200, 409, 199, 410, 198, 411, 197, 412, 196, 413, 195, 414, 194, 415, 193, 416, 192, 417, 191, 418, 190, 419, 189, 420, 188, 421, 187, 422, 186, 423, 185, 424, 184, 425, 183, 426, 182, 427, 181, 428, 180, 429, 179, 430, 178, 431, 177, 432, 176, 433, 175, 434, 174, 435, 173, 436, 172, 437, 171, 438, 170, 439, 169, 440, 168, 441, 167, 442, 166, 443, 165, 444, 164, 445, 163, 446, 162, 447, 161, 448, 160, 449, 159, 450, 158, 451, 157, 452, 156, 453, 155, 454, 154, 455, 153, 456, 152, 457, 151, 458, 150, 459, 149, 460, 148, 461, 147, 462, 146, 463, 145, 464, 144, 465, 143, 466, 142, 467, 141, 468, 140, 469, 139, 470, 138, 471, 137, 472, 136, 473, 135, 474, 134, 475, 133, 476, 132, 477, 131, 478, 130, 479, 129, 480, 128, 481, 127, 482, 126, 483, 125, 484, 124, 485, 123, 486, 122, 487, 121, 488, 120, 489, 119, 490, 118, 491, 117, 492, 116, 493, 115, 494, 114, 495, 113, 496, 112, 497, 111, 498, 110, 499, 109, 500, 108, 501, 107, 502, 106, 503, 105, 504, 104, 505, 103, 506, 102, 507, 101, 508, 100, 509, 99, 510, 98, 511, 97, 512, 96, 513, 95, 514, 94, 515, 93, 516, 92, 517, 91, 518, 90, 519, 89, 520, 88, 521, 87, 522, 86, 523, 85, 524, 84, 525, 83, 526, 82, 527, 81, 528, 80, 529, 79, 530, 78, 531, 77, 532, 76, 533, 75, 534, 74, 535, 73, 536, 72, 537, 71, 538, 70, 539, 69, 540, 68, 541, 67, 542, 66, 543, 65, 544, 64, 545, 63, 546, 62, 547, 61, 548, 60, 549, 59, 550, 58, 551, 57, 552, 56, 553, 55, 554, 54, 555, 53, 556, 52, 557, 51, 558, 50, 559, 49, 560, 48, 561, 47, 562, 46, 563, 45, 564, 44, 565, 43, 566, 42, 567, 41, 568, 40, 569, 39, 570, 38, 571, 37, 572, 36, 573, 35, 574, 34, 575, 33, 576, 32, 577, 31, 578, 30, 579, 29, 580, 28, 581, 27, 582, 26, 583, 25, 584, 24, 585, 23, 586, 22, 587, 21, 588, 20, 589, 19, 590, 18, 591, 17, 592, 16, 593, 15, 594, 14, 595, 13, 596, 12, 597, 11, 598, 10, 599, 9, 600, 8, 601, 7, 602, 6, 603, 5, 604, 4, 605, 3, 606, 2, 607, 1, 608, 1216, 607, 1217, 606, 1218, 605, 1219, 604, 1220, 603, 1221, 602, 1222, 601, 1223, 600, 1224, 599, 1225, 598, 1226, 597, 1227, 596, 1228, 595, 1229, 594, 1230, 593, 1231, 592, 1232, 591, 1233, 590, 1234, 589, 1235, 588, 1236, 587, 1237, 586, 1238, 585, 1239, 584, 1240, 583, 1241, 582, 1242, 581, 1243, 580, 1244, 579, 1245, 578, 1246, 577, 1247, 576, 1248, 575, 1249, 574, 1250, 573, 1251, 572, 1252, 571, 1253, 570, 1254, 569, 1255, 568, 1256, 567, 1257, 566, 1258, 565, 1259, 564, 1260, 563, 1261, 562, 1262, 561, 1263, 560, 1264, 559, 1265, 558, 1266, 557, 1267, 556, 1268, 555, 1269, 554, 1270, 553, 1271, 552, 1272, 551, 1273, 550, 1274, 549, 1275, 548, 1276, 547, 1277, 546, 1278, 545, 1279, 544, 1280, 543, 1281, 542, 1282, 541, 1283, 540, 1284, 539, 1285, 538, 1286, 537, 1287, 536, 1288, 535, 1289, 534, 1290, 533, 1291, 532, 1292, 531, 1293, 530, 1294, 529, 1295, 528, 1296, 527, 1297, 526, 1298, 525, 1299, 524, 1300, 523, 1301, 522, 1302, 521, 1303, 520, 1304, 519, 1305, 518, 1306, 517, 1307, 516, 1308, 515, 1309, 514, 1310, 513, 1311, 512, 1312, 511, 1313, 510, 1314, 509, 1315, 508, 1316, 507, 1317, 506, 1318, 505, 1319, 504, 1320, 503, 1321, 502, 1322, 501, 1323, 500, 1324, 499, 1325, 498, 1326, 497, 1327, 496, 1328, 495, 1329, 494, 1330, 493, 1331, 492, 1332, 491, 1333, 490, 1334, 489, 1335, 488, 1336, 487, 1337, 486, 1338, 485, 1339, 484, 1340, 483, 1341, 482, 1342, 481, 1343, 480, 1344, 479, 1345, 478, 1346, 477, 1347, 476, 1348, 475, 1349, 474, 1350, 473, 1351, 472, 1352, 471, 1353, 470, 1354, 469, 1355, 468, 1356, 467, 1357, 466, 1358, 465, 1359, 464, 1360, 463, 1361, 462, 1362, 461, 1363, 460, 1364, 459, 1365, 458, 1366, 457, 1367, 456, 1368, 455, 1369, 454, 1370, 453, 1371, 452, 1372, 451, 1373, 450, 1374, 449, 1375, 448, 1376, 447, 1377, 446, 1378, 445, 1379, 444, 1380, 443, 1381, 442, 1382, 441, 1383, 440, 1384, 439, 1385, 438, 1386, 437, 1387, 436, 1388, 435, 1389, 434, 1390, 433, 1391, 432, 1392, 431, 1393, 430, 1394, 429, 1395, 428, 1396, 427, 1397, 426, 1398, 425, 1399, 424, 1400, 423, 1401, 422, 1402, 421, 1403, 420, 1404, 419, 1405, 418, 1406, 417, 1407, 416, 1408, 415, 1409, 414, 1410, 413, 1411, 412, 1412}

setmetatable(cache, {__index = function(self, ind)
local prev = cache[ind - 1]
if prev - ind <= 0 then
rawset(self, ind, prev + ind)
return prev + ind
else
rawset(self, ind, prev - ind)
return prev - ind
end
end})

local function recaman(ind)
return cache[ind]
end
``````

I don’t find these challenges as interesting when there’s already an algorithm given. Might not continue doing these challenges in the future.

6 Likes

First attempt:

``````RT = {}

function R(n)
if n == 0 then
return 0
end
local BeforeN = RT[n-1] or R(n-1)

if BeforeN - n > 0 then
RT[n] = RT[n] or BeforeN - n
return BeforeN - n
else
RT[n] = RT[n] or BeforeN +n
return BeforeN + n
end
end

``````
1 Like

``````local function Recaman(n)
local sequence = table.create(n, 0);
for i = 1, #sequence do
local prev = sequence[i - 1] or 0;
if (prev - i > 0 and not table.find(sequence, prev - i)) then
sequence[i] = prev - i;
else
sequence[i] = prev + i;
end
end
return sequence[n] or 0;
end
``````
2 Likes