Add 2024 Quest 4

This commit is contained in:
Chris Alge 2024-11-09 14:56:27 +01:00
parent 6a9783b7c6
commit abdce07d58
10 changed files with 832 additions and 0 deletions

View file

@ -0,0 +1,6 @@
[package]
name = "day04_royal_smiths_puzzle"
version = "0.1.0"
edition = "2021"
[dependencies]

View file

@ -0,0 +1,33 @@
Part I
One of the grand tournament's most time-honoured traditions is the Master of the Royal Forge challenge. Knights proceed to the colossal forge, where the song of steel echoes from afar. The King's Smith awaits, silently gesturing towards a section of the courtyard where wooden logs have been meticulously arranged. Massive nails, with heads the size of a human hand, are embedded in the logs. Next to each log lies a hammer. Each contender stands by one.
The blacksmith explains the rules of the first round. Several nails have been driven into the top of the log, each protruding at a different height. You must drive the nails into the logs so that their heads form a perfectly straight line.
You begin hammering, but it's hard to tell if the nail has moved even a fraction. It seems this will be a test of endurance... To pass the time, you note the length each nail protrudes. It turns out that they are precisely measured, each expressed in whole units. Additionally, you notice that each nail head has a small black dot in the center. Examining your hammer closely, you find a similar dot on its head. You take a swing, aiming to align the dots upon impact. The nail drives into the log exactly one unit deeper with each strike! It's not about endurance, but precision and accuracy! The blacksmith glances your way and smiles knowingly. You know the length of all the nails, so you can calculate how many strikes at minimum it will take to align them all perfectly.
Example based on the following notes:
3
4
7
8
The lengths of the nails are 3, 4, 7, and 8 units. The shortest nail is 3 units, and the rest must be levelled to this height.
It takes 1 strike to drive the 4-unit nail to 3 units; 4 strikes to bring the 7-unit nail down to 3 units; and 5 strikes to do the same for the 8-unit nail.
In total, you need 10 strikes of the hammer.
What is the minimum number of hammer strikes needed to level all the nails?
Part II
As soon as the last nail is perfectly aligned with the others, the log begins to rotate with a soft creak, revealing another side bristling with many more nails, each awaiting its turn to be levelled. Despite the seemingly endless challenge, the rules remain unchanged: your task is to hammer each nail into the log until their heads are perfectly level, forming a straight, unbroken line across the surface of the log. You take a deep breath, knowing that precision and patience will once again be your greatest allies in this test of skill.
What is the minimum number of hammer strikes needed to level all the nails?
Part III
You're getting the hang of it and swiftly complete the task. The log rotates again, revealing another section filled with nails. This time, however, the nails have additional white dots. Inspecting your hammer once more, you notice that the other side of the head has a corresponding white dot. Curious, you align the dots and strike. To your surprise, the nail moves up exactly one unit!
The nails are much longer than before, so it would be wise to level them in the most efficient manner possible. To achieve this, you must first determine the optimal height to which the nails should be driven or pulled so that the total number of hammer strikes is minimized.
Example based on the following notes:
2
4
5
6
8
The lengths of the nails are 2, 4, 5, 6, and 8 units. Assuming you want to level them all to 5 units, you need to hit the 2-unit nail 3 times and the 4-unit nail once on their white dots, and strike the 6-unit nail once and the 8-unit nail 3 times on their black dots.
In total, this requires 8 hammer strikes, which is the minimal number for this nail set.
What is the minimum number of hammer strikes needed to level all the nails?

View file

@ -0,0 +1,69 @@
fn strikes_to_align(components: &[isize]) -> isize {
components.iter().sum::<isize>() - components.len() as isize * *components.iter().min().unwrap_or(&0)
}
fn strikes_to_align_omni(components: &[isize]) -> isize {
let sum: isize = components.iter().sum();
let len = components.len() as isize;
let mut estimate = (sum + len/2) / len;
let mut y0: isize = components.iter().map(|c| c.abs_diff(estimate) as isize).sum();
let mut y1: isize = components.iter().map(|c| c.abs_diff(estimate+1) as isize).sum();
let y_m1: isize = components.iter().map(|c| c.abs_diff(estimate-1) as isize).sum();
let step;
if y1 < y0 {
step = 1;
} else if y_m1 < y0 {
step = -1;
y1 = y_m1;
} else {
return y0;
}
loop {
y0 = y1;
estimate += step;
y1 = components.iter().map(|c| c.abs_diff(estimate+step) as isize).sum();
if y1 > y0 {
return y0;
}
}
}
pub fn run(input: &str, part: usize) -> Result<isize, std::num::ParseIntError> {
let nails: Vec<_> = input.lines().map(|l| l.parse::<isize>()).collect::<Result<Vec<_>, _>>()?;
match part {
1 | 2 => Ok(strikes_to_align(&nails)),
3 => Ok(strikes_to_align_omni(&nails)),
_ => panic!("Illegal part number"),
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::read_to_string;
fn read_file(name: &str) -> String {
read_to_string(name).expect(&format!("Unable to read file: {name}")[..]).trim().to_string()
}
#[test]
fn test_sample() {
let expected = [10, 10, 8];
for part in 1..=3 {
let sample_input = read_file(&format!("tests/sample{part}"));
assert_eq!(run(&sample_input, part), Ok(expected[part-1]));
}
}
#[test]
fn test_challenge() {
let expected = [64, 815526, 120375970];
for part in 1..=3 {
let challenge_input = read_file(&format!("tests/challenge{part}"));
assert_eq!(run(&challenge_input, part), Ok(expected[part-1]));
}
}
}

View file

@ -0,0 +1,11 @@
12
14
16
10
13
15
12
19
12
11
7

View file

@ -0,0 +1,200 @@
6082
1865
5738
4635
3988
3243
4643
2652
7304
4098
6339
4755
3243
8262
4041
8375
3758
2784
8216
7926
3982
3780
3786
9152
3340
8398
5463
2600
7326
8477
1873
1313
4471
3264
5474
7356
8565
2873
9301
3903
4005
8730
8243
3154
2908
7835
5592
7741
1737
1958
3141
1746
5073
9579
2553
2611
3343
1854
4861
2236
3106
9639
5351
6897
9716
7188
2084
3210
7802
5962
2424
7972
4639
2578
9158
7868
8363
6382
3779
3487
3874
7805
5529
9918
6173
4657
1923
1965
9826
1841
2116
6401
7200
8410
4467
9378
7245
4699
1609
1863
6472
1407
6239
3828
4600
2076
7195
5484
2222
4011
6985
6547
6466
1589
2873
4937
3804
6836
6020
5492
7866
7691
4027
5208
9370
9789
6878
8439
1507
2202
9265
9976
4596
1314
1114
9629
9558
2818
6102
1106
5695
9519
7672
6114
1966
1641
1937
8732
4166
2280
7451
3612
3055
4725
3379
7047
6048
7307
6854
1292
8415
9739
1778
9352
8534
5409
3214
1839
4898
2932
1354
1147
6963
5119
7908
4399
2698
5905
5502
4904
5810
7188
9260
2151
7545
5538
9677
5372
1133
5391
1339
1420
3729
5255
7724
3246
6212
5542
5845
1262

View file

@ -0,0 +1,500 @@
27929850
27665140
27862080
27283118
27549203
27098090
27865186
27650904
27315998
27950285
27543118
27556568
27849523
27234930
27973527
27356710
27987741
27556730
27245257
27201087
27129556
27136389
27070990
27322803
27453359
27836122
27921828
27860361
27856839
27896116
27125454
27664237
27578064
27183509
27698624
27335769
27960193
27416757
27069473
27614316
27472567
27763831
27454971
27043009
27213487
27498773
27504888
27723629
27440421
27479140
27544780
27551694
27020369
27108074
27166681
27122196
27687166
27400493
27856154
27436309
27717500
27127029
27735457
27445307
27197775
27662280
27543294
27786331
27132353
27468611
27256152
27699864
27898298
27217549
27242136
27084362
27949994
27158541
27261679
27428284
27476407
27436586
27626038
27714903
27548237
27920058
27852366
27679707
27228880
27848202
27899442
27366922
27564900
27989306
27174453
27435802
27400776
27912611
27997319
27671743
27523999
27366511
27392176
27030893
27780810
27721096
27547911
27014595
27026304
27875990
27863804
27065720
27273994
27902913
27120827
27038426
27226313
27387880
27595092
27859540
27403337
27930727
27724521
27826169
27029138
27821199
27183537
27088280
27852941
27978849
27276894
27491222
27659004
27658196
27275189
27759673
27026386
27075466
27406510
27842115
27284130
27563629
27267899
27237900
27307761
27377935
27901874
27949465
27775551
27848645
27143468
27598222
27380527
27347405
27571115
27879045
27433174
27575497
27478871
27790849
27239194
27090427
27705474
27312241
27538862
27078500
27529479
27942995
27590491
27973927
27729899
27892572
27760173
27675885
27650116
27806869
27763983
27177288
27065207
27807043
27636878
27417583
27007363
27576919
27289259
27856150
27784768
27536023
27182638
27555285
27037848
27134965
27222747
27841585
27460252
27289700
27170366
27586954
27052819
27643659
27175881
27509937
27837772
27148866
27447775
27697568
27556825
27159973
27200327
27062327
27946819
27227890
27476196
27502677
27624517
27549137
27649819
27958868
27656885
27595260
27306391
27820057
27171783
27031278
27567723
27015275
27033255
27159694
27239814
27839706
27972998
27377627
27519736
27257476
27927181
27016785
27698740
27117924
27829899
27775580
27195610
27821690
27956976
27775064
27533510
27349096
27410304
27474262
27322583
27254492
27276750
27431955
27049104
27183458
27568440
27553651
27130888
27345986
27490866
27150873
27319868
27368671
27918518
27079670
27954053
27324034
27571299
27220834
27268925
27567831
27637670
27947384
27999010
27510083
27399345
27609460
27609419
27709725
27418719
27673007
27921614
27132481
27423547
27942405
27441864
27873206
27243562
27335406
27166121
27674234
27259061
27533603
27990423
27386401
27557232
27255604
27321117
27530684
27707137
27182653
27332364
27559051
27894533
27759162
27392081
27079231
27657229
27634889
27785980
27896976
27834058
27531115
27711706
27231097
27574942
27149531
27209934
27627761
27875881
27837564
27145986
27915124
27300809
27461518
27811788
27687153
27175470
27441923
27520086
27891431
27617765
27951048
27453327
27863927
27990128
27820242
27140586
27385275
27312871
27734872
27252527
27019820
27441292
27767035
27392215
27258481
27499666
27413436
27124486
27675893
27798114
27515384
27551788
27250373
27622491
27502004
27916162
27452577
27780256
27209777
27442443
27968117
27725442
27113430
27758971
27467736
27369190
27754764
27599257
27721679
27177032
27871473
27494608
27528465
27592312
27804009
27232972
27002291
27365139
27609169
27437517
27207866
27177329
27342362
27330520
27078076
27942038
27683865
27790166
27464313
27946830
27922513
27853191
27866403
27554184
27967898
27553521
27531038
27820438
27620147
27034647
27915623
27571604
27504397
27467883
27767761
27171107
27345609
27397109
27343665
27957256
27957676
27721276
27637243
27104435
27185326
27588123
27808998
27150710
27413102
27472519
27807301
27983786
27206492
27288733
27084609
27999203
27734639
27771240
27476651
27547567
27544497
27814147
27812527
27438147
27976060
27523202
27127711
27641803
27722392
27540974
27745462
27935554
27866587
27073448
27395065
27831659
27013465
27721802
27223598
27284684
27651368
27344315
27252747
27402756
27975767
27009556
27075012
27432616
27688742
27409775
27319929
27404651
27550707
27483904
27666549
27152397
27302845
27964751
27935580
27526100
27779551
27475313
27247354
27590500
27876596
27943397
27827561
27072631
27002908
27804819
27443447
27741516
27601585
27450915
27189864
27206111
27240439
27055348
27830726
27865037
27828382
27806805
27520431
27535931
27300146
27546434
27446505
27295499
27144781

View file

@ -0,0 +1,4 @@
3
4
7
8

View file

@ -0,0 +1,4 @@
3
4
7
8

View file

@ -0,0 +1,5 @@
2
4
5
6
8