11use std:: io:: { self , BufRead } ;
2+ use std:: fmt:: Display ;
3+ use std:: fmt:: Formatter ;
4+ use std:: net:: Ipv4Addr ;
5+ use std:: net:: AddrParseError ;
6+ use std:: str:: FromStr ;
7+ use std:: num:: ParseIntError ;
28
9+ enum MyError {
10+ ParseIntError ( ParseIntError ) ,
11+ ParseIpv4Error ( AddrParseError ) ,
12+ }
313
4- fn ipv4todec ( ipv4 : String ) -> u32 {
5- let v: Vec < & str > = ipv4. split ( '.' ) . collect ( ) ;
6- let mut sum: u32 = 0 ;
7- for x in v {
8- sum = sum* 256 + x. parse :: < u32 > ( ) . unwrap ( ) ;
14+ impl Display for MyError {
15+ fn fmt ( & self , _: & mut Formatter ) -> std:: fmt:: Result {
16+ match * self {
17+ MyError :: ParseIntError ( ref e) => print ! ( "Parse int error {}" , e) ,
18+ MyError :: ParseIpv4Error ( ref e) => print ! ( "Parse Ipv4 address error {}" , e)
19+ }
20+ Ok ( ( ) )
921 }
10- return sum;
1122}
1223
13- fn dectoipv4 ( mut dec : u32 ) -> String {
14- let mut ret: String = "" . to_string ( ) ;
15- for i in 0 ..4 {
16- if i > 0 {
17- ret = "." . to_string ( ) + & ret;
18- }
19- ret = ( dec % 256 ) . to_string ( ) + & ret;
20- dec /= 256 ;
24+ impl std:: convert:: From < ParseIntError > for MyError {
25+ fn from ( e : ParseIntError ) -> Self {
26+ MyError :: ParseIntError ( e)
2127 }
22- return ret;
2328}
2429
25- // Calculate Network address from CIDR block
26- fn calc_network_addr ( cidr : String ) -> String {
27- let v: Vec < & str > = cidr. split ( '/' ) . collect ( ) ;
28- let net = v[ 0 ] . to_string ( ) ;
29- let mask = v[ 1 ] . parse :: < u32 > ( ) . unwrap ( ) ;
30- let mask_num = 2_u32 . pow ( 32 - mask) ;
31- let network_address_num = ipv4todec ( net) /mask_num * mask_num;
32- return dectoipv4 ( network_address_num) ;
30+ impl std:: convert:: From < AddrParseError > for MyError {
31+ fn from ( e : AddrParseError ) -> Self {
32+ MyError :: ParseIpv4Error ( e)
33+ }
3334}
3435
35- // Calculate Broadcast address from CIDR block
36- fn calc_broadcast_addr ( cidr : String ) -> String {
37- let v: Vec < & str > = cidr. split ( '/' ) . collect ( ) ;
38- let net = v[ 0 ] . to_string ( ) ;
39- let mask = v[ 1 ] . parse :: < u32 > ( ) . unwrap ( ) ;
40- let mask_num = 2_u32 . pow ( 32 - mask) ;
41- let network_address_num = ( 1 + ipv4todec ( net) /mask_num) * mask_num - 1 ;
42- return dectoipv4 ( network_address_num) ;
36+
37+ #[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
38+ struct Ipv4Cidr {
39+ address : Ipv4Addr ,
40+ mask : u8 ,
4341}
4442
45- // Calculate Network mask from CIDR block
46- fn calc_network_mask ( cidr : String ) -> u32 {
47- let v: Vec < & str > = cidr. split ( '/' ) . collect ( ) ;
48- let mask = v[ 1 ] . parse :: < u32 > ( ) . unwrap ( ) ;
49- return mask;
43+ impl Ipv4Cidr {
44+ fn new ( address : Ipv4Addr , mask : u8 ) -> Self {
45+ let cidr = Ipv4Cidr { address, mask } ;
46+ return Self {
47+ address : cidr. network_addr ( ) ,
48+ mask : cidr. network_mask ( ) ,
49+ }
50+ }
51+ fn to_string ( & self ) -> String {
52+ format ! ( "{}/{}" , self . address, self . mask)
53+ }
54+ fn mask_filter ( & self ) -> u32 {
55+ ( !0u32 ) . checked_shr ( self . mask as u32 ) . unwrap_or ( 0 )
56+ }
57+ fn network_addr ( & self ) -> Ipv4Addr {
58+ Ipv4Addr :: from ( u32:: from ( self . address ) & !self . mask_filter ( ) )
59+ }
60+ fn broadcast_addr ( & self ) -> Ipv4Addr {
61+ Ipv4Addr :: from ( u32:: from ( self . address ) | self . mask_filter ( ) )
62+ }
63+ fn network_mask ( & self ) -> u8 {
64+ self . mask
65+ }
66+ fn generate_wrap_cidr ( & self ) -> Ipv4Cidr {
67+ Ipv4Cidr :: new (
68+ self . address ,
69+ self . mask - 1
70+ )
71+ }
5072}
5173
52- // Generate CIDR from Network address and mask
53- fn gen_cidr ( network : String , mask : u32 ) -> String {
54- return network + "/" + & mask. to_string ( )
74+ impl FromStr for Ipv4Cidr {
75+ type Err = MyError ;
76+ fn from_str ( cidr : & str ) -> Result < Self , Self :: Err > {
77+ let v: Vec < & str > = cidr. split ( '/' ) . collect ( ) ;
78+ Ok ( Ipv4Cidr :: new (
79+ Ipv4Addr :: from_str ( v[ 0 ] ) . unwrap ( ) ,
80+ v[ 1 ] . parse :: < u8 > ( ) ?
81+ ) )
82+ }
5583}
5684
57- // Merge two CIDR blocks
58- fn merge ( cidr1 : String , cidr2 : String ) -> Vec < String > {
59- let cidr1_net = ipv4todec ( calc_network_addr ( cidr1. clone ( ) ) ) ;
60- let cidr2_net = ipv4todec ( calc_network_addr ( cidr2. clone ( ) ) ) ;
61- let cidr1_brd = ipv4todec ( calc_broadcast_addr ( cidr1. clone ( ) ) ) ;
62- let cidr2_brd = ipv4todec ( calc_broadcast_addr ( cidr2. clone ( ) ) ) ;
63- let cidr1_mask = calc_network_mask ( cidr1. clone ( ) ) ;
64- let cidr2_mask = calc_network_mask ( cidr2. clone ( ) ) ;
6585
66- //inclusion
67- if cidr1_net <= cidr2_net && cidr2_brd <= cidr1_brd {
68- return vec ! [ cidr1] ;
86+ // Merge two CIDR blocks
87+ fn merge ( cidr1 : Ipv4Cidr , cidr2 : Ipv4Cidr ) -> Option < Ipv4Cidr > {
88+ // Check wether cidr1 includes cidr2 vice versa
89+ if cidr1. network_addr ( ) <= cidr2. network_addr ( ) && cidr2. broadcast_addr ( ) <= cidr1. broadcast_addr ( ) {
90+ return Some ( cidr1) ;
6991 }
70- if cidr2_net <= cidr1_net && cidr1_brd <= cidr2_brd {
71- return vec ! [ cidr2] ;
92+ if cidr2 . network_addr ( ) <= cidr1 . network_addr ( ) && cidr1 . broadcast_addr ( ) <= cidr2 . broadcast_addr ( ) {
93+ return Some ( cidr2) ;
7294 }
7395
74- //adjascent
75- let cidr1_wrap_net = ipv4todec ( calc_network_addr ( gen_cidr ( dectoipv4 ( cidr1_net) , cidr1_mask - 1 ) ) ) ;
76- let cidr2_wrap_brd = ipv4todec ( calc_broadcast_addr ( gen_cidr ( dectoipv4 ( cidr2_net) , cidr2_mask - 1 ) ) ) ;
77- if cidr1_wrap_net == cidr1_net && cidr1_brd + 1 == cidr2_net && cidr2_wrap_brd == cidr2_brd {
78- return vec ! [ gen_cidr( dectoipv4( cidr1_net) , cidr1_mask - 1 ) ] ;
96+ // Check wether cidr1 is adjascent to cidr2 vice versa
97+ let cidr3 = cidr1. generate_wrap_cidr ( ) ;
98+ let cidr4 = cidr2. generate_wrap_cidr ( ) ;
99+ //println!("[{}-{}]{} == {}: {}", cidr1.to_string(), cidr2.to_string(), cidr3.to_string(), cidr4.to_string(), cidr3==cidr4);
100+ if cidr3 == cidr4 && cidr1 != cidr2 {
101+ return Some ( cidr3) ;
79102 }
80- return vec ! [ cidr1 , cidr2 ] ;
103+ return None ;
81104}
82105
83- // Check wether two CIDR blocks are adjascent
84- fn is_adjascent ( cidr1 : String , cidr2 : String ) -> bool {
85- let cidr2_net = ipv4todec ( calc_network_addr ( cidr2. clone ( ) ) ) ;
86- let cidr1_brd = ipv4todec ( calc_broadcast_addr ( cidr1. clone ( ) ) ) ;
87- return cidr1_brd + 1 == cidr2_net;
106+ // Check wether two CIDR blocks are not mergable but adjascent
107+ fn is_adjascent ( cidr1 : Ipv4Cidr , cidr2 : Ipv4Cidr ) -> bool {
108+ return u32:: from ( cidr1. broadcast_addr ( ) ) + 1 == u32:: from ( cidr2. network_addr ( ) ) ;
88109}
89110
111+
90112fn main ( ) {
91113 let stdin = io:: stdin ( ) ;
92114 let mut cidrs = Vec :: new ( ) ;
93115 for line in stdin. lock ( ) . lines ( ) {
94- //println!("{}", dectoipv4(ipv4todec(line.unwrap())+1));
95- cidrs. push ( line. unwrap ( ) ) ;
116+ let line = line. unwrap ( ) ;
117+ let line = line. as_str ( ) . trim ( ) ;
118+ if line. is_empty ( ) || line. starts_with ( '#' ) {
119+ continue ;
120+ }
121+ let cidr = match Ipv4Cidr :: from_str ( line) {
122+ Ok ( cidr) => cidr,
123+ Err ( e) => panic ! ( "Failed to parse {:?} as CIDR: {}" , line, e) ,
124+ } ;
125+ cidrs. push ( cidr) ;
96126 }
97127 //cidrs.sort();
98128 /*cidrs.sort_by(|a, b| {
@@ -103,29 +133,28 @@ fn main() {
103133 stack. push ( cidr) ;
104134 //println!("{:?}", stack);
105135 while stack. len ( ) >= 2 {
106- let m2 = stack. pop ( ) . unwrap ( ) ;
107- let m1 = stack. pop ( ) . unwrap ( ) ;
108- let merged = merge ( m1. clone ( ) , m2. clone ( ) ) ;
109- if merged. len ( ) == 1 {
110- //mergeable
111- stack. push ( merged[ 0 ] . clone ( ) ) ;
112- } else {
113- stack. push ( merged[ 0 ] . clone ( ) ) ;
114- if ! is_adjascent ( m1. clone ( ) , m2. clone ( ) ) {
115- for x in stack {
116- println ! ( "{}" , x) ;
136+ let cidr2 = stack. pop ( ) . unwrap ( ) ;
137+ let cidr1 = stack. pop ( ) . unwrap ( ) ;
138+ let merged = merge ( cidr1, cidr2) ;
139+ match merged {
140+ Some ( merged) => {
141+ stack. push ( merged) ;
142+ } ,
143+ None => {
144+ stack. push ( cidr1) ;
145+ if ! is_adjascent ( cidr1, cidr2) {
146+ for x in stack {
147+ println ! ( "{}" , x. to_string( ) ) ;
148+ }
149+ stack = Vec :: new ( ) ;
117150 }
118- stack = Vec :: new ( ) ;
119- }
120- stack. push ( merged[ 1 ] . clone ( ) ) ;
121- break ;
151+ stack. push ( cidr2) ;
152+ break ;
153+ } ,
122154 }
123155 }
124156 }
125157 for x in stack {
126- println ! ( "{}" , x) ;
158+ println ! ( "{}" , x. to_string ( ) ) ;
127159 }
128- /*let args: Vec<String> = env::args().collect();
129- let dec = dectoipv4(ipv4todec(&args[1]));
130- println!("{}", dec);*/
131160}
0 commit comments