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";
|
||
|
}
|