parent
fdde07dee2
commit
5555907e0a
@ -0,0 +1,9 @@ |
|||||||
|
[package] |
||||||
|
name = "task1-appendsort" |
||||||
|
version = "0.1.0" |
||||||
|
authors = ["inga-lovinde <52715130+inga-lovinde@users.noreply.github.com>"] |
||||||
|
edition = "2018" |
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||||
|
|
||||||
|
[dependencies] |
@ -0,0 +1,161 @@ |
|||||||
|
use std::{cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}, io::{self, BufRead}, ops::{Add, Index, Shl}}; |
||||||
|
|
||||||
|
#[derive(Debug)] |
||||||
|
struct BigInt { |
||||||
|
storage: Vec<u8>, |
||||||
|
} |
||||||
|
|
||||||
|
impl BigInt { |
||||||
|
fn size(&self) -> usize { |
||||||
|
self.storage.len() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Index<usize> for BigInt { |
||||||
|
type Output = u8; |
||||||
|
fn index(&self, offset: usize) -> &u8 { |
||||||
|
if offset < self.storage.len() { |
||||||
|
return &self.storage[offset]; |
||||||
|
} else { |
||||||
|
return &0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Add for &BigInt { |
||||||
|
type Output = BigInt; |
||||||
|
|
||||||
|
fn add(self, other: Self) -> BigInt { |
||||||
|
let mut result = vec![0; self.size().max(other.size())]; |
||||||
|
let mut carry = 0; |
||||||
|
for i in 0..result.len() { |
||||||
|
let mut digit = self[i] + other[i] + carry; |
||||||
|
if digit >= 10 { |
||||||
|
digit -= 10; |
||||||
|
carry = 1; |
||||||
|
} else { |
||||||
|
carry = 0; |
||||||
|
} |
||||||
|
result[i] = digit; |
||||||
|
} |
||||||
|
|
||||||
|
if carry > 0 { |
||||||
|
result.push(carry); |
||||||
|
} |
||||||
|
|
||||||
|
BigInt { |
||||||
|
storage: result, |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Shl<usize> for &BigInt { |
||||||
|
type Output = BigInt; |
||||||
|
|
||||||
|
fn shl(self, rhs: usize) -> BigInt { |
||||||
|
let mut result = vec![0; rhs]; |
||||||
|
result.extend_from_slice(&self.storage); |
||||||
|
|
||||||
|
BigInt { |
||||||
|
storage: result, |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl PartialEq for BigInt { |
||||||
|
fn eq(&self, other: &Self) -> bool { |
||||||
|
for i in 0..self.size().max(other.size()) { |
||||||
|
if self[i] != other[i] { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl Eq for BigInt { |
||||||
|
} |
||||||
|
|
||||||
|
impl Ord for BigInt { |
||||||
|
fn cmp(&self, other: &Self) -> Ordering { |
||||||
|
for i in (0..self.size().max(other.size())).rev() { |
||||||
|
//println!("{} {}", self[i], other[i]);
|
||||||
|
let comparison = self[i].cmp(&other[i]); |
||||||
|
if comparison != Ordering::Equal { |
||||||
|
//println!("{:?}", comparison);
|
||||||
|
return comparison; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return Ordering::Equal; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl PartialOrd for BigInt { |
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { |
||||||
|
Some(self.cmp(other)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl From<u32> for BigInt { |
||||||
|
fn from(mut num: u32) -> BigInt { |
||||||
|
let mut result = vec![]; |
||||||
|
|
||||||
|
while num > 0 { |
||||||
|
result.push((num % 10) as u8); |
||||||
|
num = num / 10; |
||||||
|
} |
||||||
|
|
||||||
|
BigInt { |
||||||
|
storage: result, |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fn get_next_value(previous_value: &BigInt, current_value: &BigInt) -> (BigInt, usize) { |
||||||
|
let current_value_plus = current_value + (&BigInt::from(1)); |
||||||
|
let previous_value_plus = previous_value + (&BigInt::from(1)); |
||||||
|
|
||||||
|
//println!("{:?} {:?} {:?} {:?}", previous_value, current_value, previous_value_plus, current_value_plus);
|
||||||
|
for shift in 0..10000usize { |
||||||
|
let current_value_shifted = current_value << shift; |
||||||
|
let current_value_plus_shifted = (¤t_value_plus) << shift; |
||||||
|
//println!("{:?} {:?}", current_value_shifted, current_value_plus_shifted);
|
||||||
|
|
||||||
|
if (¤t_value_shifted) > previous_value { |
||||||
|
return (current_value_shifted, shift); |
||||||
|
} |
||||||
|
|
||||||
|
if (¤t_value_plus_shifted) > (&previous_value_plus) { |
||||||
|
return (previous_value_plus, shift); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
panic!("too large shift"); |
||||||
|
} |
||||||
|
|
||||||
|
fn solve(list: Vec<u32>) -> usize { |
||||||
|
let mut result = 0; |
||||||
|
|
||||||
|
let mut last_value = BigInt::from(0); |
||||||
|
for current_num in list { |
||||||
|
let (next_value, shift) = get_next_value(&last_value, &BigInt::from(current_num)); |
||||||
|
last_value = next_value; |
||||||
|
result += shift; |
||||||
|
} |
||||||
|
|
||||||
|
result |
||||||
|
} |
||||||
|
|
||||||
|
fn main() { |
||||||
|
let stdin = io::stdin(); |
||||||
|
let mut lines = stdin.lock().lines(); |
||||||
|
|
||||||
|
let test_number: u32 = lines.next().unwrap().unwrap().parse().unwrap(); |
||||||
|
for t in 1..=test_number { |
||||||
|
let _length: u32 = lines.next().unwrap().unwrap().parse().unwrap(); |
||||||
|
let list: Vec<u32> = lines.next().unwrap().unwrap().split(char::is_whitespace).map(|part| part.parse().unwrap()).collect(); |
||||||
|
println!("Case #{}: {}", t, solve(list)); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue