Skip to content

Commit 0d95eb4

Browse files
committed
day 4 part 2 solution
1 parent 68f88ec commit 0d95eb4

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

04/2.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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

Comments
 (0)