Quest 4: Teeth of the Wind

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

Link to participate: https://everybody.codes/

  • mykl@lemmy.world
    link
    fedilink
    arrow-up
    3
    ·
    6 days ago

    Uiua

    Fortunately the ratios for the common gears all proved to be rational in part 3.

    ⌊×2025/÷⊏¯1_0[128 64 32 16 8]              # ->32400
    ⌈×⊙÷°⊟⊏¯1_0⊙10000000000000[128 64 32 16 8] # -> 625000000000
    ⊜□⊸≠@\s "5 5|10 10|20 5"
    ⌊×100×⊃(÷∩⋕⊃⊣⊢|/×≡◇(/÷⊜⋕⊸≠@|)↘1↘¯1) # -> 400
    
  • ystael@beehaw.org
    link
    fedilink
    arrow-up
    2
    ·
    6 days ago

    In 1980 we didn’t have tuple or set or vector types. We addressed elements of our cons-based data structures with nonsense incantations like caddar and we liked it that way.

    (ql:quickload :cl-ppcre)
    
    (defun read-inputs (filename)
      (mapcar #'parse-integer (uiop:read-file-lines filename)))
    
    (defun main-1 (filename)
      (let ((gears (read-inputs filename)))
        (truncate (* 2025 (/ (first gears) (car (last gears)))))))
    
    (defun main-2 (filename)
      (let ((gears (read-inputs filename)))
        (ceiling (* 10000000000000 (/ (car (last gears)) (first gears))))))
    
    (defun read-inputs-3 (filename)
      (flet ((parse-line (line)
               (or (ppcre:register-groups-bind
                       (a b)
                       ("^([0-9]+)[|]([0-9]+)$" line)
                     (cons (parse-integer a) (parse-integer b)))
                   (let ((a (parse-integer line)))
                     (cons a a)))))
        (mapcar #'parse-line (uiop:read-file-lines filename))))
    
    (defun gear-ratio-3 (gears)
      (labels ((iter (gears ratio)
                 (if (< (length gears) 2)
                     ratio
                     (let ((out-gear (cdar gears))
                           (in-gear (caadr gears)))
                       (iter (cdr gears) (* ratio (/ out-gear in-gear)))))))
        (iter gears 1)))
    
    (defun main-3 (filename)
      (let ((gears (read-inputs-3 filename)))
        (truncate (* 100 (gear-ratio-3 gears)))))
    
  • vole@lemmy.world
    link
    fedilink
    English
    arrow-up
    2
    ·
    6 days ago

    maaath

    Scheme/Guile

    (import (rnrs io ports (6)))
    
    (define (parse-file file-name)
           (map string->number (string-split (call-with-input-file file-name get-string-all) #\newline)))
    
    (let* ((gears (parse-file "notes/everybody_codes_e2025_q04_p1.txt")))
      (format #t "P1 Answer: ~a\n\n" (* 2025 (/ (car gears) (car (last-pair gears))))))
    
    
    (let* ((gears (parse-file "notes/everybody_codes_e2025_q04_p2.txt")))
      (format #t "P2 Answer: ~a\n\n" (ceiling (* 10000000000000 (/ (car (last-pair gears)) (car gears))))))
    
    
    (define (parse-file-p3 file-name)
           (map
                  (lambda (line) (map string->number(string-split line #\|)))
                  (string-split (call-with-input-file file-name get-string-all) #\newline)))
    (let* ((gears (parse-file-p3 "notes/everybody_codes_e2025_q04_p3.txt")))
      (format #t "P2 Answer: ~a\n\n"
              (floor (* 100
                 (apply * (map (lambda (gear) (if (= 1 (length gear)) 1 (/ (cadr gear) (car gear)))) gears))
                 (/ (caar gears) (caar (last-pair gears)))))))
    
  • hades@programming.devOPM
    link
    fedilink
    arrow-up
    2
    ·
    11 days ago

    Rust

    use num::{BigInt, Integer};
    
    pub fn solve_part_1(input: &str) -> String {
        let gears: Vec<i64> = input.trim().lines().map(|g| g.parse().unwrap()).collect();
        (2025 * gears[0] / gears.last().unwrap()).to_string()
    }
    
    pub fn solve_part_2(input: &str) -> String {
        let gears: Vec<i64> = input.trim().lines().map(|g| g.parse().unwrap()).collect();
        let res = (BigInt::parse_bytes(b"10000000000000", 10).unwrap() * gears.last().unwrap())
            .div_ceil(&(BigInt::ZERO + gears[0]));
        res.to_string()
    }
    
    pub fn solve_part_3(input: &str) -> String {
        let mut lines = input.trim().lines();
        let first_gear = BigInt::parse_bytes(lines.next().unwrap().as_bytes(), 10).unwrap();
        let mut nominator: BigInt = first_gear * 100;
        let mut denominator: BigInt = BigInt::ZERO + 1;
        for line in lines {
            let mut split = line.split("|");
            denominator *= BigInt::parse_bytes(split.next().unwrap().as_bytes(), 10).unwrap();
            match split.next() {
                Some(size) => {
                    nominator *= BigInt::parse_bytes(size.as_bytes(), 10).unwrap();
                }
                None => {
                    break;
                }
            }
        }
        (nominator / denominator).to_string()
    }
    
  • janAkali@lemmy.sdf.org
    link
    fedilink
    arrow-up
    2
    ·
    11 days ago

    Nim

    For part 3 I parse gears as tuples, with regular gears having same value on both ends e.g.

    3|5 -> (3, 5)
    3   -> (3, 3)
    
    proc parseGears(input: string): seq[int] =
      for line in input.splitLines():
        result.add parseInt(line)
    
    proc parseNestedGears(input: string): seq[(int, int)] =
      for line in input.splitLines():
        let nested = line.split('|').mapIt(it.parseInt)
        result.add:
          if nested.len == 1: (nested[0], nested[0])
          else: (nested[0], nested[1])
    
    proc solve_part1*(input: string): Solution =
      let gears = parseGears(input)
      result := 2025 * gears[0] div gears[^1]
    
    proc solve_part2*(input: string): Solution =
      let gears = parseGears(input)
      result := ceil(10000000000000'f64 / (gears[0] / gears[^1])).int
    
    proc solve_part3*(input: string): Solution =
      let gears = parseNestedGears(input)
      let ratios = (0..gears.high-1).mapIt(gears[it][1] / gears[it+1][0])
      result := int(100 * ratios.prod)
    

    Full solution at Codeberg: solution.nim

  • Amy@piefed.blahaj.zone
    link
    fedilink
    English
    arrow-up
    2
    ·
    10 days ago

    I liked this one!

    import Control.Arrow  
    import Control.Monad  
    import Data.List  
    import Data.Ratio  
    
    simpleTrain = uncurry (%) . (head &&& last) . map read  
    
    compoundTrain input =  
      let a = read $ head input  
          z = read $ last input  
          gs =  
            map  
              ( uncurry (%)  
                  . (read *** read . tail)  
                  . break (== '|')  
              )  
              $ (tail . init) input  
       in foldl' (/) (a % z) gs  
    
    part1, part2, part3 :: [String] -> Integer  
    part1 = floor . (2025 *) . simpleTrain  
    part2 = ceiling . (10000000000000 /) . simpleTrain  
    part3 = floor . (100 *) . compoundTrain  
    
    main =  
      forM_  
        [ ("everybody_codes_e2025_q04_p1.txt", part1),  
          ("everybody_codes_e2025_q04_p2.txt", part2),  
          ("everybody_codes_e2025_q04_p3.txt", part3)  
        ]  
        $ \(input, solve) -> readFile input >>= print . solve . lines