82 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
<?php
 | 
						|
 | 
						|
/*
 | 
						|
 * Advent of Code 2016
 | 
						|
 * Day 4 (part 1 and 2)
 | 
						|
 */
 | 
						|
 | 
						|
function extractRoomInfo($input_line) {
 | 
						|
	if(preg_match("/(\S+)-(\d+)\[([^\]]*)\]/", $input_line, $output_array)) {
 | 
						|
		return array(
 | 
						|
			'room_name' => $output_array[1], 
 | 
						|
			'sector_id' => $output_array[2], 
 | 
						|
			'checksum' => $output_array[3]
 | 
						|
		);
 | 
						|
	}
 | 
						|
	return false;
 | 
						|
}
 | 
						|
 | 
						|
function generateChecksum($room_name) {
 | 
						|
	// calculate char occurrences
 | 
						|
	$char_count_array = count_chars(str_replace('-', '', $room_name), 1);
 | 
						|
 | 
						|
	// sort by occurrence count
 | 
						|
	arsort($char_count_array);
 | 
						|
 | 
						|
	// group chars into occurrence count
 | 
						|
	$dedupe = array();
 | 
						|
	foreach($char_count_array as $char => $occurrence) {
 | 
						|
		$dedupe[$occurrence][] = $char;
 | 
						|
	}
 | 
						|
	
 | 
						|
	// cross my fingers and hope this actually works
 | 
						|
	$checksum = '';
 | 
						|
	foreach($dedupe as $occurrence => $chars) {
 | 
						|
		sort($chars);
 | 
						|
		for($i = 0; $i < count($chars); $i++) {
 | 
						|
			$checksum .= chr($chars[$i]);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	// cut off the excess and return
 | 
						|
	return substr($checksum, 0, 5);
 | 
						|
}
 | 
						|
 | 
						|
function decryptRoomName($name, $sector_id) {
 | 
						|
	$key = $sector_id % 26; // this should work right?
 | 
						|
	$a_start = ord('a');
 | 
						|
	$output = '';
 | 
						|
 | 
						|
	for($i = 0; $i < strlen($name); $i++) {
 | 
						|
		$a = ord(substr($name, $i, 1));
 | 
						|
		if($a == ord('-'))
 | 
						|
			$output .= ' ';
 | 
						|
		else
 | 
						|
			$output .= chr($a_start + ((($a - $a_start) + $key) % 26));
 | 
						|
	}
 | 
						|
 | 
						|
	return $output;
 | 
						|
}
 | 
						|
 | 
						|
$input = file('day4_input.txt');
 | 
						|
//$input = array("aaaaa-bbb-z-y-x-123[abxyz]", "a-b-c-d-e-f-g-h-987[abcde]", "not-a-real-room-404[oarel]");
 | 
						|
 | 
						|
// Part 1
 | 
						|
$valid_room_sum = 0;
 | 
						|
$valid_rooms = array();
 | 
						|
foreach($input as $line) {
 | 
						|
	$room_info = extractRoomInfo($line);
 | 
						|
	$generated_checksum = generateChecksum($room_info['room_name']);
 | 
						|
	if($generated_checksum == $room_info['checksum']) {
 | 
						|
		$valid_rooms[] = $room_info;
 | 
						|
		$valid_room_sum += (int)$room_info['sector_id'];
 | 
						|
	}
 | 
						|
}
 | 
						|
echo "valid room sum: $valid_room_sum<br />\n";
 | 
						|
 | 
						|
// Part 2
 | 
						|
foreach($valid_rooms as $room) {
 | 
						|
	$decrypted_name = decryptRoomName($room['room_name'], (int)$room['sector_id']);
 | 
						|
	echo "room name: $decrypted_name, sector: {$room['sector_id']}<br />\n";
 | 
						|
}
 |