1use std::io;
28
29pub fn add_one<T: io::Write>(digits: &[u8], output: &mut T) -> Result<(), io::Error> {
30 let (minus, digits) = match digits.split_first() {
32 Some((&b'-', digits)) => (true, digits), _ => (false, digits),
34 };
35
36 if digits.is_empty() || !digits.iter().all(|&c| c >= b'0' && c <= b'9' || c == b'.') {
38 return Err(io::Error::new(
39 io::ErrorKind::InvalidInput,
40 "Invalid characters in input".to_string(),
41 ));
42 }
43
44 let digits = &digits[digits.iter().position(|&c| c != b'0').unwrap_or(digits.len())..];
46
47 let z = digits.iter().position(|&c| c == b'.').unwrap_or(digits.len()); let (prefix, trailing) = digits[..z].split_at(
51 digits[..z].iter()
52 .rposition(|&c| c != if minus { b'0' } else { b'9' })
53 .map_or(0, |x| x + 1) );
55
56 if let Some((&digit, prefix)) = prefix.split_last() {
57 let new_digit = if minus {
60 if prefix.is_empty() && trailing.is_empty() && digit == b'1' {
61 return output.write_all(b"0");
63 }
64 output.write_all(b"-")?;
65 digit - 1
66 } else {
67 digit + 1
68 };
69 output.write_all(prefix)?;
71 if !prefix.is_empty() || new_digit != b'0' {
73 output.write_all(&[new_digit])?;
74 }
75 } else if minus && digits.len() > 0 && digits[0] == b'.' && !digits[1..].iter().all(|&d| d == b'0') {
76 output.write_all(b"0")?;
77 } else {
78 output.write_all(b"1")?;
79 }
80 for _ in 0..trailing.len() {
81 output.write_all(if minus { b"9" } else { b"0" })?;
82 }
83 if minus && z == 0 && digits.len() > 1 {
84 output.write_all(&digits[0..1])?;
86 let mut iter = digits[1..].iter().rev().peekable();
87 let mut decimal_digits = Vec::new();
88 while let Some(&b'0') = iter.peek() {
89 decimal_digits.push(*iter.next().unwrap());
90 }
91 if let Some(_) = iter.peek() {
92 decimal_digits.push(b'9' - *iter.next().unwrap() + b'0' + 1);
93 }
94 while let Some(_) = iter.peek() {
95 decimal_digits.push(b'9' - *iter.next().unwrap() + b'0');
96 }
97 output.write_all(decimal_digits.iter().rev().cloned().collect::<Vec<u8>>().as_slice())?;
98 } else {
99 output.write_all(&digits[z..])?;}
101 Ok(())
102}
103
104#[test]
105fn add_one_test_integer() {
106 fn test(num: &str, result: &str) {
107 use std::str::from_utf8;
108 let mut s = Vec::new();
109 add_one(num.as_bytes(), &mut s).unwrap();
110 assert_eq!(from_utf8(&s).unwrap(), result);
111 }
112 test("1234", "1235");
113 test("0", "1");
114 test("9", "10");
115 test("19", "20");
116 test("99", "100");
117 test("99988999", "99989000");
118 test("99999999", "100000000");
119 test("0001234", "1235");
120 test("-9", "-8");
121 test("-10", "-9");
122 test("-100", "-99");
123 test("-0100", "-99");
124 test("-1100", "-1099");
125 test("-01100", "-1099");
126 test("-1", "0");
127 test("-001", "0");
128 test("-0", "1");
129 test("-000", "1");
130 test(
131 "1256146513513224524524524524522452165841613615616516516",
132 "1256146513513224524524524524522452165841613615616516517",
133 );
134 test(
135 "1237801293471034709342345050491203491230949139249123949999999",
136 "1237801293471034709342345050491203491230949139249123950000000",
137 );
138 test(
139 "-1237801293471034709342345050491203491230949139249123940000000",
140 "-1237801293471034709342345050491203491230949139249123939999999",
141 );
142 test("-2", "-1");
143}
144
145#[test]
146fn add_one_test_float() {
147 fn test(num: &str, result: &str) {
148 use std::str::from_utf8;
149 let mut s = Vec::new();
150 add_one(num.as_bytes(), &mut s).unwrap();
151 assert_eq!(from_utf8(&s).unwrap(), result);
152 }
153 test("0.0", "1.0");
154 test("5000.0", "5001.0");
155 test("1139.67", "1140.67");
156 test("123.321", "124.321");
157 test("99.99", "100.99");
158 test("-1.0", "0");
159 test("2.0", "3.0");
160 test("000.000", "1.000");
161 test("-000.00", "1.00");
162 test("-0.9", "0.1");
163 test("-0.76987965465", "0.23012034535");
164 test("0123456789.0987654321", "123456790.0987654321");
165}
166