1
+ #include < iostream>
2
+ #include < fstream>
3
+ #include < iterator>
4
+ #include < string>
5
+ #include < vector>
6
+ #include < array>
7
+ #include < algorithm>
8
+ #include < numeric>
9
+
10
+ #include < boost/spirit/include/qi.hpp>
11
+
12
+ namespace qi = boost::spirit::qi;
13
+
14
+ size_t constexpr game_size{ 5 };
15
+
16
+
17
+ using value_t = std::pair< uint64_t , bool >;
18
+ using line_t = std::array< value_t , game_size >;
19
+ using card_t = std::array< line_t , game_size * 2 >;
20
+ using cards_t = std::vector< card_t >;
21
+
22
+
23
+ int main ( int argc, char * argv[] )
24
+ {
25
+ if ( argc < 2 )
26
+ return 0 ;
27
+
28
+ std::ifstream ifs ( argv[ 1 ] );
29
+
30
+ std::vector< uint64_t > game;
31
+ std::string sinp;
32
+ ifs >> sinp;
33
+ if ( !qi::phrase_parse ( sinp.cbegin (), sinp.cend (), qi::int_ % ' ,' , qi::space, game ) )
34
+ {
35
+ std::cout << " parse error" << std::endl;
36
+ return 0 ;
37
+ }
38
+
39
+ cards_t cards;
40
+ while ( !ifs.eof () )
41
+ {
42
+ std::array< uint64_t , game_size * game_size > nums;
43
+ for ( uint64_t & n : nums )
44
+ ifs >> n;
45
+
46
+ card_t card;
47
+ for ( size_t i ( 0 ); i != game_size; ++i )
48
+ for ( size_t j ( 0 ); j != game_size; ++j )
49
+ {
50
+ card[ i ][ j ] = { nums[ i * game_size + j ], false };
51
+ card[ i + 5 ][ j ] = { nums[ j * game_size + i ], false };
52
+ }
53
+
54
+ cards.push_back ( std::move ( card ) );
55
+ }
56
+
57
+ cards_t out;
58
+ uint64_t last_number{ 0 };
59
+ for ( uint64_t const & number : game )
60
+ {
61
+ for ( card_t & card : cards )
62
+ {
63
+ for ( line_t & line : card )
64
+ {
65
+ auto i = std::find ( line.begin (), line.end (), std::make_pair ( number, false ) );
66
+ if ( i != line.end () )
67
+ i->second = true ;
68
+ }
69
+ }
70
+
71
+ auto outed{
72
+ std::remove_if ( cards.begin (), cards.end (),
73
+ []( card_t const & card ) -> bool
74
+ {
75
+ return std::transform_reduce ( card.begin (), card.end (),
76
+ false ,
77
+ std::logical_or (),
78
+ []( line_t const & line ) -> bool
79
+ {
80
+ return std::transform_reduce ( line.begin (), line.end (),
81
+ true ,
82
+ std::logical_and (),
83
+ []( value_t const & v ) -> bool
84
+ {
85
+ return v.second ;
86
+ }
87
+ );
88
+ }
89
+ );
90
+ }
91
+ )
92
+ };
93
+ if ( outed != cards.end () )
94
+ {
95
+ out.insert ( out.end (), outed, cards.end () );
96
+ cards.erase ( outed, cards.end () );
97
+ }
98
+
99
+ last_number = number;
100
+ if ( cards.empty () )
101
+ break ;
102
+ }
103
+
104
+ if ( !out.empty () )
105
+ {
106
+ card_t const & card ( out.back () );
107
+
108
+ uint64_t const sum_unmarked{
109
+ std::transform_reduce ( card.begin (), card.begin () + game_size,
110
+ 0ULL ,
111
+ std::plus (),
112
+ []( line_t const & line ) -> uint64_t
113
+ {
114
+ return std::transform_reduce ( line.begin (), line.end (),
115
+ 0ULL ,
116
+ std::plus (),
117
+ []( value_t const & v ) -> uint64_t
118
+ {
119
+ return v.second ? 0ULL : v.first ;
120
+ }
121
+ );
122
+ }
123
+ )
124
+ };
125
+
126
+ std::cout << " result = " << ( last_number * sum_unmarked ) << std::endl;
127
+
128
+ return 0 ;
129
+ }
130
+
131
+ return 0 ;
132
+ }
0 commit comments