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
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
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
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')) --> _
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