Skip to content

Commit

Permalink
Solve p15 in lua
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Sep 12, 2024
1 parent 8a476cd commit b2f3199
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Olivia's Project Euler Solutions
| | Browser [#]_ | | |CodeQL| |br| |
| | | | |ESLint| |
+------------+----------------------------+--------+-------------------+
| Lua | Lua 5+ [#]_ | 14 | |Luai| |br| |
| Lua | Lua 5+ [#]_ | 15 | |Luai| |br| |
| | | | |Lu-Cov| |br| |
| | | | |LuaCheck| |
+------------+----------------------------+--------+-------------------+
Expand Down
5 changes: 5 additions & 0 deletions docs/src/lua/lib/math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ View source code :source:`lua/src/lib/math.lua`
:return: The factorial of n
:rtype: number

.. lua:function:: n_choose_r(n, r)
:return: The number of ways to choose r elements from a sample of size n
:rtype: number

.. literalinclude:: ../../../../lua/src/lib/math.lua
:language: Lua
:linenos:
23 changes: 23 additions & 0 deletions docs/src/lua/p0015.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Lua Implementation of Problem 15
================================

View source code :source:`lua/src/p0015.lua`

Includes
--------

- `math <./lib/math.html>`

Solution
--------

.. lua:function:: solution()
:return: The solution to problem 15
:rtype: number

.. literalinclude:: ../../../lua/src/p0015.lua
:language: Lua
:linenos:

.. tags:: large-numbers
84 changes: 84 additions & 0 deletions lua/src/lib/math.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,90 @@ local function factorial(n)
return answer
end

local function n_choose_r(n, r)
if n < 20 -- fast path if number is small
then
return factorial(n) / factorial(r) / factorial(n - r)
end

-- slow path for big numbers// slow path for larger numbers
local factors = {}
local answer
local tmp

-- collect factors of final number
for i = 2,n,1
do
factors[i] = 1
end

-- negative factor values indicate need to divide
for i = 2,r,1
do
factors[i] = factors[i] - 1
end
for i = 2,(n - r),1
do
factors[i] = factors[i] - 1
end

-- this loop reduces to prime factors only
for i = n,2,-1
do
for j = 2,(i - 1),1
do
if i % j == 0
then
factors[j] = factors[j] + factors[i]
factors[i / j] = factors[i / j] + factors[i]
factors[i] = 0
break
end
end
end

local i = 2
local j = 2
answer = 1;
while i <= n
do
while factors[i] > 0
do
tmp = answer
answer = answer * i
while answer < tmp and j <= n
do
while factors[j] < 0
do
tmp = math.floor(tmp / j)
factors[j] = factors[j] + 1
end
j = j + 1;
answer = tmp * i
end

if answer < tmp
then
return nil, "math error: overflow"
end
factors[i] = factors[i] - 1
end
i = i + 1
end

while j <= n
do
while factors[j] < 0
do
answer = answer / j
factors[j] = factors[j] + 1
end
j = j + 1
end

return answer
end

return {
factorial = factorial,
}
2 changes: 1 addition & 1 deletion lua/src/p0013.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- Project Euler Problem 11
-- Project Euler Problem 13
--
-- Problem:
--
Expand Down
22 changes: 22 additions & 0 deletions lua/src/p0015.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- Project Euler Problem 15
--
-- Turns out this is easy, if you think sideways a bit
--
-- You can only go down or right. If we say right=1, then you can only have 20 1s, since otherwise you go off the grid.
-- You also can't have fewer than 20 1s, since then you go off the grid the other way. This means you can look at it as a
-- bit string, and the number of 40-bit strings with 20 1s is 40c20.
--
-- Problem:
--
-- Starting in the top left corner of a 2×2 grid, and only being able to move to the right and down, there are exactly 6
-- routes to the bottom right corner.

-- How many such routes are there through a 20×20 grid?

local n_choose_r = loadlib("math").n_choose_r

return {
solution = function()
return n_choose_r(40, 20)
end
}
2 changes: 1 addition & 1 deletion lua/src/p0028.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
--
-- What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way?

local range_entry = loadfile("src/lib/range.lua")().range_entry3
local range_entry = loadlib("range").range_entry3

return {
solution = function()
Expand Down
2 changes: 1 addition & 1 deletion lua/src/p0034.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
--
-- Note: as 1! = 1 and 2! = 2 are not sums they are not included.

local factorial = loadfile('src/lib/math.lua')().factorial
local factorial = loadlib('math').factorial

return {
solution = function()
Expand Down
1 change: 1 addition & 0 deletions lua/test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ local problems = {
["p0009.lua"] = {31875000, false},
["p0011.lua"] = {70600674, false},
["p0013.lua"] = {5537376230, false},
["p0015.lua"] = {137846528820, false},
["p0017.lua"] = {21124, false},
["p0028.lua"] = {669171001, false},
["p0034.lua"] = {40730, false},
Expand Down

0 comments on commit b2f3199

Please sign in to comment.