9000's recent activity

  1. Comment on Day 4: Secure Container in ~comp.advent_of_code

    9000
    Link
    Language: Rust As everyone else is saying, this one was much easier. I felt that there was probably a pure math way to solve this, but I couldn't quite work it out and I don't think it would work...

    Language: Rust

    As everyone else is saying, this one was much easier. I felt that there was probably a pure math way to solve this, but I couldn't quite work it out and I don't think it would work for arbitrary ranges. Anyway, the solution:

    Solution
    fn main() {
        let mut num_1: usize = 0;
        let mut num_2: usize = 0;
        for n in 382345..843167{
            let mut increasing = true;
            let mut double_1 = false;
            let mut double_2 = false;
            let mut prev_digit = n % 10;
            let mut run_length = 1;
            for digit in 1..6 {
                let next_digit = (n / 10_u32.pow(digit)) % 10;
                if prev_digit < next_digit {
                    increasing = false;
                    break;
                } else if prev_digit == next_digit {
                    double_1 = true;
                    run_length += 1;
                } else {
                    if run_length == 2 {
                        double_2 = true;
                    }
                    run_length = 1;
                }
                prev_digit = next_digit;
            }
            if increasing && double_1 {
                num_1 += 1;
            }
            if increasing && (double_2 || run_length == 2) {
                num_2 += 1;
            }
        }
    
        println!("Number of passwords (Part 1): {}", num_1);
        println!("Number of passwords (Part 2): {}", num_2);
    }
    
    2 votes
  2. Comment on Day 3: Crossed Wires in ~comp.advent_of_code

    9000
    Link
    Language: Rust This problem was much more intricate, so the code is much more complicated. I really wish it was cleaner and easier to follow. I had to refactor several times to get part 2 to work...

    Language: Rust

    This problem was much more intricate, so the code is much more complicated. I really wish it was cleaner and easier to follow. I had to refactor several times to get part 2 to work at all. If people have readability suggestions, I'm willing to listen (though, please don't be too pedantic).

    When I first started working on this problem, I tried to be clever and account for the case where two horizontal or two vertical wires crossed, and then choose the correct point. It's possible, but super complicated and not necessary for the problem, so I gave up (hence the _ case in the cross_*() functions).

    Part 1 and 2
    use std::fs;
    use std::vec::Vec;
    
    struct Line {
        horizontal: bool,
        x: isize,
        y: isize,
        length: isize,
    }
    
    impl Line {
        fn new (line: &str, x: &mut isize, y: &mut isize) -> Line {
            let (dir, length) = line.split_at(1);
            let length = length.parse().unwrap();
    
            let ret;
            match dir {
                "R" => {
                    ret = Line {horizontal : true, x : *x, y : *y, length : length};
                    *x += length;
                }
                "D" => {
                    ret = Line {horizontal : false, x : *x, y : *y, length : -1 * length};
                    *y -= length;
                }
                "L" => {
                    ret = Line {horizontal : true, x : *x, y : *y, length : -1 * length};
                    *x -= length;
                }
                "U" => {
                    ret = Line {horizontal : false, x : *x, y : *y, length : length};
                    *y += length;
                }
                _ => {panic!("Cannot parse line: {}", line);}
            }
    
            ret
        }
    
        /* Returns the point at which the lines cross (if they do cross)
         * Only used for part 1
         */
        fn cross_point(&self, other: &Line) -> Option<(isize, isize)> {
            match (self.horizontal, other.horizontal) {
                (true, false) => {
                    let (self_lower, self_upper) = order(self.x, self.x + self.length);
                    let (other_lower, other_upper) = order(other.y, other.y + other.length);
                    if self_lower < other.x
                        && self_upper > other.x
                        && other_lower < self.y
                        && other_upper > self.y {
                            return Some((other.x, self.y))
                        }
                }
                (false, true) => {
                    let (self_lower, self_upper) = order(self.y, self.y + self.length);
                    let (other_lower, other_upper) = order(other.x, other.x + other.length);
                    if self_lower < other.y
                        && self_upper > other.y
                        && other_lower < self.x
                        && other_upper > self.x {
                            return Some((self.x, other.y))
                        }
                }
                _ => {}
            }
    
            None
        }
    
        /* Returns the length of wire, until the lines cross, for each line (if they do cross)
         * Only used for part 2
         */
        fn cross_length(&self, other: &Line) -> Option<(isize, isize)> {
            match (self.horizontal, other.horizontal) {
                (true, false) => {
                    let (self_lower, self_upper) = order(self.x, self.x + self.length);
                    let (other_lower, other_upper) = order(other.y, other.y + other.length);
                    if self_lower < other.x
                        && self_upper > other.x
                        && other_lower < self.y
                        && other_upper > self.y {
                            return Some(((other.x - self.x).abs(), (self.y - other.y).abs()))
                        }
                }
                (false, true) => {
                    let (self_lower, self_upper) = order(self.y, self.y + self.length);
                    let (other_lower, other_upper) = order(other.x, other.x + other.length);
                    if self_lower < other.y
                        && self_upper > other.y
                        && other_lower < self.x
                        && other_upper > self.x {
                            return Some(((self.x - other.x).abs(), (other.y - self.y).abs()))
                        }
                }
                _ => {}
            }
    
            None
        }
    
    }
    
    fn main() {
        let paths = fs::read_to_string("input").unwrap();
        let paths: Vec<&str> = paths.split('\n').collect();
        let mut x = 0;
        let mut y = 0;
        let path_1: Vec<Line> = paths[0].split(',').map(|line| {Line::new(line.trim(), &mut x, &mut y)}).collect();
        x = 0;
        y = 0;
        let path_2: Vec<Line> = paths[1].split(',').map(|line| {Line::new(line.trim(), &mut x, &mut y)}).collect();
    
        println!("The closest point by Manhattan distance (Part 1): {}", manhattan_distance_of_closest_point(&path_1, &path_2));
        println!("The closest point by wire distance (Part 2): {}", wire_distance_of_closest_point(&path_1, &path_2));
    }
    
    /* Finds the closest point by Manhattan distance, and returns that distance.
     * Only used for part 1
     */
    fn manhattan_distance_of_closest_point(path_1: &Vec<Line>, path_2: &Vec<Line>) -> isize {
        let mut closest_point: isize = isize::max_value();
        for line_1 in path_1 {
            for line_2 in path_2 {
                match line_1.cross_point(line_2) {
                    Some((x, y)) => {
                        if x.abs() + y.abs() < closest_point {
                            closest_point = x.abs() + y.abs();
                        }
                    }
                    None => {}
                }
            }
        }
    
        closest_point
    }
    
    /* Finds the closest point by cumulative wire length, and returns that distance.
     * Only used for part 2
     */
    fn wire_distance_of_closest_point(path_1: &Vec<Line>, path_2: &Vec<Line>) -> isize {
        let mut closest_point: isize = isize::max_value();
        let mut line_1_length = 0;
        for line_1 in path_1 {
            let mut line_2_length = 0;
            for line_2 in path_2 {
                match line_1.cross_length(line_2) {
                    Some((line_1_cross_dist, line_2_cross_dist)) => {
                        if line_1_length + line_1_cross_dist + line_2_length + line_2_cross_dist < closest_point {
                            closest_point = line_1_length + line_1_cross_dist + line_2_length + line_2_cross_dist;
                        }
                    }
                    None => {}
                }
                line_2_length += line_2.length.abs();
            }
            line_1_length += line_1.length.abs();
        }
    
        closest_point
    }
    
    #[inline]
    fn order(n: isize, m: isize) -> (isize, isize) {
        if n < m {
            return (n, m);
        }
        (m, n)
    }
    
    2 votes
  3. Comment on Day 1: The Tyranny of the Rocket Equation in ~comp.advent_of_code

    9000
    Link
    Language: Rust I initially thought that we had to run the rocket equation on the total mass of fuel instead of each module's fuel, so my initial answer was high. But, that was just me misreading...

    Language: Rust

    I initially thought that we had to run the rocket equation on the total mass of fuel instead of each module's fuel, so my initial answer was high. But, that was just me misreading the instructions.

    Part 1 I got a little carried away with argument parsing in my main function... It's way too complicated. I should have just assumed there would be one file. Oh well.
    /* day_1
     *
     * USAGE
     *     cargo run [input files]
     * 
     * Input files must be a newline-separated list of positive integers greater 
     * than 5. For each input file listed, day_1 will return the answer for both
     * part one and part two.
     *
     */
    
    use std::env;
    use std::fs;
    use std::vec::Vec;
    
    fn main() {
        let args: Vec<String> = env::args().collect();
        if args.len() <= 1 {
            eprintln!("File name(s) required!");
            return;
        }
    
        for index in 1..args.len() {
            println!("{}", args[index]);
            println!("----------");
            let mut module_masses: Vec<u32> = Vec::new();
            for line in fs::read_to_string(&args[index]).unwrap().lines() {
                module_masses.push(line.parse().unwrap());
            }
            println!("Fuel required for modules (part 1): {}", calculate_fuel_required_for_part_one(&module_masses));
            println!("Fuel required for modules (part 2): {}", calculate_fuel_required_for_part_two(&module_masses));
            if index != args.len() - 1 {
                println!();
            }
        }
    }
    
    fn calculate_fuel_required_for_part_one(module_masses: &Vec<u32>) -> u32 {
        let mut total_fuel = 0;
        for module_mass in module_masses {
            total_fuel += (module_mass / 3) - 2;
        }
    
        total_fuel
    }
    
    fn calculate_fuel_required_for_part_two(module_masses: &Vec<u32>) -> u32 {
        let mut total_fuel = 0;
        for module_mass in module_masses {
            total_fuel += calculate_fuel_required_for_a_module(module_mass);
        }
    
        total_fuel
    }
    
    fn calculate_fuel_required_for_a_module(mass: &u32) -> u32 {
        let mut total_fuel = 0;
        let mut fuel_delta = (mass / 3) - 2;
    
        while fuel_delta > 6 {
            total_fuel += fuel_delta;
            fuel_delta = (fuel_delta / 3) - 2;
        }
    
        total_fuel + fuel_delta
    }
    
    3 votes
  4. Comment on Day 2: 1202 Program Alarm in ~comp.advent_of_code

    9000
    (edited )
    Link
    Language: Rust I just refactored and extended my initial solution to give me the answer to both parts, so i don't have a Part 1/2 distinction. I used this as an opportunity to get a little more...

    Language: Rust

    I just refactored and extended my initial solution to give me the answer to both parts, so i don't have a Part 1/2 distinction.

    I used this as an opportunity to get a little more used to streams! I haven't really used them at all before, but structured file parsing is a good use case where streams prevent me from allocating unnecessary Vecs.

    Solution
    /* day_2
     *
     * USAGE
     *     day_2 [filename]
     * 
     * Runs the Intcode program at `filename`.
     */
    use std::env;
    use std::fs;
    use std::vec::Vec;
    
    const GOAL: usize = 19690720;
    
    fn main() {
        // Get filename
        let args: Vec<String> = env::args().collect();
        let filename = "input".to_string();
        let filename = args.get(1).unwrap_or(&filename);
    
        // Parse instructions
        let instructions = fs::read_to_string(filename).unwrap();
        let instructions: Vec<usize> = instructions.split(',')
            .map(|x| x.trim().parse().unwrap())
            .collect();
    
        // Constants given in problem for part 1
        println!("Part 1: {}", run_intcode(&instructions, 12, 2));
    
        for noun in 0..100 {
            for verb in 0..100 {
                if run_intcode(&instructions, noun, verb) == GOAL {
                    println!("Part 2: noun = {}, verb = {}, answer = {}", noun, verb, 100 * noun + verb);
                    return;
                }
            }
        }
    }
    
    fn run_intcode(instructions: &Vec<usize>, noun: usize, verb: usize) -> usize {
        let mut instructions = instructions.clone();
        instructions[1] = noun;
        instructions[2] = verb; 
    
        let mut index = 0;
        while index < instructions.len() {
            match instructions[index] {
                1 => { // Add
                    let num_1 = instructions[instructions[index + 1]];
                    let num_2 = instructions[instructions[index + 2]];
                    let dest = instructions[index + 3];
                    instructions[dest] = num_1 + num_2;
                }
                2 => { // Multiply
                    let num_1 = instructions[instructions[index + 1]];
                    let num_2 = instructions[instructions[index + 2]];
                    let dest = instructions[index + 3];
                    instructions[dest] = num_1 * num_2;
                }
                99 => { // End
                    return instructions[0];
                }
                _ => { // Error
                    eprintln!("ERROR: Received instruction {} at position {}", instructions[index], index);
                }
            }
            index += 4;
        }
    
        eprintln!("WARNING: End of memory! Did not end at opcode 99.");
        instructions[0]
    }
    
    2 votes
  5. Comment on A Comment Is An Invitation For Refactoring in ~comp

    9000
    Link Parent
    I think it also depends on the kind of churn you expect your project to have. Because, like you said, domain experts don't need comments. So, if you're working with the same code day in and day...

    I think it also depends on the kind of churn you expect your project to have. Because, like you said, domain experts don't need comments. So, if you're working with the same code day in and day out such that you become a domain expert, you might find all comments to be unnecessary. But, even another competent programmer (or, your future self) might not have the context that makes it clear. Sure, you can have variable and function names that are a sentence long (especially if you use an IDE), but sometimes it's just more clear and ergonomic to use shorter names and have a comment that explains their relationship. Or, keep more lines of code in the same function and leave an inline comment to group them without as much boilerplate as a new function (and thus, without forcing the reader to CTRL-f back and forth to understand what's going on).

    For instance, I don't like the first example. I'd rather just leave the context in the function. Otherwise, if I wanted to change something, I have to search through a deep callstack to understand what's going on. Why create a function if you're not planning on reusing the code? If it's just to name what's going on, that seems wasteful of line space and mental real estate.

    I've seen codebases where there were three login*() functions in a class, one calling the next, before the logic was implemented in a different class! To discover that, I found the first login call, and had to keep searching through it's callstack, understanding a new context each time, until I found the implemented logic. Self-documenting code is nice, but it's a tool, not a Platonic form.

    6 votes
  6. Comment on Tildes Pen Pals in ~talk

    9000
    Link
    Age group: early twenties Topics of interest: (no particular order) philosophy (esp. ethics, philosophy of mind, political philosophy, and some epistemology. But I'll discuss anything!) world...

    Age group: early twenties

    Topics of interest: (no particular order)

    • philosophy (esp. ethics, philosophy of mind, political philosophy, and some epistemology. But I'll discuss anything!)
    • world politics
    • spirituality (esp. Buddhism)
    • free culture
    • wildlife
    • travel
    • distributed systems (DAT, ipfs, etc.)
    • computer security/cryptography

    Country: USA

    Happy to mail anywhere in the world or email.

    5 votes
  7. Comment on Exploring the feasibility of brute-force guessing a 64-bit number through different techniques in ~comp

    9000
    Link Parent
    That's an interesting point! You could open an issue or pull request, since they say help is welcome?

    That's an interesting point! You could open an issue or pull request, since they say help is welcome?

    2 votes
  8. Comment on Exploring the feasibility of brute-force guessing a 64-bit number through different techniques in ~comp

  9. Comment on Peertube 2.0 is out in ~tech

    9000
    Link Parent
    What you say is true, but not quite what @WendigoTulpa seems to be asking about. They seem to be asking about whether users' machines will be involved in serving videos to other users, and the...

    What you say is true, but not quite what @WendigoTulpa seems to be asking about. They seem to be asking about whether users' machines will be involved in serving videos to other users, and the answer there is "yes". Not only does the server serve the video content to you, but other users will as well (à la bittorrent or LimeWire). For instance, if you click on the video in the OP article, it will list some number of peers that you are connected and sharing data with.

    This is an important property of PeerTube. Video hosting is expensive. Like, really expensive. So, to be able to compete with YouTube, not only would you want decentralization with ActivityPub, but you also want to distribute the load across your clients. This means that if a video becomes super popular, the server sees a lot less load than they would otherwise. For the long tail of videos, the server will still be doing about as much work as YouTube, but those are also the videos that are significantly less likely to be seen.

    3 votes
  10. Comment on The Mandalorian | S01E01+E02 in ~tv

    9000
    Link Parent
    You're right! I thought he was a Mandalorian, but according to the fan wikis, he is not. My bad!

    I don't think Boba Fett is related to the Mandalorians, aside from the armor he wears.

    You're right! I thought he was a Mandalorian, but according to the fan wikis, he is not. My bad!

    3 votes
  11. Comment on The Mandalorian | S01E01+E02 in ~tv

    9000
    (edited )
    Link
    So far I've been really enjoying it! The aesthetics are very high quality and really help to set the tone. I also really like how they reference but also expand on things we already know about the...

    So far I've been really enjoying it! The aesthetics are very high quality and really help to set the tone. I also really like how they reference but also expand on things we already know about the Star Wars universe. The Force Awakens felt so copycat and The Last Jedi, like The Phantom Menace, seemed to break some of the pre-established lore. But I really like the direction The Mandalorian is going, because it expands on existing lore, bringing in new concepts, but without overwriting anything. At least, so far.

    There are a few things I am either confused about, or didn't like. On the confusion side, I'd be interested in the backstory to the female Mandalorian. Because, my understanding was that Boba Fett and the clones in the Prequels were all clones of Jengo Fett. But, I'm opticimistic that there will be an interesting backstory here, since it seems like the Mandalorians have developed a sort of group identity and "religion". Honestly, I was confused that there was anyone more than just Boba Fett!

    In terms of dislike, I don't like how easily the baby Yoda could use the Force. They make a big fuss in all the movies about how important and difficult it is to train, and that prior to training the Force shows itself in subtler, harder to control ways. Like, I get that Yoda was a super masterful jedi, but I always assumed that was through centuries of training and self-discipline. But, I digress.

    All in all, I am very excited to see where this goes!


    EDIT: Jengo and Boba Fett were not Mandalorians, they just wore Mandalorian armor [1]

    4 votes
  12. Comment on What are some good news outlets you would recommend? in ~talk

    9000
    Link Parent
    I'm sorry, but my initial investigation was not thorough enough. Please see my edit. It appears that NewsHour is now owned by an independent public broadcasting company based out of Washington...

    I'm sorry, but my initial investigation was not thorough enough. Please see my edit. It appears that NewsHour is now owned by an independent public broadcasting company based out of Washington D.C.

    Apologies for the initial misrepresentation.

    3 votes
  13. Comment on What are some good news outlets you would recommend? in ~talk

    9000
    (edited )
    Link Parent
    I cannot find any evidence that the Koch brothers are on the board of NewsHour. I found that they have donated (though my cursory search has not turned up a number), but I can't find evidence they...

    I cannot find any evidence that the Koch brothers are on the board of NewsHour. I found that they have donated (though my cursory search has not turned up a number), but I can't find evidence they are on the board.

    According to the Wikipedia page, Liberty Media bought a controlling stake in NewsHour in 1994, and John C. Malone has a controlling stake in Liberty Media [SEE EDIT]. There is no mention of the Kochs, though.

    I recommend reading the Criticism and Scholarly Analysis sections of the NewsHour Wikipedia page for a discussion of bias, because I don't feel comfortable summarizing in any fewer words.


    EDIT: Apparently Liberty Media no longer owns NewsHour. In 2013, they sold their stake to WETA-TV, a PBS member station. It mentions this in the NewsHour history section, and NewsHour is listed as a former asset on Liberty Media's page.

    WETA-TV itself is owned by Greater Washington Educational Telecommunications Association, which also owns the WETA NPR station. So, WETA-TV seems to almost exclusively be an independent public media company.

    8 votes
  14. Comment on Detectorists - "unremarkable lives gone slightly awry" in ~tv

    9000
    Link
    I really enjoyed watching the Detectorists, but I've never met anyone else bring it up again, so I thought I was the only one. I'm glad it's getting some love, as it is a wonderful series.

    I really enjoyed watching the Detectorists, but I've never met anyone else bring it up again, so I thought I was the only one.

    I'm glad it's getting some love, as it is a wonderful series.

    6 votes
  15. Comment on Re-Licensing Sentry in ~comp

    9000
    Link Parent
    Yeah, I'm not entirely sure why they didn't go that route. They could easily offer a separate proprietary license for those who required it, and could strictly control what could be done in that...

    Yeah, I'm not entirely sure why they didn't go that route. They could easily offer a separate proprietary license for those who required it, and could strictly control what could be done in that license. (They could still accept community contributions with a Contributor License Agreement.)

    My understanding is that a lot of businesses are very afraid of viral licenses like the AGPL for fear of accidentally infecting their proprietary code, so it may have reduced their free/libre consumer base. But, I'm not Sentry, so I don't actually know what their decision-making process was.

  16. Comment on Re-Licensing Sentry in ~comp

    9000
    (edited )
    Link Parent
    Yes, this is true. I mentioned Red Hat twice in my post. But, many businesses have tried that route, and very few have been stable for as long as Red Hat. Also, Red Hat has not felt the need to...

    Yes, this is true. I mentioned Red Hat twice in my post. But, many businesses have tried that route, and very few have been stable for as long as Red Hat. Also, Red Hat has not felt the need to relicense their code because like you say, they are not selling their code, just support. And finally, Sentry isn't primarily selling either support or custom contracts, they are primarily selling use of their platform. That is why they need the BSL, because it prevents alternative hosts from appearing.

    Red Hat doesn't really care about CentOS, because it would be very difficult for a community who didn't write the code to provide as quality documentation and support as they can. Sentry cannot afford this because a single competitor can competently host their software, again because it's hard to sell open source software as the product.

    EDIT: typos

    2 votes
  17. Comment on Re-Licensing Sentry in ~comp

    9000
    Link Parent
    I don't know if the BSL is what's necessary for open source to counter the new cloud world order. For instance, I feel like Gitlab taking Sentry's open source code and running it on their servers...

    I don't know if the BSL is what's necessary for open source to counter the new cloud world order. For instance, I feel like Gitlab taking Sentry's open source code and running it on their servers under their brand is analogous to Juniper Networks taking FreeBSD and rebranding it as JunOS and selling it. In fact, this is not uncommon with BSD distributions. Their permissive license structure allows companies to come in and profit off their work.

    Don't get me wrong, I think the BSDs have a lot going for them, but I think the GPL, and explicitly its "viral" nature, allowed Linux to take off so intensely. Changes had to be made available to consumers who had the right to merge them back upstream. This meant that Linux gained features and grew into a broader platform faster. However, it also meant that it was harder for someone to make money on Linux! Companies contribute because having the changes to Linux are valuable, and you might as well get them upstream if they're going to be public anyway (Android OEMs excluded).

    So, instead, Sentry could consider something like the AGPL, but since that is frowned upon by a lot of corporations, they won't. But, critically, it's hard to make money on open source at all!

    Linus Torvalds is nowhere close to being the richest man in the world; Bill Gates and Steve Jobs came much closer. Open source hasn't been very profitable as a product. It's been incredibly valuable as a process, but it has always been hard to capitalize on it in more conventional economic terms.

    Red Hat and Sun Microsystems came close to having a model, but neither became a top ten company. Open source seems to more successfully be driven by collaborative development. Groups of people with common needs coming together to make something to fulfill those needs and forking when they can't agree. This is why some of the most successful names in open source are GNU, the Linux Foundation, the Debian Project, and the Mozilla Foundation; all collaborative efforts that are not really trying to sell anything. Sure, Red Hat and Canonical do alright (especially the former), but there doesn't seem to be a lot of room in their part of the market.

    This is not to say that highly profitable companies don't produce open source software, in fact much of it is written by them, but instead to say that most of them don't try to monetize said software. Google can release all the open source code it wants, but it won't release GSuite or search or God forbid ads, and they've even backtracked some on Android with their focus on Play Services.

    5 votes
  18. Comment on How will Tildes users be able to visualize trust? in ~tildes

    9000
    Link Parent
    I agree, however, computers are already in the mix messing things up. Brains are good at remembering faces. Brains are good at remembering up to a couple hundred people they interact with...

    I agree, however, computers are already in the mix messing things up. Brains are good at remembering faces. Brains are good at remembering up to a couple hundred people they interact with regularly before defaulting to heuristics like tribalism. And look, we're already breaking those rules. We can't see faces, and there are hundreds of people here already, and someday there may be thousands of active members or more.

    My point is not that you're wrong, my point is that it will already be difficult to maintain trust relationships on a large forum site, so if that's something we want to do, we might have to augment the UI or structure of the site to enable it. Will that change perfectly capture the essence of trust? No, but it might help grease the wheels of trust, allowing it to operate smoothly.

    For the record, I don't know what that change should be, but I like some of the ideas in this thread.

    2 votes
  19. Comment on The State of California Could Have Stopped 8Chan: It Didn’t in ~tech

    9000
    Link Parent
    You are correct. Clients do not route traffic in Tor, as it is currently implemented. Instead, volunteers run relays, which are used by clients to randomize their traffic. A related project, i2p,...

    Tor is not p2p afaik. Unless you are relaying while browsing?

    You are correct. Clients do not route traffic in Tor, as it is currently implemented. Instead, volunteers run relays, which are used by clients to randomize their traffic.

    A related project, i2p, does route peer-to-peer using a strategy similar to Tor's onion routing that they call garlic routing. However, i2p does not tend to offer access to the public internet, does not offer a self-contained browser, and is much less used than Tor (source).

    3 votes
  20. Comment on What programming/technical projects have you been working on? in ~comp

    9000
    Link Parent
    My advice is start with something small. Even if the change isn't something you actually care about, find a part of the codebase that you can understand. For instance, change the way something is...

    My advice is start with something small. Even if the change isn't something you actually care about, find a part of the codebase that you can understand. For instance, change the way something is shown to the user, even if it looks worse. Or intentionally break something in a way that you can predict. Or change the color of something.

    This is important, because a lot of programming is about having a mental model of the program in your head, so that you know what to change or where bugs probably are. To build this mental model, it's best to start small and build out from there. Tweak a small part of the code you understand, then extend out to understand more of the code, then repeat. As you go on, you'll also pick up parts of this project's coding and development style, which will help you be more productive as you go along.

    The highlighting feature might be a big refactor, but I imagine that improving search time might be a smaller task (though, depending on the complexity of the project, this very well might not be true).

    Anyway, good luck!

    8 votes