Skip to content

Commit

Permalink
Add problem 1643: Kth Smallest Instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Oct 21, 2023
1 parent 1c7ab5a commit 1d5eb65
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,7 @@ pub mod problem_1639_number_of_ways_to_form_a_target_string_given_a_dictionary;
pub mod problem_1640_check_array_formation_through_concatenation;
pub mod problem_1641_count_sorted_vowel_strings;
pub mod problem_1642_furthest_building_you_can_reach;
pub mod problem_1643_kth_smallest_instructions;
pub mod problem_1646_get_maximum_in_generated_array;
pub mod problem_1647_minimum_deletions_to_make_character_frequencies_unique;
pub mod problem_1652_defuse_the_bomb;
Expand Down
81 changes: 81 additions & 0 deletions src/problem_1643_kth_smallest_instructions/combinations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

use std::convert::TryInto;
use std::iter;

impl Solution {
fn combinations(n: usize) -> Box<[u32]> {
let mut result = vec![0; n * n].into_boxed_slice();
let mut iter = result.chunks_exact_mut(n);
let mut prev_row = iter.next().unwrap();

prev_row[0] = 1;

for row in iter {
let mut top_left = 0;

for (value, &mut top) in row.iter_mut().zip(prev_row) {
*value = top_left + top;
top_left = top;
}

prev_row = row;
}

result
}

pub fn kth_smallest_path(destination: Vec<i32>, k: i32) -> String {
let [row, column]: [_; 2] = destination.try_into().ok().unwrap();
let mut row = row as u32 as usize;
let mut column = column as u32 as usize;
let mut k = k as u32;
let length = row + column;
let combinations = Self::combinations(length);
let mut result = String::with_capacity(length);

let (c, count) = loop {
let count = combinations[length * (row + column - 1) + row];

if k <= count {
result.push('H');
column -= 1;

if column == 0 {
break ('V', row);
}
} else {
result.push('V');
row -= 1;

if row == 0 {
break ('H', column);
}

k -= count;
}
};

result.extend(iter::repeat(c).take(count));

result
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn kth_smallest_path(destination: Vec<i32>, k: i32) -> String {
Self::kth_smallest_path(destination, k)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
22 changes: 22 additions & 0 deletions src/problem_1643_kth_smallest_instructions/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
pub mod combinations;

pub trait Solution {
fn kth_smallest_path(destination: Vec<i32>, k: i32) -> String;
}

#[cfg(test)]
mod tests {
use super::Solution;

pub fn run<S: Solution>() {
let test_cases = [
((&[2, 3] as &[_], 1), "HHHVV"),
((&[2, 3], 2), "HHVHV"),
((&[2, 3], 3), "HHVVH"),
];

for ((destination, k), expected) in test_cases {
assert_eq!(S::kth_smallest_path(destination.to_vec(), k), expected);
}
}
}

0 comments on commit 1d5eb65

Please sign in to comment.