For part 2, it's actually probably simpler to check if the line starts with one of our match conditions (a word or a digit) and then shift by one character each time. The regex is how I did it, but in hindsight, I think it's more complicated than necessary and I think manually scanning the line would be much smarter. This is basically just how the regex does it under the hood but it's probably easier to understand and doesn't require you to understand (?=...). Also, I got the name of that wrong, sorry. It's a lookahead assertion ("this thing is ahead, but don't match it") not a non-capturing group (completely unrelated).
that's how i solved it, working through each character, saving a mapping of all (potentially half consumed) digit-words to their actual int value. once the key is only once character long and matches the current character, i returned the value (must be the first one). then i repeated the process, but reversing the line, and reversing the keys of the mapping (three -> eerht) wasn't that much easier tbh
Your solution is so good and simple. When i solved part 2 i implemented some kind of a data structure called Trie and it worked, but took me a while. Great video!
Great solution. Much cleaner than mine. I replaced "one" with "one1one" for each number, and then removed non-digits. This preserves the text for overlaps, but still gets the digits in the right order. I think your solution is cleaner. For future videos, can you make your font way bigger. It was nearly impossible to read on a phone.
I bypassed the attempt at frustrating things with the overlapping words by searching for the first string index and last string index of all pairs '1' and 'one', '2' and 'two' and so on. I keep track of the highest and lowest index and value during the loop. Not sure if Python has a 'lastIndexOf()' kind of thing
You can use str.rfind! That's a much smarter solution and if I revisit this problem in the future, I already have a couple of better approaches in mind than using this hacky regex solution.
That's definitely a possibility, but the first place submission was done in 12 seconds so it seems like it didn't work perfectly! That is maybe why though.
I'm like 99% sure that was done by AI, lol. I don't believe anyone could've actually solved the problem in literally 12 seconds - it takes just about that long to even start reading the problem
Since the two isn't the first or last digit, it won't cause errors here, but if you had "foureightwo" as a test case, it would give 48 and not the expected 42 if you don't account for overlaps.
Thank you for sharing! it will be great if you could increase the font size for the upcoming videos, is very difficult to see clearly specially with that typeface
I was stuck on part 2 for exactly the reason you described for around 10 minutes before someone on chat gave me a hint to try the testcase "eightwo", which my code of course transformed to "8wo". That was pretty annoying indeed that the testcase didn't exercise that behaviour since stepping through the full input to look for possible issues was a bit impractical and it wasn't obvious behaviour.
Yep. It's especially hard to catch because it only ever matters if the overlap cuts out the last digit in the string, so the test case including "eightwothree" is still totally ambiguous.
What I did in second part was: -> generated all overlapping digit words combinations (like twone,oneight) and the corrected ones -> replaced the ovelapping words with corrected ones -> replaced all the words with numbers
That's also a pretty clever way to do it! Using regex you can actually also just search for .*(match string) since * is greedy; later on I might revisit some of these problems and discuss different/better/more efficient approaches just for fun.
Monaspace Radon from Github Next; I like it but I might switch to something else for these videos as it occurred it might be a bit weird or hard to read for some people. Let me know what you think about it!
Here's my code: ~~~ def get_digits(line: str) -> int: """ Takes in a string, finds spelled out numbers and digits. Returns the first and last numbers found, concatenated as a single two digit int """ NUMS = 'one two three four five six seven eight nine'.split() num_dic = {k: str(v) for v, k in enumerate(NUMS, 1)} found = [] for n in NUMS: match = line.find(n) if match >= 0: found.append((match, num_dic.get(n))) for i, l in enumerate(line): if l.isdigit(): found.append((i, str(l))) found = sorted(found, key=lambda x: x[0]) print(found) if len(found) == 1: return int(found[0][1]*2) else: return int(found[0][1] + found[-1][1]) ~~~
For part 2, it's actually probably simpler to check if the line starts with one of our match conditions (a word or a digit) and then shift by one character each time. The regex is how I did it, but in hindsight, I think it's more complicated than necessary and I think manually scanning the line would be much smarter.
This is basically just how the regex does it under the hood but it's probably easier to understand and doesn't require you to understand (?=...).
Also, I got the name of that wrong, sorry. It's a lookahead assertion ("this thing is ahead, but don't match it") not a non-capturing group (completely unrelated).
that's how i solved it, working through each character, saving a mapping of all (potentially half consumed) digit-words to their actual int value. once the key is only once character long and matches the current character, i returned the value (must be the first one). then i repeated the process, but reversing the line, and reversing the keys of the mapping (three -> eerht)
wasn't that much easier tbh
thanks for the specific regex, did not know about that before
Your solution is so good and simple. When i solved part 2 i implemented some kind of a data structure called Trie and it worked, but took me a while. Great video!
The edge cases on `oneight`, `eightwo`, etc. were something i missed considering so got stuck for a while on this problem thanks a lot! :D
Thank you for your videos! I learn a lot from them.
Glad to hear! Thanks for watching :)
Great solution. Much cleaner than mine. I replaced "one" with "one1one" for each number, and then removed non-digits. This preserves the text for overlaps, but still gets the digits in the right order. I think your solution is cleaner.
For future videos, can you make your font way bigger. It was nearly impossible to read on a phone.
Of course - sorry, I did that last year but I just forgot this year since it's been a while since I've done this.
@@hyper-neutrino - no worries! has bit me many times!
I bypassed the attempt at frustrating things with the overlapping words by searching for the first string index and last string index of all pairs '1' and 'one', '2' and 'two' and so on. I keep track of the highest and lowest index and value during the loop.
Not sure if Python has a 'lastIndexOf()' kind of thing
You can use str.rfind! That's a much smarter solution and if I revisit this problem in the future, I already have a couple of better approaches in mind than using this hacky regex solution.
Maybe they chose to limit the test data in that way to "slow down" anyone using LLMs?
That's definitely a possibility, but the first place submission was done in 12 seconds so it seems like it didn't work perfectly! That is maybe why though.
@@hyper-neutrino Yeah, but part one was pretty straight forward from the examples. 12 seconds tho - jeez..
I'm like 99% sure that was done by AI, lol. I don't believe anyone could've actually solved the problem in literally 12 seconds - it takes just about that long to even start reading the problem
@@hyper-neutrino yes I totally agree!
On the "eightwothree" entry, I was of the opinion that the two didn't exist because the "t" was consumed by the eight. It gave me the right answer.
Since the two isn't the first or last digit, it won't cause errors here, but if you had "foureightwo" as a test case, it would give 48 and not the expected 42 if you don't account for overlaps.
Thank you for sharing! it will be great if you could increase the font size for the upcoming videos, is very difficult to see clearly specially with that typeface
Hey! Yeah, sorry, I forgot to do that for this video, but I'll remember that for my future ones (already did for day 2). Thanks for watching!
great content !
I was stuck on part 2 for exactly the reason you described for around 10 minutes before someone on chat gave me a hint to try the testcase "eightwo", which my code of course transformed to "8wo". That was pretty annoying indeed that the testcase didn't exercise that behaviour since stepping through the full input to look for possible issues was a bit impractical and it wasn't obvious behaviour.
Yep. It's especially hard to catch because it only ever matters if the overlap cuts out the last digit in the string, so the test case including "eightwothree" is still totally ambiguous.
What I did in second part was:
-> generated all overlapping digit words combinations (like twone,oneight) and the corrected ones
-> replaced the ovelapping words with corrected ones
-> replaced all the words with numbers
3:01 feels like tyla water 2:39
th-cam.com/video/XoiOOiuH8iI/w-d-xo.htmlsi=PFFPZWjNtT6yZFsE&t=159
D = {'one' : 1, 'two' : 2, 'three':3, 'four':4, 'five':5, 'six':6, 'seven':7, 'eight':8, 'nine':9, '1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '0':0}
that's what i initially/intuitively did /// geez 1st day
Please zoom in, thx for your content
Hey! Yeah, sorry, I forgot to do that for this video, but I'll remember that for my future ones (already did for day 2). Thanks for watching!
Hi, thanks for the video I didn't know the possitive lookahead pattern.
Anyways, I got the correct solution just normalazing the string for special cases:
private string Normalize(string cad) {
Dictionary replaces = new() {
{"oneight", "oneeight"},
{"eightwo", "eighttwo"},
{"eighthree", "eightthree"},
{"threeight", "threeeight"},
{"twone", "twoone"},
{"sevenine", "sevennine"},
{"nineight", "nineeight"},
{"fiveight", "fiveeight"},
{"one", "1"},
{"two", "2"},
{"three", "3"},
{"four", "4"},
{"five", "5"},
{"six", "6"},
{"seven", "7"},
{"eight", "8"},
{"nine", "9"}
};
foreach (var kv in replaces) {
cad = cad.Replace(kv.Key,kv.Value);
}
return cad;
}
That's also a pretty clever way to do it! Using regex you can actually also just search for .*(match string) since * is greedy; later on I might revisit some of these problems and discuss different/better/more efficient approaches just for fun.
what font you using?
Monaspace Radon from Github Next; I like it but I might switch to something else for these videos as it occurred it might be a bit weird or hard to read for some people. Let me know what you think about it!
I'm getting 54429. Wish I knew what I was doing wrong.
Here's my code:
~~~
def get_digits(line: str) -> int:
""" Takes in a string, finds
spelled out numbers and digits. Returns the
first and last numbers found, concatenated
as a single two digit int """
NUMS = 'one two three four five six seven eight nine'.split()
num_dic = {k: str(v) for v, k in enumerate(NUMS, 1)}
found = []
for n in NUMS:
match = line.find(n)
if match >= 0:
found.append((match, num_dic.get(n)))
for i, l in enumerate(line):
if l.isdigit():
found.append((i, str(l)))
found = sorted(found, key=lambda x: x[0])
print(found)
if len(found) == 1:
return int(found[0][1]*2)
else:
return int(found[0][1] + found[-1][1])
~~~
You're only looking at the first occurrence of each digit. Try appending line.rfind(n) as well
W
Would you mind linking the code to your GitHub or in the decription if possible. Thx
For sure! Just added it