From 9dff459bcbf948a19e87b945b55319575ff36394 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Tue, 7 Dec 2021 08:34:57 -0800 Subject: [PATCH] yay --- src/bin/day7.rs | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/bin/day7.rs diff --git a/src/bin/day7.rs b/src/bin/day7.rs new file mode 100644 index 0000000..a7f45ca --- /dev/null +++ b/src/bin/day7.rs @@ -0,0 +1,118 @@ +const TEST_DATA: &[u64] = &[16, 1, 2, 0, 4, 2, 7, 1, 2, 14]; +const REAL_DATA: &[u64] = &[ + 1101, 1, 29, 67, 1102, 0, 1, 65, 1008, 65, 35, 66, 1005, 66, 28, 1, 67, 65, 20, 4, 0, 1001, 65, + 1, 65, 1106, 0, 8, 99, 35, 67, 101, 99, 105, 32, 110, 39, 101, 115, 116, 32, 112, 97, 115, 32, + 117, 110, 101, 32, 105, 110, 116, 99, 111, 100, 101, 32, 112, 114, 111, 103, 114, 97, 109, 10, + 616, 0, 1633, 1048, 833, 967, 161, 22, 823, 601, 603, 538, 340, 798, 1053, 400, 54, 41, 54, + 296, 1336, 1013, 9, 763, 650, 313, 15, 177, 1289, 307, 741, 314, 289, 63, 183, 503, 764, 187, + 225, 596, 273, 387, 1, 1165, 61, 19, 78, 514, 355, 605, 103, 483, 291, 1781, 1137, 398, 593, + 38, 444, 204, 274, 528, 147, 131, 1021, 812, 430, 710, 257, 1408, 1587, 517, 773, 218, 99, 357, + 301, 543, 1668, 11, 311, 350, 373, 145, 507, 325, 1006, 696, 607, 281, 433, 302, 148, 519, 846, + 1528, 766, 158, 51, 850, 216, 1320, 690, 338, 298, 631, 560, 306, 5, 888, 242, 1230, 1694, + 1330, 570, 184, 946, 97, 96, 272, 537, 312, 1246, 847, 138, 325, 28, 253, 785, 483, 906, 412, + 28, 178, 485, 828, 823, 1035, 1001, 108, 1068, 90, 308, 223, 18, 191, 1269, 39, 238, 307, 7, + 643, 1546, 203, 254, 371, 402, 207, 666, 786, 793, 361, 441, 105, 15, 421, 1748, 255, 152, + 1376, 626, 296, 707, 4, 627, 885, 49, 316, 34, 379, 1591, 39, 1087, 135, 1515, 69, 725, 419, + 924, 414, 78, 1169, 8, 1331, 2, 771, 1295, 570, 323, 9, 406, 75, 42, 1003, 180, 188, 174, 145, + 128, 625, 1312, 85, 427, 56, 15, 87, 449, 831, 906, 34, 186, 609, 1597, 531, 104, 1034, 615, + 608, 1338, 192, 280, 982, 334, 853, 1155, 194, 124, 205, 1384, 135, 906, 239, 761, 1357, 16, + 328, 623, 3, 1432, 634, 1698, 31, 981, 347, 75, 222, 896, 77, 1204, 1272, 711, 106, 772, 1366, + 279, 162, 98, 487, 1281, 188, 71, 307, 398, 470, 40, 12, 459, 449, 984, 1271, 260, 1132, 493, + 1117, 129, 36, 1040, 947, 570, 89, 853, 373, 102, 771, 107, 266, 106, 59, 485, 61, 87, 353, + 164, 278, 1489, 542, 442, 4, 62, 788, 63, 130, 723, 919, 1169, 327, 459, 431, 1107, 992, 1162, + 1287, 901, 838, 638, 261, 307, 761, 533, 119, 336, 4, 422, 173, 172, 64, 222, 531, 998, 1250, + 1007, 20, 1231, 69, 289, 531, 757, 185, 519, 184, 1139, 369, 2, 1102, 857, 339, 1267, 1357, + 217, 774, 1352, 23, 136, 2, 1389, 253, 87, 883, 28, 247, 292, 15, 332, 69, 170, 20, 544, 75, + 850, 310, 1137, 301, 155, 265, 100, 842, 189, 7, 584, 40, 168, 22, 548, 7, 30, 1027, 744, 1294, + 329, 100, 1255, 424, 515, 460, 163, 375, 26, 618, 275, 1012, 935, 160, 181, 84, 186, 990, 1208, + 152, 753, 508, 590, 578, 81, 625, 600, 430, 306, 311, 156, 5, 56, 187, 25, 249, 1090, 316, 224, + 173, 199, 71, 221, 1219, 335, 87, 260, 607, 121, 25, 1326, 473, 224, 92, 87, 734, 179, 64, 325, + 320, 117, 302, 1247, 879, 716, 984, 284, 239, 738, 30, 90, 61, 844, 997, 823, 387, 956, 842, + 580, 540, 648, 1947, 32, 63, 380, 873, 1086, 142, 512, 206, 742, 584, 157, 858, 1300, 992, 311, + 139, 906, 693, 1, 36, 1320, 236, 48, 58, 32, 147, 34, 229, 497, 1, 657, 616, 309, 494, 1419, + 264, 595, 729, 1374, 984, 74, 446, 436, 77, 1516, 156, 915, 565, 159, 269, 263, 442, 775, 12, + 6, 337, 115, 971, 598, 87, 1283, 533, 991, 204, 1382, 1204, 277, 27, 801, 260, 198, 426, 89, + 72, 458, 1164, 571, 1329, 501, 1547, 125, 376, 865, 642, 268, 626, 167, 429, 901, 623, 103, + 100, 1064, 125, 450, 695, 28, 1470, 469, 187, 119, 1363, 44, 485, 1243, 1163, 507, 139, 147, + 72, 100, 160, 624, 506, 1360, 66, 444, 581, 729, 531, 701, 1091, 178, 476, 22, 926, 354, 88, + 1076, 946, 213, 38, 43, 125, 291, 714, 113, 54, 1214, 1067, 641, 374, 411, 64, 1364, 415, 133, + 752, 372, 212, 19, 1941, 780, 902, 512, 852, 157, 8, 175, 90, 913, 125, 771, 764, 381, 947, + 572, 391, 313, 249, 201, 106, 1500, 487, 107, 868, 464, 984, 1471, 550, 642, 196, 571, 18, 306, + 293, 659, 1274, 290, 352, 0, 528, 754, 564, 316, 685, 57, 293, 75, 584, 251, 1107, 217, 11, 21, + 329, 493, 175, 600, 259, 380, 30, 148, 556, 136, 180, 12, 26, 507, 199, 3, 0, 143, 87, 1452, + 359, 989, 170, 64, 269, 17, 1018, 105, 317, 289, 127, 275, 269, 359, 511, 690, 205, 423, 356, + 19, 177, 260, 789, 51, 119, 210, 1151, 707, 869, 194, 773, 159, 216, 759, 16, 161, 47, 1254, + 293, 54, 504, 432, 1230, 213, 26, 253, 424, 98, 1515, 162, 346, 326, 12, 122, 79, 210, 912, 55, + 705, 597, 369, 1381, 284, 1163, 316, 34, 384, 36, 1254, 1455, 994, 60, 1395, 476, 100, 38, 726, + 198, 605, 103, 489, 361, 9, 24, 158, 1056, 264, 1103, 175, 1423, 266, 45, 93, 271, 331, 673, + 788, 48, 12, 580, 697, 593, 480, 268, 559, 302, 87, 281, 6, 401, 170, 90, 939, 543, 223, 137, + 809, 139, 182, 571, 68, 1112, 20, 1004, 1090, 249, 1435, 267, 10, 375, 504, 906, 946, 1503, + 1362, 184, 233, 112, 1058, 16, 235, 548, 563, 162, 102, 746, 439, 105, 259, 27, 19, 817, 1444, + 119, 175, 341, 130, 202, 31, 432, 480, 710, 1127, 682, 454, 134, 823, 168, 276, 113, 914, 1112, + 118, 10, 1041, 902, 141, 1428, 282, 485, 353, 589, 906, 987, 488, 144, 154, 25, 930, 368, 261, + 176, 168, 85, 814, 1915, 248, 49, 1012, 3, 143, 951, 30, 411, 336, 46, 1383, 26, 857, 1650, + 192, 1477, 194, 73, 154, 91, 287, 229, 144, 675, 989, 135, 360, 74, 60, 223, 219, 625, 182, + 793, +]; + +#[derive(Copy, Clone, PartialEq)] +enum CostMetric { + OneToOne, + Compounding, +} + +fn distance_from(metric: CostMetric, x: u64, y: u64) -> u64 { + match metric { + CostMetric::OneToOne if x > y => x - y, + CostMetric::OneToOne => y - x, + CostMetric::Compounding if x > y => distance_from(metric, y, x), + CostMetric::Compounding => { + let diff = y - x; + (diff * (diff + 1)) / 2 + } + } +} + +#[test] +fn compounding_distance_checks() { + assert_eq!(66, distance_from(CostMetric::Compounding, 16, 5)); + assert_eq!(10, distance_from(CostMetric::Compounding, 1, 5)); + assert_eq!(6, distance_from(CostMetric::Compounding, 2, 5)); + assert_eq!(15, distance_from(CostMetric::Compounding, 0, 5)); + assert_eq!(1, distance_from(CostMetric::Compounding, 4, 5)); +} + +fn minimum_fuel(metric: CostMetric, positions: &[u64]) -> u64 { + let maximum_value = *positions.iter().max().unwrap() as usize; + let mut distances = vec![0; maximum_value + 1]; + + for position in positions.iter() { + for (from_point, cur_value) in distances.iter_mut().enumerate() { + *cur_value += distance_from(metric, from_point as u64, *position); + } + } + + *distances.iter().min().unwrap() +} + +#[test] +fn regression() { + assert_eq!(37, minimum_fuel(CostMetric::OneToOne, TEST_DATA)); + assert_eq!(336721, minimum_fuel(CostMetric::OneToOne, REAL_DATA)); + + assert_eq!(168, minimum_fuel(CostMetric::Compounding, TEST_DATA)); + assert_eq!(91638945, minimum_fuel(CostMetric::Compounding, REAL_DATA)); +} + +fn main() { + println!( + "Minimul fuel for test data: {} or {}, depending on fuel metric", + minimum_fuel(CostMetric::OneToOne, TEST_DATA), + minimum_fuel(CostMetric::Compounding, TEST_DATA) + ); + println!( + "Minimul fuel for real data: {} or {}, depending on fuel metric", + minimum_fuel(CostMetric::OneToOne, REAL_DATA), + minimum_fuel(CostMetric::Compounding, REAL_DATA) + ); +}