Hello,

I am trying to solve the day 7 using Rust and this is what I came up with so far:

use std::fs;

fn calculate(answer: &i32, numbers: &mut Vec<i32>) -> bool {
    if numbers.len() >= 2 {
	let tmp1 = numbers[0];
	let tmp2 = numbers[1];
	numbers.remove(0);
	numbers.remove(0);

	numbers.insert(0, tmp1 * tmp2);

	if calculate(answer, numbers) == true {
	    return true;
	} else {
	    numbers.remove(0);
	    numbers.insert(0, tmp1 + tmp2);
	    if calculate(answer, numbers) == true {
		return true;
	    } else {
		return false;
	    }
	}
    } else {
	if *answer == numbers[0] {
	    println!("> {} true", numbers[0]);
	    return true;
	} else {
	    println!("> {} false", numbers[0]);
	    return false;
	}
    }
}

fn main() {
    let contents = fs::read_to_string("sample.txt")
        .expect("Should have been able to read the file");

    for line in contents.lines() {
	let tmp = line.split(":").collect::<Vec<&str>>();
	let answer = tmp[0].to_string().parse::<i32>().unwrap();
	println!("{:?}", answer);
	let numbers_str = tmp[1].split(" ");
	let mut numbers: Vec<i32> = Vec::new();
	for num in numbers_str {
	    if num.len() == 0 {
		continue;
	    }
	    numbers.push(num.parse::<i32>().unwrap());
	}
	println!("{:?}", numbers);
	if calculate(&answer, &mut numbers) == true {
	    println!("it's true");
	}
    }
}

I don’t know why the recursion is not working. any help would be appreciated.

  • @Acters
    link
    1
    edit-2
    5 days ago

    I am not sure what is the real bug in here but I do know one thing.

    you should not work forwards in the list of numbers to see if it equates.
    Instead you should work from the last number back to the first one. This is because if the each number tested cannot divide without a remainder or be subtracted to 0 or above then the list of numbers is entirely invalid.

    This is a state solver type problem. You are basically bruteforcing each possible state and seeing if one is valid. This is computationally expensive.

    take a look at the example:
    3267: 81 40 27
    81 + 40 * 27 and 81 * 40 + 27 both equal 3267 when evaluated left-to-right
    So working backwards from the final state 3267 to the first state in the list 81:
    3267 / 27 = 121 - 40 = 81 and so it is valid!
    3267 - 27 = 3240 / 40 = 81 Also valid!

    but here are also examples that show being invalid:
    192: 17 8 14
    192 / 14 = 13.7 Invalid, skip checking the rest to save time!
    192 - 14 = 178 / 8 = 22.25 invalid! needs to be the same as the first number in the list and cannot have a remainder!
    192 - 14 = 178 - 8 = 170 != 17 invalid! needs to be the same as the first number in the list!
    this exhausts all paths that can be created!

    • whoareuOP
      link
      fedilink
      14 days ago

      wow, that’s a nice idea. I will try to solve this problem with this method if mine doesn’t work.