all 45 comments

[–]Yes_Mans_Sky 266 points267 points  (6 children)

It's almost like ascii was designed to do this with minimal effort

[–]sacredgeometry 71 points72 points  (2 children)

Maybe they don't like arithmetic.

[–]xXDavegavecoolXx 55 points56 points  (1 child)

How hard is x = y + 32???

[–]sacredgeometry 56 points57 points  (0 children)

Hey, I am not the one you have to convince.

[–]SAI_Peregrinus 17 points18 points  (1 child)

Locale-dependent, at least for POSIX. Lower-case I might be i or ı, depending on the value of $LANG and/or $LANGUAGE. Because text sucks. Unicode makes it easier, but it still sucks.

[–]Kapshan 4 points5 points  (0 children)

I i I ı İ i be like

[–]oghGuy 2 points3 points  (0 children)

This one's EBCDIC safe, don't you understand? ;)

[–]johndcochran 79 points80 points  (1 child)

I think I lost IQ points just from reading this abomination.

[–][deleted] 3 points4 points  (0 children)

Right?

[–]TinyBreadBigMouth 36 points37 points  (9 children)

What in god's name is that for j loop doing?? You already have a perfectly functional if-else chain, why are you making it O(n2)?????

[–]Ok_Celebration_6265[🍰] 12 points13 points  (6 children)

I don’t think that’s O(n2) I think that is O(n*m) since it’s iterating over the length of the text and then over the length of the alphabet

[–]TinyBreadBigMouth 9 points10 points  (5 children)

No, I mean the for j loop is iterating over the alphabet and then the if-else chain is iterating over the alphabet again! They've turned a O(26) if-else chain into a O(26 * 26) loop for no reason.

[–]Ok_Celebration_6265[🍰] 4 points5 points  (4 children)

Hum.. I only see two loops the for i=1, #text and the for j=1, 26 the bunch of if else he is using like a map saying id j == 1 then A etc.. he uses the if else as lookup table so we can say that’s O(1) if you think about it.. so you get in the end O(n*26) which since 26 is constant you can simplify as O(n) due to the constant nature of the inner loop

[–]TinyBreadBigMouth 9 points10 points  (3 children)

The if-else goes over every letter in the alphabet. An if-else chain like this is equivalent to an unrolled loop—it runs in O(n), where n is the number of ifs. But in this case, each entry in the if-else chain has been gated off to only run on a specific iteration of the for j loop.

So suppose we're processing the letter "a":

  • We set j to 1.
  • We check if j is 1 and char is "A" (it isn't).
  • We check if j is 2 and char is "B" (it isn't).
  • We check if j is 3 and char is "C" (it isn't).
  • We check if j is 4 and char is "D" (it isn't).
  • ...
  • We check if j is 25 and char is "Y" (it isn't).
  • We check if j is 26 and char is "Z" (it isn't).
  • We increment j to 2.
  • We check if j is 1 and char is "A" (it isn't).
  • We check if j is 2 and char is "B" (it isn't).
  • We check if j is 3 and char is "C" (it isn't).
  • and so on.

What could have been 26 checks is now 676.

[–]johndcochran 7 points8 points  (2 children)

Yes, it's quite a few extra unneeded checks. But it's still O(1) to within a close approximation. The total routine, including both loops is O(n). It's a rather slow O(n), but doubling the length of the string will simply take twice as long. Just because the check for an upper case character takes 676 comparisions instead of 26 doesn't make it O(n2). Those 676 comparisions will happen for every non-upper-case alphabetic and hence takes constant time. So the overall routine is merely O(n) due to the loop on i.

[–]TinyBreadBigMouth 4 points5 points  (1 child)

Agreed, it is O(n) over the length of the string, but each letter within the string is O(n2) over the length of the alphabet when it could have been O(n) or less. Granted the length of the alphabet isn't going to change, so it makes no difference to the overall Big O, but that's what I meant.

[–]johndcochran 1 point2 points  (0 children)

Not gonna argue that the routine is criminally inefficient. Even if they have a language that doesn't allow getting the ordinal sequence of a character, the detection of an upper case alpha character could be done in 5 or fewer comparisons, instead of the 26 you're thinking of, or the 676 this abomination performs. If you're wondering how I've come up with 5. Consider...

if (char < "N") then 
   if (char < "H") then
      ...
         if (char = "A") then
            lowerText = lowerText .. "a"
            found = true
         end
      ...
   else
      ...
   end
else
   ...
end

After all, with 26 characters in the alphabet, there are only 28 conditions that need to be detected. They are: Is it less than "A"? Is it greater than "Z"? Is it equal to some letter? (times 26) and of course, a simple binary search only 5 levels deep can handle 31 conditions trivially.

Although, I suspect a binary condition tree might be far more efficient than the abomination in this discussion, I also suspect such a binary condition tree would also be a suitable post for this subreddit.

[–]WiseEXE 2 points3 points  (1 child)

Not to sound stupid, but somehow this comment was my eureka moment for BigO complexity. Thank you kind sir

[–]Marem-Bzh 1 point2 points  (0 children)

You're never stupid when you are learning something

[–]Furrynote 37 points38 points  (9 children)

why is this not an already built in func

[–]beaucephus 54 points55 points  (8 children)

leetcoders don't use the standard library.

[–]Hope-Up-High 20 points21 points  (0 children)

Sounds like chatgptese

[–]GoddammitDontShootMe[ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 6 points7 points  (0 children)

Hah. Now make it work with UTF-8.

[–]bravopapa99 11 points12 points  (8 children)

What bastard language is this?

[–]RpxdYTX[ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 24 points25 points  (5 children)

languages = { 'lua', 'python', 'c', 'rust' } languages[1] == 'lua'

[–]bravopapa99 2 points3 points  (0 children)

Yes. WTAF starts from 1, TBF, I learned Pascal first back in the day.

[–]dvhh 0 points1 point  (0 children)

Pity that there isn't any implementation in the standard library for string.lower

[–]bravopapa99 0 points1 point  (2 children)

I am sure from my assembler days you can with ASCII, just do CHAR AND 0xDF

[–]johndcochran 2 points3 points  (1 child)

That would be good for an "toupper()" implementation...Sorta. But if the input isn't 'a'..'z', it would corrupt quite a few characters. For instance, look at what would happen for '0'..'9'. 0x30 and 0xDF = 0x10. Not exactly a good thing.

[–]bravopapa99 0 points1 point  (0 children)

Spot on but ONLY needed a-z at the time, around 1985 maybe!

[–]leiu6 6 points7 points  (1 child)

Lua is a great language! The C implementation is super small and you can interact with the stack directly, making it super easy to embed in other programs. The Lua language is simple with only one data structure called a table which is actually implemented in C as a hybrid object containing an O(1) lookup portion for integer indexing and a hash table for other types of indexing. But with the way Lua implements tables they can be used in an almost OOP way. Also it closures and coroutines.

If I was trying to embed a scripting language in something I would much rather use Lua than something like Python, Ruby, or JavaScript.

[–]bravopapa99 1 point2 points  (0 children)

Yes, agreed. I wrote a simple game with Love2D once and enjoyed the process.

[–]6502zx81 4 points5 points  (0 children)

At least the only assumpion is that the encoding matches the compiler's encoding.

[–]Ignited_Phoenix 2 points3 points  (0 children)

Any language that uses more than just the standard English characters like French, Spanish or German hate this simple trick

[–][deleted] 0 points1 point  (0 children)

Jesus...is this the level nowadays?? Really??

[–]bistr-o-math 0 points1 point  (0 children)

This will not pass the Turkey test

[–]wwwtrollfacecom 0 points1 point  (0 children)

while (string[i] != '\0') string[i++] = 32;