Making quines in Rust

fn main() {
    let src = r#"fn main() {
    let src = r❤"?"❤;
    for c in src.chars() {
        match c {
            '\u{2764}' => print!("{}", "❤"),
            '\u{3f}' => print!("{}", src),
            _ => print!("{}", c),
        }
    }
}
"#;
    for c in src.chars() {
        match c {
            '\u{2764}' => print!("{}", "#"),
            '\u{3f}' => print!("{}", src),
            _ => print!("{}", c),
        }
    }
}
✗ diff temp src/main.rs   
✗ shasum temp src/main.rs 
9c7812ddd1efba1142300b71f8b2b04c8b3d669a  temp
9c7812ddd1efba1142300b71f8b2b04c8b3d669a  src/main.rs```

:slight_smile:

6 Likes

Shorter version of the same idea:

fn main() {
    let src = r#"fn main() {
    let src = r$"?"$;
    println!("{}", src.replace('\u{24}', "$").replace('\u{3f}', src));
}"#;
    println!("{}", src.replace('\u{24}', "#").replace('\u{3f}', src));
}
7 Likes

Cool.

I remember the first time I saw that project:

I hope someone sees it for the first time too ^^

4 Likes

Oh my God!

Even the source code is an ASCII art drawing of an ouroboros

1 Like

I bet that @quinedot has a lot to say about this :grin:.

1 Like

So now I autogenerate the Quine program. I have a program in program.js which is then "quined" by build.rs

program.js

fn quine() {
    let src = r#"?"#;
    let output = src.replace('\u{2764}', "#").replace('\u{3f}', src);
    println!("{}", output);
}

fn main() {
    quine();
}

build.rs:

use std::fs;
use std::io::{self, Read, Write};

fn main() -> io::Result<()> {
    // Read the program to be quined
    let mut file = fs::File::open("src/program.rs")?;
    let mut program = String::new();
    file.read_to_string(&mut program)?;

    // Replace the hashes use in raw string literals
    let mut source = program.replace('#', "❤");
    // Remove trailing newline
    source.pop();

    // Quine the program by writing it's own (modified) source into it.
    let output = program.replace('?', &source);

    // Write quined program out as main.rs.
    let mut file = fs::File::create("src/main.rs")?;
    file.write_all(output.as_bytes())?;

    Ok(())
}

Which produce the Quine in main.rs:

fn quine() {
    let src = r#"fn quine() {
    let src = r❤"?"❤;
    let output = src.replace('\u{2764}', "❤").replace('\u{3f}', src);
    println!("{}", output);
}

fn main() {
    quine();
}"#;
    let output = src.replace('\u{2764}', "#").replace('\u{3f}', src);
    println!("{}", output);
}

fn main() {
    quine();
}

Which is then built and run:

✗ cargo build
   Compiling quine v0.1.0 (/Users/michaael/quine)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.21s
✗ rustc src/main.rs -o quine
✗ ./quine > source          
✗ diff source src/main.rs   
✗ shasum  source src/main.rs
dd91e81c02a08116171c40de708e1c26c5c59305  source
dd91e81c02a08116171c40de708e1c26c5c59305  src/main.rs

Which now means the program can be modified and extended without manually quining it.

An even shorter version can be found here: Golf you a quine for great good! - Code Golf Stack Exchange

Cool.

I'm looking to extend this Quine easily, hence the automation.

A quine is defined as:

A quine is a computer program that takes no input and produces a copy of its own source code as its only output.

Which does not exclude the source being output in interesting ways...

Technically, this also is a quine:

fn main() {
    print!("{}", include_str!("src/main.rs"));
}

as it doesn't read main.rs at runtime.

5 Likes

Wow, what? That is far too obvious and simple.

Feels like cheating but it complies with the Quine definition.

Oddly if there were a Rust interpreter then it would be cheating as it would end up reading main.rs at runtime.

i replicated a quine that shows local time, originally written in c:

1 Like

this should be illegal

Excellent. Have you been watching tsoding?

1 Like

i came across his post about quines on X, and i just thought to recreate it in rust. he gave me a link to the video on YT tho

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.