Jump to content

zhick

Member
  • Posts

    50
  • Joined

  • Last visited

Awards

Profile Information

  • Gender
    Male
  • Location
    Germany

Recent Profile Visitors

848 profile views
  1. Minor nitpick: Java has no operator overloading.
  2. I'm not sure there is a proper way to achieve this with arduino. And are you sure the esp-idf is recompiled as well? You could check this by looking for a file named httpd_main.c in somewhere in your installation and adding a line . If building now fails (with error "This should not compile"), you should indeed be able to just change the variable in sdkconfig.h.
  3. @Unimportant: You raise some valid points, namely that the size of int (and unsigned int) have been left implementation defined for a reason, but I think your suggestions overshoot by quite a bit. E.g.: Why? If the API returns an unsigned value it's likely because there's no possible way for the value to be negative (size, number of elements, age, there's a whole lot of types/values out there that logically never can be negative). Why would you convert them to a less fitting (and possibly slower, as unsigned integer arithmetic can be faster in some cases) data type? Also how do you go about converting the value safely? To convert safely from signed to unsigned you'll always need the next bigger signed type or make some assumptions about the possible/reasonable range of return values you expect. Which opens a whole new can of worms, like safely figuring out what the next biggest sized signed type is (the standard makes no guarantee that a long int is actually bigger than an [unsigned] int) or handling the possible error case that the conversion was not possible. Ideally we'd all be using (u)int(8|16|32|64|...)_fast_t types when caring about performance while having requirements about the possible range of values, as these are supposed to be the fastest data-type large enough to handle the requested size (but may be larger), but unfortunately these also come with their own set of problems like not necessarily being correct for compatibility reasons. In the end, there's no 100% clear cut solution. Especially not shunning unsigned integers completely.
  4. Kconfig is a tool used to change compile-time definitions for a piece of software, like in this case the size of a buffer used to store a http request header. It basically works by generating a header (sdkconfig.h) which has all the defines and injecting that into the build process. Your #undef CONFIG_HTTPD_MAX_REQ_HDR_LEN #define CONFIG_HTTPD_MAX_REQ_HDR_LEN 1024 would in theory work, if it was at the correct place, which is right before where the relevant buffer is declared (somewhere in esp-idf, possibly esp_http_server.h, but probably in some .c file). What you'd need to do is to change the value defined in sdkconfig.h and recompile the relevant files. Normally you'd do that using make menuconfig , changing the relevant options and recompiling your firmware. The link to espressifs documentation you found has all the details. However apparently esp32-arduino ships a precompiled esp-idf (according to this forum post I found at least: https://esp32.com/viewtopic.php?t=5225 , I've never used arduino myself), so as is pointed out there, there's no way for you to change the definitions easily. You'd need to compile your own esp-idf. The above forum post has a link to https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md which has more details on how you'd go about that, but depending on your level of experience this is probably not going to be trivial task. I'm assuming you're running windows, so you'll first need to follow this: https://docs.espressif.com/projects/esp-idf/en/latest/get-started/windows-setup.html , to setup a suitable development environment.
  5. do-loops often get a bad rep, and not entirely without reason, as it can really become a mess if there's several exits or whatever scattered around in the loop body. But in cases like this where it's basically just a while loop (condition is still checked right at the top of the loop) they can be quite handy. Another, arguably even better approach is to keep the loop as a while-loop and just change the way input is read: int read_int() { int input = 0; printf("Enter an integer:\n"); scanf("%d", &input); return input; } // ... int user_input = 0; while ((user_input = read_int()) != 0) { // ... } Some oldschool c-folks will scream and shout that this is not optimal because of the extra function call, but any non-braindead compiler will optimize this out.
  6. Maybe to expand on this a little bit: Yes, this is a very simple mistake, but mistakes of this kind are quite common and stem from doing "the same thing" at two different points, which makes it easy to mess up. In this case you could restructure your program to make it so the input is only always read at one point: Instead of int user_input = 0; // ... printf("Enter an integer:\n"); scanf("%d", &user_input); while(user_input != 0) { // ... printf("Enter an integer:\n"); scanf("%d", &user_input); // ... } You could just have this as do { int user_input = 0; printf("Enter an integer:\n"); scanf("%d", &user_input); if (user_input == 0) exit; // .. } while (1) This way it's always clear when input is read (only ever at the beginning of the loop) and when it's processed.
  7. Yeah, maybe I could've worded that better. What's the value of the variable you're comparing to zero (don't worry, that part is correct) at that point in the program? Btw, I don't mean to lead you on, so if you'd prefer me to just tell you the solution just say so. I just think it's better to point someone in the right direction and let them figure out the rest of the way themselves.
  8. Again: To be more precise: Which number are you using to decide whether a number is negative or positive?
  9. Your problem is not that you're not counting negative numbers, but you're not counting the last number entered: Enter an integer: 1 Enter an integer: 1 Enter an integer: 0 Overall: Count is 2, sum is 2, maximum is 1, minimum is 0, average is 1.000000 Positives: Count is 1, sum is 1, maximum is 1, minimum is 1, average is 1.000000 Negatives: Count is 0, sum is 0, maximum is -65535, minimum is 65535, average is 0.000000 Take a close look at when you do the counting.
  10. Took me a while to figure out this was a recursive with statement, since whatever SQL syntax that is I'm unfamiliar with. What is it, out of curiosity? Anyway, your problem is that your select basically builds a list of all possible routes, and then selects the shortest one, but the number of possible routes is infinite if there are cycles in your graph. You have to ensure that you don't visit a node/town you've already visited before, by checking whether it's already been visited == is in your current path (...or trajet in this case). Hope this is enough to point you in the right direction.
  11. Replace With args.matrix = malloc(args.size * sizeof(int*)); for (int i = 0; i < args.size; ++size) args.matrix[i] = malloc(args.size * sizeof(int)); // and then when you're done: for (int i = 0; i < args.size; ++i) free(args.matrix[i]); free(args.matrix); However, as Unimportant has noted, you'll probably not get a continuous chunk of memory this way which will incur performance penalties. However you can avoid this and still keep your struct as is and keep the ability to access elements as matrix[x][y] by initializing the matrix in the following way: args.matrix = malloc(args.size * sizeof(int*)); args.matrix[0] = malloc(args.size * args.size * sizeof(int)); for (int i = 0; i < args.size; ++size) args.matrix[i] = args.matrix[0] + (i * args.size); // and then when you're done: free(args.matrix[0]); free(args.matrix); This will however have the following maybe unexpected side-effect: args.matrix[1][0] = 1337; args.matrix[0][matrix.size] = 666; printf("%d\n", args.matrix[1][0]); // will print 666 Because matrix[1][0] and matrix[0][matrix.size] both point to matrix[0] + matrix.size. This would be the same in @Unimportants solution, but is prevented because of the asserts in the function used to access the matrix (though only in debug-builds).
  12. The assignment is to use a subquery, not a join (which I personally would prefer as well). However, with the schema the OP has given, this can't be solved. There is no association between songs and artists as it stands. But assuming song.artist is a foreign key referencing artist.name (which I would strongly discourage, as you usually really only should create foreign keys referencing primary keys): select title from song where artist in ( select name from artist where genre = 'Pop' );
  13. A simple c++ sudoku solver using recursive backtracking I wrote a few weeks ago. This version only solves 9x9 sudokus, but adjusting to other sizes is only a matter of initializing the Sudoku template with another value (eg. Sudoku<4> for 16x16 sudokus). It's plenty fast for any 9x9 sudoku and some 16x16 sudokus, usually only taking a few microseconds, but on harder sudokus it will take several minutes or hours (or more). It's 107 lines of code actually, but I'm counting it anyway since the actual program only starts at line 10. To compile using gcc, save as sudoku_solver.cpp and then type g++ --std c++17 -O3 sudoku_solver.cpp -o sudoku_solver. Usage: ./sudoku_solver sudoku.txt #include <iostream> #include <fstream> #include <iomanip> #include <array> #include <algorithm> #include <optional> using namespace std; template<int n> struct Sudoku { static const int width = n * n; static const int n_cells = width * width; typedef array<int, width> Row; typedef array<Row, width> Field; Field m_field; inline Sudoku<n>() : m_field{} {} inline bool validate_row(int num, int i_row) const { return none_of(m_field[i_row].begin(), m_field[i_row].end(), [&](const int cell) { return cell == num; }); } inline bool validate_col(int num, int i_col) const { return none_of(m_field.begin(), m_field.end(), [&](const Row &row) { return row[i_col] == num; }); } inline bool validate_block(int num, int i_row, int i_col) const { const int block_row = i_row / n * n; const int block_col = i_col / n * n; for (int i = 0; i < width; ++i) if (num == m_field[block_row + i / n][block_col + i % n]) return false; return true; } inline bool validate_cell(int num, int i_row, int i_col) const { return validate_row(num, i_row) && validate_block(num, i_row, i_col) && validate_col(num, i_col); } inline optional<Sudoku<n>> get_solution() { Sudoku<n> solution(*this); return solution.solve_recursive(*this, 0) ? solution : optional<Sudoku<n>>{}; } inline bool solve_recursive(const Sudoku<n> &sudoku, int index) { if (index == n_cells) return true; const int i_row = index / width; const int i_col = index % width; if (sudoku.m_field[i_row][i_col] != 0) return solve_recursive(sudoku, index + 1); for (int num = 1; num <= width; ++num) { if (validate_cell(num, i_row, i_col)) { m_field[i_row][i_col] = num; if (solve_recursive(sudoku, index + 1)) return true; } } m_field[i_row][i_col] = 0; return false; } }; template<int n> ostream & operator<<(ostream &os, const Sudoku<n> &sudoku) { for (const auto &row: sudoku.m_field) { for (const auto &cell: row) os << setw(2) << cell << " "; os << "\n"; } return os; } template<int n> istream & operator>>(istream &is, Sudoku<n> &sudoku) { for (auto &row: sudoku.m_field) for (auto &cell: row) is >> cell; return is; } int main(int argc, char **argv) { Sudoku<3> sudoku; ifstream(argv[1]) >> sudoku; auto solution = sudoku.get_solution(); cout << "Input:\n" << sudoku << "\n"; if (solution) { cout << "Found a solution:\n" << *solution; return 0; } cout << "No solution found.\n"; return 1; } Example input file: Example output:
  14. @Sauron Most likely not, since he's looking to increase the probability in steps. Also, I'd wager a guess that for most common RNGs there's no performance difference between generating a number between 0 and 4 and generating a number between 1 and 100.
×