Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdint.h>
- // priority is 1 to 52, for a-zA-Z
- int priority( char letter ) {
- return (islower(letter) ? letter - 'a' + 1
- : letter - 'A' + 27);
- }
- // use bits to do a set on letters, trailing zeros is priority
- uint64_t as_bit_set( const char str[], int length ) {
- uint64_t set = 0;
- for (int i = 0; i < length; i++) {
- set |= (uint64_t) 1 << priority( str[i] );
- }
- return (set);
- }
- // Get trailing zeros after only remaining bit in set is the priority.
- // Simple, but just as fast as __builtin_ctzl or a binary search on my machine.
- int bit_priority( uint64_t bit ) {
- int pri = 0;
- while (bit >>= 1) {
- pri++;
- }
- return (pri);
- }
- int main() {
- char line[80];
- int part1 = 0;
- int part2 = 0;
- // state machine variables for part 2
- int state = 0;
- uint64_t badge;
- while (fgets( line, sizeof(line), stdin ) != NULL) {
- // part 1 - intersection of compartments
- const int half = strlen( line ) / 2;
- const uint64_t comp1 = as_bit_set( line, half );
- const uint64_t comp2 = as_bit_set( &line[half], half );
- uint64_t inter = comp1 & comp2;
- part1 += bit_priority( inter );
- // part 2 - union to get full sack, intersect groups of three
- uint64_t all = comp1 | comp2;
- // state machine
- state = (state + 1) % 3;
- if (state == 1) {
- badge = all; // new badge
- } else {
- badge &= all; // intersect with sack
- if (state == 0) {
- part2 += bit_priority( badge );
- }
- }
- }
- printf( "Part 1: %d\n", part1 );
- printf( "Part 2: %d\n", part2 );
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement