Skip to content

Instantly share code, notes, and snippets.

@AnthonyMikh
Last active March 20, 2018 14:43
Show Gist options
  • Save AnthonyMikh/059ce2e8e71858823f3b21853f8f3180 to your computer and use it in GitHub Desktop.
Save AnthonyMikh/059ce2e8e71858823f3b21853f8f3180 to your computer and use it in GitHub Desktop.
Решение задачи №15 от UniLecs
type Bar = u32; //Тип столбца гистограммы
//Вспомогательная функция -- вывод гистограммы на печать
fn print_bar_chart(chart: &[Bar]) {
//Находим максимальную высоту столбцов
let max_height = chart.iter().map(|&x| x).fold(0, |acc, x| acc.max(x));
//Для каждого значения от максимальной высоты до 1 включительно
for height in (0..max_height).map(|x| x + 1).rev() {
//и каждой колонки гистограммы
for &bar in chart {
if bar < height { //если колонка ниже текущей высоты
print!(" ");
} else {
print!("#");
}
}
print!("\n");
}
}
//Подсчитывает количество воды, которое гистограмма может удержать
fn water_volume(chart: &[Bar]) -> Bar {
//Вспомогательная функция.
//Возвращает возвышения гистограммы
fn steep<I: ::std::iter::Iterator<Item = Bar>>(row: I) -> Vec<Bar> {
row.fold((Vec::new(), 0), |(mut buf, acc), x| {
let max = acc.max(x);
buf.push(max);
(buf, max)
}).0
}
//Колонки гистограммы
let bars = chart.iter().cloned();
let left_steep = steep(bars.clone());
let right_steep = steep(bars.clone().rev());
let smallest = left_steep
.into_iter()
.zip(right_steep.into_iter().rev())
.map(|(a, b)| a.min(b));
bars.zip(smallest).fold(0, |volume, (height, bound)| {
volume + (bound - height)
})
}
fn main() {
let chart = [1, 2, 6, 4, 8, 6, 4, 2, 4, 7];
print_bar_chart(&chart);
println!("Volume: {}", water_volume(&chart));
}
@AnthonyMikh
Copy link
Author

AnthonyMikh commented Mar 17, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment