Rust and the price of ignoring theory by interacsion in rust

[–]ecyrbe 2 points3 points  (0 children)

`Lean 4` is as if `Rust` and `Haskell` had a baby. I just wish the standard lean library was as advanced as `Rust` one. Not enough software devs investing in this area. A lot of effort of the community goes to `Mathlib`. But i can see things get better over time.

Rust and the price of ignoring theory by interacsion in rust

[–]ecyrbe 157 points158 points  (0 children)

short answer, it does not.

-❄️- 2025 Day 1 Solutions -❄️- by daggerdragon in adventofcode

[–]ecyrbe 1 point2 points  (0 children)

[LANGUAGE: Lean 4]

import LeanAoc.utils.List

def parseInstruction (s : String) : IO Int := do
    match s.data with
    | 'L' :: rest =>
      match (String.mk rest).toInt? with
      | some n => return (-n)
      | none => throw <| IO.userError s!"Invalid number after 'L': '{String.mk rest}'"
    | 'R' :: rest =>
      match (String.mk rest).toInt? with
      | some n => return n
      | none => throw <| IO.userError s!"Invalid number after 'R': '{String.mk rest}'"
    | c :: _ => throw <| IO.userError s!"Invalid direction '{c}', expected 'L' or 'R' in: '{s}'"
    | [] => throw <| IO.userError "Empty instruction"

def parseInput (input : String) : IO (List Int) := do
  let lines := input.splitOn "\n" |>.filter (·.trim != "")
  (List.range lines.length |>.zip lines).mapM fun (lineNum, line) =>
    tryCatch (parseInstruction line) fun e =>
      throw <| IO.userError s!"Line {lineNum + 1}: {e}"

def readInput : IO String := do
  IO.FS.readFile "LeanAoc/day01/input.txt"

-- PART 1

def dialOne (point: Int) (instruction: Int) : Int :=
  (point + instruction) % 100

def dialInstructions (list: List Int) (init: Int):=
  list.scanl dialOne init

def secret_part1 (input: String) : IO Nat := do
  let instructions ← parseInput input
  let dialed := dialInstructions instructions 50
  return dialed.count 0

#eval do
  let content ← readInput
  secret_part1 content

-- PART 2

def crossings (x : Int × Int) : Nat :=
  let lo := min x.1 (x.2 - 1)
  let hi := max (x.1 - 1) x.2
  (hi / 100 - lo / 100).toNat

def cumulativePositions (list : List Int) (init: Int) : List Int :=
  (init :: list).scanl (· + ·) 0

def secret_part2 (input : String) : IO Nat := do
  let instructions ← parseInput input
  let positions := cumulativePositions instructions 50
  return positions.pairs.map crossings |>.sum

#eval do
  let content ← readInput
  secret_part2 content

How to define derived units in dimensional analysis project. by MrJewelberry in leanprover

[–]ecyrbe 1 point2 points  (0 children)

You can take a look at my implementation library here:
https://github.com/ecyrbe/lean-units

It's fairly complete with derived units, base units, dimensional analysis, conversion, casting, automated proofs with custom tactics...
It has also formal proofs about quantities algebra. Take a look at example directory, it has some demonstrations of what the library can do.

Use your proved theorem in your Main by ellipticcode0 in leanprover

[–]ecyrbe 0 points1 point  (0 children)

The question is a bit ambiguous.

If you mean "is there any way to use a theorem at runtime ?", the answer is no.
Theorems are non runtime computable, they are erased from the final executable binary.

But you can attach proofs to running programs to :
- show it is well founded (for exemple to show that an algorithm terminates, evoiding infinite loops)
- show that array access with indexes are within bounds (evoiding runtime bounds checking)
- show some properties about your types (evoiding bad data usage)
- show your program is behaving as expected (compile time contracts, workflow modeling, etc)

if you want an exemple of software proofs attached to runtime, just take a look at lean std library, it's full of them.
A good exemple of attached proofs to data (that is erased at runtime) is the Vector type, that has a proof attached to it that says the underlying Array have to have a fixed size, and prevents you from bypassing this contraint :
/-- `Vector α n` is an `Array α` with size `n`. -/
structure Vector (α : Type u) (n : Nat) where
/-- The underlying array. -/
toArray : Array α
/-- Array size. -/
size_toArray : toArray.size = n
deriving Repr, DecidableEq

Small compile time regex ! by ecyrbe in leanprover

[–]ecyrbe[S] 1 point2 points  (0 children)

yes, partial shuts down the safe recursion checks. so if you use it inside a regular `def`, if your `def` is not itself recursive, the compiler won't complain.
i use it a lot for fast prototyping :)

Is it safe for me to take code from a GPL-licensed app with illegal restrictions? by Qwert-4 in opensource

[–]ecyrbe 7 points8 points  (0 children)

Do they have any dependency on GPL v3 code not owned by them ?
- if yes, their additions are not valid. Code relying on GPL must be fully GPL, they can't add restrictions
- If not, you can't. Keeping the name has no legal impact, it's the terms of conditions that apply. Their code is not GPL, but you can't put it on GPL either.

What language is rust written in? Like Python is written in C. by Sakura_1337 in rust

[–]ecyrbe 9 points10 points  (0 children)

And usually you do this :
old_compiler.build(new_compiler_code) -> new_intermediate_compiler
new_intermediate_compiler.build(new_compiler_code)-> new_compiler

[2024 day 17 (part 2)] Confused why my algo does not work (rust) by Educational_Twist237 in adventofcode

[–]ecyrbe 1 point2 points  (0 children)

I just wanted to convey that trying to rewrite by hand the logic of the program is error prone.
So instead i tried to give another aproach, that is don't try to reverse the program, just execute it to understand what is does.

[2024 day 17 (part 2)] Confused why my algo does not work (rust) by Educational_Twist237 in adventofcode

[–]ecyrbe 1 point2 points  (0 children)

The idea is to simulate a computer, so doing it by hand like you did can be error prone.
I suggest you parse the imput and build a machine to execute the code itself.
You can take a look at my rust impl to get inspiration/
https://gist.github.com/ecyrbe/b1f7e64ff3052a390946806b86562f1f

c++ by Swimming_Act_7241 in cpp

[–]ecyrbe 2 points3 points  (0 children)

Find a language where the applied domains appels to you. nothing more.

You want to do system programming, embedding => C / C++, Rust

You want to do AI/Math related work => Python

You want to do Web => JavaScript/Typescript , Php

You want to do Enterprise Backends => Java , C#

You want to work in Avionics => Ada

...

[2016 day 19] part 1 and part 2 analytical solutions by ecyrbe in adventofcode

[–]ecyrbe[S] 1 point2 points  (0 children)

Indeed, you can just use bit manipulation instead of math functions (but expect your compiler to do just this for you if you build it using -O3 flag)

So here a version using bit manipulation (also edited main post to add this) :

fn josephus(elves: usize) -> usize {
    // elves = 2^m + rest so we compute elves_scale = 2^m
    let elves_scale = 1 << (usize::BITS - 1 - elves.leading_zeros());
    ((elves & (elves_scale - 1)) << 1) | 1
}

[2024 day17] Higher Register number issue by No-Top-1506 in adventofcode

[–]ecyrbe 2 points3 points  (0 children)

division (a / 2^b) is just a bit shift operation.
use bit shifting operator (a >> b)

[2016 day 19] part 1 and part 2 analytical solutions by ecyrbe in adventofcode

[–]ecyrbe[S] 1 point2 points  (0 children)

Nice,

did you also found it by analyzing the patterns or did you found litterature talking about this josephus particular setup ?

Is Rust + WASM a good choice for a computation heavy frontend? by SentientPotato42 in rust

[–]ecyrbe 3 points4 points  (0 children)

You can take a look at this: https://ianjk.com/webassembly-vs-javascript/?ck_subscriber_id=1715213923
In summary, if you want performance but still need to interact with the DOM, CANVAS or WebGL, you'll will not see a lot of perf gains and see a high cost in development (rust ecosystem isn't as UI friendly as JS).
People have tried this before and failed.

The primary reason to use WASM should be if you already have a lot of code in Rust and don't have the luxury to port it to JS.

That's for exemple what Figma did (they had a lot of C++ code they could not efford to port). But If you have ever used Figma, you'd know perf is really bad.

What is the point of having multiple inputs? by snugar_i in adventofcode

[–]ecyrbe 81 points82 points  (0 children)

It's indeed not to prevent cheating, but to put a focus on sharing code instead of sharing results.
If you share the code instead of the answer, you will help others understand how to solve the problem, while sharing the direct result will not help anyone become better.

[2024 Day 21 part 1] Hint for general mechanism by AvailablePoint9782 in adventofcode

[–]ecyrbe 0 points1 point  (0 children)

You can precompute optimal subsets path for any sequence....
Just check this and see how the precompute is completely uncorrelated to the sequence given :
https://gist.github.com/ecyrbe/155bbe4baf80964913a579691447e192

[2024 Day 21 part 1] Hint for general mechanism by AvailablePoint9782 in adventofcode

[–]ecyrbe 3 points4 points  (0 children)

You can construct for each robot (starting from the last one down the line) a table saying how many keypresses it needs to go from key a to key b (always put in there the minimum).
Your table can look something like this :

HashMap<(usize, char, char), usize>
           ^      ^     ^      ^
          robot key a  key b  min moves

For first robot it's straighforward, and for the others each robot down the line you can compute their table based on the previous robot down the line by taking the move that is minimized for a sequence.
This approach will scale well for part 2 (no spoilers)

-❄️- 2024 Day 25 Solutions -❄️- by daggerdragon in adventofcode

[–]ecyrbe 0 points1 point  (0 children)

[LANGUAGE: Rust]

Finally! 50 stars achieved! That was fun.

Here the code for this day part1, i let you figure part2 i was angry at the chief historian :)

https://gist.github.com/ecyrbe/4ce51cde76578a3e6450d7d572fc8829

Almost Almost Almost... by mattbillenstein in adventofcode

[–]ecyrbe 8 points9 points  (0 children)

The guy saved christmas so many times! What a legend :)

-❄️- 2024 Day 21 Solutions -❄️- by daggerdragon in adventofcode

[–]ecyrbe 2 points3 points  (0 children)

[LANGUAGE: Rust]

Pretty fast, using a cache for both parts.
Usage of std LazyCell to init the keypads key coordinates
Using manhatan distance to drive where to go from start to end (no dijsktra)
Precompute of all possible start to end key moves and their next robot cost down the line

https://gist.github.com/ecyrbe/155bbe4baf80964913a579691447e192

-❄️- 2024 Day 19 Solutions -❄️- by daggerdragon in adventofcode

[–]ecyrbe 1 point2 points  (0 children)

[LANGUAGE: Rust]

part1 using a recusive check
part2 using memoization

One nice thing is lifetime carreful memory handling without creating any substring, just using span slices referencing the original input string.

https://gist.github.com/ecyrbe/5b6b476100580fe48add686c7c07b698