lainchan / λ

Simple/Small Programs

push · 2022-05-22 05:54
in this thread, we make programs/code as small as possible. this means you can do anything you want as long as its on just one file and is under 150 lines. you can use your preferred programming language for this, in this case I used the C programming language. take a look at a small program I made in C, it's quite pointless but I made it for fun. #include <stdio.h> #include <unistd.h> #include <stdlib.h> void game() { char name[15]; printf("LainChan: The VideoGame\nBut wait... you gotta tell me your name first: "); fgets(name, sizeof(name), stdin); printf("that name sounds amazing, %s", name); printf("your name is so good I would actually impersonate you.\n"); } int main() { game(); sleep(2); printf("Let's start the game!!!\n"); sleep(3); printf("Do you like lain serial experiments? Yes or No: "); char resp[3]; fgets(resp, sizeof(resp), stdin); printf("You sure do like Lain. you surely would watch it with me, wouldn't you?\n"); sleep(10); return 0; }
word · 2022-05-22 14:19
>>31244 Your post has terrible formatting for code. Making the code appear "shorter" in expense of readability is stupid. The code is for people to read. Thankfully I can easily record a keyboard macro (search for the next ; and add a new line) in emacs. If you are worried that the code would be too long, you could just use a pastebin service.
James K · 2022-05-22 21:09
>>31244 >>31249 Unfûcked version. #include <stdio.h> #include <unistd.h> #include <stdlib.h> void game() { char name[15]; printf("LainChan: The VideoGame\nBut wait... you gotta tell me your name first: "); fgets(name, sizeof(name), stdin); printf("that name sounds amazing, %s", name); printf("your name is so good I would actually impersonate you.\n"); } int main() { game(); sleep(2); printf("Let's start the game!!!\n"); sleep(3); printf("Do you like lain serial experiments? Yes or No: "); char resp[3]; fgets(resp, sizeof(resp), stdin); printf("You sure do like Lain. you surely would watch it with me, wouldn't you?\n"); sleep(10); return 0; }
x<->y · 2022-05-26 01:18
i have a feeling that huge hacks like the ones found in the obfuscated c contest would do extremely well here. i'm down for a game of printf tic tac toe
limited · 2022-05-28 01:30
total programming n00b here, this is one of the very first functional programs i've ever written. Rate my code pls. #include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ /* DECLARING VARIABLES */ char typ[20], square[20], cube[20], circle[20], cylinder[20], sphere[20], rectangle[20], b; /* INITIAL INPUT */ printf("Enter your shape\n"); scanf("%s", &typ); /* b is just for testing */ if (strcmp(typ, "b") == 0){ printf("\nThere are no easter eggs in here, go away. \n"); } /*shapes are the elseifs */ else if (strcmp(typ, "square") == 0){ int sideA, area; printf("Enter side length: \n"); scanf("%d", &sideA); area = sideA * sideA; printf("\n The area of the square is: %d \n", area); } else if (strcmp(typ, "cube") == 0){ int sideA, volume, surf; printf("\nEnter side length "); scanf("%d", &sideA); volume = sideA * sideA * sideA; surf = sideA * sideA * 6; printf("\n The volume of the cube is: %d", volume); printf("\n The Suface Area is: %d \n", surf); } else if (strcmp(typ, "circle") == 0){ float pi = 3.141592, area, circ; int rad; printf("\nEnter radius: "); scanf("%d", &rad); area = pi * rad * rad; printf("\nArea of circle : %f", area); circ = 2 * pi * rad; printf("\nCircumference of circle : %f \n", circ); } else if (strcmp(typ, "cylinder") == 0){ float pi = 3.141592, circ, surf, volume; int rad, height; printf("\nEnter radius: "); scanf("%d", &rad); printf("\nEnter Height: "); scanf("%d", &height); surf = pi * rad * rad * (height + rad); printf("\n Surface area : %f", surf); circ = (2 * pi *rad); printf("\nCircumference : %f", circ); volume = (pi * rad * rad * height); printf("\nThe volume of the cylinder is: %f \n", volume); } else if (strcmp(typ, "sphere") == 0){ float volume, surf, pi = 3.141592, magic = 4 / 3; int rad; printf("\n Enter radius: "); scanf("%d", &rad); volume = (magic * pi * rad * rad * rad); surf = (4 * pi * rad * rad); printf("\n The volume of the sphere is: %f", volume); printf("\n The Surface area is: %f \n", surf); } else if (strcmp(typ, "rectangle") == 0){ int area, sideA, sideB; printf("\n Enter one side"); scanf("%d", &sideA); printf("\n Enter the other side"); scanf("%d", &sideB); area = sideA * sideB; printf("\n The area of the rectangle is: %d \n", area); } else{ printf("Shape not recognized! \n"); } return 0; }
Iverson · 2022-05-28 14:32
>>31318 Pls use code tags next time. >. Rate my code pls. I think making a new function for each of the shapes would be better (first ask the user which one he wants and then use a switch statement to figure out the right shape/function). You could also print a menu and ask the user to select an option (you could even ask user to select a menu number instead of typing out the full word, or you could support both). Second, I think you should always use doubles instead of floats. Also, you should use the C preprocessor for defining constants (like pi): #define PI 3.141592 And your program has a small bug on line 12: you aren't checking/limiting the size of the input you read with scanf and you shouldn't use a & here because you use a char array. Change it to scanf("%20s", typ); . Finally, you don't need to define any of square[20], cube[20], circle[20], cylinder[20], sphere[20], rectangle[20], b because you aren't using them to hold any data. I would also put the else if s on the same line with the closing { of the previous if statement (but you really want to split the calculations to different functions and use a switch statement here).
Tyrell Wellick · 2022-05-28 16:28
>>31318 >>31324 this Your code has no error handling on bad user input. I recommend reading https://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html . You can use !strcmp(typ, "sphere") instead of strcmp(typ, "cylinder") == 0 which is cleaner. I would recommend creating a wrapper function around printf, gets and strtol to get user input and handle errors by prompting again in case of wrong input. I think one of the general threads would be better for code review.
Nobody important · 2022-05-29 23:09
>>31326 I always find it worthy for readability to make a static inline wrapper called streq/strequal around strcmp.
Torvalds · 2022-05-29 23:59
>>31324 Sorry i thought the site would do it automatically. I assume its something like printf("hello world") ? And yeah i tried to do it with switches because i know having a bunch of elseif's is sloppy. Couldn't get it to work properly though, i don't remember the issue though, its been a while. Printing a menu is a good idea, I'll try that out. You're saying C already knows the value of pi so i dont need to define it? Also why don't i need the &? isn't that what tells it to take the input of scanf and store it as "typ" ? >>31326 I found your link informative, thank you. What do you mean by wrapper?
hash table · 2022-05-30 04:47
>>31353 >You're saying C already knows the value of pi so i dont need to define it? What he's suggesting is that constant values like pi shouldn't be declared as variables and constant values which are universal shouldn't be declared under a specific scope. Also, yes most C compilers do have a definition PI in math.h . Generally placed just under your #include directives, universal constants are usually declared with a line like: #define PI 3.141592 Note the lack of semicolon. #define is really just find/replace and it happens during the compiler's pre-processing step, that's before it even looks at your syntax. The punch-line is: if you added a semicolon it would be included in the replacement. If you had a magic number which is specific to a particular block of code you should use a line like: const double MAGIC = 4/3.0; And do note the ".0" there. 4/3 is an integer division, it's going to be 1 even though you put it in a float.
Case · 2022-05-30 19:53
>>31353 Here is how I would do it: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> //or #define PI 3.141592 /* Function prototypes */ void print_menu(void); void calc_square(void); void print_menu(void){ puts("Select menu option:\n"); puts("1. square \t2. cube \t3. circle \n"); puts("4. cylinder \t5. sphere \t6. rectangle\n"); } void calc_square(void){ int sideA, area; puts("Enter side length: \n"); //TODO: what if the input is not valid: add some error handling? scanf("%d", &sideA); area = sideA * sideA; printf("\n The area of the square is: %d\n", area); } int main(void){ /* DECLARING VARIABLES */ int menu_choice = 0; print_menu(); //you could have a get_menu_input() function where you get the input, make sure it's valid and then handle it. scanf("%1d", &menu_choice); // if you want to test strings, you may have to use if/else-if chain (i.e. do it the way you did it previously). /* TODO: Implement the rest of the functions/choices */ switch(menu_choice){ case 1: calc_square(); return EXIT_SUCCESS; //or ask for a new menu choice in loop? break; default: printf("ERROR! Invalid choice: %d!\n", menu_choice); return EXIT_FAILURE; break; } return EXIT_SUCCESS; } >why don't i need the &? isn't that what tells it to take the input of scanf and store it as "typ" ? The & means "address of", while a * either means "this is a pointer" or "get the data that this ptr points to": // ... int num1 = 42; int* num1_ptr = &num1; char my_str[] = "hello!"; //this is a C string, same as char*, more or less... char* my_str2 = NULL; //a pointer to char my_str2 = (char*) &my_str; printf("ptr addr:%p -> %d (num1 via num1_ptr)\n", &num1_ptr, *num1_ptr); printf("num1 is located at:%p\n", &num1); printf("ptr addr:%p -> %s (my_str2)\n", &my_str2, my_str2); // ... Working with strings is painful in C. Because C strings are actually arrays of characters and not proper strings (languages like C++, Java/C#, Ruby, etc. have a proper/dedicated string type). Also, pointers are the hardest thing to "get" in C.
JARGON · 2022-05-30 20:50
>>31365 I forgot: you can't compare Cstrings in a switch statement in C. (Sorry. I haven't used C in a while)
Spike Spiegel · 2022-06-01 20:17
Thanks guys, i'm learning a lot in this thread >>31357 Yeah i'm not surprised that the 4/3 isn't working right. My calculation for the sphere kept coming out fuarrrked up and that explains it. The "magic number" was just supposed to be a work-around but i guess it still didnt work. >>31365 I still don't have any grasp of pointers. I always hear people bitching about them though. >Working with strings is painful in C. Because C strings are actually arrays of characters and not proper strings yep lol which is why this project took me twice as long as i expected. >>31366 hmm i guess that was the issue i was running in to. Which is why i ended up with all the elseif's.
Apoc · 2022-06-01 20:47
>>31392 >I still don't have any grasp of pointers. You could think of pointers as similar to a street address. The address itself is just text but you can use the address to find a specific house. Similarly, a pointer doesn't contain any data itself but it can be used to find the data that the pointer points to. A pointer is simply a memory address.
John Doe · 2022-06-17 15:52
Guessing word game or hangman without the hangman graphic. package main import ( "bufio" "bytes" "fmt" "os" ) type chars []byte func (chs chars) String() string { return string(chs) } func newChars(s string) chars { w := make([]byte, 0, len(s)) for _, c := range s { w = append(w, byte(c)) } return w } // Replace the character at index i with a NUL character to indicate that character has already been guessed func (chs *chars) terminate(i int) { (*chs)[i] = '\000' } func (chs chars) indexOf(char byte) int { return bytes.IndexByte(chs, char) } func buildBytes(len int, char byte) chars { chs := make([]byte, len) for i := range chs { chs[i] = char } return chs } func main() { tries := 6 correct := 0 w := "nigger" chs := newChars(w) guess := buildBytes(len(w), '_') // To show what letter has been guessed so far scanner := bufio.NewScanner(os.Stdin) for tries > 0 && correct != len(chs) { fmt.Println(guess) fmt.Printf("You have %d tries left\n", tries) fmt.Print("Your guess (only take the first character): ") scanner.Scan() if len(scanner.Bytes()) == 0 { continue } char := scanner.Bytes()[0] // Get the first character from standard input ci := chs.indexOf(char) if ci == -1 { tries-- continue } correct++ chs.terminate(ci) guess[ci] = char } if correct != len(chs) { fmt.Println("You failed!") } else { fmt.Println("Congrats!") } fmt.Println("The word is", w) }
null · 2022-06-20 17:15
>>31511 I hate that I saw n_____ and immediately knew it
Mitnick · 2022-06-20 20:18
>>31558 naggers? print("short and empty");
x<->y · 2022-06-21 02:48
>>31567 use std::io::{stdin,stdout,Write}; fn main() { let word: String = String::from("cheese"); let mut answer = "_".repeat(word.len()); let mut input = String::new(); let mut lives: u32 = 3; let flush = stdout().flush(); flush.expect("failed to flush stdout"); loop { println!("{}", answer); stdin() .read_line(&mut input) .expect("invalid input"); if input.len() == 2 { let c = input.chars().next().expect("no character found"); if word.find(c) == None { lives -= 1; } answer = answer.chars().enumerate().map(|(i,x)| { if word.chars().nth(i).unwrap() == c { c } else { x } }).collect::<String>(); } else { println!("Please enter a single character"); } if lives == 0 { println!("You died!"); return; } if answer == word { break; } input = "".to_owned(); } println!("Congratulations!"); }
over · 2022-06-21 18:56
Sierpiński triangle using chaos game method in Python. Can be executed like: python main.py | mpv --no-correct-pts --fps=60 --fs - python from random import randrange from sys import stdout from math import ceil class P6: def __init__(self, width, height): self.width = width self.height = height self.buffer = bytearray(3 * width * height) def set(self, x, y, rgb): r, g, b = rgb i = 3 * (y * self.width + x) self.buffer[i], self.buffer[i + 1], self.buffer[i + 2] = rgb def write(self, f): f.write(f'P6\n{self.width} {self.height}\n255\n'.encode()) f.write(self.buffer) def mid_point(p1, p2): return ceil((p1[0] + p2[0]) / 2), ceil((p1[1] + p2[1]) / 2) def random_point(width, height): return randrange(width), randrange(height) def sierpinski(width, height, triangle): POINTS_PER_FRAME = 10 im = P6(width, height) r = random_point(width, height) im.set(*r, (0, 255, 0)) for x, y in triangle: im.set(x, y, (255, 0, 0)) for i in range(100_000): p = triangle[randrange(3)] r = mid_point(p, r) im.set(*r, (255, 255, 255)) if i % POINTS_PER_FRAME == 0: im.write(stdout.buffer) if __name__ == '__main__': w, h = 800, 600 t = ((w // 2, 0), (0, h - 1), (w - 1, h - 1)) # t = ((0, 0), (0, h - 1), (w - 1, h - 1)) # t = ((0, 0), (w - 1, 0), (w // 2, h - 1)) sierpinski(w, h, t)
car · 2022-06-24 17:46
>>31511 package main import ( "flag" "fmt" "math/rand" "os" "time" ) // chars will have each character from a string as key // and its indices in the string as value type chars map[rune][]int func newChars(s string) chars { chs := make(chars, 0) for i, c := range s { chs[c] = append(chs[c], i) } return chs } func main() { flag.Parse() words := flag.Args() r := rand.New(rand.NewSource(time.Now().Unix())) // Generate a new number generator w := words[r.Intn(len(words))] chs := newChars(w) tries := len(w) correct := 0 display := make([]rune, len(w)) for i := range w { display[i] = '_' } in := "" for correct != len(w) && tries > 0 { fmt.Println(string(display)) fmt.Printf("You have %d tries left \n", tries) fmt.Printf("Enter your guess (Only take the first character): ") fmt.Fscanln(os.Stdin, &in) guess := rune(in[0]) if indices, ok := chs[guess]; len(indices) != 0 && ok { index := chs[guess][0] display[index] = guess chs[guess] = chs[guess][1:] correct++ continue } tries-- } } Rewrote this using hash map. It can only handle 1 word only.
chadols · 2022-07-03 19:23
>>31244 It's a simple, stupid and hard-coded program written in C++ that essentially creates some directories and files for a project partially based on arguments passed to the main function. I'll be improving it today by making it less hardcoded and actually good. I'll probably post it on GitHub #define FMT_HEADER_ONLY // https://github.com/fmtlib/fmt #include "fmt/core.h" #include "fmt/color.h" #include "argh.h" // https://github.com/adishavit/argh #include <iostream> #include <cstdlib> #include <string> #include <filesystem> #include <fstream> namespace fs = std::filesystem; int main(int argc, char **argv) { argh::parser cmdl(argv); if (argc == 1) { fmt::print(fg(fmt::color::red), "Use -h or --help for options.\n"); return 1; } if (cmdl[{"-h", "--help"}]) { fmt::print("projtmpl is a simple program that creates a project using a template.\nOptions:\n -h, --help: Shows this message;\n --no-git: Does not create a .gitignore file and neither does it initiate a Git repository;\n --no-cmake: Does not create a CMakeLists.txt file.\n\n"); return 1; } std::string name = argv[1]; // Project name fs::create_directory("src"); fs::create_directory("inc"); fs::create_directory("lib"); fs::create_directory("build"); fmt::print(fg(fmt::color::green), "Directories created!\n"); std::ofstream mn("src/main.cpp"); mn << "#include <iostream>\n\nint main(int argc, char **argv) {\n\n std::cout << \"Hello, world!\\n\";\n\n return 0;\n}"; mn.close(); fmt::print(fg(fmt::color::green), "main.cpp file created!\n"); if (!cmdl[{"--no-git"}]) { std::ofstream gt(".gitignore"); gt << "build/"; gt.close(); fmt::print(fg(fmt::color::green), ".gitignore file created!\n"); } if (!cmdl[{"--no-cmake"}]) { std::ofstream cmk("CMakeLists.txt"); cmk << "cmake_minimum_required(VERSION 3.23)\nset(CMAKE_CXX_STANDARD " << 20 << ")\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\nproject(" << name << " VERSION 0.1.0)\nadd_executable(" << name << " src/main.cpp)\ntarget_include_directories("<< name <<" PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc)\n"; cmk.close(); fmt::print(fg(fmt::color::green), "CMakeLists.txt file created!\n"); } std::ofstream rdm("README.md"); rdm << "# " << name << "\n\n"; rdm.close(); fmt::print(fg(fmt::color::green), "README.md file created!\n"); if (!cmdl[{"--no-git"}]) { system("git init"); fmt::print(fg(fmt::color::green), "Git repository created!\n"); } return 0; }
chadols · 2022-07-04 17:20
>>31746 Alright. I improved it. It's still below 150 LoC. https://github.com/badolsmito/projtmpl
XERXES · 2023-02-13 13:23
>>31244 silly and useless, but quite small demonstration of Wolframs Rule 30: python a = 1<<11 for i in range(12): print("{0:b}".format(a).rjust(24).replace("0", " ")) a = (a>>1)^(a|(a<<1))
Lady Jessica · 2023-02-13 20:54
>>31604 nice code, you might like trying to make it a tui with bubbletea.
Lukasiewicz · 2023-02-13 21:15
Gets the name of our processor. Works on x86 processors only of course. #include <cpuid.h> #include <cstdio> #include <cstdint> int main() { uint32_t Name[4]; for( uint32_t i = 2; i < 5; ) { __cpuid(0x80000000 | i++, Name[0], Name[1], Name[2], Name[3]); fwrite(Name, 16, 1, stdout); } } % g++ cpu-name.cpp % ./a.out Intel(R) Core(TM) i9-7900X CPU @ 3.30GHz%
byte · 2023-02-16 09:59
>>34325 made it golang package main import ( "flag" "fmt" "math/rand" "os" "time" "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" ) type chars map[rune][]int func newChars(s string) chars { chs := make(chars, 0) for i, c := range s { chs[c] = append(chs[c], i) } return chs } type model struct { tries int correct int display []rune word chars final int textinput textinput.Model } func (m model) Init() tea.Cmd { return setDisplay(m.word, m.final) } func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { case "ctrl+c": return m, tea.Quit case "enter": if m.tries > 0 { if m.textinput.Value() == "" { return m, nil } g := rune(m.textinput.Value()[0]) m.textinput.SetValue("") return m, chkGuess(g, m.word) } else { return m, tea.Quit } } case wordMsg: m.display = []rune(msg) return m, nil case correctMsg: m.display[msg.index] = msg.guess m.word[msg.guess] = m.word[msg.guess][1:] m.correct++ if m.correct == m.final { return m, tea.Quit } return m, nil case incorrectMsg: m.tries-- return m, nil } var cmd tea.Cmd m.textinput, cmd = m.textinput.Update(msg) return m, cmd } func (m model) View() string { return fmt.Sprintf("%s\nYou have %d tries left.\n", string(m.display), m.tries) + m.textinput.View() + "\n" } type wordMsg []rune func setDisplay(w chars, length int) tea.Cmd { //initial command to set display return func() tea.Msg { d := make([]rune, length) for i := 0; i < length; i++ { d[i] = '_' } return wordMsg(d) } } type correctMsg struct { index int guess rune } type incorrectMsg struct{} func chkGuess(guess rune, word chars) tea.Cmd { return func() tea.Msg { if indices, ok := word[guess]; len(indices) != 0 && ok { index := word[guess][0] return correctMsg{index: index, guess: guess} } return incorrectMsg{} } } func main() { flag.Parse() words := flag.Args() r := rand.New(rand.NewSource(time.Now().Unix())) w := words[r.Intn(len(words))] chs := newChars(w) i := textinput.New() //creates textinput model i.Focus() i.Prompt = "Enter guess (only one char): " p := tea.NewProgram(model{word: chs, tries: len(w), correct: 0, final: len(w), textinput: i}) //creates program if _, err := p.Run(); err != nil { //runs it fmt.Printf("Error starting program: %v", err) os.Exit(1) } }
James K · 2023-02-16 11:39
>>31746 >cmdl[{"--no-git"}] As someone who appreciates simplicity, this has to be one of the ugliest things I've seen in a while. There's no practical reason to do this aside from the mere existence of the language feature compelling people to use it. In fact, operator overloading as a whole is almost entirely ridiculous outside of cases where an old operator is extended to work in the same way on new types.
Delilah · 2023-09-20 05:31
>>31585 Wrote some time ago def f(n):return '\n'.join(f(-n)) if n>0 else [l.center(2*2**-n-1) for l in f(n+1)]+[l+' '+l for l in f(n+1)] if n else '▴' print(f(4)) It prints ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴ ▴
Leto Atreides I · 2023-09-21 08:23
Sierpinski triangle for the PSX. Just collecting midpoints and rendering using standard GPU primitives, nothing fancy. #include <stdint.h> #include <psxgpu.h> #define SX 320 #define SY 240 #define OT_LEN 2 #define TQ_LEN (6 * (3 * 121 + 1)) DISPENV disp; DRAWENV draw; uint32_t ot[OT_LEN]; char pt[16]; short tq[TQ_LEN]; int tqi, ti; #define tQueue(x0, y0, x1, y1, x2, y2) if (tqi < TQ_LEN){\ tq[tqi++] = (short)(x0); tq[tqi++] = (short)(y0);\ tq[tqi++] = (short)(x1); tq[tqi++] = (short)(y1);\ tq[tqi++] = (short)(x2); tq[tqi++] = (short)(y2);} int main(void) { ResetGraph(0); SetDefDispEnv(&disp, 0, 0, SX, SY);SetDefDrawEnv(&draw, 0, 0, SX, SY); setRGB0(&draw, 128, 128, 128);draw.isbg = 1; DrawSync(0);VSync(0);PutDispEnv(&disp);PutDrawEnv(&draw);SetDispMask(1); tQueue(0, SY-8, SX/2, 8, SX, SY-8); POLY_F3 *root = (POLY_F3 *) pt;setPolyF3(root); setXY3(root,tq[0],tq[1],tq[2],tq[3],tq[4],tq[5]);setRGB0(root,0,196,255); ClearOTagR(ot, OT_LEN);addPrim(ot, root);DrawOTag(ot+OT_LEN-1); do {ClearOTagR(ot, OT_LEN); short max = (tq[ti]+tq[ti+2])/2, may = (tq[ti+1]+tq[ti+3])/2, mbx = (tq[ti+2]+tq[ti+4])/2, mby = (tq[ti+3]+tq[ti+5])/2, mcx = (tq[ti+4]+tq[ti])/2, mcy = (tq[ti+5]+tq[ti+1])/2; POLY_F3 *nst = (POLY_F3 *) pt;setPolyF3(nst); setXY3(nst,max,may,mbx,mby,mcx,mcy);setRGB0(nst, 128, 128, 128); addPrim(ot, nst);DrawOTag(ot + OT_LEN - 1);DrawSync(0); tQueue(tq[ti], tq[ti+1], max, may, mcx, mcy); tQueue(max, may, tq[ti+2], tq[ti+3], mbx, mby); tQueue(mcx, mcy, mbx, mby, tq[ti+4], tq[ti+5]); ti += 6; } while (ti < TQ_LEN); VSync(0); return 0; }
Emmanuel · 2023-09-29 11:05
>>31244 Do bash scripts count? #!/bin/sh printf $1 \ | gcc \ -D_GNU_SOURCE \ -include fcntl.h \ -include sys/syscall.h \ -include sys/mman.h \ -include sys/types.h \ -include sys/socket.h \ -include signal.h \ -include sched.h \ -include limits.h \ -include linux/futex.h \ -include linux/fs.h \ -include time.h \ -include netinet/in.h \ -include netinet/sctp.h \ -include poll.h \ -E \ - \ | tail -n 1 I made this when I needed some constants and expressions (e.g. AF_INET) in a not-C language.
Waterhouse · 2023-10-05 11:23
#!/usr/bin/bash # mvi - like mv, but with the help of vim print_usage() { echo "usage: mvi OPTION* FILE+" } print_help () { print_usage cat <<EOF mvi works like good old mv, but with the help of VIM -n dry run -v explain what is being done -h display this help EOF } # let's be verbose by default VERBOSE=1 while getopts hvn name do case $name in v) VERBOSE=1;; n) DRY_RUN=1;; h) print_help; exit 1;; ?) print_usage; exit 1;; esac done shift $(($OPTIND - 1)) MIN_ARGS=1 if [[ $# -lt $MIN_ARGS ]]; then print_usage exit 1 fi ##### all options and arguments have been parsed ##### tmp=$(mktemp --tmpdir mvi-XXXXXXXXXXX.tmp) args=() for arg in "${@}"; do echo $arg >> "$tmp" args+=("$arg") done vim "$tmp" i=0 cat "$tmp" | while read line; do arg="${args[$i]}" if [[ -v VERBOSE || -v DRY_RUN ]]; then echo "$arg ---> $line" fi if [[ ! -v DRY_RUN ]]; then mv "$arg" "$line" fi i=$(($i + 1)) done # clean up rm -f "$tmp"
Anonymous · 2023-10-08 17:23
I was trying to figure out how to schedule something on random days twice a week and I realized what I wanted was a uniform random shuffle. $ ls days.json shuffle.py $ cat days.json {"monday": true, "tuesday": true, "wednesday": false, "thursday": false, "friday": false} $ python shuffle.py days.json && cat days.json {"monday": true, "tuesday": false, "wednesday": false, "thursday": true, "friday": false} $ python shuffle.py days.json && cat days.json {"monday": false, "tuesday": false, "wednesday": false, "thursday": true, "friday": true} $ python shuffle.py days.json && cat days.json {"monday": true, "tuesday": true, "wednesday": false, "thursday": false, "friday": false} $ python shuffle.py days.json && cat days.json {"monday": false, "tuesday": true, "wednesday": false, "thursday": true, "friday": false} $ $ cat days.json {"monday": false, "tuesday": true, "wednesday": false, "thursday": true, "friday": false} $ jq ".tuesday" days.json true $ jq ".wednesday" days.json false $ jq ".whatever" days.json null #public domain #provide a json file as an argument that contains a mapping #do a uniform shuffle over the range of the mapping #overwrite the json file with the shuffled json #ie {"a": true, "b": false, "c": true} can become {"a": false, "b": true, "c": true} import sys import random import json #Fisher-Yates uniform shuffle, every possible permutation has an equal probability of being the output def shuffle(l): l = l.copy() length = len(l) #iterate over every element except the last for i in range(0, length - 1): #choose an element index randomly from the current location to the end of the list j = random.randint(i, length - 1) #swap the elements l[i], l[j] = l[j], l[i] return l #seed random number generation random.seed() #check for only a single argument arg_count = len(sys.argv) - 1 if (arg_count != 1): print('should have a single json file name as an argument') sys.exit(1) file_name = sys.argv[1] #read the json file into a dictionary d = {} with open(file_name, 'r') as in_file: d = json.load(in_file) #make a new dictionary with the domain left the same and the range shuffled d = dict(zip(list(d.keys()), shuffle(list(d.values())))) #write the new dictionary to a file with open(file_name, 'w') as out_file: out_file.write(json.dumps(d)) out_file.write("\n")
dup · 2023-10-13 19:12
>>37292 >I made this when I needed some constants and expressions (e.g. AF_INET) in a not-C language. This is neat, because I was recently doing the same thing with the same constants, although I opted to pore through the headers manually. Only in a few recent instances did I resort to actually running the preprocessor like this, but I'll keep these flags in mind for next time.
Hong, Guil Dong · 2023-10-13 22:53
A Common Lisp macro which makes a truth table for any logical function. lisp (defmacro truth-table (logic) `(list (,logic T T ) (,logic T NIL) (,logic NIL T ) (,logic NIL NIL))) An x86-64 bubble sort program. Hardcoded list and size is known, I'm still a noob at this, but it's still surprisingly small. Would love to redo it with more functionality once I learn syscalls. assembly section .data listdw10, 4, 8, 4, 2, 7, 7, 4 Lengthequ8 section .text global _start _start: mov rdx, Length shl rdx, 1 ; rdx x 2 sub rdx, 2 for_1: mov rcx, 0 for_2: mov ax, [list+(rcx)] mov bx, [list+(rcx)+2] cmp ax, bx jle for_2_tail mov [list+rcx], bx mov [list+rcx+2], ax for_2_tail: add rcx, 2 cmp rcx, rdx jl for_2 for_1_tail: sub rdx, 2 cmp rdx, 0 jge for_1 exit: mov rax, 60 mov rdi, 0 syscall
Six · 2023-10-14 07:30
#!/usr/bin/perl use strict; use warnings; use vars qw($VERSION %IRSSI); use Irssi; use Irssi::TextUI; use Time::HiRes qw( usleep ); $VERSION = '0.01'; %IRSSI = ( authors => 'v', name => 'Show Last User That Spoke', description => 'Statusbar item that shows the nick who most recently posted in any of your channels', license => 'WTFPLv2', ); Irssi::print(" <span class="heading">=== sluts.pl ===</span> This script only draws the statusbar item. It doesn't add or position it. For that, see /help statusbar The item name is \"sluts\". Here are the commands for the way I do it. If you like it and want to keep it, do /save If it is like kicking dead whales down the beach and you want to get out, do /reload /statusbar window remove window /statusbar chaninfo enable /statusbar chaninfo type window /statusbar chaninfo position 2 /statusbar window position 1 /statusbar chaninfo add -priority 0 -alignment left window /statusbar window add -after user -priority 0 -alignment left sluts /statusbar padding enable /statusbar padding type window ===== Show Last User That Spoke ====="); my $ho_be_knocked_up = 0; sub by_sluts { my ($sluts, $be_bangin) = @_; my $moan = '$;'; # $; is the Irssi Special Variable for # last person to send a public message # to a channel you are on. $sluts->default_handler($be_bangin, "{sb $moan}", '', 0); return ("$sluts", "$be_bangin", "$moan"); } my ($sluts, $be_bangin, $moan) = @_; sub get_a_new_ho { if ($ho_be_knocked_up > 0) { Irssi::timeout_remove($ho_be_knocked_up); $ho_be_knocked_up = 0; } Irssi::statusbar_items_redraw('sluts'); } #As far as I can tell we don't actually need this #sub, but I thought we did when I was writing it #and now the joke won't work as well without it #so fuarrrk you. sub dat_bitch_betta_not_be_knocked_up { Irssi::timeout_remove($ho_be_knocked_up) if ($ho_be_knocked_up > 0); #If da ho' be knocked up we gon' get us a new ho'. $ho_be_knocked_up = Irssi::timeout_add(10, 'get_a_new_ho', undef); #100 } Irssi::statusbar_item_register ('sluts', 0, 'by_sluts'); Irssi::statusbars_recreate_items(); Irssi::signal_add_last ('message public', 'dat_bitch_betta_not_be_knocked_up'); # Comments for Future Me # Or, I Don't Remember a Damn Thing About Writing This # Or, There Is Nothing Better At Making You Feel Stupid # Than Having to Learn How *you* Did Something # # signal_add_last triggers sub dat_bitch_betta... when someone posts pubmsg # dat_bitch basically just points to get_a_new_ho # I don't know what timeout_add is supposed to do, but usercount.pl # used it and the joke works better with it in. # get_a_new_ho does the variable reset like dat_bitch, then redraws # the statusbar item to make it show the current value of $moan, which # is just assigned $;, which is the last user who spoke but funnier. # I can't remember what $be_bangin is for but it's funny and I'll # probably never need to tweak that part anyway.
Donna Hawthorne · 2023-10-14 10:48
A simpler bear/compiledb replacement, completely standalone and pretty portable (uses mktemp -d and realpath): #!/bin/sh set -eu # Single quote arguments quote() { printf '%s\n' "$1" | sed "s#'#'\\\\''#g; s#^#'#; s#\$#'#" } usage() { _name=$(basename "$0") cat <<EOF | { [ $1 -eq 0 ] && cat || cat >&2; } NAME $_name - Generate a JSON compilation database SYNOPSIS $_name [-h] COMPILER [DB_PATH] -- BUILD_CMD... DESCRIPTION Similar to bear [1], intercepst compiler calls during a clean build to build a compilation database for use with clang tools (cf [2]). The two mechanism to do so are PATH overriding (chosen when COMPILER is a command, e.g. "gcc") and CC/CXX environment variable overriding (for make, as fallback when COMPILER is a path). OPTIONS -h Print this notice to stdout and exit. EOF exit $1 } [ "$1" = -h ] && usage 0 compiler=$1; shift [ "$1" != -- ] && { out=$1; shift; } [ "$1" != -- ] && usage 1 || shift compiler_base=${compiler##*/} if [ "$compiler_base" != "$compiler" ] then compiler_iscmd=false echo "WARNING: compiler was specified by a path instead of a command, interception will" \ "only work through CC/CXX environment variables." >&2 else compiler_iscmd=true fi workdir=$(mktemp -d) trap 'exit 1' HUP INT QUIT ${ZSH_VERSION-ABRT} TERM trap 'rm -r -- "$workdir"' EXIT wrapper=$workdir/$compiler db=$workdir/db.json cat <<EOF >"$wrapper" #!/bin/sh set -eu compiler=$(quote "$compiler") EOF case "$compiler_base" in cc|c99|gcc|clang|icc) echo "ext_re='\\.c'" >>"$wrapper" ! $compiler_iscmd && export CC="$wrapper" ;; g++|clang++|icpc) echo "ext_re='\\.c(xx|pp|c)'" >>"$wrapper" ! $compiler_iscmd && export CXX="$wrapper" ;; *) echo "$compiler: unknown compiler" >&2 exit 1 ;; esac cat <<'EOF' >>"$wrapper" js_str() { printf '%s\n' "$1" | sed 's/["\\]/\\&/g; s/^/"/; s/$/"/'; } arg_jsarr=[$(for arg in "$compiler" "$@"; do js_str "$arg"; done | paste -sd, -)] for arg do if echo "$arg" | grep -Eq "$ext_re\$" then abs=$(realpath -- "$arg") printf '{"directory": %s, "arguments": %s, "file": %s},\n' \ "$(js_str "${abs%/*}")" \ "$arg_jsarr" \ "$(js_str "${abs##*/}")" >&3 fi done PATH="${PATH#*:}" exec "$compiler" "$@" EOF chmod u+x "$wrapper" # Hoping that the resulting writes are smaller than PIPE_BUF (cf write(3p)) { { echo '[' PATH="$workdir:$PATH" "$@" 4>&1 1>&2 2>&3 3>&4 | sed '$s/,$//' echo ']' } | { command -v jq >/dev/null && jq || cat; } >"$db" } 3>&2 2>&1 mv -- "$db" "${out:-compile_commands.json}"
phi · 2023-10-19 18:19
Swapping files/directories on Linux in a single syscall (no temporary files created): #include <errno.h> #include <fcntl.h> #include <linux/fs.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/syscall.h> #include <unistd.h> int main(int argc, char *argv[]) { // We don't care about our program's path --argc; if (argc == 2) { const int is_err = syscall(SYS_renameat2, AT_FDCWD, argv[1], AT_FDCWD, argv[2], RENAME_EXCHANGE); if (is_err) { fprintf(stderr, "fwap: %s\n", strerror(errno)); return EXIT_FAILURE; } return EXIT_SUCCESS; } if (argc) { fprintf(stderr, "fwap: expected 2 arguments, found %d\n", argc); } puts("usage: fwap FILE1 FILE2"); return EXIT_FAILURE; } >>37437 Thanks for the assembly bubble sort! Having little example programs like that makes learning assembly so much nicer.
Guthrie · 2023-12-16 07:44
A CPU level "DDOS" which works by keeping the memory bus locked for excessive periods of time. Make sure to keep the cursor in the terminal :) .intel_syntax noprefix .globl _start .equ THREAD_COUNT, 16 _start: mov ebp, THREAD_COUNT - 1 2: # clone (i.e. spawn thread) mov eax, 56 mov edi, 0x18f00 # flags (THREAD | VM | PARENT | SIGHAND | FS | FILES) mov esi, esi # stack xor edx, edx xor r10, r10 xor r8, r8 syscall test rax, rax # if zero, we're in a new thread jz 3f dec ebp jne 2b .p2align 5 3: lea rdx, [rip + dummy - 1] xor eax, eax xor ecx, ecx 4: lock cmpxchg QWORD PTR [rdx], rcx jmp 4b .section .bss .p2align 12 .zero 4096 dummy: .zero 4096 How it works: The "lock" prefix gives a core sole access to the memory bus (or at least to some of the cache lines). This lock remains until the instruction finishes. Reading or writing across a cache line is more expensive than writing inside one, and writing across a page boundary is *much* slower. As a result, cmpxchg will take a very long time to finish. Run it on all cores in a tight loop and there's a good chance your computer will become very stuttery, especially if you have many cores.
Lord Nikon · 2023-12-18 06:50
software that reverses the input from stdin or keyboard c #include <stdio.h> #include <string.h> int main() { char input[2000]; gets(input); int strleng = strlen(input); for (int i = 0; i < strleng/2; i++) { char tmp = input[i]; input[i] = input[strleng - i - 1]; input[strleng - i - 1] = tmp; } printf("%s\n",input); }
word · 2023-12-18 12:25
>>37964 >fuarrrking gets aka "buffer overflow engine" instead of getline >only reverse a single line First uni semester?
Armitage · 2023-12-18 12:50
>>37968 I am following a uni course :(
queue · 2023-12-20 12:48
>>37964 I wrote a very tiny program that does the same thing. This has a stack overflow problem but I like it anyway /* This program prints standard output in reverse */ #include <stdio.h> int main( void ) { int ch = getchar() ; if ( ch != EOF ) { main() ; putchar(ch) ; } return 0 ; }
if · 2023-12-22 14:45
Code that finds the sum of all primes below 2 million. haskell import Data.List isPrime :: Int -> Bool isPrime n = all (\p -> n `mod` p /= 0) (takeWhile (\p -> p*p <= n) primes) primes :: [Int] primes = 2 : filter isPrime [3,5..] sumNPrimes :: Int -> Int sumNPrimes n = sum $ takeWhile (< n) primes main :: IO () main = do let result = sumNPrimes 2000000 putStrLn $ "The sum all primes below 2 million is: " ++ show result
Haruyoshi · 2023-12-25 12:03
#include<stdio.h> int main(){ int sp = 0; while(1){ printf("\t<"); for(int j = 0; j < sp; j++){ printf("."); } printf(">\n"); if (sp < 11){ //n+1 sp++; }else{ sp = 0; } } return 0; }
Unspecified · 2023-12-25 12:30
>>38003 Man, I love how terse and yet so clear can Haskell programs be
Zhora · 2023-12-25 12:49
>>38016 Ya, Functional Code is so elegant.
Wander · 2024-01-04 12:40
Rust code for Sieve of Eratosthenes fn find_primes_up_to(n: u32) -> Vec<u32> { let mut sieve = vec![true; (n+1) as usize]; let mut p = 2; while p * p <= n { if sieve[p as usize] == true { let mut i = p * p; while i <= n { sieve[i as usize] = false; i += p; } } p += 1; } return sieve.iter().enumerate().filter(|(_, &v)| v).skip(2).map(|(i, _)| i as u32).collect::<Vec<u32>>(); }
if · 2024-01-05 13:47
>>37964 >>37969 Good start! I'm assuming you're pretty early in your course. It's good that they're teaching you C. It's a wonderful language once it becomes second nature. >>37985 I like the recursion Lain! Here's my implementation: #include <stdio.h> #include <unistd.h> int main() { char *b = NULL; size_t bsize = 0; for (ssize_t read = getline(&b, &bsize, stdin); read > 0; read = getline(&b, &bsize, stdin)) for (ssize_t i = read; i >= 0; i--) write(STDOUT_FILENO, &b[i], 1); }
Random · 2024-01-05 15:01
>>31256 why is main on the bottom - what the fuarrrk.
Lukasiewicz · 2024-01-05 18:46
>>38054 not that lain but back in the day, main had to be at the bottom because any functions it used needed to be declared before it. So maybe they're using an older style guide or older learning resource.
aliased · 2024-03-09 18:51
>>38057 >back in the day For C and C++ it is still required to declare a function before using it (although GCC for C annoyingly just gives a warning for it by default, then throws a "type mismatch" error later. Blech).
Agent Richard Gill · 2024-03-10 13:37
>>38507 Everyone says it's a one-pass compilation thing, but would it really be so hard to have a preprocessor that added in forward-declarations automatically?
Yet Another Lainon · 2024-03-11 14:14
This is just a chat client and server with Python 3. # A simple chat server that listens for incoming connections and broadcasts messages to all connected clients. import socket import threading def main(): print('Initializing chat server...') host = input('Host [localhost]: ') host = 'localhost' if not host else host.strip() port = input('Port [5000]: ') port = 5000 if not port else int(port) clients = [] server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) server_socket.listen(5) print(f'Server started at {host}:{port}, press CTRL+C or CTRL+Break to exit') while True: client_socket, client_address = server_socket.accept() client_thread = threading.Thread(target=handle_client, args=[clients, client_socket, client_address]) client_thread.start() def handle_client(clients, client_socket, client_address): print(f'New connection from {client_address}') clients.append(client_socket) try: while True: message = client_socket.recv(4096) if not message: break print(message.decode()) broadcast(clients, message, client_socket) except Exception as err: print(f'Error handling client {client_address}: {err}') finally: client_socket.close() clients.remove(client_socket) print(f'Connection {client_address} closed') def broadcast(clients, message, sender_socket): for client_socket in clients: if client_socket == sender_socket: continue try: client_socket.send(message) except Exception as err: print(f'Error sending message: {err}') client_socket.close() clients.remove(client_socket) if __name__ == '__main__': main() # A simple chat client that connects to a chat server and sends and receives messages. import socket import threading import random def main(): print('Initializing chat client...') host = input('Host [localhost]: ') host = 'localhost' if not host else host.strip() port = input('Port [5000]: ') port = 5000 if not port else int(port) nick = input('Nick [anonymous]: ') rnd = str(random.randint(100_000, 999_999)) nick = 'anonymous' + rnd if not nick else nick.strip() client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((host, port)) receive_thread = threading.Thread(target=receive_messages, args=[client_socket]) receive_thread.start() print('Connection successful, press CTRL+C or CTRL+Break to exit') while True: message = f'[{nick}] ' + input() client_socket.send(message.encode()) def receive_messages(client_socket): while True: try: message = client_socket.recv(1024) if not message: break print(message.decode()) except Exception as err: print('Error receiving message:', err) client_socket.close() break if __name__ == '__main__': main()
monoe · 2024-03-25 11:54
dumb thing i made 3 years ago when drunk. was inspired by this conference talk i watched on declartive control flow that made use of this "custom scoped block" idea. haven't done much programming for the last year or so, but i still mostly remember how it works. pretty neat ig cpp #include <iostream> #include <type_traits> #include <chrono> #include <functional> #include <string> namespace ch = std::chrono; template<wchar_t...CHARS> struct wt_string_impl{}; template<class T, T...CHARS> wt_string_impl<static_cast<wchar_t>(CHARS)...> operator""_wt(){ return {}; } template<class T> struct wt_string; template<wchar_t...CHARS> struct wt_string<wt_string_impl<CHARS...>>{ static inline constexpr const wchar_t* value(){ return str; } private: static constexpr wchar_t str[sizeof...(CHARS)+1] = {CHARS...,'\0'}; }; template<class...F> struct overload : F... { using F::operator()...; }; template<class...F> overload(F...) -> overload<F...>; const auto suffix_impl = overload{ [](ch::hours) {return "h"_wt;}, [](ch::minutes){return "m"_wt;}, [](ch::seconds){return "s"_wt;}, [](ch::milliseconds){return "ms"_wt;}, [](ch::microseconds){return "µs"_wt;}, [](ch::nanoseconds) {return "ns"_wt;}, [](auto&&) {return " unknown_type"_wt;}, }; template<class T> constexpr const wchar_t* suffix = wt_string<decltype(std::invoke(suffix_impl,std::declval<T>()))>::value(); template <class DURATION> class TIME_IMPL{ using duration_type = DURATION; public: TIME_IMPL(size_t line, std::wostream& os = std::wcout) :_line(line),_os(os){} template <class F> void operator+(F&& f){ static_assert(std::is_invocable_v<F>, "invalid type!"); auto _s = ch::high_resolution_clock::now(); std::invoke(std::forward<F>(f)); _os << "scope on line "<<_line<<" finished in "<<ch::duration_cast<duration_type>(ch::high_resolution_clock::now()-_s).count()<<suffix<duration_type> <<'\n'; } private: std::wostream& _os; size_t _line; }; #define TIME(DURATION) TIME_IMPL<ch:: DURATION >(__LINE__) + [&]() int main(){ TIME(microseconds) { std::cout<<"hello world!"<<'\n'; }; return 0; }
Yet another Lain · 2024-03-27 00:35
A little bit of haskell that turns tabs (and spaces) into semi colons module Main where import Data.List ( intercalate ) import System.Environment (getArgs) replaceInitial :: Char -> String -> String -> String replaceInitial orig new str = take (n * length new) (cycle new) ++ dropWhile (== orig) str where n = length (takeWhile (== orig) str) main :: IO () main = do args <- argHandler file <- lines <$> readFile (head args) let spaces = map (replaceInitial '\t' " ") file let semis = map (replaceInitial ' ' ";") spaces putStrLn (intercalate "\n" semis) where argHandler :: IO [String] argHandler = do x <- getArgs if null x then error "Please specify file name" else return x
Trinity · 2024-05-10 05:26
https://git.tebibyte.media/bonsai/coreutils/src/branch/main/src/intcmp.c https://git.tebibyte.media/bonsai/coreutils/src/branch/main/docs/intcmp.1 I'm happy with this implementation but always wonder if I could do better. https://git.tebibyte.media/bonsai/coreutils/src/branch/main/src/mm.c https://git.tebibyte.media/bonsai/coreutils/src/branch/main/docs/mm.1 This code could be better but for the functionality provided I'm happy with the line count.
Crash Override · 2024-05-20 09:37
>>31244 >>31256 This is unsafe: if the user enters a string longer than 14 characters (since `sizeof(name)` is 15, and one byte is reserved for the NULL terminator), the input will overflow the buffer array.
johnson · 2024-05-20 13:05
>>31244 stupid ass retarded recreation of ping in c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <netdb.h> #include <arpa/inet.h> #define PACKET_SIZE 64 #define IP_HDR_SIZE 20 #define ICMP_HDR_SIZE 8 #define MAX_HOSTNAME_LEN 256 unsigned short checksum(void *b, int len) { unsigned short *buf = (unsigned short *)b; unsigned int sum = 0; unsigned short result; for (sum = 0; len > 1; len -= 2) sum += *buf++; if (len == 1) sum += *(unsigned char *)buf; sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); result = ~sum; return result; } int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s <hostname/IP>\n", argv[0]); return 1; } char *target = argv[1]; struct hostent *host; struct sockaddr_in addr; if ((host = gethostbyname(target)) == NULL) { printf("err\n"); return 1; } int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sockfd < 0) { perror("socket() error"); return 1; } struct timeval timeout; timeout.tv_sec = 3; timeout.tv_usec = 0; if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)) < 0) { perror("setsockopt() error"); return 1; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr = *((struct in_addr *)host->h_addr_list[0]); struct icmphdr icmp_hdr; icmp_hdr.type = ICMP_ECHO; icmp_hdr.code = 0; icmp_hdr.un.echo.id = getpid(); icmp_hdr.un.echo.sequence = 0; icmp_hdr.checksum = 0; icmp_hdr.checksum = checksum(&icmp_hdr, ICMP_HDR_SIZE); if (sendto(sockfd, &icmp_hdr, ICMP_HDR_SIZE, 0, (struct sockaddr *)&addr, sizeof(addr)) <= 0) { perror("sendto() error"); return 1; } unsigned char buffer[PACKET_SIZE]; memset(buffer, 0, sizeof(buffer)); if (recv(sockfd, buffer, sizeof(buffer), 0) <= 0) { perror("recv() error"); return 1; } struct iphdr *ip_hdr = (struct iphdr *)buffer; struct in_addr source_ip; source_ip.s_addr = ip_hdr->saddr; printf("Ping successful, source IP: %s\n", inet_ntoa(source_ip)); close(sockfd); return 0; }
Hacker · 2024-05-21 00:46
>>38642 Hey you got me thinking thank you! Here's my first take at it, with generalization and much less needless array copying! haskell import System.Environment import System.Exit import System.IO replaceInitial :: (Eq a) => a -> [a] -> [a] -> [a] replaceInitial needle replacement = replace where replace [] = [] replace arr@(x:xs) | x == needle = replacement ++ replace xs | otherwise = arr main :: IO () main = do args <- getArgs if null args then do hPutStrLn stderr $ "Error: no arguments\n" ++ "usage: rep <file> [... everything else is ignored]" exitFailure else return () file <- readFile (head args) >>= return . lines let spaces = map (replaceInitial '\t' " ") file let semis = map (replaceInitial ' ' ";") spaces putStrLn (unlines semis) Hey, here's another take, even more general! haskell import Data.List import System.Environment import System.Exit import System.IO replaceInitialArray :: (Eq a) => [a] -> [a] -> [a] -> [a] replaceInitialArray needle replacement = replace where needleLen = length needle replace [] = [] replace haystack | needle `isPrefixOf` haystack = replacement ++ replace (drop needleLen haystack) | otherwise = haystack replaceInitial :: (Eq a) => a -> [a] -> [a] -> [a] replaceInitial needle = replaceInitialArray [needle] main :: IO () main = do args <- getArgs if null args then do hPutStrLn stderr $ "Error: no arguments\n" ++ "usage: rep <file> [... everything else is ignored]" exitFailure else return () file <- readFile (head args) >>= return . lines let spaces = map (replaceInitial '\t' " ") file let semis = map (replaceInitial ' ' ";") spaces putStrLn (unlines semis) BTW, if you mix tabs and spaces you program does not work! Here's how I fixed that! haskell import Data.List import System.Environment import System.Exit import System.IO isPrefixOfAny :: (Eq a) => [[a]] -> [a] -> Maybe Int isPrefixOfAny prefixes arr = go prefixes 0 where go [] _ = Nothing go (x:xs) n | x `isPrefixOf` arr = Just n | otherwise = go xs (n + 1) replaceInitialArrays :: (Eq a) => [[a]] -> [[a]] -> [a] -> [a] replaceInitialArrays needles replacements = replace where lens = map length needles replace [] = [] replace haystack = case isPrefixOfAny needles haystack of Just n -> (replacements !! n) ++ replace (drop (lens !! n) haystack) Nothing -> haystack main :: IO () main = do args <- getArgs if null args then do hPutStrLn stderr $ "Error: no arguments\n" ++ "usage: rep <file> [... everything else is ignored]" exitFailure else return () linesOfFile <- readFile (head args) >>= return . lines let result = unlines $ map (replaceInitialArrays ["\t", " "] [";;;;", ";"]) linesOfFile putStrLn result
renames · 2024-05-21 01:07
Or even better, look haskell isPrefixOfAny :: (Eq a) => [[a]] -> [a] -> Maybe Int isPrefixOfAny prefixes arr = go 0 where preflen = length prefixes go n | n == preflen = Nothing | (prefixes !! n) `isPrefixOf` arr = Just n | otherwise = go (n + 1)
Roger Pollack · 2024-06-13 23:57
i love python one liners despite them looking weird print('\n'.join(["".join(["█" if x^y==x+y else " " for x in range(32)]) for y in range(25)])) this prints a diagonal sierpinski triangle
Void · 2024-06-14 06:35
>>39154 Recursion here is bad. But if you want to, cdr down the list using !! Is O(n) making the code quite bad. Using HOF can make this a 1 liner, and matching for cdring would save you a few lines as well, and make the intention much clearer
Motoko Kusanagi · 2024-06-22 12:58
A minimal backup script with file deduplication and scrubbing It doesn't have any methods to recover corrupted files yet, though that's just a matter of copying from another backup or the source (in the latter case the tree needs to be scanned to figure out which file might correspond). It uses symlinks instead of hardlinks to avoid potential issues with links across multiple filesystems (or the odd filesystem that doesn't support hardlinks). I might add support for compression at some point but this is good enough for my needs right now. #!/usr/bin/env python3 """ Backup script that - stores data blobs in data/ - stores symlinks to data blobs in tree/<name>/ - named trees, can be from any file system It deduplicates on the file level, basically # HOW TO USE - Specify backup location - Specify tree name - Specify tree to copy """ from blake3 import blake3 from pathlib import Path import shutil, os _v = _vv = _vvv = lambda *x: None _v = print #_vv = print #_vvv = print def _b3_hash(path): hasher = blake3(max_threads=blake3.AUTO) hasher.update_mmap(path) return hasher.digest().hex() class Backup: __slots__ = 'root', def __init__(self, root): self.root = Path(root) def _file_to_data_path(self, path): d = _b3_hash(path) return Path(f'data/{d[0:2]}/{d[2:4]}/{d[4:6]}/{d[6:]}') def _save_data(self, path): rel_to = self._file_to_data_path(path) to = self.root / rel_to if to.exists(): _vv(' ==', to) return rel_to _vv(' ->', to) to.parent.mkdir(parents=True, exist_ok=True) shutil.copyfile(path, to, follow_symlinks=False) return rel_to def _tree_path(self, name, path, subpath): rel = subpath.relative_to(path) frm = self.root / 'tree' / name / rel return frm, rel def _is_new(self, name, path, subpath): og_mtime = subpath.lstat().st_mtime try: frm, _ = self._tree_path(name, path, subpath) bk_mtime = frm.lstat().st_mtime except FileNotFoundError: return True return og_mtime > bk_mtime def _make_link(self, name, path, subpath, to): stat = subpath.lstat() frm, rel = self._tree_path(name, path, subpath) to = ('../' * (1 + len(rel.parts))) / to _vvv(' ', frm, '->', to) frm.unlink(missing_ok=True) frm.symlink_to(to) os.utime(frm, (stat.st_atime, stat.st_mtime), follow_symlinks=False) try: frm.lchmod(stat.st_mode & 0o777) except NotImplementedError: # linux symlink garbage, alas pass def _backup(self, name, path, subpath): # do symlink first since is_file and is_dir resolve symlinks if subpath.is_symlink(): _v('l', subpath) if self._is_new(name, path, subpath): # Just copy, dgaf about absolute path _vv(' ..') frm, _ = self._tree_path(name, path, subpath) frm.unlink(missing_ok=True) shutil.copyfile(subpath, frm, follow_symlinks=False) stat = subpath.lstat() os.utime(frm, (stat.st_atime, stat.st_mtime), follow_symlinks=False) elif subpath.is_file(): _v('f', subpath) if self._is_new(name, path, subpath): to = self._save_data(subpath) self._make_link(name, path, subpath, to) elif subpath.is_dir(): _v('d', subpath) frm, _ = self._tree_path(name, path, subpath) frm.mkdir(parents=True, exist_ok=True) for p in subpath.iterdir(): self._backup(name, path, p) def backup(self, name, path): path = Path(path) self._backup(name, path, path) def _check_data(self, x, y, z, name): b3_hash = f'{x}{y}{z}{name}' _vv(b3_hash) def scrub(self): it = ( w for x in (self.root / 'data').iterdir() for y in x.iterdir() for z in y.iterdir() for w in z.iterdir() ) for p in it: _vv('?', p) p1 = p.parent p2 = p1.parent p3 = p2.parent expect = f'{p3.name}{p2.name}{p1.name}{p.name}' real = _b3_hash(p) if expect != real: print(f'!!! {p} -> {real}') def copy(backup_root, tree_name, subtree_path): assert '/' not in tree_name and tree_name not in ('.', '..') bk = Backup(backup_root) bk.backup(tree_name, subtree_path) def scrub(backup_root): bk = Backup(backup_root) bk.scrub() if __name__ == '__main__': import sys _, cmd, *args = sys.argv {'copy': copy, 'scrub': scrub}[cmd](*args)
Guthrie · 2024-06-22 13:11
>>39335 I did not understand anything you said except that the code is bad. I know it's bad. It's impossible to write good code with haskell. Runtime is not intuitive and not explained anywhere, most things are not documented, so I don't honestly care.
Sipho Nkosi · 2024-06-23 00:54
>>39393 The reason why it's bad has nothing to do with haskells runtime nor it's documentation. It's about basic logical deduction of big O for data types. You know lists have a head (car) and a tail (cdr). How would you make the index function? It's simply cdring (taking the tail until the position) until the index. This is of course O(n). This is how lists work in any languages. Also note a lot of haskells documentation does lay out the big O of functions. For most functions it's fairly obvious if you know anything about data structures,with only a few functions getting big O improvements due to laziness. The code could be substationtually simpler by pattern matching or using HOF. haskell import Data.List isPrefixOfAny :: (Eq a) => [[a]] -> [a] -> Maybe Int isPrefixOfAny prefixes xs = go 0 prefixes where no n [] = Nothing go n (p:ps) | p `isPrefixOf` xs = Just n | otherwise = go (n + 1) ps -- with HOF isPrefixOfAny :: (Eq a) => [[a]] -> [a] -> Maybe Int isPrefixOfAny prefixes xs = findIndex (`isPrefixOf` xs) prefixes safeHead (x:xs) = Just x safeHead [] = Nothing -- without findIndex -- laziness fuses the filter, zip, and makes [0..] not go on forever isPrefixOfAny prefixes xs = snd <$> (safeHead (filter (\(p,_) -> p `isPrefixOf` xs) zipped)) where zipped = zip prefixes [0..] I wrote the function a few times: 1. the first was based off of yours, making it simpler by utilizing pattern matching and not making an inefficient mess 2. was using findIndex, which is provided by Data.List that you used `isPrefixOf` from. 3. acting as if `findIndex` was not available, and restricting myself to general HOF rather than ones that would automate the entire problem away. Linked below is the definition of !that I got linked to by the docs. https://hackage.haskell.org/package/base-4.16.3.0/docs/src/GHC.List.html#concat Linked is an example doc with the big O: https://hackage.haskell.org/package/base-4.16.3.0/docs/Data-List.html#v:filter
Unknown · 2024-06-23 01:22
>>38054 >>38057 Good programmers shouldn't have warnings in their programs. It's correct convention to put main after all your functions have been declared. If you really want to put main at the top you can declare the functions just before main like in a header and define them afterward.
cond · 2024-07-06 02:17
Made a program that takes cmd args and makes them silly. Feel free to soykaf on my soykafty code #include <stdio.h> void main(int argc, char *argv[]) { if (argc < 2) fprintf(stderr, "Tivomat give a string blin\n"); else { argv++; for (int flag = 0; *argv; argv++) { for (; *(*argv); (*argv)++) { if ((flag = (flag) ? 0 : 1)) if (*(*argv) > 96 && *(*argv) < 123) *(*argv) -= 32; else if (*(*argv) < 97 && *(*argv) > 64) *(*argv) += 32; printf("%c", *(*argv)); } puts(" "); } puts("\n"); } } And now in Haskell! import Prelude import Data.Char (ord, chr, isUpper, isLower) import System.Environment (getArgs) conv :: Char -> Char conv x | isUpper x = chr $ ord x + 32 | isLower x = chr $ ord x - 32 | otherwise = x sillycase :: String -> Int -> String sillycase [] _ = " " sillycase (fstr:str) flag | flag == 1 = conv fstr:sillycase str 0 | flag == 0 = fstr:sillycase str 1 main = do str <- getArgs mapM_ (putStr . ( `sillycase` 1)) str putStr "\n" I could have just jumped twice instead of that stupid flag thing but I am too lazy for edge condition checking. Oh and the Haskell program also ends with a space before the newline.
Wirth · 2024-10-22 03:22
Bored in class one day, so I wrote the smallest possible Reverse-Polish calculator in Python. Squashed it into four lines, would love to see if anyone can take it further. python while True: stack = [] for e in input().split(): stack.append(e) if e not in set('+-*/') else stack.append(str(eval(stack.pop() + e + stack.pop()))) print(stack.pop())
Wintermute · 2024-10-22 10:31
>>40224 You can start by changing stack.append(e) if e not in set('+-*/') else stack.append(str(eval(stack.pop() + e + stack.pop()))) into stack.append(e if e not in "+-*/" else str(eval(stack.pop() + e + stack.pop()))) Here's a CL version for fun: CL-USER> (iter (with stack) (dolist (e (read)) (push (if (numberp e) e (funcall e (pop stack) (pop stack))) stack)) (princ (pop stack))) (1 2 3 + +) 6 (1.5 2 *) 3.0 (3 4 lcm) 12
Yu-ichi · 2024-10-23 08:48
>>40224 python from functools import reduce while True: print(reduce(lambda s, e: s + [e if e not in "+-*/" else str(eval(s.pop() + e + s.pop()))], input().split(), []).pop()) >map() and filter() are __builtin__, but not reduce() Damn Guido.
Void · 2024-10-24 14:55
Here's my attempt at remaking Cowsay in Zig, but with Lain. For a lack of a better name I call it... LainSay. >as long as it's on just one file and is under 150 lines. Dude, This is at 148/149 lines... I probably could've saved on a bit more lines but still would be really close to the 150 line limit. const std = @import("std"); const mem = std.mem; const fmt = std.fmt; const io = std.io; const Lain = \\ \ \\ \ \\ _..--¯¯¯¯--.._ \\ ,-'' `-. \\ ,' `. \\ , \ \\ / \ \\ / ′. \ \\' / ││ ; \\; n /│ │/ │ │ \\│ / v /\/`-'v√\'.│\ , \\: /v`,——— ————.^. ; \\' │ /′@@`, ,@@ `\│ ; \\│ n│ '.@@/ \@@ /│\ │; \\` │ ` ¯¯¯ ¯¯¯ │ \/││ \\ \ \ \ │ /\/ \\ '; `-\ `′ /│/ │′ \\ ` \ — /│ │ \\ ` `. .' │ │ \\ v,_ `;._ _.-; │ / \\ `'`\│-_`'-''__/^'^' │ │ \\ ¯¯¯¯¯ │ │ \\ │ / \\ ││ \\ ││ \\ │, ; fn pushToSay(allocator: std.mem.Allocator, line_arr: *std.ArrayList([]const u8), dest: *std.ArrayList([]const u8)) !void { const line = try line_arr.toOwnedSlice(); defer allocator.free(line); line_arr.* = std.ArrayList([]const u8).init(allocator); const line_str = try mem.join(allocator, " ", line); try dest.append(line_str); } pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); std.debug.print("What should Lain say?: ", .{}); var stdin = io.getStdIn(); defer stdin.close(); const reader = stdin.reader(); var buffer: [420]u8 = undefined; const say = try reader.readUntilDelimiter(&buffer, '\n'); const trimmed_say = mem.trim(u8, say, " "); var split_say = mem.splitAny(u8, trimmed_say, " "); var line_arr = std.ArrayList([]const u8).init(allocator); defer line_arr.deinit(); var say_arr = std.ArrayList([]const u8).init(allocator); errdefer say_arr.deinit(); var line_len: usize = 0; while (split_say.next()) |word| { if (word.len + line_len <= 30) { try line_arr.append(word); line_len += word.len + 1; if (line_len == 30 or split_say.peek() == null) { try pushToSay(allocator, &line_arr, &say_arr); line_len = 0; if (split_say.peek() == null) break; } } else if (word.len + line_len > 30) { if (word.len + line_len <= 40) { try line_arr.append(word); try pushToSay(allocator, &line_arr, &say_arr); } else { try pushToSay(allocator, &line_arr, &say_arr); try line_arr.append(word); } line_len = 0; } } const fmt_say = try say_arr.toOwnedSlice(); const total_lines = fmt_say.len; var longest_line: usize = 0; defer allocator.free(fmt_say); defer for (fmt_say) |line| { allocator.free(line); }; const say_str = try mem.join(allocator, "\n", fmt_say); defer allocator.free(say_str); for (fmt_say) |line| { if (line.len > longest_line) longest_line = line.len; } var top_bottom_lines = try allocator.alloc(u8, longest_line + 4); defer allocator.free(top_bottom_lines); for (0..top_bottom_lines.len) |i| { if (i <= 1 or i >= top_bottom_lines.len - 2) { top_bottom_lines[i] = ' '; } else { top_bottom_lines[i] = '-'; } } std.debug.print("{s}\n", .{top_bottom_lines}); if (total_lines == 1) { std.debug.print("< {s} >\n", .{say_str}); } else { for (0..total_lines) |i| { const diff = longest_line - fmt_say[i].len; var spaces = try allocator.alloc(u8, diff); defer allocator.free(spaces); var line: []const u8 = undefined; defer allocator.free(line); for (0..diff) |j| { spaces[j] = ' '; } if (i == 0) { const fmt_line = "/ {s}{s} \\\n"; line = try fmt.allocPrint(allocator, fmt_line, .{ fmt_say[i], spaces }); } else if (i == total_lines - 1) { const fmt_line = "\\ {s}{s} /\n"; line = try fmt.allocPrint(allocator, fmt_line, .{ fmt_say[i], spaces }); } else { const fmt_line = "| {s}{s} |\n"; line = try fmt.allocPrint(allocator, fmt_line, .{ fmt_say[i], spaces }); } std.debug.print("{s}", .{line}); } } std.debug.print("{s}\n", .{top_bottom_lines}); std.debug.print("{s}\n", .{Lain}); }
Molly Millions · 2024-11-03 11:06
I'm studying design patters. I just programmed a Strategy design pattern code. #include <stdio.h> // Strategy typedef struct{ void (*ptrF_RLAction)(struct s_RockectLauncher*); int RockectsPerSecond; int RocketDamage; } s_RockectLauncher; // Strategies void f_RocketLauncherDefault(s_RockectLauncher* s_RL){ s_RL->RockectsPerSecond = 10; s_RL->RocketDamage = 4; printf("Default selected\n"); } void f_RocketLauncherExtreme(s_RockectLauncher* s_RL){ s_RL->RockectsPerSecond = 30; s_RL->RocketDamage = 6; printf("Extreme selected\n"); } // Context void SetRocketLauncher(s_RockectLauncher* s_RL, void (*Execute)(s_RockectLauncher*)){ s_RL->ptrF_RLAction = Execute; s_RL->ptrF_RLAction(s_RL); } int main(){ s_RockectLauncher s_RL = {0}; SetRocketLauncher(&s_RL, f_RocketLauncherDefault); printf("RPS: %d\nRD: %d\n", s_RL.RockectsPerSecond, s_RL.RocketDamage); return 0; } What do you think?
Motoko Kusanagi · 2024-11-03 13:31
>>40324 >What do you think? I think replacing your example with a switch statement and an enum is easier to reason about: #include <stdio.h> struct RocketLauncher { int rockets_per_second; int rocket_damage; }; enum RocketLauncherMode { ROCKET_LAUNCHER_DEFAULT, ROCKET_LAUNCHER_EXTREME, }; void set_rocket_launcher(struct RocketLauncher *rl, enum RocketLauncherMode mode) { switch (mode) { case ROCKET_LAUNCHER_DEFAULT: rl->rockets_per_second = 10; rl->rocket_damage = 4; printf("Default mode selected\n"); break; case ROCKET_LAUNCHER_EXTREME: rl->rockets_per_second = 30; rl->rocket_damage = 6; printf("Extreme mode selected\n"); break; } } int main(void) { struct RocketLauncher rl = {0}; set_rocket_launcher(&rl, ROCKET_LAUNCHER_DEFAULT); printf("RPS: %d\nRD: %d\n", rl.rockets_per_second, rl.rocket_damage); return 0; }
Splicer · 2024-11-03 14:34
>>40328 That's not the approach I'm looking for. What if I had 500 rocket launchers? I don't think having 500 cases is the most efficient way to do it. That's why I'm using a design pattern.
Knuth · 2024-11-03 15:37
>>40329 #include <stdio.h> #define MAX_ROCKET_LAUNCHERS 500 struct RocketLaunchers { int rockets_per_second[MAX_ROCKET_LAUNCHERS]; int rocket_damage[MAX_ROCKET_LAUNCHERS]; }; void set_default_mode(struct RocketLaunchers *launchers, int index) { launchers->rockets_per_second[index] = 10; launchers->rocket_damage[index] = 4; printf( "Rocket Launcher %d set to Default mode (RPS: %d, Damage: %d)\n", index, launchers->rockets_per_second[index], launchers->rocket_damage[index] ); } void set_extreme_mode(struct RocketLaunchers *launchers, int index) { launchers->rockets_per_second[index] = 30; launchers->rocket_damage[index] = 6; printf( "Rocket Launcher %d set to Extreme mode (RPS: %d, Damage: %d)\n", index, launchers->rockets_per_second[index], launchers->rocket_damage[index] ); } void init_rocket_launchers(struct RocketLaunchers *launchers) { for (int i = 0; i < MAX_ROCKET_LAUNCHERS; ++i) { set_default_mode(launchers, i); } } void set_all_to_extreme(struct RocketLaunchers *launchers) { for (int i = 0; i < MAX_ROCKET_LAUNCHERS; ++i) { set_extreme_mode(launchers, i); } } int main(void) { struct RocketLaunchers rocket_launchers = {0}; init_rocket_launchers(&rocket_launchers); set_all_to_extreme(&rocket_launchers); return 0; }
vector · 2024-11-03 15:47
>>40332 I mean, 500 types of rocket launchers. That's why I said >I don't think having 500 cases is the most efficient way to do it Each case is a different type of a rocket launcher.
Boris Grishenko · 2024-11-03 17:15
>>40333 I mean how "efficient" do you want to go if jump tables aren't fast enough for you? Do you want to do the 8-bit era (NES) up to very early 32-bit era (PS1, Saturn, Intel 80386) approach of storing those RPS and DMG values in an array as opposed to a jump table (which is what the compiler would create in the assembly output by either the switch statement cases or your "strategy" design pattern functions)? Reading from an array of values does not have the overhead of an "indirect jump" (branching to the address) that you'd have in a jump table or the occasional instruction pipeline stalls.
Technician · 2024-11-03 23:41
>>40324 The most efficient way to do this is to use a static array of rocket launcher initialization values and select them based on either a hash table or just a number if your input type is already numeric & sequential. It's also easier to design around because you don't need to write a whole function for each setting, just change the array. Since you're using C your ability to create a perfect hash function (one with no collisions on the possible inputs) is pretty limited. If you were going for the absolute limits that the machine could do, I would add a constant K and then XOR together the bytes of your input type, possibly followed by a modulo operation to get it down to exactly the right length for the array of rocket launchers. Then you could do a few tests until you find a constant K that doesn't have a collision. If you really really need to eke out the maximum speed for this "hash function" (like if you're designing the decoder for a CPU or something) you can optimize this hash function further, but that's going to be extremely architecture dependent and won't usually be worth it. This avoids unnecessary branches and jumps and can be cache friendly (but again that's architecture dependent), so it is definitely the most efficient way to do it.
Torvalds · 2024-11-04 07:09
>>40334 Maybe I was ambiguous, my bad. When I talk about >I don't think that having 500 cases is the most efficient way to do it I mean in terms of scalability and modularity. For example, in my code, I can add a new type of rocket launcher easily, and if I want the output of a specific one, I just have to pass the corresponding function to SetRocketLauncher and not have a conditional statement and identifiers, like switch and enum, and that's enough for me. Honestly, I don't know why you are talking about tables and arrays.
JARGON · 2024-11-04 12:23
>>40336 Using a table means you write code once and add values initialization values as needed. The only thing that changes between the different types of rocket launcher is the values, not the operations that happen with them, so writing that code more than once is a waste of your time.
Iverson · 2024-11-04 14:52
>>40336 How about this? • No conditional statements to set rocket type. • Only two lines to add (one in both the enum and array) for any new rocket you add unlike your five line functions (or seven lines if you include the surrounding newlines). • Fewer "jmp" instructions would be produced in the assembly output on godbolt.org with O3 or Ofast flag for setting rocket types -- "jmp" instructions produced from printf or puts are unavoidable if you use those standard library I/O functions anywhere in your program -- compared to your strategy design pattern or the switch statement design. ✗ Only con is needing to keep the enum values and corresponding array values in the correct order. ✗ A little more "global pollution" which some FOSS developers might complain about, but it's not seen as a bad thing in non-generalized, self-contained software like games or embedded software at all. #include <stdio.h> struct RocketLauncher { int rockets_per_second; int rocket_damage; const char *name; }; enum RocketTypesEnum { ROCKET_BASIC, ROCKET_MAGNETOPLASMA, ROCKET_ION_DRIVE, ROCKET_ANTIMATTER, ROCKET_QUANTUM, }; struct RocketLauncher rocket_types[] = { { 10, 4, "Basic" }, { 15, 6, "Magnetoplasma" }, { 20, 5, "Ion Drive" }, { 25, 10, "Antimatter" }, { 30, 12, "Quantum" }, }; #define NUM_ROCKET_TYPES (sizeof(rocket_types) / sizeof(rocket_types[0])) void print_available_rockets() { for (int i = 0; i < NUM_ROCKET_TYPES; ++i) { struct RocketLauncher *selected_rocket = &rocket_types[i]; printf( "Rocket Type: %s\nRockets Per Second: %d\nRocket Damage: %d\n\n", selected_rocket->name, selected_rocket->rockets_per_second, selected_rocket->rocket_damage ); } } void print_current_rocket(struct RocketLauncher *rocket_launcher) { printf( "Rocket Type: %s\nRockets Per Second: %d\nRocket Damage: %d\n\n", rocket_launcher->name, rocket_launcher->rockets_per_second, rocket_launcher->rocket_damage ); } void change_current_rocket(struct RocketLauncher *current_rocket, enum RocketTypesEnum rocket_type) { *current_rocket = rocket_types[rocket_type]; } int main(void) { struct RocketLauncher rocket_launcher = rocket_types[ROCKET_BASIC]; printf("Printing all available rocket types...\n"); print_available_rockets(); printf("Your current rocket is:\n"); print_current_rocket(&rocket_launcher); change_current_rocket(&rocket_launcher, ROCKET_ION_DRIVE); printf("Changed current rocket to:\n"); print_current_rocket(&rocket_launcher); return 0; }
Von Neumann · 2024-11-05 01:05
>>40344 Looks good, but why copy all the rocket launcher data every time you want to set it? Just store a pointer into the static array.
Shogun · 2024-11-05 08:19
>>40348 Another approach could be to use an enum (integer) variable instead. Not sure if that has any more overhead than a pointer. struct RocketLauncher rocket_launcher = rocket_types[ROCKET_BASIC]; /* becomes ... */ enum RocketLauncherEnum rocket_launcher = ROCKET_BASIC; etc. etc.
byte · 2024-11-07 17:47
Single-line Bash function definition for an RFC document director and fetcher or whatever you would call it Usage:$ rfc NUMBER $F means filename, $RFC_DIR is an environment variable with a self explanatory name, source.txt lies in $RFC_DIR and contains url to ietf.org/rfc I'm new to shellscript be nice plox bash rfc() (F=rfc$1.txt;cd $RFC_DIR;less $F||(wget $(<source.txt)/$F&&rfc $1)) I used && operator and recursion at the end because it looks cleaner in the prompt if wget fails than using ; with less $F which would output the same error twice It was initially shorter (67 characters, now 73) but I wanted readability too
Hacker · 2024-11-08 00:40
>>40364 1. Use {} and `cd - >/dev/null` to get back at the end instead of (), you're spawning a subshell for nothing. Or better, don't cd and use fully qualified paths, so that you don't have to cd back (which can be annoying if you return early due to `set -e`). 2. If you do 1, use `local F=rfc$1.txt`, you don't want to override your current shell's variables. 3. Quote your variables, e.g. `cd "$RFC_DIR"`. 4. Check that RFC_DIR isn't empty via `! [ "${RFC_DIR:-}" ] && return 1`, you risk overwriting stuff if it is empty as cd bring you to your ~. Create it if the directory doesn't exist yet. 5. I'd deduce the URL from $1, personally. Like so: https://datatracker.ietf.org/doc/html/rfc$1 6. Why recurse? You risk an infinite fork chain, if less wget/less fails for any reason. The programmer's way is `! [ -f "$F" ] && wget ...; less "$F"`. 7. I suggest you switch to curl, it's the "proper" tool compared to wget. How I'd do it: rfc() { ! [ "${RFC_DIR:-}" ] && return 1 local url=https://datatracker.ietf.org/doc/html/rfc$1 local F=$RFC_DIR/${url##*/}.txt mkdir -p "$RFC_DIR" ! [ -f "$F" ] && wget -O "$F" "$url" less "$F" } $ export RFC_DIR=~/rfcs $ rfc 4180 Bonus: it's POSIX sh, not bash.
push · 2024-11-09 16:10
>>40365 Thank you for the insightful critique It was meant to be short and fit on a single line, therefore I didn't use lists because they require more characters than subshells, changing directory and setting variables in a subshell is also local to that subshell which makes it shorter than using flags to set output directory and appending local to every variable definition I explained that &&rfc $1 doesn't output the same error twice in the terminal (I wrote prompt oops) if wget fails because of the && operator which is the same length as ;less $1 which does output the error twice, otherwise I'd have to add an extra character for &&less $1 it looks cool i think, it kinda "retries" itself I did get an infinite recursion in an earlier version but now, assuming less isn't broken, there shouldn't be any problem that isn't output to the terminal and easily fixed, otherwise you only have to pull out the chord to make wget break the pipeline FYI your code downloads an html page and tries to view it through less
queue · 2024-11-09 21:33
>>40344 not that lain but i think you're missing the point of the strategy pattern. Imagine another program written to use the RocketLauncher library. If you take the switch statement, lookup table, or this enum approach, then the only way for someone to change how the RocketLauncher RLAction function works is to change the library. If you use a strategy pattern, they can just supply the function they want to use. lain's example isn't a good one since it just sets struct values and that isn't a reasonable use case for the strategy pattern.
Iverson · 2024-11-10 08:54
>>40365 local is not POSIX, it is still bash
Church · 2024-11-10 18:00
>>40379 Actually, it's ash (incl. BSD ash, dash, busybox ash) and available everywhere except in AT&T ksh (not the one in OpenBSD) and some very obscure shells. But yeah, I noticed my mistake soon after posting, didn't want to post just to correct that. Bonus: thread about the tentative standardization of local, https://www.austingroupbugs.net/view.php?id=767
Jens Hansen · 2024-11-15 20:12
I've done the project 16-5 from the book C Programming A Modern Approach, any tips or suggestions for improving my code? Does it looks good? Was gonna post this on beginners general, but the thread hit it's limit sorry if it doesn't belong in this thread #include <stdio.h> #include <stdlib.h> #include <string.h> #define INPUT_SIZE 10 #define MAXIMUM_FLIGHTS 10 #define TIME_L 20 #define MERIDIAN_SIZE 2 struct flight { int departure; //stored in minutes int arrival; //stored in minutes }; int time24_m(int hours, int minutes); void time12_s(int time, char *str_v, int n); int main(void) { // Could have been done with readable input using a create_table // function but have skipped in this exerciseb because it said time // was stored in minutes struct flight flights[MAXIMUM_FLIGHTS] = { {480, 616}, {583, 712}, {679, 811}, {767, 900}, {840, 968}, {945, 1075}, {1140, 1280}, {1305, 1438}, }; char input[INPUT_SIZE+1]; printf("Enter a 24-hour time: "); fgets(input, INPUT_SIZE, stdin); int hours, minutes; if (sscanf(input, "%2d:%2d", &hours, &minutes) != 2) { fprintf(stderr, "Invalid format, exiting.\n"); exit(EXIT_FAILURE); } int input_time_min = time24_m(hours, minutes); char fmt_departure[TIME_L+1], fmt_arrival[TIME_L+1]; for (int i = 0; i < MAXIMUM_FLIGHTS; i++) { if (input_time_min < flights[i].departure) { time12_s(flights[i].departure, fmt_departure, TIME_L); time12_s(flights[i].arrival, fmt_arrival, TIME_L); printf("Closest departure time is %s., arriving at %s", fmt_departure, fmt_arrival); exit(EXIT_SUCCESS); } } printf("No more flights today\n"); exit(EXIT_SUCCESS); } // Returns time in minutes, input time should be in 24-hours format int time24_m(int hours, int minutes) { return (hours * 60) + minutes; } //Returns a string in 12-hours format into a variable, input time //should be in minutes void time12_s(int time, char *str_v, int n) { int hours_24 = time / 60 % 24; int minutes = time % 60; int hour_12; char meridian[MERIDIAN_SIZE+1] = "AM"; if (hours_24 > 12) { hour_12 = hours_24 % 12; strncpy(meridian, "PM", MERIDIAN_SIZE+1); } else { hour_12 = hours_24; } snprintf(str_v, n, "%.2d:%.2d %s", hour_12, minutes, meridian); }
list · 2024-11-15 20:19
>>40430 Lainchan removed my tabs indentation and now I can't delete :)
Iverson · 2024-11-16 15:47
>>40431 I wonder if the admin is a spaces-only zealot.
Switch · 2024-11-24 05:58
>>40430 Just a cursory look char meridian[MERIDIAN_SIZE+1] = "AM"; You can just write char meridian[] = "AM"; and the buffer will be automatically sized to 3 bytes (the length of the string literal, including trailing null terminator). In the strncpy you can replace MERIDIAN_SIZE+1 with sizeof(meridian), since you're working with a fixed-size buffer (won't work with pointers!). But the strncpy is redundant anyway, you only use meridian for snprintf, then discard it. You can just define it like so: const char *meridian = "AM"; if (hours_24 > 12) { hour_12 = hours_24 % 12; meridian = "PM"; } which IMO is clearer. Ditto for "struct flight flights[];" time12_s doesn't use n. I'd remove it and clearly document the buffer passed must be at least TIME_L + 1 long. Also, I'm pretty sure your conversion from 24h to 12h isn't correct for 00:00 (12:00 AM) and 12:00 (12:00 PM). I haven't actually run the code though. exit(EXIT_SUCCESS) is verbose and the call is redundant when inside main(). Just do return 0 for success and return 1 for error. Lastly, you probably should define the flights array as const, perhaps move it outside the function too. This should help the compiler with optimizations a bit. >Your request looks automated; Post discarded. The hell? Guess I'll try Chromium instead of Firefox...
Netrunner · 2024-12-11 01:20
4chan scraper is a standard project for every newbie I think. It's a simple but practical program. Here is mine; args for the bash script are ./script [Dir. To Create & Save In] [Thread URL] bash #!/bin/sh list_files () { curl --silent $1 \ | sed 's/\ /\n/g' \ | grep href \ | grep i.4cdn.org \ | sed 's/href=\"\/\///g' \ | sed 's/\"$//g' \ | uniq } mkdir $1 cd $1 for i in $(list_files $2) do wget --retry-on-http-error=429 --random-wait --wait 5 $i done
Koos van der Merwe · 2024-12-23 06:30
This is a linear animation system. It automatically detects if the input image is vertical or horizontal and animates it. Very simple. I did it in about 2 hours, kinda silly code. #include "raylib.h" // note: ptf means pointer to function, used to point to AnimationHorizontal or AnimationVertical // animated object typedef struct { Texture2D sprite; // sprite, it could be a horizontal or vertical image unsigned int frames; // quantity of frames of an image unsigned int fps; unsigned int frame_x_anim; // this variable is used for increase the index of horizontal frames unsigned int frame_y_anim; // this variable is used for increase the index of vertical frames unsigned int frame_w; // widht of one frame unsigned int frame_h; // height of one frame // pointer to function (ptf), this is used for take the corresponding animation function (hor. or ver.) void (*Animation)(unsigned int*, const int, const int); unsigned int* frame_ptr; // ptf variable, used for store frame_x_anim or frame_y_anim in a animation function unsigned int frame_step; // ptf variable, used for store frame_w or frame_h unsigned int frame_max; // ptf variable, used for store the max of an image, width or height float pos_x; // position float pos_y; // ... } SimpleAnimatedObject; // animation functions // note: max-32, because the correct points are 0, 32 and 64. 96 (original widht) repeat the first frame void AnimationHorizontal(unsigned int* frame_x, const int step, const int max) { // horizontal animation (*frame_x != max-32) ? *frame_x += step : *frame_x = 0; } void AnimationVertical(unsigned int* frame_y, const int step, const int max) { // vertical animation (*frame_y != max-32) ? *frame_y += step : *frame_y = 0; } int main(void) { InitWindow(600, 600, "Animation"); SetTargetFPS(60); // instance and obj's init SimpleAnimatedObject obj = {0}; obj.pos_x = GetScreenWidth()/2; obj.pos_y = GetScreenHeight()/2; obj.sprite = LoadTexture("spr_v.png"); obj.fps = 5; obj.Animation = NULL; // set ptf null int frameCounter = 0; while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(GRAY); // when you hit enter, it determinates if the sprite is vertical or horizontal // and set a few variables if (IsKeyPressed(KEY_ENTER)) { obj.frames = 3; // set frames, obviously, this is only for simplycity // determinate if sprite is vertical or horizontal if (obj.sprite.width > obj.sprite.height) { // horizontal obj.Animation = &AnimationHorizontal; // set ptf to horizontal animation obj.frame_ptr = &obj.frame_x_anim; // frame_ptr takes the addres of memory // of frame_x_anim, it's part of the // ptf-variables obj.frame_w = obj.sprite.width / obj.frames; // it determinates que widht of each frame obj.frame_h = obj.sprite.height; // set the height image obj.frame_step = obj.frame_w; // how long has to advance the animator (the width of one frame) obj.frame_max = obj.sprite.width; // set the max widht, send it the ptf } else { // vertical obj.Animation = &AnimationVertical; // same thing here ... obj.frame_ptr = &obj.frame_y_anim; obj.frame_h = obj.sprite.height / obj.frames; obj.frame_w = obj.sprite.width; obj.frame_step = obj.frame_h; obj.frame_max = obj.sprite.height; } } frameCounter++; // increase frames // animation if (frameCounter >= 60 / obj.fps && obj.Animation != NULL) { frameCounter = 0; obj.Animation(obj.frame_ptr, obj.frame_step, obj.frame_max); } // draw sprite DrawTexturePro( obj.sprite, Rectangle{(float)obj.frame_x_anim, (float)obj.frame_y_anim, (float)obj.frame_w, (float)obj.frame_h}, Rectangle{obj.pos_x, obj.pos_y, (float)obj.frame_w, (float)obj.frame_h}, Vector2{0.0f, 0.0f}, 0.0f, WHITE ); EndDrawing(); } UnloadTexture(obj.sprite); CloseWindow(); return 0; }
Unsigned · 2024-12-26 07:28
>>38051 I think you should replace the first for loop with a while loop instead so you don't need to write the same call twice: ``` ssize_t read = 0; while( (read = getline(&b, &bsize, stdin)) > 0) while (--read >= 0) putchar(b[i]); ``` I think it's more elegant to reuse the read variable in the inner loop but it might be easier to understand to use a separate variable or a for loop. Also I think putchar is better because it buffers the output. You don't want to write a file every character because that would be slow, you would want to fill a buffer and then once that buffer gets large enough, write that. I'm not that sure about it though so if anyone knows more about this, correct me. The space between the brackets in the while is not a coincidence. This kind of assignment + while condition check is popular, or at least used to be, in C. I at least know of the example of old C socket programs. I don't remember the name of the book, but there's a very popular two-volume textbook about sockets and IPC in unix and they used this a lot there. It's probably the most popular C sockets book there is and it's from the 90's.
Cowboy · 2024-12-27 04:20
Guess number game in python one-liner import itertools, random min, max = 1, 10 extra_attempts = 3 welcome = 'I guessed a number. Can you guess?' prompt = 'Your number (0 for exit): ' less = 'Your number is too small.' greater = 'Your number is too big.' correct = 'Your number is correct! Again?' out_of_attempts = 'You are out of attempts. Again?' any_key_prompt = 'Press Enter to play...' # end on success list(itertools.chain.from_iterable(iter(lambda: itertools.chain( iter(lambda: input(any_key_prompt), ''), iter(lambda: print(welcome), None), itertools.takewhile(lambda x: x[3] is not True, itertools.chain( itertools.takewhile(lambda x: x[3] is not False, itertools.starmap( lambda inp, num, attempt: (inp, num, attempt, True if inp == num else False if attempt is None else None, print(correct) if inp == num else print(less, attempt or 0, 'attempts left.') if inp < num else print(greater, attempt or 0, 'attempts left.'))[:-1], itertools.takewhile( lambda x: x[0] is not None, ( itertools.zip_longest( iter(lambda: int(input(prompt)), 0), itertools.repeat(random.randint(min, max)), range(extra_attempts, 0, -1), fillvalue=None ) ) ) )), # end on no attempts iter(lambda: print(out_of_attempts), None) )), ), None)) )
Nguoi La · 2024-12-27 09:36
>>40816 One expression, sure, but hardly a one-liner. Also, statements like 'not True' and 'True if inp == num else False' seem rather redundant?
HELIOS · 2024-12-30 03:06
This one backups an dokuwiki instance to a local folder. It kind of is like kicking dead whales down the beach, due to how limited it is, but it works for my purposes. bash #!/usr/bin/env bash CMD="rsync --checksum --verbose --archive" USER="user@" FAR="IPADDRESSHERE:/var/www/dokuwiki/" declare -a FOLDERS=( "data/pages/" "data/attic/" "data/meta/" "data/media/" "data/media_attic/" "data/media_meta/" "conf/" "lib/" ) for folder in ${FOLDERS[@]}; do mkdir -p $folder done for folder in ${FOLDERS[@]}; do ${CMD} ${USER}${FAR}$folder $folder done
Knuth · 2024-12-30 04:26
>>40820 > 'not True' None is True => False None is False => False None is not False => True None is not True => True > 'True if inp == num else False' The full line is 'True if inp == num else False if attempt is None else None'. It can take three values.
Unsigned · 2025-04-15 21:18
Little script to download a random banner from an imageboard. [code] #!/usr/bin/perl use strict; use warnings; use v5.10; use List::Util qw(max); sub get_banner { my @cmd = ( # copy-paste "copy as curl" of the banner.php url ); pipe my ($read, $write); my $pid = fork; if (!$pid) { close $read; close STDOUT; open STDOUT, ">&", $write; exec @cmd; } else { close $write; local $/; my $bytes = <$read>; waitpid $pid, 0; if ($?) { say STDERR "ERROR: curl"; return; } return $bytes; } } sub file_extension { my $bytes = shift; if (length($bytes) >= 8 && substr($bytes, 0, 8) eq "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a") { ".png" } elsif (length($bytes) >= 3 && substr($bytes, 0, 3) eq "\xff\xd8\xff") { ".jpg" } elsif (length($bytes) >= 6 && (substr($bytes, 0, 6) eq "GIF87a" || substr($bytes, 0, 6) eq "GIF89a") ) { ".gif" } elsif (length($bytes) >= 15 && substr($bytes, 0, 15) eq "\x52\x49\x46\x46RIFF\x57\x45\x42\x50\x56\x50\x38" ) { ".webp" } else { return; } } my @files = grep { -f } map { chomp; $_ } qx{ ls }; my $pic_num = max map { /\A(\d+)\.(?:png|jpe?g|gif|webp)\z/ ? $1 : () } @files; $pic_num = defined $pic_num ? $pic_num + 1 : 1; my $bytes = get_banner(); if (!defined $bytes) { exit 1; } my $ext = file_extension($bytes); $ext //= ".bin"; my $file = $pic_num . $ext; open my $fh, ">", $file; binmode $fh; local $/; print $fh $bytes; close $fh;
nibble · 2025-04-16 04:45
>>41676 I'm surprised to see another perl programmer.
limited · 2025-04-16 11:25
>>31244 7F 45 4C 46 01 00 00 00 00 00 00 00 00 00 01 00 02 00 03 00 34 00 00 00 25 00 01 00 04 00 00 00 58 B3 34 CD 80 B3 01 B2 01 B9 20 00 01 00 B0 04 CD 80 EB EC This is the smallest elf linux i386 executable that prints something (precisely, just one character 'X') and exits correctly. 52 bytes, aka both the 32 bytes program header and 18 bytes executable fit completely and perfectly inside the elf header too. The program has to be run with no arguments though.
Unidentified · 2025-04-16 11:28
>>41705 Correct exit by the way is defined as either exiting with 0, or exiting with any byte with the absolute ability to exit with anything including with a 0.
Acid Burn · 2025-04-16 16:14
>>41688 You're the only one else here? We really are a dying breed...
melz · 2025-04-16 16:21
>>31244 please excuse the fact that i am an absolute beginner and know basically nothing about programming or anything techy but anyways this is a batch script that generates a random number (between 1 and 32768) every 5 seconds. echo Output: echo: goto generate :generate set /a rnd=%random% * 32768 / 32768 + 1 echo %rnd% sleep -m 5000 goto generate
Anonymous · 2025-04-16 18:32
>>41721 The crew is getting old and there's very little new blood. I don't use it professionally anymore, but I was in a situation recently where CGI was one of the few ways to deploy a web application, so I went back to an old familiar friend. https://git.coom.tech/gg/WeatherNews.jl/src/branch/main/www
Batou · 2025-04-18 08:18
A few months ago, I came across a site that lets you describe a diagram in a simple language consisting of square brackets and arrows. https://nomnoml.com/ There's also a command line utility that can convert this format to SVG. https://github.com/skanaar/nomnoml To facilitate a convenient edit cycle, I wrote a shell script to: - watch the current directory for changes; - if it's a noml file, render it as an SVG file. #!/bin/bash inotifywait -e close_write,moved_to,create -m . | while read -r directory events filename; do echo $directory $events $filename if [[ $filename == *.noml ]] ; then svg=${filename%.noml}.svg nomnoml $filename $svg fi done # This script watches the current dir for changes, # and if the file that changed ends in ".noml", # regenerate the corresponding SVG file. I like using with Emacs. With `M-x global-auto-revert-mode` turned on, it picks up changes to the .noml file and when the SVG is rendered, it picks up that change right away as well. Dependencies: - bash - inotifywait (from inotify-tools) - nomnoml
swap · 2025-04-18 16:17
For when you are on mobile and you always have go over the big title announcements on the catalog when scrolling down, just add this to the User CSS (Options -> User Css): /* Enter here your own CSS rules... */ /* If you want to make a redistributable style, be sure to have a Yotsuba B theme selected. */ /* You can include CSS files from remote servers, for example: */ @import "http://example.com/style.css"; .blotter { display: none; }
Demeere · 2025-04-19 08:29
>>41722 :generate set /a rnd=%random% * 32768 / 32768 + 1 & echo %rnd% & sleep 5 & goto generate
Eldon Tyrell · 2025-04-19 09:48
>>41782 might be a stupid idea, but why not simply invoke the same batch script? you can skip the goto part then and make it even smaller
Fred Nurk · 2025-04-19 16:28
>>31244 <code> import myLibrary as ml ml.run() </code> Here. Average day of a python dev.
Anonymous · 2025-04-20 12:05
#include <stdio.h> int main() { printf("Goodbye, world!"); return 0; }
Rick Deckard · 2025-04-20 20:39
I forget what I was working on exactly when I wrote this, but I got tired of looking for the keycode for each key, so instead i wrote a script to get they keycode by name from the keycodes file. grep "#define KEY_${1^^}[[:space:]]" /usr/include/linux/input-event-codes.h | awk '{print $3}'
Ivan Horvat · 2025-04-21 00:08
>>41783 Every call to the batch script would create a new process. These processes would accumulate on each loop iteration. This will eventually lead to some kind of resource exhaustion (unless the batch interpreter for Windows is somehow tail recursive which I doubt). The goto loop, on the other hand, keeps resource usage constant and can run indefinitely.
Unsigned · 2025-04-21 04:02
>>41807 Oh sorry, didn't know that. I don't use Windows or script using Batch.
let · 2025-04-21 04:42
>>41809 It's been a long time for me too, but even in bash, the result would be similar if you tried to loop by recursively calling yourself again.
noma · 2025-04-21 05:46
A minimalist bash script that uses ffmpeg to cut an MP4 video. ``` #!/bin/bash # Usage: ./cut_video.sh <input.mp4> # Check input [ $# -ne 1 ] && { echo "Usage: $0 <input.mp4>"; exit 1; } input_file="$1" [ ! -f "$input_file" ] && { echo "Error: File not found!"; exit 1; } # Get times read -p "Start time (HH:MM:SS or seconds): " start_time read -p "End time (HH:MM:SS or seconds): " end_time # Convert to seconds if HH:MM:SS [[ $start_time =~ ^[0-9]{2}:[0-9]{2}:[0-9]{2}$ ]] && start_secs=$(echo $start_time | awk -F: '{print ($1*3600)+($2*60)+$3}') || start_secs=$start_time [[ $end_time =~ ^[0-9]{2}:[0-9]{2}:[0-9]{2}$ ]] && end_secs=$(echo $end_time | awk -F: '{print ($1*3600)+($2*60)+$3}') || end_secs=$end_time duration=$(($end_secs - $start_secs)) # Set output in same directory output_file="${input_file%.*}_cut.mp4" echo "Cutting video..." # Cut with ffmpeg and show progress ffmpeg -i "$input_file" -ss "$start_time" -t "$duration" -c:v copy -c:a copy -progress pipe:1 -y "$output_file" 2>&1 | \ while read line; do [[ $line =~ "out_time_ms=" ]] && { time_ms=$(echo $line | grep -oP '(?<=out_time_ms=)\d+') time_s=$((time_ms / 1000000)) percent=$((time_s * 100 / duration)) printf "\rProgress: [%-50s] %d%%" $(printf '=%.0s' $(seq 1 $((percent/2)))) $percent } done echo -e "\nDone! Output: $output_file" ```
noma · 2025-04-21 05:54
#!/bin/bash # Script to search for a pattern in files and replace it interactively search_and_replace() { echo "Enter search pattern:" read -r pattern echo "Enter replacement string:" read -r replacement if [ -z "$pattern" ]; then echo "No pattern provided" exit 1 fi # Grep recursively, show matches, pipe to fzf matches=$(grep -r "$pattern" . 2>/dev/null | fzf --multi --height 60% --border --prompt="Select lines to replace (TAB to multi-select): " \ --preview 'echo {} | bat --style=numbers --color=always 2>/dev/null || cat -n') if [ -n "$matches" ]; then echo "Confirm replacement of '$pattern' with '$replacement' in selected files? (y/N)" read -r confirm if [[ "$confirm" =~ ^[Yy]$ ]]; then echo "$matches" | while IFS=: read -r file line; do sed -i "s/$pattern/$replacement/g" "$file" echo "Replaced in $file" done else echo "Replacement aborted" fi else echo "No matches selected" fi } search_and_replace
Anamika · 2025-04-21 14:09
>>41811 Depends on how you call/exec the script. I suppose 'exec $0' would work, because it replaces the current process with another process.
list · 2025-04-21 17:59
Code that calculates Adler32 checksums for bytes import qualified Data.ByteString as B import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8) adler32 :: B.ByteString -> Integer adler32 dat = a + 65536 * b where modulus = 65521 cumulative = scanl (\x y -> x + fromIntegral y) 1 . B.unpack $ dat a = last cumulative `rem` modulus b = (sum . tail $ cumulative) `rem` modulus main = (print . adler32 . encodeUtf8 . T.pack) "Wikipedia"
Just another Random Lainon · 2025-04-21 18:52
>>41826 Oh yeah, I guess exec would work to keep the number of processes from growing.
hash table · 2025-04-24 09:47
hello world in ~150 Byte what's the trick?!
Zuse · 2025-04-25 08:24
I call this one ffp and it's short for ffprobe. #!/bin/sh ffprobe -v error -show_streams -select_streams v:0 -of json -i $@ Usage: ffp video.mp4 Sample Output: { "streams": [ { "index": 0, "codec_name": "h264", "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", "profile": "High", "codec_type": "video", "codec_tag_string": "avc1", "codec_tag": "0x31637661", "width": 608, "height": 1080, "coded_width": 608, "coded_height": 1080, "closed_captions": 0, "has_b_frames": 2, "sample_aspect_ratio": "1:1", "display_aspect_ratio": "76:135", "pix_fmt": "yuv420p", "level": 31, "chroma_location": "left", "refs": 1, "is_avc": "true", "nal_length_size": "4", "r_frame_rate": "30/1", "avg_frame_rate": "18600/607", "time_base": "1/60000", "start_pts": 0, "start_time": "0.000000", "duration_ts": 60700, "duration": "1.011667", "bit_rate": "532934", "bits_per_raw_sample": "8", "nb_frames": "31", "disposition": { "default": 1, "dub": 0, "original": 0, "comment": 0, "lyrics": 0, "karaoke": 0, "forced": 0, "hearing_impaired": 0, "visual_impaired": 0, "clean_effects": 0, "attached_pic": 0, "timed_thumbnails": 0 }, "tags": { "language": "und", "handler_name": "Twitter-vork muxer", "vendor_id": "[0][0][0][0]" } } ] }
78 · 2025-04-25 08:37
Need help creating a page for a website. Could you do it?
Hong, Guil Dong · 2025-04-30 03:34
>>41908 I made this one a little more user-friendly. - If you pass no parameters, it uses fzf to help you pick a file. - The output is filtered through jq to unwrap the data. #!/bin/bash if [ "$#" -eq 0 ] ; then ffprobe -v error -show_streams -select_streams v:0 -of json -i "$(fzf)" | jq '.streams[0]' else ffprobe -v error -show_streams -select_streams v:0 -of json -i "$@" | jq '.streams[0]' fi It's a nice way to quickly get video metadata from the command line.
vector · 2025-04-30 09:44
>>41960 DRY and ffprobe's -i takes a single parameter. f=${1:-$(fzf)} ffprobe -v error -show_streams -select_streams v:0 -of json -i "$f" | jq '.streams[0]'
Linda Lee · 2025-04-30 10:51
>>41966 Thanks for the improvements. I'll try to remember the technique you used on the first line for the next time I need an optional file argument.
car · 2025-05-24 23:00
>>31244 perl my $input_file = 'input.txt'; my $output_file = 'output'; open my $in, '<', $input_file or die "Cannot open $input_file: $!"; open my $out, '>', $output_file or die "Cannot open $output_file: $!"; while (<$in>) { print $out $_, "%\n"; } close $in; close $out; print "Done. Fortunes now in $output_file.\n"; originally written to turn /lib/theo into a usable fortune file
Roy Batty · 2025-05-24 23:23
>>42191 perl -pe '$_ .= "%\n"' input.txt > output pic from `man perlrun`
Crash Override · 2025-05-25 23:58
>>42192 yeah... I'm new to perl
Ender · 2025-05-28 21:05
>>42203 It's OK as long as it worked for you. https://en.wiktionary.org/wiki/TMTOWTDI
Random · 2025-05-29 14:58
#include <stdio.h> #include <string> #include <string.h> #include <iostream> int main(int argc, char* argv[]) { int readBytes = 0; char inputChar; std::cin.read(&inputChar, 1); // Everything up to the data field const int metaLengthBytes = 44; //---- Byte fields ---- //---- will store as big-endian ---- // Big-Endian in header char chunkID[5]; chunkID[4] = '\0'; char format[5]; format[4] = '\0'; char subchunk1ID[5]; subchunk1ID[4] = '\0'; char subchunk2ID[5]; subchunk2ID[4] = '\0'; // Little-Endian in header uint32_t chunkSize = 0; uint32_t subchunk1Size = 0; uint32_t subchunk2Size = 0; uint16_t audioFormat = 0; uint16_t numChannels = 0; uint32_t sampleRate = 0; uint32_t byteRate = 0; uint16_t blockAlign = 0; uint16_t bitsPerSample = 0; while( (readBytes < metaLengthBytes) && !(std::cin.eof()) ) { switch (readBytes) { // ChunkID case 0 ... 3 : chunkID[readBytes] = inputChar; break; // ChunkSize case 4 ... 7 : chunkSize |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 4)*8); break; // Format case 8 ... 11 : format[readBytes - 8] = inputChar; break; // Subchunk1ID case 12 ... 15 : subchunk1ID[readBytes - 12] = inputChar; break; // Subchunk1Size case 16 ... 19 : subchunk1Size |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 16)*8); break; // AudioFormat case 20 ... 21 : audioFormat |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 20)*8); break; // NumChannels case 22 ... 23 : numChannels |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 22)*8); break; // SampleRate case 24 ... 27 : sampleRate |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 24)*8); break; // ByteRate case 28 ... 31 : byteRate |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 28)*8); break; // BlockAlign case 32 ... 33 : blockAlign |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 32)*8); break; // BitsPerSample case 34 ... 35 : bitsPerSample |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 34)*8); break; // Subchunk2ID case 36 ... 39 : subchunk2ID[readBytes - 36] = inputChar; break; // Subchunk2Size case 40 ... 43 : subchunk2Size |= (static_cast<uint8_t>(inputChar)) << ((readBytes - 40)*8); break; default : break; } std::cin.read(&inputChar, 1); readBytes++; } // Interpret AudioFormat field std::string audioFormatDescriptor; switch (audioFormat) { case 1 : audioFormatDescriptor = "Linear PCM"; break; default : audioFormatDescriptor = "Unsupported sample representation"; break; } // Do checks for unsupported formatting if (strcmp(chunkID, "RIFF")) { printf("Non-RIFF format, aborting"); return 1; } if (strcmp(format, "WAVE")) { printf("Non-WAVE format, aborting"); return 1; } if (strcmp(subchunk2ID, "data")) { printf("Extra header fields, aborting"); return 1; } printf("ChunkID : %s\n", chunkID); printf("ChunkSize : %u bytes\n", chunkSize); printf("Format : %s\n", format); printf("Subchunk1ID : %s\n", subchunk1ID); printf("Subchunk1Size : %u bytes\n", subchunk1Size); printf("AudioFormat : %u (%s)\n", audioFormat, audioFormatDescriptor.c_str()); // Todo interpret printf("NumChannels : %u\n", numChannels); printf("SampleRate : %u samples / s\n", sampleRate); printf("ByteRate : %u bytes / s\n", byteRate); printf("BlockAlign : %u bytes / sample\n", blockAlign); printf("BitsPerSample : %u bits / channel\n", bitsPerSample); printf("Subchunk2ID : %s\n", subchunk2ID); printf("Subchunk2Size : %u bytes\n", subchunk2Size); return 0; }
Yet Another Lainon · 2025-05-29 15:09
>>42217 Sorry forgot to explain - this is the first step in some audio processing stuff I'm in the process of writing Extracts information from the header on the wav file and at the moment just pastes it to console after doing some checks
Miho Iwakura · 2025-05-29 16:16
>>41793 it'd be funnier if it printed and then deliberately segfaulted
Elliot Alderson · 2025-05-31 11:39
>>42218 Added a few extra features (won't repost, especially since it's now ~ 190 lines) - but now it extracts trailing metadata added by the generator that has been properly declared in the chunksize - and anything else at the end of the file that hasn't been declared
Nanashi No Gombe · 2025-05-31 11:50
(ql:quickload '(:lparallel)) (setf lparallel:*kernel* (lparallel:make-kernel 16)) (defun relative-dir-func (base new) "Returns a function that relativizes a dir off of a base, and returns its position on a new dir" (let ((bl (length (pathname-directory base)))) (lambda (dir) (merge-pathnames (make-pathname :directory (cons :relative (nthcdr bl (pathname-directory dir)))) new)))) (defun relative-file-func (base new) "Returns a function that relativizes a file off of a base, and returns its position on a new dir" (let ((bl (length (pathname-directory base)))) (lambda (file) (merge-pathnames (make-pathname :directory (cons :relative (nthcdr bl (pathname-directory file))) :defaults file) new)))) (defun convertable-p (file) "Checks if a file is convertable." (member (pathname-type file) '("flac" "mp3" "m4a") :test #'string-equal)) (defun transcode-file-func (base new) "Returns a function that converts a directory, if suitable, to a set of files for transcoding." (let ((relativizer (relative-file-func base new))) (lambda (dir) (when (every #'convertable-p (uiop:directory-files dir)) (mapcar (lambda (f) ;; TODO: switch to .ogg once possible (list f (make-pathname :type "mp3" :defaults (funcall relativizer f)))) (uiop:directory-files dir)))))) (defun collect-transcoding-files (base new) "Returns a list of all files and their destinations, for transcoding" (let ((col nil) (func (transcode-file-func base new))) (uiop:collect-sub*directories base (constantly t) (constantly t) (lambda (f) (push (funcall func f) col))) (apply #'nconc col))) (defun transcodable-files-count (base) (let ((col nil)) (uiop:collect-sub*directories base (constantly t) (constantly t) (lambda (dir) (when (every #'convertable-p (uiop:directory-files dir)) (push (uiop:directory-files dir) col)))) (setf col (apply #'nconc col)) (length col))) (defun transcode-dir (base new) "The actual tool. Use this function to convert all the files in one directory to another." (let ((files (collect-transcoding-files base new))) (mapc (lambda (fileset) (ensure-directories-exist (second fileset))) files) (lparallel:pmapc (lambda (fileset) (handler-case (uiop:run-program (format nil "ffmpeg -i \"~d\" -ab 320k \"~d\"" (first fileset) (second fileset))) (error (c) (format t "Failed on ~s!~&" (first fileset)) c))) files)) (format t "Success rate: ~d out of ~d~&" (transcodable-files-count new) (transcodable-files-count base))) ;; run (transcode-dir #P"/source/dir/here/" #P"/end/dir/here/") Wrote this Common Lisp script a couple months ago to convert my massive library of .flacs into .mp3s (so I could play music on my phone). "Transcode" is probably not the right verb but whatever
Nanashi No Gombe · 2025-05-31 12:12
>>42222 I've never really tried functional programming (might try to learn a little Erlang at some point...) but props to you for commenting and naming well so even I can mostly tell what's going on - cool little tool
Linda Lee · 2025-05-31 17:05
>>42222 I appreciate the docstrings too. Coming from Elisp where nearly everything has a docstring attached to it, I was a little surprised when sometimes some symbols don't have a docstring in Common Lisp.
Wintermute · 2025-05-31 20:44
>>42222 Doesn't ffmpeg already use threads of its own? I feel like lparallel is overkill if that's the case. One ffmpeg is already going as fast as it can on your hardware, and then you're going to ask another N ffmpegs to start up in parallel?
Erik Johansson · 2025-06-01 08:28
>>42228 The script issues a command to convert each mp3 individually. With regular mapping, it'd work at converting 1 mp3, finish, go to the next, and so on. If ffmpeg itself was multithreaded then I guess it would be sort of pointless, but I noticed a drastic speedup by uses lparallel, so I don't think ffmpeg uses more than 1 core when converting 1 audio file.
Lady Jessica · 2025-06-01 13:46
A script that rotates the (libinput) touchpad input together with the monitor. Unfortunately, it doesn't rotate the scrolling. #!/bin/sh rotation=$1 rotation=${rotation:=normal} # Replace with the result from `xinput --list` touchpad="XXXX:XXXX Touchpad" # Replace with the result from `xrandr --query` output="eDP" case $rotation in "normal") xinput set-prop "$touchpad" --type=float "Coordinate Transformation Matrix" \ 0 0 0 0 0 0 0 0 0 ;; "left") xinput set-prop "$touchpad" --type=float "Coordinate Transformation Matrix" \ 0 -1 1 1 0 0 0 0 1 ;; "right") xinput set-prop "$touchpad" --type=float "Coordinate Transformation Matrix" \ 0 1 1 -1 0 0 0 0 1 ;; "inverted") xinput set-prop "$touchpad" --type=float "Coordinate Transformation Matrix" \ -1 0 0 0 -1 0 0 0 1 ;; *) echo "Usage: $0 [rotation]" echo " Rotation can be one of 'normal', 'left', 'right' or 'inverted'." exit 1 ;; esac xrandr --output "$output" --rotate "$rotation"
⍕ · 2025-06-02 12:21
>>42239 I had no idea you could do that, neat
over · 2025-06-02 23:02
soykafty clone of python's range function i wrote for a shell script shell range() { # Usage: range END # range START END [STEP] [ $# = 1 ] && set -- 0 "$1" set -- $(($1)) $(($2)) $((${3:-1})) if [ $3 = 0 ]; then printf 'The STEP argument cannot be zero\n' >&2 return 1 fi if [ $1 -lt $2 ]; then [ $3 -lt 0 ] && return set -- "$@" -lt elif [ $1 -gt $2 ]; then [ $3 -gt 0 ] && return set -- "$@" -gt else return fi while [ $1 $4 $2 ]; do printf "%d " $1 set -- $(($1 + $3)) $2 $3 $4 done printf "\n" }
Nanashi No Gombe · 2025-06-02 23:26
I use windows 10/11, I'm practicing programming for work needs, however, I'm having serious issues with windows and powershell as they won't let met install and create the codes I want. I've already tried the best I could to change it. I'm still stucked, does anyone knows how to crack it?
Sipho Nkosi · 2025-06-03 01:21
>>42255 Bash has the 'for( start ; end ; step)' construct - Not sure if that script actually works because I'm on mobile at the moment - but if it does it's eldritch and I hate it
push · 2025-06-03 01:26
>>42257 >>42255 I might chat soykaf, I had no idea that 'set --' was a thing so thanks for teaching me that
FILLER · 2025-06-05 22:05
>>39501 Alright, made it less retarded (only the C version).... #include <stdio.h> int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "String not given\n"); return 1; } else { argv++; char *HeadStr = NULL; for (; *argv; argv++) { HeadStr = (*argv); for (; *(*argv) && *(*(argv) + 1); (*argv) += 2) { /* Didn't want to import string.h so I have my own my own implementation of case conversion functions */ if (*(*argv) > 96 && *(*argv) < 123) *(*argv) -= 32; else if (*(*argv) < 97 && *(*argv) > 64) *(*argv) += 32; } printf("%s ", HeadStr); } puts(""); return 0; } }
Tomohisa "Tom" Kanezaki · 2025-06-05 22:18
>>42290 The curse of tabs strikes again.
Drifter · 2025-06-05 23:21
>>42290 >mixing tabs and spaces >5 spaces indentation What kind of maniac are you?
Jean Dupont · 2025-06-05 23:30
That reminds me. I need to setup a .editorconfig file for a new project.
H.R. Giger · 2025-06-07 02:28
>>42290 reformatted #include <stdio.h> int main(int argc, char *argv[]) { if (argc < 2) { fprintf(stderr, "String not given\n"); return 1; } else { argv++; char *HeadStr = NULL; for (; *argv; argv++) { HeadStr = (*argv); for (; *(*argv) && *(*(argv) + 1); (*argv) += 2) { /* Didn't want to import string.h so I have my own my own implementation of case conversion functions */ if (*(*argv) > 96 && *(*argv) < 123) *(*argv) -= 32; else if (*(*argv) < 97 && *(*argv) > 64) *(*argv) += 32; } printf("%s ", HeadStr); } puts(""); return 0; } }
byte · 2025-06-07 11:08
>>42305 I haven't run this but assuming its playing around with capital and lowercase letters don't you want the upper bound on that else if to be 91?
Jet Black · 2025-06-07 15:49
Silly little implementation for "Execute a Markov algorithm" from Rosetta Code. lisp (defun parse-rules (str) "Transform a STR into alist of rules. Single rule is delimited by a newline." (reverse (seq-reduce (lambda (res rule) (cons (let ((index (string-search "->" rule 1))) (cons (string-trim-right (substring rule 0 index)) (string-trim-left (substring rule (+ index 2))))) res)) (string-split str "\n") '()))) (defun apply-rules-helper (result rules) "Transform a RESULT applying all the RULES to it. If the rule is terminating, bail out of the iteration." (catch 'bail-fr (seq-reduce (lambda (res rule) (let ((pattern (cdr rule)) (match (car rule))) (cond ((string-empty-p pattern) res) ((eq ?. (seq-elt pattern 0)) (throw 'bail-fr (string-replace match (substring pattern 1) res))) (t (string-replace match pattern res))))) rules result))) (defun apply-rules (str rules) "Apply RULES to STR. RULES are represented as an alist where every entry has a form of a cons `(PATTERN . REPLACEMENT)`. The dot in the beginning of a REPLACEMENT string signifies that it is a terminating rule." (let ((prev-result str) (result nil)) (while (not (string= result prev-result)) (setq result (apply-rules-helper prev-result rules)) (setq prev-result result)) result))
Unnamed · 2025-06-08 22:01
>>42314 You are right, my bad.
Junichi Fujiwara · 2025-06-11 03:32
This is my favourite videogame :- module(core, [call_slot/1, slot/3]). :- use_module(library(gensym)). :- dynamic(slot/3). call_slot(SlotHead) :- SlotHead =.. [_, ID|_], call_slot(ID, SlotHead). call_slot(CallerID, SlotHead) :- (slot(CallerID, SlotHead, Body), call(Body) ; (slot(CallerID, inherits(CallerID, InheritsID), Body), Body, call_slot(InheritsID, SlotHead))). slot(root, make_obj(Self, Slots, ID), (gensym(obj_, ID), asserta(slot(ID, metaobject(_, Self), true)), call_slot(make_slots(Self, ID, Slots)))). slot(root, make_slots(_Self, _, []), true). slot(root, make_slots(Self, ID, [(SlotHead, SlotBody)|Slots]), (asserta(slot(ID, SlotHead, SlotBody)), call_slot(make_slots(Self, ID, Slots)))).
Anamika · 2025-07-31 05:53
#!/bin/bash slop=$(slop --nodecorations -f "%x %y %w %h %g %i") || exit 1 read -r X Y W H G ID <<< $slop ffmpeg -f x11grab -s "$W"x"$H" -i :0.0+$X,$Y $@ I used this script to create screen recordings of an X11 window. >>42681 >>41592 To record a video, run the following. screen-record video.webm - Then select a window to record. - When you're done recording, hit Ctrl-C.
Knuth · 2025-07-31 11:46
fragment shader like rendering of images with imagemagick's convert convert -size 1080x1350 \ xc:#cef \ -fx '(u-sin((j/w))) + (cos(i*.1)*sin(j*.1))' \ -swirl 180 \ "${0##*/}.png"
Agent Jones · 2025-07-31 16:15
>>42689 I had no idea you could give it math expressions to evaluate.
aliased · 2025-09-02 05:31
A script to manage a bunch of hostname.if(5) files on OpenBSD, which I made so I could have a static IP on my home WiFi network, and use dhcpleased(8) for school and work. #!/bin/sh if="iwn0" active=$(cat "/etc/hostname.configs/active") switchto=$1 if [ -z "$1" ]; then echo "Missing new net" echo "Usage: switchto NEWNET" exit 1 fi if [ ! -s /etc/hostname.configs/hostname.iwn0_$switchto ]; then echo "Error: /etc/hostnames.configs/hostname.iwn0_$switchto does not exist" exit 1 fi echo "switching FROM $active TO $switchto" doas ifconfig $if down doas wpa_cli terminate echo "stopped wpa_supplicant" doas ifconfig iwn0 -nwid doas route delete default doas ifconfig $if delete doas ifconfig $if up echo "old config removed" echo "starting resolvd" doas rcctl start resolvd echo "starting dhcpleased" doas rcctl start dhcpleased doas rm /etc/hostname.$if doas cp /etc/hostname.configs/hostname*$switchto /etc/hostname.$if echo -n "$switchto" | doas tee /etc/hostname.configs/active > /dev/null doas sh /etc/netstart echo "done" if you're curious, the hostname.if(5) of my static network looks like this: !rcctl stop dhcpleased !rm -f /etc/resolv.conf !printf "nameserver 9.9.9.9\\nsearch localdomain home.arpa\\n" | tee /etc/resolv.conf > /dev/null nwid 'wifi-ssid' wpakey 'p4ssw0rd' inet 192.168.1.201 255.255.255.0 255.255.255.255 !route add default 192.168.1.1
Tyrell Wellick · 2025-09-02 06:22
>static IP on my home WiFi network Why not set a static IP on the dhcp server?
Nemissa · 2025-09-02 07:01
>>42255 FYI, GNU coreutils has `seq`. https://learnbyexample.github.io/cli_text_processing_coreutils/seq.html
Erik Johansson · 2025-09-02 11:43
>>40237 i thought maybe there's a shorter way to do it using string rewrites, but no, both of my attempts came out longer: import re def rpn1(s): for i in range(len(s)): s = re.sub(r'([0-9.]+)\s+([0-9.]+)\s*([+\-*/])', lambda m: str(eval(m[1]+m[3]+m[2])), s) return s def rpn2(s): for i in range(len(s)): s = re.sub(r"\s*([+\-*/])(.*)f(.*)f(.*)|\s*(\d+)(.*)|f(.*)", r"\2\6f(\3\1\4\5)\7", s) def f(x=None): return x or f return eval(s) print(rpn1("1 2 3 * + 4 5 6 / - / 7 8 * +")) print(rpn2("1 2 3 * + 4 5 6 / - / 7 8 * +")) if anyone figures out what rpn2 is doing, i'll be mildly impressed, though
Wintermute · 2025-09-02 15:22
>>42887 Looking at the regex, I see 3 being applied in a loop. I think it works something like this: 1. skip whitespace, swizzle operator (postfix to infix) 2. skip whitespace, convert integer 3. no-op I think the funny-looking def f(x=None) is to handle cases where group 3, 1, 4 or 5 are empty. One evident case where this happens is if 3. matches, as it only captures group 7 and leaves the rest empty, leading to "f... -> f()...". Presumably there are braces already, so "f(...) -> f()(...)" works too I guess. 2. takes a whole integer in 5. and puts the rest in group 6. 5. is put in f(...) Interesting to note is that group 6 is put before group 5, so operands end up at the end of the string. This is important for 1., where the operands are in group 3. and 4. and the operator in group 1. f(<x> <op> <y>) So postfix is rewritten to infix, with f() serving as braces but in a way that works better with regexes? Or is shorter. Then the whole string is passed to eval. I tried rewriting it without f and found I still got empty (), leading to an error. Debugging further I now realize it's because you actually get a valid expression about halfway through, but because we just apply the regex a fixed number of times, the numbers get taken out, leaving you with empty braces. ... or so I thought, but now I get the wrong result. I tried adding f again and that works, so I guess greedy matching is messing with me. def rpn3(s): # broken while s[0] != '(': s = re.sub(r"\s*([+\-*/])(.*)(\(.*\))(\(.*\))|\s*(\d+)(.*)", r"\2\6(\3\1\4\5)", s) return eval(s) def rpn4(s): while s[0] != 'f': s = re.sub(r"\s*([+\-*/])(.*)f(.*)f(.*)|\s*(\d+)(.*)", r"\2\6f(\3\1\4\5)", s) def f(x): return x return eval(s) print(rpn3("1 2 3 * + 4 5 6 / - / 7 8 * +")) # bad result print(rpn4("1 2 3 * + 4 5 6 / - / 7 8 * +")) # good result
Joe Bloggs · 2025-09-02 17:32
>>42890 i don't quite understand your explanation, but you fixed the soykaftiest part of my code in rpn4, so now the f hack isn't even needed. great job! dunno why i didn't think of just checking the first char like that: def rpn5(s): while s[0] != ',': s = re.sub(r"\s*([+\-*/])(.*),(.*),(.*)|\s*(\d+)(.*)", r"\2\6,(\3\1\4\5)", s) return eval(s[1:]) but this is still a few characters longer than the trivial stack implementation. which makes me very sad
Iverson · 2025-09-03 15:00
>>42885 I say home, but it's not really; I don't have access to the router.
Otto Normalverbraucher · 2025-09-15 05:42
rust impl Hate for ThatStupidMouse { fn cope(&mut self) { self.harm() } fn defense(&mut self) { self.destruction() } }
Wirth · 2025-11-05 09:14
>>39392 Using symlinks was an absolutely terrible idea with horrendous performance. It is especially stupid considering one could just use hardlinks when on the same FS. Who on earth would use a separate FS for file tree and data anyway? Hence: unfuck_symlinks.py #!/usr/bin/env python3 def f(): import errno from pathlib import Path def get_data_symlink(depth, in_dir, path): if not path.is_symlink(): return None l = path.readlink() if str(l).startswith('../' * depth + 'data'): return (in_dir / l).resolve() return None def copy_dir(depth, in_dir, out_dir): log = lambda x: print(f'{depth:>3}{" " * depth}{x}') log(f'd {in_dir}') out_dir.mkdir(exist_ok = True) for e in sorted(in_dir.iterdir()): out = out_dir / e.name if e.is_dir() and not e.is_symlink(): copy_dir(depth + 1, e, out) continue target = get_data_symlink(depth, in_dir, e) if out.exists() or out.is_symlink(): log(f'E {e}') if target is None: assert e.is_file() == out.is_file() assert e.is_symlink() == out.is_symlink() else: assert out.is_file() continue if target is not None: log(f'H {e} -> {target}') # ext4 has a limit of 65000 hardlinks # as workaround, create a symlink when this situation is detected i = 0 tgt = target while True: try: out.hardlink_to(tgt) break except IOError as e: if e.errno != errno.EMLINK: raise i += 1 tgt = target.with_suffix(f'.{i}') if not tgt.exists(): tgt.symlink_to(target.name) else: log(f'f {e}') out.hardlink_to(e) def main(in_dir, volname, out_dir): in_dir = Path(in_dir) out_dir = Path(out_dir) copy_dir(2, in_dir / 'tree' / volname, out_dir) if __name__ == '__main__': import sys main(*sys.argv[1:]) f() (I like scoping variables) Regarding hardlink limit: turns out there are a lot of empty files. Perhaps I should have special-cased that...
Crash Override · 2025-11-25 22:50
we are learning type inference via ocaml examples in my compilers class. using my limited exposure to the language, i wrote a simple function to reverse a list. has anyone worked with ocaml before? i haven't really seen it mentioned on this board let rec last_element list = match list with h::[] -> h | h::t -> last_element t let rec all_but_last list = match list with [] -> [] | h::[] -> [] | h::t -> h::all_but_last t let rec reverse_list list = match list with [] -> [] | h::[] -> [h] | h::t -> last_element list :: reverse_list (all_but_last list)
Eldon Tyrell · 2025-11-28 16:52
>>43456 i've never seen this pattern where you have a main inside of a main (f), and your imports are nested. Seems like it just adds an extra layer of nesting that doesn't do anything.
Stallman · 2025-11-29 03:47
Did a blog post (https://world-playground-deceit.net/blog/2025/11/code-golfing-fizzbuzz-in-88-bytes-of-c.html) about the smallest FizzBuzz I could muster in C: main(i){while(printf(i%3*i%5?"%d ":"%2$s%3$s ",i,i%3?"":"Fizz",i%5?"":"Buzz"),i++<100);} Try to beat it, anon! Good warmup for the AoC starting in two days.
⍕ · 2025-11-29 05:56
>>43578 JavaScript: for (let i = 1; i < 100; ++i) console.log(`${i % 3 == 0 ? "Fizz" : ""}${i % 5 == 0 ? "Buzz" : ""}` || i) Nice blog btw.
DEBUG-CONTENTS · 2025-11-29 05:59
>>43580 Small improvement (and hopefully no scrollbar in post): for (let i = 1; i < 100; ++i) console.log(`${i % 3 ? "" : "Fizz"}${i % 5 ? "" : "Buzz"}` || i)
Turner · 2025-11-30 07:11
>>43578 87 in perl, lol for$n(1..100){$\=$/;$n3=$n%3;$n5=$n%5;print!$n3&&!$n5?fizzbuzz:!$n5?buzz:!$n3?fizz:$n}
roll · 2025-11-30 08:06
>>43581 This one is 72 btw: for(let i=1;i<100;++i)console.log(`${i%3?"":"Fizz"}${i%5?"":"Buzz"}`||i)
Lady 3Jane.. · 2025-11-30 09:17
>>43585 Yeah but that's not the same language. Anyway, nice trick using the fact that the empty string is false in JS. >Nice blog btw. Thanks anon.
Vasya Pupkin · 2025-12-08 08:48
>>41881 >>41705 here 7F 45 4C 46 B2 0C B9 40 00 04 00 B3 01 EB 05 90 02 00 03 00 B0 04 EB 08 04 00 04 00 2C 00 00 00 CD 80 B3 4C B0 01 CD 80 34 00 20 00 01 00 00 00 00 00 00 00 00 00 04 00 45 45 45 45 4C 00 00 00 48 65 6C 6C 6F 20 57 6F 72 6C 64 0A Here's Hello World in 76 bytes. I could make it smaller probably, but my aim was that 52 byte executable and I'm not interested in hello world anymore.
Anonymous · 2026-05-12 13:14
As is oddly common nowadays I was looking for a simple program to do a simple thing but couldn't find something to my liking. In this case: I wanted to tap through images on my phone while avoiding "infinite scroll" or loading a huge amount of images at once. I ended up with this: #!/usr/bin/env python3 from http.server import BaseHTTPRequestHandler from socketserver import TCPServer from pathlib import Path from urllib.parse import quote, unquote def is_img_ext(path): return path.suffix in ('.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.avif') def mime_from_ext(path): return { '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg', '.webp': 'image/webp', '.avif': 'image/avif', }.get(path.suffix, 'application/octet-stream') class Serb(BaseHTTPRequestHandler): def do_GET(self): if self.path in ('..', '../', '/..') or '/../' in self.path: return self.respond_html(403, 'nice try') if self.path == '/': self.send_response(302) self.send_header('location', '/0') self.end_headers() return try: num = int(self.path[1:]) except: num = None if num is not None: try: x = images[num] except: x = None if x is None: return self.respond_html(200, f'out of range') x = quote(str(x)) body = '''<style> *{margin:0;padding:0} body{position:relative} div{position:absolute;top:0;left:0;width:100vw;height:100vh} a{display:inline-block;width:50%;height:100%} </style>''' body += '<body>' body += f'<img width=100% src={x}>' body += '<div>' body += '<a' if num > 0: body += f' href=/{num - 1}' body += '></a><a' if num < len(images) - 1: body += f' href=/{num + 1}' body += '></a>' body += '</div>' body += '</body>' return self.respond_html(200, body) path = Path(unquote(self.path[1:])) with path.open('rb') as f: body = f.read() self.send_response(200) self.send_header('content-type', mime_from_ext(path)) self.send_header('content-length', len(body)) self.send_header('cache-control', 'public,max-age=31536000') self.end_headers() self.wfile.write(body) def respond_html(self, status, body): body = body.encode('utf-8') self.send_response(status) self.send_header('content-type', 'text/html;charset=utf-8') self.send_header('content-length', len(body)) if status == 200: # cache briefly for faster "back" behaviour self.send_header('cache-control', 'public,max-age=300') self.end_headers() self.wfile.write(body) if __name__ == '__main__': import sys _, port, *dirs = sys.argv images = [ x for y in dirs for x in Path(y).iterdir() if x.is_file() and is_img_ext(x) ] TCPServer(("", int(port)), Serb).serve_forever() Use it like so: /path/to/html-image-scroller/main.py 9876 . */ other-dir It also works on desktop but doesn't look very nice. Related: I found that if I laser-focus on just getting a program to work without regard for other potential usecases I can keep the code way simpler, smaller and more hackable.
null · 2026-05-19 19:12
This isn't exactly about golfing but idk where else to put this really
Gyula Kovacs · 2026-06-07 05:56
>>41761 Hello from the future nomnoml is really cool - didn't know there was a utility out there that could do this and was thinking the other day about making my own purely because I'm sick of drawio Cloned - I'm going to use this all the goddamn time
Nanashi No Gombe · 2026-06-07 08:06
>>44320 Bystander from the present: How is nomnoml different from the graphviz language? (Also text based)
SHODAN · 2026-06-07 10:13
>>41761 Similar utilities: PlantUML, for UML diagrams: https://github.com/plantuml/plantuml Graphviz, for simple graphs (limited control): https://graphviz.org/ CeTZ, package for typst, can draw arbitrary diagrams: https://typst.app/universe/package/cetz/ Tikz, for TeX/LaTeX, can draw arbitrary diagrams: https://github.com/pgf-tikz/pgf
queue · 2026-06-15 10:32
>>44321 I didn't know those things existed either :) There's a lot more going on with those by the look of it - nomnoml seems a little simpler but maybe that's just because it has an interactive webpage example and I don't have to dive into docs to figure it out
Marly Krushkhova · 2026-07-03 08:33
I was inspired by https://libraryofbabel.info/ to try and make a program to create a random "book" in the form of a text file. Currently it's only set up to make one file and continually recreate it when the program is run again instead of making more books, but I can deal with that later. C #include <stdio.h> #include <stdlib.h> #include <time.h> #define PAGE_MAX 410 int main(void){ srand(time(0)); char alph_arr[29] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',',','.',' '}; size_t i; size_t j; size_t lines_per_page = 40; size_t line_width = 80; size_t line_count = 0; size_t page_count = 0; FILE* f; f = fopen("babel_book.txt", "w+"); if(f == NULL) { fprintf(stderr, "ERROR: could not open file \"babel_book.txt\""); return(-1); } for (page_count = 0; page_count < PAGE_MAX; ++page_count) { for(i = 0; i < lines_per_page; ++i) { for(j = 0; j < line_width; ++j) { char c = alph_arr[(rand() % 28)]; fprintf(f, "%c", c); } fprintf(f,"\n"); } if (page_count < PAGE_MAX - 1) fprintf(f,"\n\n\n\n\n"); } fclose(f); if(f == NULL) { fprintf(stderr, "ERROR: could not close file \"babel_book.txt\""); return(-1); } return(0); }
Emmanuel · 2026-07-03 11:18
>>44413 Not sure why my indentation got messed up, sorry Lains.
Netrunner · 2026-07-04 12:34
>>44414 Lainchan doesn't like tabs, only spaces. e.g. long long random_constant_source(void) { return 0xc3050f583c6a; } void my_exit(int ret) { char *f = ((char *)random_constant_source) + 6; ((void (*)(int status))f)(ret); } int main() { my_exit(42); } long long random_constant_source(void) { return 0xc3050f583c6a; } void my_exit(int ret) { char *f = ((char *)random_constant_source) + 6; ((void (*)(int status))f)(ret); } int main() { my_exit(42); } I'm guessing your editor has been setup to automatically replace 4 spaces with tabs. I also guess you manually indent by pressing the spacebar twice?
Junichi Fujiwara · 2026-07-05 08:40
>>44425 thanks for the info, Lain.
hash table · 2026-07-08 11:05
I did this small todo program to practice, I tried doing a more complex one but got stuck and frustrated at the querying. It's surprisingly easy to program a DSL based on a dialect tho. Red [Title: "Todo"] save: does [write %todo.db db] create-db: does [db: #[id 0 tasks #[]] save] unless exists? %todo.db [create-db] db: load %todo.db show: func [id] [print rejoin [ id space either reduce db/tasks/(id)/done ["^[[0;32m+"] ["^[[0;31m-"] db/tasks/(id)/name "^[[0;37m"]] list: does [foreach id keys-of db/tasks [show id]] create: func [name] [db/id: db/id + 1 put db/tasks db/id to-map reduce ['name name 'done false] save] update: func [id field value] [put db/tasks/(id) field value save] delete: func [id] [if db/tasks/(id) [db/id: db/id - 1 remove/key db/tasks id save]] args: system/options/args switch to-word args/1 [ -l [list] -p [show args/2] -c [create-db] -d [delete to-integer args/2] -a [create args/2] -y [update to-integer args/2 'done true] -n [update to-integer args/2 'done false] -r [update to-integer args/2 'name args/3]]
The Plague · 2026-08-05 12:19
I was kind of curious if there is anything like a software platform for creating small programs on android that can actually interact with system APIs (like using push notifs) without having to touch gross stuff like android studio to make an actual APP. Basically, something like quickshell or emacs packages that go too far. The closest thing I can imagine is making hosting an HTTP server in termux. Is there any other alternatives?
Zarathustra · 2026-08-20 07:57
>>31249 I've noticed that C/C++ has a terrible readability problem. This happens in Python too. People make it less readable not because they have to, but because they choose to.
Meddler · 2026-08-20 10:34
I had to post this because it's genuinely impressive, it's a 54 byte snake game in x86 asm. If you are lazy you can run it in this web wasm demo : https://donno2048.github.io/snake-bios/ Obviously, this was NOT made by me : https://github.com/donno2048/snake x86asm start: ; used for game reset lds di, [BYTE bx+si] ; SI=0x100 and BX=0x0 at program start, this initializes DS and DI, using the BYTE prefix adds a 0 byte that serves as a dummy byte for the LDS itself as machine code at 0x100 will be 0xC5,0x78,0x00,0xB8 mov ax, 0x200A ; first byte of the instruction is 0xB8 used for LDS, also sets AX to the initial value for DX to swap later: DH set to empty space, DL to 0xA, DX satisfies DX*8%0x10000=0x50 so good for the wall building cwd ; set DX to 0x0 to swap later with AX to set video mode (AH=0x0) to mode 0 (AL=0x0), text mode 40x25 16 colors xchg ax, dx ; swap AX and DX int 0x10 ; set video mode using BIOS interrupt call, also clears the screen pop bx ; reset head position offset, we can use POP as even if the POPed position is deadly it is not a problem because we address the head as SI+BX, so the next head position is essentially randomized by repeated addition with SI mov sp, di ; set SP to current head pointer .food: ; create new food item add ah, cl ; decreasing AH for randomization ensures SI is still divisble by 2 and if the snake isn't filling all the possible options, below 0x7D0 xchg ax, si ; alternate SI between the last head position (not to iterate over the same food locations) and the end of the screen xor [si], cl ; place food item and check if position was empty by applying XOR with CL jp .food ; if position was occupied by snake or wall in food generation => try again .input: ; handle keyboard input mov si, 0x7D0 ; initialize SI in al, 0x60 ; read scancode from keyboard controller - bit 7 is set in case key was released imul dl ; we want to map scancodes for arrow up (0x48/0xC8), left (0x4B/0xCB), right (0x4D/0xCD), down (0x50/0xD0) to movement offsets aam 0x14 ; IMUL (AH is irrelevant here), AAM and AAD with some magic constants maps up => -80, left => -2, right => 2, down => 80 aad 0x44 ; using arithmetic instructions is more compact than checks and conditional jumps cbw ; but causes weird snake movements though with other keys xchg bx, ax ; set AX to offset of old head position add bx, ax ; and BX to new offset add ax, si ; set AX to old head position, also, checks if head crossed vertical edge, since AX is between -0x7D0 and 0 if inside the screen so after the ADD we get CF=1 iff head is in the screen stosw ; store old head position (SS=ES by default) and advance head pointer adc [bx+si], dh ; ADC head position (0x7D0 + offset) to set snake character jz .food ; if food was consumed, ZF=1 from ADC => generate new food jnp start-0x4B ; if it already had snake or wall in it or if it crossed a vertical edge, PF=0 from ADC => game over, going to `start-0x4B` adds 0x4B null bytes before the LDS thus changing it into 0x25 (=(0x4b-1)/2) repetitions of `add [bx+si],al` which we don't care for as there's an `int 0x10` afterwards to clear the screen, then, `add ch,al` which also doesn't matter as CH's only affect is the wall color (as we'll soon show) which we don't care for, then `js $+2` which is practically a NOP, then we continue at `start`, also after doing JNZ to .wall-1 we get here byte 0x89 .wall: ; draw an invisible wall on the left side or al, 0x29 ; it's obvious this instruction will always set ZF=0 salc ; we don't care about AL at this point so this is practically a NOP, however, after `jnz .wall-1` we get the bytes 0x89 (from the JNP), 0x0C,0x29 (from the OR) and then 0xD6 (from this SALC) which encode the instruction `mov [si], cx`, `sub si, dx`, the new SUB makes us go one line and 0x2000 bytes backwards (the added bytes wrap nicely as 0x10000%0x2000=0) [using DX like that - and not 0x50 - makes this loop a delay loop also] and the new MOV sets all wall position characters to 0 jnz .wall-0x1 ; on first enrty to .wall this will always jump as ZF=0 from OR, after the first loop it jumps to draw the next wall because we jump to .wall-1 and will stop at the last wall at DS:0 pop si ; no food was consumed so pop tail position into SI mov [si], dh ; clear old tail position on screen jns .input ; loop to keyboard input, SF=0 from SUB
Moore · 2026-08-20 10:45
>>44581 >>>/tech/93845 https://files.catbox.moe/sz9pgu.gz (new link) you can make very small apps (a few kb) without android studio, gradle, or anything besides https://packages.gentoo.org/packages/dev-util/android-sdk-cmdline-tools note that the sdk also includes versions of clang to cross-compile to arm64 android with the android libc, so it is the same dependency even if you just want to compile native binaries (that you can run from tmux) if you really don't want to make more than one app, technically, you can load native .so files from java code, so you could make a single app that just loads arbitrary .so files, you can call the android api through the jni. another option would be to write an app that is just a wasm interpreter, and then expose the android api to the wasm code
Emmanuel · 2026-09-01 00:04
>>44581 There is termux-api, which is essentially just a collection of binaries that allow you to use a limited set of system APIs through stuff like shell scripts and so on: https://github.com/termux/termux-api