~jpl8/text-to-piet

52232844cf25f347869d7c847a0eedfc4c90fe0e — jpl 1 year, 7 months ago 75f682d
Add first attempt to predict the size of the instruction spiral.
Next step should be to walk through the instructions and count how many
blocks each will need to enhance the predictability of the spiral size.
4 files changed, 64 insertions(+), 18 deletions(-)

M spiral.png
M src/main.rs
M src/spiral.rs
M test.png
M spiral.png => spiral.png +0 -0
M src/main.rs => src/main.rs +44 -17
@@ 24,7 24,7 @@ struct Args {

    /// Image size
    #[clap()]
    img_size: u32,
    img_size: Option<u32>,
}

fn main() {


@@ 35,11 35,17 @@ fn main() {

    println!("{:?}", instrs);
    println!("num_instructions {:?}", instrs.len());
    println!("{:?}", eval(&instrs));
    //println!("{:?}", eval(&instrs));

    let colors = instructions_to_blocks(&instrs, args.img_size);
    println!("colors {:?}", colors);
    colors_to_img(colors, args.img_size, "test.png".to_string());
    let img_size = args.img_size.unwrap_or(expected_size(&instrs));
    println!("img_size: {:?}", img_size);
    println!("spiral_len: {:?}", Spiral2D::length(img_size));

    let colors = instructions_to_blocks(&instrs, img_size);
    println!("img_size: {:?}", img_size);
    //println!("colors {:?}", colors);
    colors_to_img(colors, img_size, "test.png".to_string());
    println!("img_size: {:?}", img_size);
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]


@@ 175,6 181,27 @@ fn update_x_y_spiral(x: u32, y: u32, step: u32, dir: &Direction) -> (u32, u32) {
    }
}

fn expected_size(instructions: &Vec<Instructions>) -> u32 {
    let n = instructions.len();

    // Num of extra blocks for corner_turn = 2 * num_corners
    // num_corners(side) = side - 3, for side > 2, 0 otherwise
    // num_blocks(instructions, side) = instructions.len() + corner_turn.len() * num_corners(side)
    //            = n + 2 * (side - 3)

    // len_spiral(side) = floor(side²/2)

    // num_blocks <= len_spiral
    // n + 2 * (side - 3) <= floor(side²/2)

    // solving for side should work out to

    //4 + (((2 * n - 8) as f64).sqrt() as u32) + 1
    //2 + ((2 * n - 8) as f64).sqrt() as u32
    //3 + ((2 * n - 9) as f64).sqrt() as u32
    10 + ((2.5 * (n as f64)) as f64).sqrt() as u32
}

fn instructions_to_blocks(instructions: &Vec<Instructions>, img_size: u32) -> Vec<Color> {
    let mut colors = vec![];
    let mut prev = Color::Red;


@@ 186,7 213,7 @@ fn instructions_to_blocks(instructions: &Vec<Instructions>, img_size: u32) -> Ve
    let mut direction = Direction::Right;

    for instr in instructions {
        println!("remaining_space: {}", remaining_space);
        //println!("remaining_space: {}", remaining_space);
        match instr {
            PUSH(n) => {
                // (n - 1) + 1 + corner_turn.len <= remaining_space


@@ 197,24 224,24 @@ fn instructions_to_blocks(instructions: &Vec<Instructions>, img_size: u32) -> Ve
                //
                // TODO: If there isn't enough space split into two pushes
                if remaining_space < (*n as u32) + corner_turn.len() as u32 {
                    eprintln!(
                        "SPLIT PUSH - remaining_space: {:?}, n: {:?}, prev: {:?}",
                        remaining_space, n, prev
                    );
                    //eprintln!(
                    //    "SPLIT PUSH - remaining_space: {:?}, n: {:?}, prev: {:?}",
                    //    remaining_space, n, prev
                    //);
                    let first_push = remaining_space as usize - corner_turn.len();
                    let second_push = n - first_push;
                    eprintln!("first: {}, second: {}", first_push, second_push);
                    //eprintln!("first: {}, second: {}", first_push, second_push);
                    for _ in 0..first_push {
                        colors.push(prev);
                    }
                    prev = colors::instruction_to_block(PUSH(first_push), prev).0;
                    eprintln!("COLOR: {:?}", prev);
                    //eprintln!("COLOR: {:?}", prev);

                    // colors.push(prev);
                    for _instr in corner_turn {
                        colors.push(prev);
                        prev = colors::instruction_to_block(_instr, prev).0;
                        eprintln!("COLOR: {:?}", prev);
                        //eprintln!("COLOR: {:?}", prev);
                    }

                    direction = direction.clockwise();


@@ 229,11 256,11 @@ fn instructions_to_blocks(instructions: &Vec<Instructions>, img_size: u32) -> Ve
                    }
                    remaining_space -= second_push as u32;
                    prev = colors::instruction_to_block(PUSH(second_push), prev).0;
                    eprintln!("COLOR: {:?}", prev);
                    //eprintln!("COLOR: {:?}", prev);

                    colors.push(prev);
                    prev = colors::instruction_to_block(ADD, prev).0;
                    eprintln!("COLOR: {:?}", prev);
                    //eprintln!("COLOR: {:?}", prev);
                    remaining_space -= 1;
                    continue;
                } else {


@@ 250,12 277,12 @@ fn instructions_to_blocks(instructions: &Vec<Instructions>, img_size: u32) -> Ve
        }

        if *instr == OUTCHAR {
            eprintln!("prev1: {:?}", prev);
            //eprintln!("prev1: {:?}", prev);
        }
        // TODO: make this functon only return the color
        prev = colors::instruction_to_block(*instr, prev).0;
        if *instr == OUTCHAR {
            eprintln!("prev2: {:?}", prev);
            //eprintln!("prev2: {:?}", prev);
        }

        if remaining_space == corner_turn.len() as u32 {

M src/spiral.rs => src/spiral.rs +20 -1
@@ 48,6 48,19 @@ impl Spiral2D {
            spiral_tightness: 2,
        }
    }

    /// Length of a spiral given it's inital side
    pub fn length(initial_side: u32) -> u32 {
        (initial_side * initial_side + 1) / 2
    }

    pub fn num_of_turns(initial_side: u32) -> u32 {
        if initial_side < 3 {
            0
        } else {
            initial_side - 2
        }
    }
}

impl Iterator for Spiral2D {


@@ 69,7 82,13 @@ impl Iterator for Spiral2D {
                // or if it should be a function of the original
                // direction
                match self.dir {
                    Direction::Down | Direction::Up => self.curr_side -= self.spiral_tightness,
                    Direction::Down | Direction::Up => {
                        self.curr_side = if self.curr_side < self.spiral_tightness {
                            0
                        } else {
                            self.curr_side - self.spiral_tightness
                        }
                    }
                    _ => (),
                }
                self.remaining_space = self.curr_side;

M test.png => test.png +0 -0