# Codegolf! a LUA challenge

**URL:** <https://forum.defold.com/t/codegolf-a-lua-challenge/64165>\
**Category:** General\
**Created:** [December 27, 2019, 11:05pm UTC](https://forum.defold.com/t/codegolf-a-lua-challenge/64165 "2019-12-27T23:05:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![88.josh](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/88.josh/32/20137_2.png) [@88.josh](https://forum.defold.com/u/88.josh)\
**Post date:** [December 27, 2019, 11:05pm UTC](https://forum.defold.com/t/codegolf-a-lua-challenge/64165/1 "2019-12-27T23:05:20Z")

</div>

Hi!

I’ve realised that I only come here when I’m asking for help, which is a little selfish. So, with no further ado, I’d like to invite you to take part in a game of codegolf! Whoever can achieve the outcome with the fewest lines of lua code wins.

The rules?

- self.levmap is a table with 70 entries used to generate a 7 by 10 grid.
- if an entry is greater than 0, it is occupied.
- you need to get the width and height of the full tiles in the grid (self.width, self.height).
- you need to print the width and height once the sorting is complete.

For example.

if self.levmap =  
{0,0,0,0,0,0,0,  
0,0,0,0,0,0,0,  
0,0,0,0,0,0,0,  
0,0,0,0,0,0,0,  
0,0,0,1,1,1,0,  
0,0,0,1,1,1,0,  
0,0,0,0,0,0,0,  
0,0,0,0,0,0,0,  
0,0,0,0,0,0,0,  
0,0,0,0,0,0,0}

then  
self.width= 3  
self.height = 2

Here’s my entry (self taught amateur coder)

```
	local toppest = 1
	local bottomest = 11
	local leftest = 8
	local rightest = 1
	for k, v in pairs(self.levmap) do 
		local x = ((k-1)%7)+1 --1, 7
		local y = math.ceil(k/7) --1,10
		if v > 0 then
			if x < leftest then
				leftest = x
			end
			if x > rightest then
				rightest = x 
			end
			if y < bottomest then
				bottomest = y
			end
			if y > toppest then
				toppest = y
			end
			self.height = (toppest-bottomest)+1
			self.width = (rightest-leftest)+1
		end
	end
	if self.levmaps[key+1] == nil then
		print("size acquired! (josh don't forget to calculate tilesize here)",self.width,self.height)
	end
end

```

---

<div class="post-metadata">

**Author:** ![88.josh](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/88.josh/32/20137_2.png) [@88.josh](https://forum.defold.com/u/88.josh)\
**Post date:** [December 28, 2019, 11:23pm UTC](https://forum.defold.com/t/codegolf-a-lua-challenge/64165/2 "2019-12-28T23:23:43Z")

</div>

after 24 hours I am still in first place.  
de-fault! de-fault! de-fault! de-fault!

---

<div class="post-metadata">

**Author:** ![britzl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/britzl/32/23_2.png) [@britzl](https://forum.defold.com/u/britzl)\
**Post date:** [December 30, 2019, 7:22pm UTC](https://forum.defold.com/t/codegolf-a-lua-challenge/64165/3 "2019-12-30T19:22:06Z")

</div>

Here’s another solution:

```
self.width = 0
local first_row = nil
local last_row = nil
for r=1,9 do
    local row = table.concat(self.levmap, "", 1+(r-1)*7, 1+(r-1)*7+6) -- concatenate each row into a string
    local trimmed_row = row:match("^0*(.-)0*$") -- trim initial and ending 0's
    self.width = math.max(self.width, #trimmed_row) -- width of the row is the length of the remaining string
    if #trimmed_row > 0 and not first_row then
        first_row = r
    end
    if #trimmed_row > 0 and (not last_row or last_row < r) then
        last_row = r
    end
end
self.height = (first_row and last_row) and last_row - first_row + 1 or 0

```

There must be a better way to figure out the height though…

@88.josh’s solution is more efficient since it doesn’t rely on string manipulation.

---

<div class="post-metadata">

**Author:** ![lrx](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/lrx/32/18081_2.png) [@lrx](https://forum.defold.com/u/lrx)\
**Post date:** [December 30, 2019, 11:28pm UTC](https://forum.defold.com/t/codegolf-a-lua-challenge/64165/4 "2019-12-30T23:28:59Z")

</div>

Hi 88.josh,

you can shorten by using math.max and math.min

If you like you can shorten locals initialization in one line.

You can do the same thing inside the inner loop, but I think is awful 🤮  
(Or is it a Perl code competition?? 🤣)

Is better to move the result evaluation out of the loops,  
and compute x and y only if needed

```
	local toppest,rightest,bottomest,leftest=1,1,11,8 
	for k, v in pairs(self.levmap) do 
		if v > 0 then
			local x = ((k-1)%7)+1 --1, 7
			local y = math.ceil(k/7) --1,10
			leftest=math.min(x,leftest)
			rightest=math.max(x,rightest)
			bottomest=math.min(y,bottomest)
			toppest=math.max(y,toppest)
		end
	end
	self.height = (toppest-bottomest)+1
	self.width = (rightest-leftest)+1

```

If you change your level map into a bidimensional array

self.levmap =  
{ {0,0,0,0,0,0,0},  
{0,0,0,0,0,0,0},  
{0,0,0,0,0,0,0},  
{0,0,0,0,0,0,0},  
{0,0,0,1,1,1,0},  
{0,0,0,1,1,1,0},  
{0,0,0,0,0,0,0},  
{0,0,0,0,0,0,0},  
{0,0,0,0,0,0,0},  
{0,0,0,0,0,0,0} }

you can avoid computing x and y with remainder and math.ceil, but code length is the same

```
	local toppest,rightest,bottomest,leftest=1,1,11,8
	for y,row in ipairs(self.level) do
		for x,v in ipairs(row) do
			if v > 0 then
				leftest=math.min(x,leftest)
				rightest=math.max(x,rightest)
				bottomest=math.min(y,bottomest)
				toppest=math.max(y,toppest)
			end
		end
	end
	self.height = (toppest-bottomest)+1
	self.width = (rightest-leftest)+1

```

Without my locals init “cheat”, @britzl’s solution is shorter!

I won’t win the prize 😅

---

<div class="post-metadata">

**Author:** ![88.josh](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/88.josh/32/20137_2.png) [@88.josh](https://forum.defold.com/u/88.josh)\
**Post date:** [December 31, 2019, 10:09am UTC](https://forum.defold.com/t/codegolf-a-lua-challenge/64165/5 "2019-12-31T10:09:08Z")

</div>

Results are in!  
@lrx first place  
@88.josh second place  
And @britzl is disqualified for using string manipulation. Cruel, but ultimately the student has become the master, just like in star wars.
