Created
May 31, 2021 22:52
-
-
Save miguelraz/d0341e9fee8c728baa99fd6fe86c1be1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- mode: snippet -*- | |
# name: template | |
# uuid: | |
# key: TEMP | |
# condition: t | |
# -- | |
//! Generic utility for reading data from standard input, based on [voxl's | |
//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375). | |
use std::io; | |
use std::str; | |
#[allow(unused_imports)] | |
use std::collections::*; | |
/// Reads white-space separated tokens one at a time. | |
pub struct Scanner<R> { | |
reader: R, | |
buffer: Vec<String>, | |
} | |
impl<R: io::BufRead> Scanner<R> { | |
pub fn new(reader: R) -> Self { | |
Self { | |
reader, | |
buffer: vec![], | |
} | |
} | |
/// Use "turbofish" syntax token::<T>() to select data type of next token. | |
/// | |
/// # Panics | |
/// | |
/// Panics if there's an I/O error or if the token cannot be parsed as T. | |
pub fn token<T: str::FromStr>(&mut self) -> T { | |
loop { | |
if let Some(token) = self.buffer.pop() { | |
return token.parse().ok().expect("Failed parse"); | |
} | |
let mut input = String::new(); | |
self.reader.read_line(&mut input).expect("Failed read"); | |
self.buffer = input.split_whitespace().rev().map(String::from).collect(); | |
} | |
} | |
} | |
/// Same API as Scanner but nearly twice as fast, using horribly unsafe dark arts | |
/// **REQUIRES** Rust 1.34 or higher | |
pub struct UnsafeScanner<R> { | |
reader: R, | |
buf_str: Vec<u8>, | |
buf_iter: str::SplitAsciiWhitespace<'static>, | |
} | |
impl<R: io::BufRead> UnsafeScanner<R> { | |
pub fn new(reader: R) -> Self { | |
Self { | |
reader, | |
buf_str: vec![], | |
buf_iter: "".split_ascii_whitespace(), | |
} | |
} | |
/// This function should be marked unsafe, but noone has time for that in a | |
/// programming contest. Use at your own risk! | |
pub fn token<T: str::FromStr>(&mut self) -> T { | |
loop { | |
if let Some(token) = self.buf_iter.next() { | |
return token.parse().ok().expect("Failed parse"); | |
} | |
self.buf_str.clear(); | |
self.reader | |
.read_until(b'\n', &mut self.buf_str) | |
.expect("Failed read"); | |
self.buf_iter = unsafe { | |
let slice = str::from_utf8_unchecked(&self.buf_str); | |
std::mem::transmute(slice.split_ascii_whitespace()) | |
} | |
} | |
} | |
} | |
pub fn scanner_from_file(filename: &str) -> Scanner<io::BufReader<std::fs::File>> { | |
let file = std::fs::File::open(filename).expect("Input file not found"); | |
Scanner::new(io::BufReader::new(file)) | |
} | |
pub fn writer_to_file(filename: &str) -> io::BufWriter<std::fs::File> { | |
let file = std::fs::File::create(filename).expect("Output file not found"); | |
io::BufWriter::new(file) | |
} | |
fn main() { | |
let stdin = io::stdin(); | |
let stdout = io::stdout(); | |
let reader = Scanner::new(stdin.lock()); | |
let writer = io::BufWriter::new(stdout.lock()); | |
solve(reader, writer); | |
} | |
#[allow(unused_must_use)] | |
fn solve<B: io::BufRead, W: io::Write>(mut scan: Scanner<B>, mut w: W) { | |
// Read a string | |
//let str = scan.token::<String>(); | |
// Convert to a bitstring | |
//let v: Vec<bool> = s.chars().map(|ch| ch == ‘1’).collect(); | |
// Read an Int | |
//let n = scan.token::<i64>(); | |
${1} | |
//let mut a = Vec::with_capacity(n); | |
//let mut b = Vec::with_capacity(n); | |
//for _ in 0..n { | |
//a.push(scan.token::<i64>()); | |
//b.push(scan.token::<i64>()); | |
//} | |
//let mut order: Vec<_> = (0..n).collect(); | |
//order.sort_by_key(|&i| b[i] - a[i]); | |
//let ans: i64 = order.into_iter() | |
//.enumerate() | |
//.map(|(i, x)| a[x] * i as i64 + b[x] * (n - 1 - i) as i64) | |
//.sum(); | |
writeln!(w, "{}", ans); | |
} |
@categulario nais!
Lo voy a tomar en cuenta. Lo bonito del template que puse es que es un snippet: solo pongo TEMP<TAB>
y se autocompleta todo - de ahi solo borro las lineas que aplican y casi de inmediato ya capturo mi entrada completamente.
La razón (hasta donde entiendo) que el código es más complicado es que se supone que hay problemas que te van a dar timeout si hay demasiados datos por entrada y siempre estás flusheando el Buffer - se supone que este código evita ese cuello de botella, pero la verdad mientras funcione no me preocupa mucho.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Eso se ve increíblemente complicado y ofuscado. Mira te enseño el que yo uso:
Ya en el main solamente me preocupo por leer números de la entrada (que vengan uno por línea) usando
o si vienen varios números en la misma línea:
y listo.