Guild icon
DDraceNetwork
Development / developer
Development discussion. Logged to https://ddnet.org/irclogs/ Connected with DDNet's IRC channel, Matrix room and GitHub repositories — IRC: #ddnet on Quakenet | Matrix: #ddnet-developer:matrix.org GitHub: https://github.com/ddnet
Between 2023-11-21 00:00:00Z and 2023-11-22 00:00:00Z
Avatar
chillerdragon BOT 2023-11-21 00:02:04Z
:c
Avatar
Avatar
Mr.Gh0s7
hmm it appears that qsort uses quicksort which in worst-case performance is O(n^2) while Bitonic sort worst-case is O(log^2(n)).
bitonic sort cannot be implemented on (current) CPUs though
00:17
so it's not really useful for C ^^
Avatar
:O true
Avatar
Avatar
Mr.Gh0s7
hmm it appears that qsort uses quicksort which in worst-case performance is O(n^2) while Bitonic sort worst-case is O(log^2(n)).
not always
00:30
glibc qsort will try mergesort first, musl uses heapsort, msvc uses quicksort
Avatar
ah ty I was looking for this info 😉
Avatar
glibc also might be falling back to insertion sort when it gets small enough, though I don't remember
Avatar
Avatar
Mr.Gh0s7
This is an example of what I mean. Rust itertools has this https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.k_smallest which probably from my understading (correct me if I am wrong :)) is this https://en.wikipedia.org/wiki/Sorting_network. In C you gotta implement/make it yourself
ic, well then this is nullified xD
Avatar
https://elixir.bootlin.com/glibc/latest/source/stdlib/qsort.c yeah if it resorts to quicksort, it'll only partially quicksort and finish it off with insertion sort
Elixir Cross Referencer - Explore source code in your browser - Particularly useful for the Linux kernel and other low-level projects in C/C++ (bootloaders, C libraries...)
Avatar
Avatar
Mr.Gh0s7
btw Learath have you heard about this before?
Only in context of hardware
Avatar
ok ty :)
Avatar
Funnily enough as far as the standard is concerned qsort doesn't even have any requirements, it could be quantum bogo sort
Avatar
I guess that this makes standard-compliance practically easier than having to prove performance requirements for compliance -- zogtib
Avatar
Sometimes requirements can become an issue, like the requirements on unordered_map in C++ permanently crippling it. So maybe the C approach of leaving it up to the implementers was the better choice
Avatar
I guess that performace behaviour is something important but it can make standard-compliance maybe harder than necessary because programmers don't care only for things required by the standards anyways.
00:52
*because programmers depend on implementations also for things the standards doesn't include etc
00:57
Thus, including things like that in standards would make doings things correctly harder because of the compliance overhead, even if those are practically necessary in implementations anyways. (I think this is what I mean) (edited)
Avatar
Avatar
Learath2
Sometimes requirements can become an issue, like the requirements on unordered_map in C++ permanently crippling it. So maybe the C approach of leaving it up to the implementers was the better choice
what's this
Avatar
I just found out that desmos has tone() funcion 😮
Avatar
Avatar
chillerdragon
What even are you scanning?
The server automatically does that bcs of spoofed atks
Avatar
Avatar
Ryozuki
engineering is how you architect applications in whole
This. You can reinvent the wheel million times. But for stuff that doesn't exist anyway you are forced to engineer, no way around it
Avatar
morning poggers2
Avatar
Good morning
Avatar
gm :)
Avatar
Avatar
Mr.Gh0s7
I just found out that desmos has tone() funcion 😮
xD it's been 6 hours since this
Avatar
chillerdragon BOT 2023-11-21 08:37:12Z
Still don’t get it. Is someone spoofing a ip and pinging you with master traffic which your server then responds to? The reflection attack? What’s the target of the attack? Did your Hoster Complain?
Replying to @Jupstar ✪ The server automatically does that bcs of spoofed atks
Avatar
Avatar
chillerdragon
Still don’t get it. Is someone spoofing a ip and pinging you with master traffic which your server then responds to? The reflection attack? What’s the target of the attack? Did your Hoster Complain?
Well that's the question. If the hoster also complains for master servers, then rip
08:50
Let's wait until the attacker reads this chat and tries out😬
Avatar
lot of places say the abi in linux is parameters in rdi, rsi, rdx, rcx, r8, and r9. but i found for syscalls rcx is replaced by r10
09:21
why are all cheat sheets using at&t omg
Avatar
Functions preserve the registers rbx, rsp, rbp, r12, r13, r14, and r15; while rax, rdi, rsi, rdx, rcx, r8, r9, r10, r11 are scratch registers. The return value is stored in the rax register, or if it is a 128-bit value, then the higher 64-bits go in rdx. Optionally, functions push rbp such that the caller-return-rip is 8 bytes above it, and set rbp to the address of the saved rbp. This allows iterating through the existing stack frames. This can be eliminated by specifying the -fomit-frame-pointer GCC option.
09:29
@heinrich5991 this is from the osdev wiki
Avatar
ws-client BOT 2023-11-21 11:55:22Z
<ChillerDragon> @Jupstar ✪ do you think it is a targeted attack to you? Or are all servers abused for one bundled reflection attack?
Avatar
The target is teeworlds ofc
12:00
Not me
12:01
If it would be me personally. I'd demand a wild Western like fight to settle this once and for all
Avatar
ws-client BOT 2023-11-21 12:48:50Z
<ChillerDragon> lmao
12:49
<ChillerDragon> Ah you assume the target is the master server it self
12:49
<ChillerDragon> Which servers do you even host? Some alive fng 0.7 servers?
Avatar
Why arent there more emotes
12:59
Like a hammer or hook emote
12:59
Hf emote
Avatar
because teeworlds didnt have hammerflying intended
Avatar
Who cares about that
Avatar
Avatar
ws-client
<ChillerDragon> Ah you assume the target is the master server it self
Not the target, but kind of the source
13:16
The fake source
13:16
For the reflection
Avatar
do u guys knows how much players a vps can handle per core/ghz
Avatar
i broke hammer welp
13:59
but really, where can i fix it?
Avatar
Avatar
Ryozuki
do u guys knows how much players a vps can handle per core/ghz
128p per shittiest vps u can buy
Avatar
Avatar
-StormAx
i broke hammer welp
😂brownbear
Avatar
and after i updated my client
14:51
gg
Avatar
Avatar
-StormAx
and after i updated my client
Provide src and we can help you troll
Avatar
fair (edited)
14:52
DDraceNetwork, a free cooperative platformer game. Contribute to StormAxs/StA development by creating an account on GitHub.
Avatar
oh lol didn't actually think it was open source
Avatar
Avatar
Teero
oh lol didn't actually think it was open source
Avatar
XDD how long did you not merge master?
Avatar
i just synced the fork (edited)
Avatar
do u use vulkan?
Avatar
Avatar
MilkeeyCat
do u use vulkan?
i tryed all render metods
14:56
even open gl 106
Avatar
rip
Avatar
U see far into the future
14:57
I'd say you have a missing data directory entry
14:57
Do a clean rebuild
Avatar
@Jupstar ✪ helped as always
15:03
thanks jupi
15:03
happy_cry_cat
15:05
well
15:06
where can i find hammer position while spectating?
Avatar
Avatar
-StormAx
i broke hammer welp
still this goofy bug
Avatar
@Jupstar ✪ do u think player count scales log or linear
15:25
perf wise
15:28
Uncorrelated
Avatar
@Learath2 ok i had a brain fart
15:28
i meant perf per player count
15:29
hmm like if u get a beefy vps
Avatar
Okay that makes more sense 😄
15:30
Theoretically it should exhibit polynomial behaviour with all the n^2 algorithms we use
15:31
But that's assuming one gameserver with player count going to infinity 😄
15:36
at work they doing a backend game server with elixir and i think something in rust
15:36
on a 24 core machine they could handle 600 players
15:36
which idk if its a lot
15:37
but well completly unrelated game
15:37
i think its 3d too
Avatar
Avatar
Ryozuki
on a 24 core machine they could handle 600 players
Uff that's really bad
Avatar
i thought so too
15:37
xd
Avatar
Is the game so complex?
Avatar
i doubt
15:37
im not in the team
15:37
i dont do elixir
Avatar
But network can quickly become a limiting factor
Avatar
i think its mainly cuz elixir ngl
15:38
true
15:38
i think they use websockets tho
15:38
they considering quic
Avatar
I assume these 600 players are on different lobbies too?
15:39
lobbies of 10 players iirc
Avatar
I c
Avatar
2.9ghz
15:39
256gb ram
15:39
but itjust uses 2gb iirc
15:39
xd
Avatar
XD
Avatar
gotta have backup kek
15:44
@Learath2 when use quad trees or bsp on ddnet
Avatar
maybe in @Zwelf's rust impl of ddnet physics 😉
15:46
it's probably easier there
Avatar
chillerdragon BOT 2023-11-21 16:43:31Z
Oh yea had the same. I think something with the mapres changed. Make sure your user wide storage location matches the source code generated data folders and so on. So just running a make install in your repo should fix it
Replying to @-StormAx and after i updated my client
16:47
Or updating ddnet via the package manager
Avatar
https://paste.pr0.tips/Hnw?c if anyone has a couple minutes, I'm curious how you would do this task
Avatar
Avatar
Learath2
https://paste.pr0.tips/Hnw?c if anyone has a couple minutes, I'm curious how you would do this task
where is the task?
Avatar
You just merge two sorted linked lists
Avatar
list.append(list2)
Avatar
The resulting list must also be sorted 😄
Avatar
then i'd use a datatype that is called sortedlist xd
Avatar
Avatar
Learath2
https://paste.pr0.tips/Hnw?c if anyone has a couple minutes, I'm curious how you would do this task
is that yours or from someone else?
Avatar
That's mine
Avatar
seems trivialish but also interesting, lemme try 🙂
Avatar
It's absolutely trivial, just curious how other people would go about it, there are lots of ways to do it
Avatar
Avatar
Learath2
That's mine
struct ListNode *mergeTwoLists(struct ListNode *list1, struct ListNode *list2) { struct ListNode dummy; // Dummy head node. struct ListNode *cur = &dummy; // While there are elements in either list. while (list1 && list2) { if (list1->val < list2->val) { cur->next = list1; list1 = list1->next; } else { cur->next = list2; list2 = list2->next; } cur = cur->next; } // Append the remaining elements of `list1` or `list2`. cur->next = list1 ? list1 : list2; return dummy.next; }
Avatar
hello chatgpt
Avatar
hi
Avatar
Avatar
Jupstar ✪
struct ListNode *mergeTwoLists(struct ListNode *list1, struct ListNode *list2) { struct ListNode dummy; // Dummy head node. struct ListNode *cur = &dummy; // While there are elements in either list. while (list1 && list2) { if (list1->val < list2->val) { cur->next = list1; list1 = list1->next; } else { cur->next = list2; list2 = list2->next; } cur = cur->next; } // Append the remaining elements of `list1` or `list2`. cur->next = list1 ? list1 : list2; return dummy.next; }
nice one
Avatar
ChatGPT definitely ruined the world
Avatar
yea, I think I like that one better
Avatar
It's the same as my first one 😄
17:53
Well same idea
Avatar
I was going to complain that yours does unnecessary writes
Avatar
Avatar
Learath2
It's the same as my first one 😄
inner cycle got removed
Avatar
also I find your first solution/chatgpt's solution easier to understand
Avatar
Yeah, I think I like that one better too
Avatar
struct ListNode *mergeTwoLists(struct ListNode *list1, struct ListNode *list2) { if (!list1) return list2; if (!list2) return list1; if (list1->val < list2->val) { list1->next = mergeTwoLists(list1->next, list2); return list1; } else { list2->next = mergeTwoLists(list1, list2->next); return list2; } }
17:54
xd
Avatar
no
Avatar
NOOO
Avatar
Meh, chatgpt definitely ruined the fun of these kinds of challanges
Avatar
I got zogpt
17:56
aka I just ask zogtib
Avatar
I was curious how you'd solve it, not how a machine learning model trained on stackoverflow where this question has been asked 10000 times would solve it
Avatar
the problem is, u didnt ask me if u want the fastest, or the cleanst, or the shortest
Avatar
fastest: don't use linked lists
Avatar
Avatar
Learath2
I was curious how you'd solve it, not how a machine learning model trained on stackoverflow where this question has been asked 10000 times would solve it
hm, are you golfing on so?
Avatar
I have a feeling you'd just ask chatgpt either way
Avatar
i think there's no gpt answers
Avatar
Avatar
Learath2
I have a feeling you'd just ask chatgpt either way
i mean i've done such coding challenges so often already
Avatar
Avatar
gerdoe
hm, are you golfing on so?
I'm just doing some leetcode to warm back up to coding
Avatar
Avatar
Jupstar ✪
i mean i've done such coding challenges so often already
Which solution you'd pick on your own volition given nothing but the challange is what's curious to me
Avatar
@Learath2 ok, here's is one i 100% did myself https://www.codewars.com/kata/52774a314c2333f0a7000688
Write a function that takes a string of parentheses, and determines if the order of the parentheses is valid. The function should return true if the string is valid, and false if it's invalid. Ex...
17:59
my solution: #include <stdbool.h> bool validParentheses(const char *s) { int CurP = 1; while(*s) { switch(*s++) { case '(': CurP *= 2; break; case ')': CurP /= 2; break; } } return CurP == 1; } (edited)
Avatar
Ah I did this one yesterday too
17:59
Oh, actually a different one nvm
Avatar
Avatar
Jupstar ✪
my solution: #include <stdbool.h> bool validParentheses(const char *s) { int CurP = 1; while(*s) { switch(*s++) { case '(': CurP *= 2; break; case ')': CurP /= 2; break; } } return CurP == 1; } (edited)
See now that's cute
Avatar
Avatar
Learath2
Which solution you'd pick on your own volition given nothing but the challange is what's curious to me
give me the codewars next time, then it's more fun, bcs it can compile etc.
Avatar
Hm, never tried codewars, let me give that a go too
Avatar
Avatar
Jupstar ✪
my solution: #include <stdbool.h> bool validParentheses(const char *s) { int CurP = 1; while(*s) { switch(*s++) { case '(': CurP *= 2; break; case ')': CurP /= 2; break; } } return CurP == 1; } (edited)
🤓 CurP <<= 1; CurP >>= 1;
Avatar
Oh actually I did try codewars a bit apparently
Avatar
struct list { int val; struct list *next; }; struct list *merge_inplace(struct list *a, struct list *b) { struct list *result; struct list **cur = &result; while(a && b) { if(a->val < b->val) { *cur = a; cur = &cur->next; a = a->next; } else { *cur = b; cur = &cur->next; b = b->next; } } if(a) { *cur = a; } else { *cur = b; } return result; }
18:02
here's mine, untested
18:02
it has also never seen a compiler
Avatar
As a fan of the double pointer trick I approve, the dummy head in gpts answer was ugly
Avatar
yea, I also didn't like it so much
18:05
it's essentially a hidden double pointer with a useless value field
Avatar
You are missing some *s I think
Avatar
yes
Avatar
Atleast my mental compiler isn't liking the amount of -> and & there per datatype 😄
Avatar
compiler says I should use &(*cur)->next instead of &cur->next
this 1
18:06
not necessary in rust :p
Avatar
Yeah I think I would change the very last if block to a ternary and have this as my final answer
Avatar
use std::mem; struct List { val: i32, next: Option<Box<List>>, } fn merge_inplace(mut a: Option<Box<List>>, mut b: Option<Box<List>>) -> Option<Box<List>> { let mut result = None; let mut cur: &mut Option<Box<List>> = &mut result; loop { match (a, b) { (Some(mut a_inner), Some(mut b_inner)) => { if a_inner.val < b_inner.val { let a_next = mem::replace(&mut a_inner.next, None); cur = &mut cur.insert(a_inner).next; a = a_next; b = Some(b_inner); } else { let b_next = mem::replace(&mut b_inner.next, None); cur = &mut cur.insert(b_inner).next; a = Some(a_inner); b = b_next; } } (Some(a_inner), None) => { *cur = Some(a_inner); break; } (None, Some(b_inner)) => { *cur = Some(b_inner); break; } (None, None) => break, } } result }
18:24
wow, that took a while
18:24
can chatgpt do this? I'd be impressed 😮
18:24
took me ~15min
18:25
this time developed together with the compiler
18:25
@Learath2 ^
Avatar
Avatar
heinrich5991
can chatgpt do this? I'd be impressed 😮
use std::mem; // Definition for singly-linked list. #[derive(PartialEq, Eq, Clone, Debug)] pub struct ListNode { pub val: i32, pub next: Option<Box<ListNode>>, } impl ListNode { #[inline] fn new(val: i32) -> Self { ListNode { next: None, val } } } pub fn merge_two_lists( list1: Option<Box<ListNode>>, list2: Option<Box<ListNode>>, ) -> Option<Box<ListNode>> { // Using a dummy head to simplify edge cases let mut dummy = Box::new(ListNode::new(0)); let mut cur = &mut dummy; // Two mutable references to list1 and list2 let mut l1 = list1; let mut l2 = list2; while l1.is_some() && l2.is_some() { let next_node = if l1.as_ref().unwrap().val < l2.as_ref().unwrap().val { // Temporarily replace l1 with None and take its value mem::replace(&mut l1, None).unwrap().next } else { // Temporarily replace l2 with None and take its value mem::replace(&mut l2, None).unwrap().next }; // Append the smaller node to the result cur.next = if l1.as_ref().unwrap().val < l2.as_ref().unwrap().val { l1.take() } else { l2.take() }; // Move the cur pointer forward cur = cur.next.as_mut().unwrap(); // Move the list pointers (l1 or l2) forward if l1.is_none() { l1 = next_node; } else { l2 = next_node; } } // Attach the remaining part of l1 or l2 cur.next = if l1.is_some() { l1 } else { l2 }; // Return the merged list, skipping the dummy head dummy.next }
18:25
NOT CHECKED
18:25
just copy pasted
Avatar
rip chiller
Avatar
not bad, compiles
Avatar
It's impressive that it can write rust at all given it's training set doesn't include quite as much of it
Avatar
it's writing rust like C though
Avatar
it is pretty bad in it tbh
Avatar
Yeah, it just wrote whatever one would write in C in Rust 😄
Avatar
Avatar
heinrich5991
use std::mem; struct List { val: i32, next: Option<Box<List>>, } fn merge_inplace(mut a: Option<Box<List>>, mut b: Option<Box<List>>) -> Option<Box<List>> { let mut result = None; let mut cur: &mut Option<Box<List>> = &mut result; loop { match (a, b) { (Some(mut a_inner), Some(mut b_inner)) => { if a_inner.val < b_inner.val { let a_next = mem::replace(&mut a_inner.next, None); cur = &mut cur.insert(a_inner).next; a = a_next; b = Some(b_inner); } else { let b_next = mem::replace(&mut b_inner.next, None); cur = &mut cur.insert(b_inner).next; a = Some(a_inner); b = b_next; } } (Some(a_inner), None) => { *cur = Some(a_inner); break; } (None, Some(b_inner)) => { *cur = Some(b_inner); break; } (None, None) => break, } } result }
arent strusts just objects LOL
Avatar
but color me impressed
Avatar
but now that it can serch the internet it's sometimes useful to find crates, bcs it reads the docs and at least kind of understands it 😄
Avatar
hmm. what was the prompts, @Jupstar ✪?
Avatar
Avatar
Jupstar ✪
my solution: #include <stdbool.h> bool validParentheses(const char *s) { int CurP = 1; while(*s) { switch(*s++) { case '(': CurP *= 2; break; case ')': CurP /= 2; break; } } return CurP == 1; } (edited)
*s++ would increment the value not the pointer no?
Avatar
Avatar
heinrich5991
use std::mem; struct List { val: i32, next: Option<Box<List>>, } fn merge_inplace(mut a: Option<Box<List>>, mut b: Option<Box<List>>) -> Option<Box<List>> { let mut result = None; let mut cur: &mut Option<Box<List>> = &mut result; loop { match (a, b) { (Some(mut a_inner), Some(mut b_inner)) => { if a_inner.val < b_inner.val { let a_next = mem::replace(&mut a_inner.next, None); cur = &mut cur.insert(a_inner).next; a = a_next; b = Some(b_inner); } else { let b_next = mem::replace(&mut b_inner.next, None); cur = &mut cur.insert(b_inner).next; a = Some(a_inner); b = b_next; } } (Some(a_inner), None) => { *cur = Some(a_inner); break; } (None, Some(b_inner)) => { *cur = Some(b_inner); break; } (None, None) => break, } } result }
Does rust have some guarantee as to the order match branches will be checked?
Avatar
Avatar
heinrich5991
hmm. what was the prompts, @Jupstar ✪?
rewrite in rust
Avatar
Avatar
Learath2
Does rust have some guarantee as to the order match branches will be checked?
top to bottom
Avatar
Avatar
Teero
*s++ would increment the value not the pointer no?
or does ++ have more priority than derefrence
Avatar
*s++ increments the pointer
Avatar
Avatar
Teero
or does ++ have more priority than derefrence
++ sticks harder
18:28
good to know (edited)
Avatar
Avatar
Learath2
Does rust have some guarantee as to the order match branches will be checked?
everything is evaluated in order it's written
18:29
also applies to function arguments, etc.
Avatar
Avatar
heinrich5991
everything is evaluated in order it's written
Hm, that sounds bad for performance, the compiler isn't allowed to reorder stuff?
Avatar
no, unless it can prove it doesn't affect the outcome
Avatar
Oh, okay
Avatar
I think C++ does the same nowadays?
Avatar
I thought even if it could prove it doesn't matter it wasn't allowed to change the order
Avatar
Avatar
Jupstar ✪
my solution: #include <stdbool.h> bool validParentheses(const char *s) { int CurP = 1; while(*s) { switch(*s++) { case '(': CurP *= 2; break; case ')': CurP /= 2; break; } } return CurP == 1; } (edited)
why *= and /= instead of just += and -= xdd
Avatar
Avatar
heinrich5991
I think C++ does the same nowadays?
C and C++ both use the same as-if rule, as long as there is no observable change it's fine
Avatar
Avatar
Teero
why *= and /= instead of just += and -= xdd
that actually serves a value there 😉
Avatar
Avatar
Learath2
C and C++ both use the same as-if rule, as long as there is no observable change it's fine
same for rust
18:31
but in C, order was undefined at some point, I thought
18:31
and C++
Avatar
Avatar
heinrich5991
that actually serves a value there 😉
what value xd
Avatar
1 / 2 * 2 = 0 ≠ 1 (edited)
18:32
that makes sense
Avatar
0 - 1 + 1 = 0 = 0
Avatar
Avatar
Jupstar ✪
my solution: #include <stdbool.h> bool validParentheses(const char *s) { int CurP = 1; while(*s) { switch(*s++) { case '(': CurP *= 2; break; case ')': CurP /= 2; break; } } return CurP == 1; } (edited)
what if there are more than 64 parenthesis?
Avatar
Avatar
heinrich5991
but in C, order was undefined at some point, I thought
If there are no sequence points order is undefined. If there are sequence points the compiler is only allowed to reorder if it can prove that it changes nothing
Avatar
Avatar
Chairn
what if there are more than 64 parenthesis?
*31
Avatar
If no sequence points the compiler can do whatever anyway
18:35
I don't think Rust has the idea of sequence points though, atleast I haven't encountered it yet
Avatar
Avatar
Chairn
what if there are more than 64 parenthesis?
then your computer explodes
18:42
gcc -Dint=__int128
18:43
😏
Avatar
Did any of you know about the Boyer-Moore string search algorithm?
18:50
After doing an exercise implementing strstr I was curious what a less naive solution looks like and came across it
Avatar
Avatar
Jupstar ✪
use std::mem; // Definition for singly-linked list. #[derive(PartialEq, Eq, Clone, Debug)] pub struct ListNode { pub val: i32, pub next: Option<Box<ListNode>>, } impl ListNode { #[inline] fn new(val: i32) -> Self { ListNode { next: None, val } } } pub fn merge_two_lists( list1: Option<Box<ListNode>>, list2: Option<Box<ListNode>>, ) -> Option<Box<ListNode>> { // Using a dummy head to simplify edge cases let mut dummy = Box::new(ListNode::new(0)); let mut cur = &mut dummy; // Two mutable references to list1 and list2 let mut l1 = list1; let mut l2 = list2; while l1.is_some() && l2.is_some() { let next_node = if l1.as_ref().unwrap().val < l2.as_ref().unwrap().val { // Temporarily replace l1 with None and take its value mem::replace(&mut l1, None).unwrap().next } else { // Temporarily replace l2 with None and take its value mem::replace(&mut l2, None).unwrap().next }; // Append the smaller node to the result cur.next = if l1.as_ref().unwrap().val < l2.as_ref().unwrap().val { l1.take() } else { l2.take() }; // Move the cur pointer forward cur = cur.next.as_mut().unwrap(); // Move the list pointers (l1 or l2) forward if l1.is_none() { l1 = next_node; } else { l2 = next_node; } } // Attach the remaining part of l1 or l2 cur.next = if l1.is_some() { l1 } else { l2 }; // Return the merged list, skipping the dummy head dummy.next }
looks weird xd
Avatar
Avatar
heinrich5991
*s++ increments the pointer
one thing i dislike about c++, this is confusing, but it makes some code look "nice" or "smart"
Avatar
Avatar
Ryozuki
one thing i dislike about c++, this is confusing, but it makes some code look "nice" or "smart"
It makes code look sexy asf and you know it
Avatar
@Learath2 it makes it look smart as i said
18:52
but not always writing "smart" code is good
18:52
specially if its not for a code golf
18:53
anyway rn im a nasm guy not rust guy
18:53
poggers2
🔥 1
18:54
@Learath2 i found a snippet of asm to calc next power of 2
18:54
and its rly nice
Avatar
Avatar
Ryozuki
one thing i dislike about c++, this is confusing, but it makes some code look "nice" or "smart"
void a () { int c = 0; ++++++++++++++c; } how do you like this code?
18:54
Contribute to edg-l/aoc2023-nasm development by creating an account on GitHub.
Avatar
oh look yet another snippet no one would ever see anywhere but in IOCCC
Avatar
next_pow_2: dec eax bsr rcx, rax inc ecx mov eax, 1 shl rax, cl ret
18:55
@Learath2 can u generate this with C
Avatar
Oh wait, is AOC now?
Avatar
no its in december
Avatar
Avatar
Ryozuki
@Learath2 can u generate this with C
Yes, I think I even sent a blog post about it sometime 😄
Avatar
@Learath2 this snippet uses eax and rax
18:55
so my understanding is
18:56
using eax builds to a instruction that is smaller
18:56
than rax?
18:56
and thats why its better?
18:56
or using rax will result in same perf
18:56
smaller instructions = better cache
Avatar
that's a question for @Chairn
18:57
It should in theory, but who knows, maybe it ends up pipelining worse and performs worse with 131 of them in a row
18:57
Modern CPUs are a mystery
Avatar
(it's taken me a while (I have some "minor" health difficulties))
18:57
struct listnode { int val; struct listnode *next; } struct listnode * mergeTwoLists(struct listnode *a, struct listnode *b) { struct listnode **p[2] = { &a, &b }; struct listnode *n, *lh; int i; if (!a) return b; if (!b) return a; lh = a->val < b->val ? a : b; /* list head */ n = lh; while (1) { i = a->val < b->val; n = n->next = *p[i]; if (!(*p = (*p)->next)) { n->next = *p[i ^ 1]; break; } } return lh; }
Avatar
i found out there is a mov instruction that can be used for branchless programming
Avatar
Avatar
Ryozuki
i found out there is a mov instruction that can be used for branchless programming
Ah yep, it's also iirc turing complete on it's own 😄
Avatar
COVIDL
18:58
18:58
there is lot of variants
Avatar
@Ryozuki if u want the real fun, do the opposite: reverse engineerig
Avatar
Avatar
Jupstar ✪
@Ryozuki if u want the real fun, do the opposite: reverse engineerig
too hard, i gotta start with mastering assembly first
Avatar
conditional moves are so hard to program with, I learned assembly on things that don't have them
19:00
You also don't think in terms of conditional moves when programming in C either, so it's not easy from that direction either
Avatar
but thats the dope thing about asm
19:00
fine grained control
19:00
u cant get more control
19:00
if ur a master of asm u are a magician
Avatar
Avatar
Ryozuki
u cant get more control
At that point, I found it's just more rope to hang yourself with, atleast on modern cpus 😦
Avatar
Call expected server callback functions to simulate clients dynamically connecting and disconnecting when changing the dbg_dummies variable. This makes the debug dummies more useful for debugging. Previously, the debug dummies were considered invalid clients, whereas they are now considered to be ingame, so they should behave mostly like real clients being connected to the server. The debug dummies also have correct client names now, e.g. "Debug dummy 42". The game server code is cleaned...
Avatar
I wish it was possible for mere humans like me to properly understand and program assembly for cpus that span a decade and are complicated beyond belief
Avatar
well im off, im taking a bike to some place and walk a mountain with a friend
19:01
cya later
Avatar
Avatar
Ryozuki
well im off, im taking a bike to some place and walk a mountain with a friend
don't, it's too late, bears will eat you
19:01
its rly relaxing to do this
19:01
u see the whole city of barcelona
19:01
with their lights
19:01
from the mountain
19:02
a good stress relief from work
19:02
19:02
took this some time ago
19:02
and my camera is shot
19:02
shit
19:02
mobile
Avatar
That is a nice picture
Avatar
Avatar
zogtib
struct listnode { int val; struct listnode *next; } struct listnode * mergeTwoLists(struct listnode *a, struct listnode *b) { struct listnode **p[2] = { &a, &b }; struct listnode *n, *lh; int i; if (!a) return b; if (!b) return a; lh = a->val < b->val ? a : b; /* list head */ n = lh; while (1) { i = a->val < b->val; n = n->next = *p[i]; if (!(*p = (*p)->next)) { n->next = *p[i ^ 1]; break; } } return lh; }
This is incorrect actually, this could be OK but it's definitely less wrong.
19:10
struct listnode * mergeTwoLists(struct listnode *a, struct listnode *b) { struct listnode **p[2] = { &a, &b }; struct listnode *n, ln; int i; if (!a) return b; if (!b) return a; n = &ln; while (1) { i = a->val < b->val; n = n->next = *p[i]; if (!(*p = (*p)->next)) { n->next = *p[i ^ 1]; break; } } return lh.next; }
19:14
That's also wrong. This compiles though (last submission): struct listnode * mergeTwoLists(struct listnode *a, struct listnode *b) { struct listnode **p[2] = { &a, &b }; struct listnode *n, ln; int i; if (!a) return b; if (!b) return a; n = &ln; while (1) { i = a->val < b->val; n = n->next = *p[i]; if (!(*p[i] = (*p[i])->next)) { n->next = *p[i ^ 1]; break; } } return ln.next; }
Avatar
Avatar
Jupstar ✪
gcc -Dint=__int128
what if more than 128 parenthesis ?
Avatar
Avatar
Chairn
what if more than 128 parenthesis ?
ryozuki can give you the llvm code to allow any amount of bits
19:16
xd
Avatar
i want your solution with recursive call
Avatar
Avatar
zogtib
That's also wrong. This compiles though (last submission): struct listnode * mergeTwoLists(struct listnode *a, struct listnode *b) { struct listnode **p[2] = { &a, &b }; struct listnode *n, ln; int i; if (!a) return b; if (!b) return a; n = &ln; while (1) { i = a->val < b->val; n = n->next = *p[i]; if (!(*p[i] = (*p[i])->next)) { n->next = *p[i ^ 1]; break; } } return ln.next; }
If I wanted to sell it I'd prob say that it checks if a or b is NULL only they get changed and not on every iteration. 🙂
Avatar
Avatar
Ryozuki
smaller instructions = better cache
in general yes, but there can be alignment issues or different uops generated leading to overall less performance. But that's intel's fault though
Avatar
Avatar
Voxel
another concept i JUST thought of: why not modernize the killfeed to include more information? Rather it be icons for how someone is killed, or even misc. things, like stealing someone else's kill, or winning a race? this could also crunch down a few elements, like if you restart multiple times or if you score a wrong goal in FNG, so the feed isnt too cluttered?
@furo ancient idea but lol
Avatar
With a single type of paren you can just use a single bit to keep track of it, no?
19:34
Mh, not enough, just a single int should be enough for 2^sizeof (int) pairs tho
19:37
Open paren is always legal s++, close paren legal iff s > 0 s--, if you end with anything but s == 0 invalid, otherwise valid
Avatar
Yeah, that also how I solved recursively, but the same works in a loop: bool ValidParenthesesImpl(const char *pStr, unsigned Num) { switch(pStr[0]) { case '(': return ValidParenthesesImpl(pStr + 1, Num + 1); case ')': return Num > 0 && ValidParenthesesImpl(pStr + 1, Num - 1); case '\0': return Num == 0; default: return ValidParenthesesImpl(pStr + 1, Num); } } bool ValidParentheses(const char *pStr) { return ValidParenthesesImpl(pStr, 0); }
Avatar
Avatar
Robyt3
Yeah, that also how I solved recursively, but the same works in a loop: bool ValidParenthesesImpl(const char *pStr, unsigned Num) { switch(pStr[0]) { case '(': return ValidParenthesesImpl(pStr + 1, Num + 1); case ')': return Num > 0 && ValidParenthesesImpl(pStr + 1, Num - 1); case '\0': return Num == 0; default: return ValidParenthesesImpl(pStr + 1, Num); } } bool ValidParentheses(const char *pStr) { return ValidParenthesesImpl(pStr, 0); }
Why did your mind go directly to recursive? The problem doesn't intuitively look recursive to me
Avatar
I only went specifically for recursive because Chairn asked
Avatar
Ah, I see
19:54
I really need to make peace with recursion. Whenever I feel like doing recursion for a problem I'll use an explicit stack instead
Avatar
Avatar
Learath2
Did any of you know about the Boyer-Moore string search algorithm?
yes, default substring search algorithm AFAIK
Avatar
Avatar
heinrich5991
yes, default substring search algorithm AFAIK
Atleast for glibc yeah
20:04
glibc is my goto for seeing what is better than naive
Avatar
Avatar
zogtib
struct listnode { int val; struct listnode *next; } struct listnode * mergeTwoLists(struct listnode *a, struct listnode *b) { struct listnode **p[2] = { &a, &b }; struct listnode *n, *lh; int i; if (!a) return b; if (!b) return a; lh = a->val < b->val ? a : b; /* list head */ n = lh; while (1) { i = a->val < b->val; n = n->next = *p[i]; if (!(*p = (*p)->next)) { n->next = *p[i ^ 1]; break; } } return lh; }
interesting. I think I like the earlier solutions better, due to clarity. this one might minimize branches though
Avatar
Avatar
Learath2
I really need to make peace with recursion. Whenever I feel like doing recursion for a problem I'll use an explicit stack instead
that's usually the better idea, no stack smashing due to untrusted input (edited)
Avatar
struct ListNode *mergeTwoLists(struct ListNode *list1, struct ListNode *list2) { struct ListNode *head = (struct ListNode *)&list1; struct ListNode **tail = &head; while (list1 && list2) { struct ListNode **min = list1->val < list2->val ? &list1 : &list2; *tail = *min; *min = (*min)->next; tail = &((*tail)->next); } *tail = (struct ListNode *)((uintptr_t)list1 | (uintptr_t)list2); return head->next; }
20:31
GPeakT
20:31
the line before the return is cool xd
Avatar
it might also break clang
Avatar
it might break more than clang as it's implementation defined behaviour
Avatar

Checklist

  • [X] Tested the change ingame
  • [ ] Provided screenshots if it is a visual change
  • [ ] Tested in combination with possibly related configuration options
  • [ ] Written a unit test (especially base/) or added coverage to integration test
  • [ ] Considered possible null pointers and out of bounds array indexing
  • [ ] Changed no physics that affect existing maps
  • [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addres...
Avatar
ah right nullptr doesn't need to be 0
Avatar
Avatar
Learath2
it might break more than clang as it's implementation defined behaviour
hmmm. but in clang/gcc on common targets, this is defined to be all-0-bit-pattern, no?
Avatar
where is the impl defined behavior
Avatar
((uintptr_t)list1 | (uintptr_t)list2)
21:34
nullptr isn't guaranteed to translate to 0 if it is cast to some integer type
21:36
seems annoying to have to list1 ? list1 : 0 lol
21:36
darn
Avatar
i got a problem while using TAB to fill commands /top5 for example but get the game crash, the question is: where can i find NumCommands probably this is where i missed
21:43
Avatar
does this happen in ddnet
Avatar
own client
21:44
or means gameMode?
Avatar
Avatar
-StormAx
i broke hammer welp
btw i still have this hammer issue
Avatar
that's a divide by zero error
21:50
% implicitly divides to find the remainder
Avatar
Maybe more of a concept? Not sure if this is too hacky and can't guarantee this doesn't break things. Adds /mode that can enable teams to behave like team 0 with the added benefit of being able to manage it with /lock and /invite. Tested with possible configurations such as sv_team, sv_max_team_size, sv_min_team_size, sv_solo_server. Teams in "team 0 mode" can't use /save, /load or /practice. Closes #7380 Very little showcase: https://github.com/ddnet/dd...
22:57
0d8a0d3 Dynamically connect/disconnect debug dummies, cleanup - Robyt3 7c0c705 Merge pull request #7519 from Robyt3/Server-Debug-Dummies-Dynamic - def-
Avatar
aoc will be interesting
23:35
Stable Video Diffusion is a proud addition to our diverse range of open-source models. Spanning across modalities including image, language, audio, 3D, and code, our portfolio is a testament to Stability AI’s dedication to amplifying human intelligence.
23:35
@Jupstar ✪ gg
Avatar

Checklist

  • [ ] Tested the change ingame
  • [ ] Provided screenshots if it is a visual change
  • [ ] Tested in combination with possibly related configuration options
  • [ ] Written a unit test (especially base/) or added coverage to integration test
  • [ ] Considered possible null pointers and out of bounds array indexing
  • [ ] Changed no physics that affect existing maps
  • [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresss...
Exported 362 message(s)