Advent of Code 2020 day08
20419 단어 Rustadventofcodetech
part1
입력
nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
jmp -4
acc +6
.nop
값을 accumultator에 추가한 다음 다음 줄로 들어갑니다.acc
현재 줄에서 다음 줄이 아닌 상대값 줄로 이동합니다.실제로 0줄부터 순서대로 실행하면 무한 순환이 되므로 순환을 통해 2주차에 접어들기 전의 accumulator 값을 되돌려줍니다.
우직한 simulation을 하고 실행하면 됩니다.실행된 줄만 저장
jmp
하면서 한 줄 한 줄 PARse를 기록하면서 실행합니다.실행이 완료된 줄에 도착하면 그때의 accumulator 값을 돌려주면 됩니다.struct Solution {
inputs: Vec<String>,
}
impl Solution {
fn new(inputs: Vec<String>) -> Self {
Self { inputs }
}
fn solve_1(&self) -> i32 {
let mut visited: Vec<bool> = vec![false; self.inputs.len()];
let (mut i, mut acc) = (0, 0);
loop {
if visited[i as usize] {
return acc;
}
visited[i as usize] = true;
let instruction = &self.inputs[i as usize];
if let Ok(arg) = instruction[4..].parse::<i32>() {
match &instruction[..3] {
"acc" => acc += arg,
"jmp" => i += arg - 1,
_ => {}
}
}
i += 1;
}
}
}
part2
실제로 한 곳
Vec
과 nop
만 바뀌었기 때문에 무한순환이 형성되었고, 이 순환을 수정하면 최종행에 정확하게 도달할 수 있을 것이다.이런 질문 입력법을 어떻게 만드는지...파트1과 마찬가지로 simulation을 실행하는 방법을 준비했습니다.
jmp
를 매개변수에 전달하도록 지정하면 행Option<i32>
과 nop
만 대체합니다.방법의 반환값은 jmp
이고 마지막 줄Result<i32, i32>
까지 정확하게 실행하면 순환에 들어간 후에 되돌아온다Ok
.그리고 입력은 전 줄을 앞당겨 완성하는 것이 좋습니다.
struct Solution {
instructions: Vec<(String, i32)>,
}
impl Solution {
fn new(inputs: Vec<String>) -> Self {
Self {
instructions: inputs
.iter()
.map(|input| (input[..3].to_string(), input[4..].parse().unwrap()))
.collect(),
}
}
fn run(&self, change: Option<i32>) -> Result<i32, i32> {
let mut visited: Vec<bool> = vec![false; self.instructions.len()];
let (mut i, mut acc) = (0, 0);
while i < self.instructions.len() as i32 {
if visited[i as usize] {
return Err(acc);
}
visited[i as usize] = true;
let instruction = &self.instructions[i as usize];
match instruction.0.as_str() {
"acc" => acc += instruction.1,
"jmp" if change != Some(i) => i += instruction.1 - 1,
"nop" if change == Some(i) => i += instruction.1 - 1,
_ => {}
}
i += 1;
}
Ok(acc)
}
}
part1은 이 지정Err
을 사용하여 아무 것도 변경하지 않고 실행한 None
의 값을 사용할 수 있습니다.part2는 brute force에서 지정한 Err
이외의 줄을 사용해 보십시오. acc
되돌아오면 끝납니다.입력은 600줄 정도이기 때문에 이런 방법으로 해결 방안을 먼저 얻을 수 있다.
더 효과적으로 하고 싶다면 백트랙 방법으로 중도 상태로 유지하고, 실패하면 거기로 돌아가는 게 좋겠죠.
code
fn solve_1(&self) -> i32 {
self.run(None).unwrap_err()
}
fn solve_2(&self) -> i32 {
for (i, input) in self.inputs.iter().enumerate() {
if !input.starts_with("acc") {
if let Ok(n) = self.run(Some(i as i32)) {
return n;
}
}
}
0
}
Reference
이 문제에 관하여(Advent of Code 2020 day08), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/sugyan/articles/6a9bfea6eab229텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)