Coding Challenge #4: Non-repeating character

Here’s my answer without looking at the solution, probably not the best but it should work:

My answer

function NonRepeatingChar(str)
     local charCounts = {}
     for 1, #str, 1 do
          local c = string.sub(str, i, i)

          if charCounts[c] then
                charCounts[c] = charCounts[c] + 1
          else
                charCounts[c] = 1
          end


     end
     for i, v in pairs(charCounts) do
          if v == 1 then
               return i
          end
     end
     return "_"
end
1 Like

Hold my loops! :rofl:

local function nonRepeatingChar(str)
	local chars = {}
	local real = {}

	for letter in string.gmatch(str, ".") do
		chars[letter] = (chars[letter] or 0) + 1
	end
	
	local c = 0
	for i,v in pairs(chars) do
		c += 1
		table.insert(real, {char = i, repeated = v, count = c})
	end

	table.sort(chars, function(a,b)
		if a.repeated >= b.repeated then
			return true
		else
			return false
		end
	end)
	
	local lowest = math.huge
	local letter
	
	for i,v in pairs(real) do
		if v.repeated == 1 and v.count < lowest then
			lowest = v.count
			letter = v.char
		end
	end	

	return letter or "_"
end
1 Like

I was sent a link to this challenge through DMs, and it seemed fun. Here is my solution:

local function NonRepeatingChar(str)
	local stringRepeatCount = {}
	
	for char in str:gmatch(".") do
		stringRepeatCount[char] = stringRepeatCount[char] or 0
		stringRepeatCount[char] += 1
	end
	
	local nonRepeatedString, repeatCount = nil, nil
	
	for str, count in pairs(stringRepeatCount) do
		if not (nonRepeatedString or repeatCount) then
			nonRepeatedString, repeatCount = str, count
			continue
		end
		
		if count < repeatCount then
			nonRepeatedString, repeatCount = str, count
		end
	end
	
	return nonRepeatedString
end

 print(NonRepeatingChar("eebbbzzzeee1"))

Alternative solution which does the same thing, completely redundant but did it for fun because why not.

local function NonRepeatingChar(str)
	local stringRepeatCount = {}
	
	for char in str:gmatch(".") do
		stringRepeatCount[char] = stringRepeatCount[char] or 0
		stringRepeatCount[char] += 1
	end
	
	local nonRepeatedStrings = {}
	local lowestRepeatCount = 0
	
	for str, count in pairs(stringRepeatCount) do
		if (#nonRepeatedStrings == 0) then
			lowestRepeatCount = count
			table.insert(nonRepeatedStrings, count)
			continue
		end
		
		if count < lowestRepeatCount then
			-- Remove the string if its repeated, table.find is linear but 
			-- due to the new Luau VM, its very fast:
			table.remove(nonRepeatedStrings, table.find(nonRepeatedStrings, str))
			table.insert(nonRepeatedStrings, str)
			lowestRepeatCount = count
		end
	end

	return nonRepeatedStrings[#nonRepeatedStrings]
end

print(NonRepeatingChar("eebbbzzzeee1"))
Off topic but a benchmark on table.find
-- create table with 50 million elements 
local t =  table.create(50_000_000, true)


local before = os.clock()

table.find(t, #t)

print(os.clock() - before)

-- 0.09
1 Like

I did so:

function NonRepeatingChar(str)
	local ret = '_'
	local chars = {}
	
	for _, c in ipairs(str:split('')) do
		if (not chars[c]) then
			chars[c] = 0
		end
		chars[c] += 1
	end
	
	local char = nil
	for c, counter in pairs(chars) do
		if (counter == 1) then
			char = c
			break
		end
	end
	
	if (char) then
		ret = char
	end
	
	return ret
end

print(NonRepeatingChar('aaaabcc')) --> b
print(NonRepeatingChar('bbaccdb')) --> a
print(NonRepeatingChar('aacbbdf')) --> c
print(NonRepeatingChar('aababd')) --> d
print(NonRepeatingChar('aabababd')) --> d
print(NonRepeatingChar('aabbcc')) --> _
3 Likes
local function NonRepeatingChar(str)
	local chars = string.split(str,"")
	for _,v in pairs(chars) do
		local count = 0
		for _,b in pairs(chars) do
			if v == b then
				count += 1
				if count >= 2 then
					break
				end
			end
		end
		if count == 1 then
			return v
		end
	end
	return "_"
end

local strings = {
	"aaaabcc", --> b
	"bbaccdb", --> a
	"aacbbdf", --> c
	"aababd", --> d
	"aabababd", --> d
	"aabbcc" --> _
}

for _,str in pairs(strings) do
	print(NonRepeatingChar(str))
end