1
-
2
1
#[ derive( Debug ) ]
3
2
pub struct Trie {
4
3
children : [ Option < Box < Trie > > ; 5 ] ,
@@ -14,15 +13,14 @@ impl Trie {
14
13
}
15
14
16
15
fn index_stripe ( stripe : char ) -> usize {
17
- // allos us to use a super sparse children array
16
+ // allows us to use a super sparse children array
18
17
match stripe {
19
18
'b' => 0 ,
20
19
'g' => 1 ,
21
20
'r' => 2 ,
22
21
'u' => 3 ,
23
22
'w' => 4 ,
24
- _ => panic ! ( "That towel stripe is not allowed in this onsen" )
25
-
23
+ _ => panic ! ( "That towel stripe is not allowed in this onsen" ) ,
26
24
}
27
25
}
28
26
@@ -34,37 +32,36 @@ impl Trie {
34
32
current = current. children [ i] . get_or_insert_with ( || Box :: new ( Trie :: new ( ) ) ) ;
35
33
}
36
34
current. is_word = true ;
37
-
38
35
}
39
36
40
- pub fn get_prefixes < ' a > ( & self , towel : & ' a str ) -> Vec < & ' a str > {
37
+ pub fn get_prefixes < ' a > ( & self , towel : & ' a str ) -> Vec < & ' a str > {
41
38
let mut current = self ;
42
- let mut prefixes: Vec < & str > = vec ! [ ] ;
39
+ let mut prefixes: Vec < & str > = vec ! [ ] ;
43
40
44
- for ( len, stripe) in towel. chars ( ) . enumerate ( ) {
41
+ for ( len, stripe) in towel. chars ( ) . enumerate ( ) {
45
42
let i = Trie :: index_stripe ( stripe) ;
46
-
43
+
47
44
if let Some ( next) = & current. children [ i] {
48
45
if next. is_word {
49
46
prefixes. push ( & towel[ ..=len] )
50
47
}
51
48
current = next
52
49
} else {
53
- return prefixes
50
+ return prefixes;
54
51
}
55
52
}
56
53
prefixes
57
54
}
58
55
59
56
pub fn is_possible ( & self , towel : & str ) -> bool {
60
57
let n = towel. len ( ) ;
61
- let mut memo = vec ! [ false ; n+ 1 ] ;
58
+ let mut memo = vec ! [ false ; n + 1 ] ;
62
59
memo[ 0 ] = true ;
63
60
for start in 0 ..n {
64
61
if memo[ start] {
65
62
for prefix in self . get_prefixes ( & towel[ start..] ) {
66
63
let end = start + prefix. len ( ) ;
67
- memo[ end] =true ;
64
+ memo[ end] = true ;
68
65
if n == end {
69
66
return true ;
70
67
}
@@ -73,6 +70,25 @@ impl Trie {
73
70
}
74
71
memo[ n]
75
72
}
73
+
74
+ pub fn count_possible ( & self , towel : & str ) -> u64 {
75
+ // this is basically identical to is_possible
76
+ // but without the early exit
77
+ let n = towel. len ( ) ;
78
+ let mut memo = vec ! [ 0 ; n + 1 ] ;
79
+ memo[ 0 ] = 1 ;
80
+ for start in 0 ..n {
81
+ if memo[ start] > 0 {
82
+ for prefix in self . get_prefixes ( & towel[ start..] ) {
83
+ let end = start + prefix. len ( ) ;
84
+ if end <= n {
85
+ memo[ end] += memo[ start] ;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ memo[ n]
91
+ }
76
92
}
77
93
78
94
#[ cfg( test) ]
@@ -83,23 +99,41 @@ mod test {
83
99
let mut t = Trie :: new ( ) ;
84
100
t. insert ( "bwg" ) ;
85
101
t. insert ( "bwgr" ) ;
86
-
102
+
87
103
assert_eq ! ( t. get_prefixes( "bwgrra" ) , vec![ "bwg" , "bwgr" ] ) ;
88
104
}
89
105
90
106
#[ test]
91
107
fn test_possible ( ) {
92
108
let mut t = Trie :: new ( ) ;
93
109
[ "r" , "wr" , "b" , "g" , "bwu" , "rb" , "gb" , "br" ]
94
- . iter ( ) . for_each ( |p| t. insert ( p) ) ;
110
+ . iter ( )
111
+ . for_each ( |p| t. insert ( p) ) ;
95
112
96
- // assert_eq!(t.is_possible("brwrr"), true);
97
- // assert_eq!(t.is_possible("bggr"), true);
98
- // assert_eq!(t.is_possible("gbbr"), true);
99
- // assert_eq!(t.is_possible("rrbgbr"), true);
100
- // assert_eq!(t.is_possible("ubwu"), false);
101
- // assert_eq!(t.is_possible("bwurrg"), true);
102
- // assert_eq!(t.is_possible("brgr"), true);
113
+ assert_eq ! ( t. is_possible( "brwrr" ) , true ) ;
114
+ assert_eq ! ( t. is_possible( "bggr" ) , true ) ;
115
+ assert_eq ! ( t. is_possible( "gbbr" ) , true ) ;
116
+ assert_eq ! ( t. is_possible( "rrbgbr" ) , true ) ;
117
+ assert_eq ! ( t. is_possible( "ubwu" ) , false ) ;
118
+ assert_eq ! ( t. is_possible( "bwurrg" ) , true ) ;
119
+ assert_eq ! ( t. is_possible( "brgr" ) , true ) ;
103
120
assert_eq ! ( t. is_possible( "bbrgwb" ) , false ) ;
104
121
}
105
- }
122
+
123
+ #[ test]
124
+ fn count_possible ( ) {
125
+ let mut t = Trie :: new ( ) ;
126
+ [ "r" , "wr" , "b" , "g" , "bwu" , "rb" , "gb" , "br" ]
127
+ . iter ( )
128
+ . for_each ( |p| t. insert ( p) ) ;
129
+
130
+ assert_eq ! ( t. count_possible( "brwrr" ) , 2 ) ;
131
+ assert_eq ! ( t. count_possible( "bggr" ) , 1 ) ;
132
+ assert_eq ! ( t. count_possible( "gbbr" ) , 4 ) ;
133
+ assert_eq ! ( t. count_possible( "rrbgbr" ) , 6 ) ;
134
+ assert_eq ! ( t. count_possible( "ubwu" ) , 0 ) ;
135
+ assert_eq ! ( t. count_possible( "bwurrg" ) , 1 ) ;
136
+ assert_eq ! ( t. count_possible( "brgr" ) , 2 ) ;
137
+ assert_eq ! ( t. count_possible( "bbrgwb" ) , 0 ) ;
138
+ }
139
+ }
0 commit comments