Finish day 14

This commit is contained in:
Kienan Stewart 2020-12-14 03:27:59 -05:00
parent 0035850050
commit d39285ca0f
3 changed files with 907 additions and 0 deletions

27
day14/build.zig Normal file
View File

@ -0,0 +1,27 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b.standardTargetOptions(.{});
// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("day14", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

584
day14/input Normal file
View File

@ -0,0 +1,584 @@
mask = 1X11X010X000X0X101X00100011X10100111
mem[40278] = 36774405
mem[51306] = 55175378
mem[31036] = 805355
mem[8433] = 48148
mem[58481] = 45466
mask = 1000101X11001XXX00X01110X1X000XX0100
mem[42362] = 2765432
mem[20493] = 213778
mem[52954] = 756325
mask = 10010000X00X1010000101X0010X001X1X10
mem[34108] = 155448
mem[19047] = 166539692
mask = 1X0000111X0X10100X10X1110010X0100000
mem[44380] = 108787272
mem[50688] = 178803
mem[13224] = 18328
mem[47270] = 41220136
mem[1679] = 5379693
mem[25086] = 5316
mask = 100010X011001X1000X1000XXX0000X010X0
mem[8433] = 12191
mem[45074] = 466358
mem[57607] = 88673989
mem[1764] = 3258736
mask = X0011010110010010000X00100100X1001X0
mem[42636] = 8106931
mem[26732] = 819582135
mem[61324] = 115576
mem[46608] = 259438
mem[62850] = 325
mask = 11XX001111001X1001110X1XXX1110001X0X
mem[52922] = 2111
mem[39872] = 2919426
mem[49237] = 13351029
mem[25369] = 403711
mem[25714] = 525
mem[11361] = 930295699
mask = 100010001100X110X0111000X000X00X0000
mem[55023] = 398985
mem[1543] = 794
mem[47160] = 65745
mask = 1000001011X010XX00001001010X11101X01
mem[3993] = 6186451
mem[15936] = 678
mem[12520] = 889
mask = 110010XX10X0101X01X011X1010X00001100
mem[21281] = 1112
mem[1813] = 834
mem[23778] = 88
mem[877] = 4305190
mem[41759] = 688804
mem[31991] = 4165476
mask = 1000X0101X001010000X10X00X00X01X00X1
mem[62604] = 118285948
mem[25086] = 804036
mem[52954] = 414491
mem[61838] = 14920
mem[12372] = 14382
mask = XXX1X00010001000X00X101X001000X01111
mem[38767] = 23779
mem[15107] = 3739
mem[19591] = 35246
mem[64406] = 27640
mem[47997] = 1470326
mask = 1011101011X0X1X100X0X11110010100X011
mem[57638] = 42095143
mem[18633] = 7407282
mem[23584] = 1861
mem[9800] = 35320
mem[25647] = 17074
mask = X0XX10X0100X1010X000X00011X100001101
mem[19475] = 11720838
mem[22303] = 3396
mem[31371] = 963
mem[27119] = 913
mem[48910] = 28628571
mem[48457] = 3430746
mask = 1000101X1XX011010000010001000011XX00
mem[42746] = 439123
mem[26673] = 186688
mem[9335] = 104841
mem[47814] = 814
mem[31051] = 23
mem[26161] = 192849624
mask = 110000X1X100101X011X001X0011XX011001
mem[10584] = 8361
mem[21594] = 83379
mem[47043] = 458757662
mem[1767] = 3878
mem[37986] = 5338251
mem[59740] = 779934
mem[22725] = 495512
mask = 10110X10100010X1011010X00010X11101X1
mem[32885] = 15961
mem[49329] = 11659
mem[49589] = 883656
mem[58578] = 3299
mem[13410] = 16573
mem[57567] = 56589
mem[17446] = 2435
mask = 100100001XX01110X00010000X100101X0X0
mem[46571] = 57904
mem[64234] = 1904852
mem[17836] = 917
mem[3697] = 79951109
mem[17934] = 311
mem[62943] = 105198
mem[43632] = 127650
mask = 110X001X00001X100X001X011100X01X0X01
mem[32984] = 5679479
mem[2985] = 52007072
mask = 1000X01011001100XX0000X1110X00010101
mem[52709] = 46005248
mem[64106] = 148
mem[10607] = 177262862
mem[1672] = 768
mem[55771] = 114128471
mem[102] = 407505
mask = X0X01010X1X011000X0000000X1001101X10
mem[24357] = 37895788
mem[4818] = 12679
mem[1895] = 677
mem[19538] = 1012377512
mem[51317] = 290
mem[26273] = 3433
mask = 100X0X10X101100X1X10X111111001001X00
mem[30547] = 1084
mem[55023] = 38977
mem[62922] = 235723
mem[26793] = 2101257
mem[3343] = 846
mem[23767] = 749476
mask = 10001XXX11X01101X0101X11101X1110X010
mem[61302] = 2841122
mem[54867] = 8646
mem[50226] = 130817
mem[48234] = 29376
mem[39560] = 605311
mask = 110010101X001X1X000000000X0001110X10
mem[44651] = 1982752
mem[46095] = 7221
mem[22548] = 1154372
mask = 11X100X0XX101010X00011101110X1010X01
mem[28851] = 10138786
mem[40188] = 9003080
mem[46594] = 260547019
mem[13047] = 644
mem[61575] = 318501037
mem[17933] = 130721
mask = 10X000111X01X010XX1X0XX11001010001X0
mem[17836] = 11610
mem[60798] = 17334088
mem[18040] = 8111502
mem[5507] = 3549486
mask = 100010101X001XXX00X0X10001X10111X01X
mem[1101] = 1830700
mem[12750] = 44919
mem[61081] = 1145728
mem[221] = 98190
mem[5230] = 1674762
mask = 10110101X0X0100001X01101X1111X011011
mem[63476] = 774
mem[38765] = 6583
mem[53101] = 425799
mem[2689] = 76519
mask = 1X0X0X001XX010100000X1X0X1000X010100
mem[63306] = 25107559
mem[29367] = 7911
mem[33854] = 333886
mem[34129] = 1601023
mem[19106] = 105039
mem[20340] = 33500
mask = 1XX11X10100XX00X0X001010011010010111
mem[17552] = 318
mem[52954] = 755503843
mem[45796] = 251387
mask = 110010X01000101001000101X100001X010X
mem[19611] = 4546530
mem[94] = 16405
mem[37449] = 16299407
mem[63044] = 1717
mem[60882] = 53035
mask = 1X111010100010X10X00X110XX0010010XX1
mem[46825] = 38742
mem[1559] = 2601
mem[17127] = 10125964
mem[45796] = 17645381
mem[57067] = 650
mem[12750] = 7052753
mem[51876] = 223481
mask = X00X1010110010010X000X000110X0X0X00X
mem[20021] = 98402475
mem[62492] = 59443811
mask = 100X101X100X1010000100010X000010X011
mem[11361] = 790603
mem[32392] = 1461971
mem[16860] = 55486
mem[48278] = 118088
mem[6887] = 436990
mem[44042] = 244740
mask = 1000X01XX100X10000XX1X0011001XX01110
mem[20112] = 2750699
mem[12269] = 52907343
mem[42636] = 6065
mem[17001] = 169286
mask = 10X1101X1X001X010X00011X0X0111001X11
mem[37947] = 96
mem[63306] = 7396
mem[5465] = 1081
mem[14662] = 1011
mem[65279] = 131
mask = 110100111100XX1X0111011110101000000X
mem[37780] = 7990
mem[31512] = 40679485
mem[14491] = 737737
mem[30998] = 124949091
mask = X1011X001000101XX0001X0X00111101001X
mem[33157] = 12243
mem[56747] = 419147
mem[11586] = 6256
mem[64708] = 76550
mem[37957] = 243778
mem[5091] = 2456
mask = 11X110X0X0001011X0000X0000100101X0X1
mem[25324] = 2093940
mem[36379] = 2777325
mem[54213] = 228702576
mem[32976] = 5846431
mem[29430] = 119936
mask = 1101010000101000X0001111100XXX111X11
mem[31402] = 7431602
mem[2073] = 7956
mem[36885] = 3966
mem[32392] = 37896
mem[6832] = 173996362
mem[53853] = 16478619
mem[65160] = 667963
mask = 100XX10X100X101X0X00000011X00X110X00
mem[62304] = 3584301
mem[57317] = 963348
mem[16414] = 7872061
mem[34763] = 1271472
mask = 10XX001011000100000010X0100X01100111
mem[48910] = 527784663
mem[6555] = 360
mem[52875] = 2675
mem[18803] = 524
mem[42703] = 3789970
mask = 1X0100101X00X00X011100X1X11100X0101X
mem[45317] = 6806741
mem[48723] = 23187771
mem[34283] = 291852
mem[29981] = 115905
mem[63917] = 245041
mask = 10010X0011001X10000000001X1001X10XX0
mem[24836] = 124320580
mem[13017] = 387784
mem[49496] = 6149582
mem[40990] = 3612867
mem[42530] = 414515530
mask = 11010XX01100X001XX1100X00001XX001011
mem[49876] = 340001
mem[12520] = 447064754
mem[31346] = 2199326
mem[38744] = 3174513
mask = 100X101XX100100100101X000X00011111X0
mem[58504] = 161861
mem[51785] = 352
mem[5035] = 14642386
mask = 10XX0011100X101010110001110X11001X0X
mem[55328] = 912776
mem[54729] = 404668417
mem[1081] = 1230593
mem[43126] = 275450
mem[9568] = 6977
mem[38414] = 258888
mem[17523] = 628
mask = 11011X10110010001110110X0XX1XX001101
mem[14522] = 3706
mem[23442] = 84315
mem[60757] = 7650
mem[64106] = 4820
mem[12365] = 24537836
mem[46911] = 2142190
mem[60482] = 14617749
mask = 11X1001111001X10X11100X000X010100110
mem[30003] = 4640103
mem[46235] = 8912631
mem[28941] = 239
mem[3232] = 2552211
mem[14072] = 24479
mem[45848] = 97107
mem[27490] = 7267061
mask = X00XXX1111X01101X0101110001XXX101110
mem[50700] = 61091
mem[2006] = 46171
mem[54190] = 13801104
mem[437] = 700
mem[25806] = 370455
mask = 1X00X0X0X00010100X00X00X010XX1100101
mem[23418] = 3953103
mem[4151] = 16351752
mem[33858] = 2781804
mem[40347] = 48747047
mem[24323] = 185098
mem[13410] = 3244984
mem[22024] = 2046007
mask = 101110XXX1001X01X100X1XX000111111111
mem[42442] = 6862901
mem[37947] = 133
mem[52715] = 90558
mask = 1X0XX0X0100010X0000X010X010X0001010X
mem[41622] = 3864588
mem[37947] = 2574041
mem[36379] = 282
mem[7539] = 1884
mem[43885] = 252462770
mask = 1X0000XX110XX0X0X01101X0100X11101010
mem[31739] = 122014445
mem[12525] = 35483
mem[49565] = 120526
mask = 10000X00111X1010X0X00X0001X001X111X0
mem[50] = 184186855
mem[26970] = 28009237
mem[43747] = 57180
mask = XX01X010110X1XX101X11011X00101000011
mem[34649] = 23812
mem[19379] = 739289
mem[9427] = 290837028
mask = 1000001101X0X1000011111XX000101X11XX
mem[53212] = 976414185
mem[54319] = 309721
mem[61044] = 26059565
mem[58543] = 112
mem[47508] = 485916879
mem[58912] = 603
mask = 11X100000000100X000011101X001X0X0011
mem[12536] = 1079539
mem[60933] = 890
mem[38277] = 24422421
mem[31503] = 275497096
mask = 10111010111011110X001111X0X01XX0X011
mem[36315] = 732755
mem[12521] = 5283380
mem[14593] = 11354059
mask = 110X10001000100X00001100X10000001XX0
mem[178] = 10049489
mem[58352] = 1284
mem[55836] = 13364
mem[8955] = 148648
mask = 1001001X110010X01111001X0001010X1101
mem[51286] = 424
mem[24896] = 685
mem[35764] = 984973816
mem[1767] = 21227
mem[58224] = 509700911
mem[54139] = 681
mask = 10X0101001001100X010X11001110X1X1101
mem[4197] = 3959433
mem[28314] = 4080074
mem[64406] = 2275763
mask = 10111011110011010XX0X111X00X1111111X
mem[53633] = 24715
mem[12901] = 288197152
mem[61838] = 365048
mem[9985] = 113625770
mask = 1000101011X0110X00000XX001XX0X1XX011
mem[18728] = 2722863
mem[62115] = 373062209
mem[24406] = 14575043
mem[1135] = 1658799
mem[36109] = 27585
mem[43154] = 932674865
mask = 1X00001X1100101000XX01110001X01010X0
mem[38443] = 2595746
mem[45834] = 8200415
mem[32618] = 2473
mem[45317] = 204863
mem[36385] = 1258950
mem[1559] = 178687
mem[7129] = 274257
mask = 1X01X010110X1000111X11X00X1101011X01
mem[64351] = 89231
mem[23767] = 2060338
mem[8182] = 3870
mem[55067] = 3498
mem[27490] = 113212315
mask = 10000010110010100001XX01000X1XX00000
mem[22484] = 465878
mem[199] = 492230203
mem[40351] = 41069
mem[40347] = 28883121
mem[54190] = 132583179
mem[45157] = 1230
mem[3262] = 763080
mask = 1001010110011011X0X0100011X00X00X011
mem[9068] = 1859901
mem[65291] = 1860
mem[4025] = 21940594
mask = 11010X00X0X01X000000111010X0X1111X01
mem[33551] = 154606
mem[11586] = 6143673
mem[55294] = 602657
mem[25418] = 1846
mem[31307] = 32063880
mem[20048] = 1695818
mask = 1X111X10110010110100110X110110X00000
mem[24896] = 9413794
mem[37579] = 13947393
mem[62604] = 5335
mem[9937] = 13537
mem[14199] = 601827
mask = 111110101X00X0110X000110X000101000X0
mem[48234] = 1067197062
mem[43126] = 1849938
mem[26161] = 32826701
mem[42432] = 2056
mask = 10001X10110011000X100001X1100X000000
mem[35283] = 15811124
mem[6943] = 592604
mem[25032] = 189694567
mem[36455] = 163580
mem[23535] = 61178
mem[28952] = 363311
mask = 1XX0000000001X10000X100001001X10X1X1
mem[14987] = 1027
mem[59069] = 14400510
mem[27100] = 13017
mem[70] = 22529
mem[9653] = 120954062
mask = 1X001X1010001010X001X0101000X1100001
mem[36385] = 7634
mem[51785] = 373478
mem[62871] = 1219093
mem[48687] = 720
mem[46211] = 184017955
mem[44651] = 4180012
mask = 1X111X1X1100110100X0X11X011100010101
mem[30714] = 86493051
mem[9781] = 6458038
mem[44042] = 196093756
mem[54852] = 49986
mask = 1X0X001XX10010X0XX11001100X1000100X1
mem[59055] = 8554849
mem[30511] = 238
mem[59740] = 291
mem[46825] = 4021
mem[57257] = 47883555
mask = 1001XX0X100X10000000X101XX0101X1X011
mem[57317] = 3753201
mem[36109] = 89435982
mem[2071] = 92612
mem[51306] = 3807708
mem[60626] = 16185176
mem[6288] = 52787155
mem[51876] = 5014
mask = 10X10X0X10X0100X0X00010X100111010000
mem[47779] = 2632
mem[44258] = 3287861
mem[55067] = 554823
mem[5507] = 16374932
mask = X00000X01X0X101001XX00011010X010X110
mem[15082] = 734057
mem[20325] = 9406
mem[43154] = 681
mem[14046] = 2718549
mem[36608] = 18836
mask = 10001XX1110XX10X00X01100001011001010
mem[64106] = 948524
mem[63156] = 717606237
mem[21756] = 8193201
mem[61081] = 12060571
mem[26182] = 1980
mask = 100XX0X011001X0X00100101010100X100X0
mem[40347] = 7113
mem[20846] = 1812874
mem[52954] = 31235865
mem[15176] = 73255675
mem[33551] = 45182604
mask = 1000101X1000100000001001X10001010X1X
mem[53536] = 78486
mem[14207] = 25081
mem[6943] = 406911928
mem[20627] = 33813239
mem[52083] = 5810
mem[51593] = 2963
mask = 100XX01010X0100100XX1X0X011001111110
mem[50540] = 521342322
mem[25666] = 517512832
mem[19475] = 60787116
mask = 100X1010XX0011X000100010X0X1X0111X11
mem[44296] = 11404
mem[19921] = 12860
mask = 10011000XX0X100000X1X10X001X00X10X10
mem[15030] = 28046260
mem[36124] = 53286373
mem[18115] = 57486
mem[14821] = 6413
mem[46807] = 4097123
mem[5230] = 758650
mem[47154] = 2777
mask = 1001X0101X0010000X11011X01001XX11101
mem[61830] = 63370
mem[31503] = 16024
mem[12525] = 246729437
mem[33593] = 115066
mem[46594] = 59939695
mem[178] = 6489337
mask = 110XX000100010000000100110110XX0XX01
mem[61044] = 1681
mem[48145] = 78509
mem[14662] = 317884442
mask = 10010011110XX01000111011011X1011X111
mem[63129] = 26
mem[3729] = 72549
mem[60816] = 33039
mem[5097] = 620696594
mem[24325] = 1480
mem[52500] = 507
mem[9653] = 77992342
mask = 10X11010XX00X00100X0011X100X110X0011
mem[50406] = 75245910
mem[65160] = 121691
mem[10605] = 5972898
mem[31113] = 122549
mask = 10X0111111101101001X1XXX1X0011101010
mem[32648] = 13078
mem[16040] = 42554293
mem[49180] = 14823
mem[12178] = 18873
mem[45060] = 58303
mem[49248] = 59412
mask = 1000X010110X101001100X0010100100011X
mem[14950] = 106014
mem[41759] = 6142194
mem[53704] = 2925
mask = 1000001011001010000X10010000X110X10X
mem[38572] = 30247028
mem[23767] = 23066
mem[32618] = 542388
mem[10770] = 411
mem[16831] = 40856
mem[13505] = 2142
mem[28786] = 140994490
mask = 1100X0X000001XX00100X0010110X0X01X01
mem[17768] = 45460151
mem[4197] = 705
mem[2953] = 12201
mask = 1000000011XX10X00X0010X1011X111X0111
mem[18985] = 29719899
mem[45172] = 258207909
mem[49882] = 85394924
mem[21653] = 603
mem[31300] = 37290319
mem[5035] = 5768
mem[6427] = 15769266
mask = 10010011110010X0111101X000000101X0X1
mem[47082] = 157766
mem[13410] = 3842391
mem[58172] = 2576
mask = 10X000001000101000011101X0X000XX1001
mem[3121] = 198929928
mem[59740] = 16383
mem[12269] = 37852
mem[18190] = 1240
mask = 10000XX001000100XX0X100X1010110110X0
mem[9713] = 1435
mem[50404] = 1789
mem[28429] = 3239
mem[178] = 2804
mask = 1000010010X11011X0X01X0111010011X0X0
mem[44077] = 202823
mem[30483] = 3929
mem[25920] = 10040
mem[221] = 135771
mask = 10X0X01111001100000000000100X0001X1X
mem[9427] = 152879
mem[38057] = 11090
mem[58564] = 32957206
mask = 110X0010110X1X100010101X00100X001010
mem[30968] = 2095418
mem[3121] = 139148
mem[53666] = 26824

296
day14/src/main.zig Normal file
View File

@ -0,0 +1,296 @@
const std = @import("std");
pub fn main() anyerror!void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
var gpa = &arena.allocator;
var map = std.hash_map.AutoHashMap(u64, u64).init(gpa);
defer map.deinit();
var f = try std.fs.cwd().openFile("input", .{});
var contents = try f.readToEndAlloc(gpa, std.math.maxInt(u32));
// Part one
var and_mask : u64 = std.math.maxInt(u64);
var or_mask : u64 = 0;
var it = std.mem.tokenize(contents, "\n");
while (it.next()) |line| {
std.log.debug("{}", .{line});
if (std.mem.eql(u8, line[0..4], "mask")) {
// Set mask
var mask_iter = std.mem.tokenize(line, "=");
_ = mask_iter.next(); // skip the first one
if (mask_iter.next()) |v| {
set_masks(std.mem.trim(u8, v, " "), &and_mask, &or_mask);
}
}
else {
var memory_location: u64 = 0;
var memory_value: u64 = 0;
var mem_iter = std.mem.tokenize(line, "=[");
std.log.warn("{}", .{mem_iter.next()}); // skip 'mem['
if (mem_iter.next()) |location_line| {
std.log.debug("parsing '{}'", .{location_line});
memory_location = try std.fmt.parseUnsigned(u64, std.mem.trim(u8, location_line, " ]"), 10);
}
if (mem_iter.next()) |value_line| {
memory_value = try std.fmt.parseUnsigned(u64, std.mem.trim(u8, value_line, " "), 10);
}
try write_memory(&map, memory_location, memory_value, and_mask, or_mask);
}
}
var map_it = map.iterator();
var sum : u64 = 0;
while (map_it.next()) |entry| {
sum += entry.value;
}
std.log.info("Part 1: Sum of non-zero memory locations: {}", .{sum});
// Part 2
map.deinit();
map = std.hash_map.AutoHashMap(u64, u64).init(gpa);
gpa.free(contents);
try f.seekTo(0);
contents = try f.readToEndAlloc(gpa, std.math.maxInt(u32));
it = std.mem.tokenize(contents, "\n");
var address_mask : [36]u8 = undefined;
while (it.next()) |line| {
std.log.debug("{}", .{line});
if (std.mem.eql(u8, line[0..4], "mask")) {
// Set mask
var mask_iter = std.mem.tokenize(line, "=");
_ = mask_iter.next(); // skip the first one
if (mask_iter.next()) |v| {
std.mem.copy(u8, &address_mask, std.mem.trim(u8, v, " "));
}
}
else {
var memory_location: u64 = 0;
var memory_value: u64 = 0;
var mem_iter = std.mem.tokenize(line, "=[");
_ = mem_iter.next(); // skip 'mem['
if (mem_iter.next()) |location_line| {
std.log.debug("parsing '{}'", .{location_line});
memory_location = try std.fmt.parseUnsigned(u64, std.mem.trim(u8, location_line, " ]"), 10);
}
if (mem_iter.next()) |value_line| {
memory_value = try std.fmt.parseUnsigned(u64, std.mem.trim(u8, value_line, " "), 10);
}
try write_memory_address_masked(&map, memory_location, memory_value, address_mask[0..]);
}
}
map_it = map.iterator();
sum = 0;
while (map_it.next()) |entry| {
sum += entry.value;
}
std.log.info("Part 2: Sum of non-zero memory locations: {}", .{sum});
}
fn write_memory_address_masked(map: *std.hash_map.AutoHashMap(u64, u64), location: u64, value: u64,
mask: []const u8) !void {
// Fuse the value into the character mask
var i : u6 = 0;
var new_mask : [36]u8 = undefined;
std.mem.copy(u8, &new_mask, mask);
while (i < 36) : (i += 1) {
if (new_mask[i] == 'X') {
continue;
}
else if (new_mask[i] == '1') {
continue;
}
else if (new_mask[i] == '0') {
// mask to isolate bit at position 35 - i
// kth() counts from LSB to MSB, we are going in string order from
// MSB to LSB
new_mask[i] = switch(kth_bit(location, 35-i)) {
0 => '0',
1 => '1',
else => {
unreachable;
},
};
//std.log.warn("Index {}: {c} -> {c}", .{i, new_mask[i], mask[i]});
}
}
std.log.warn("\nValue: {b:36} ({})\nPre-fuse: {}\nPst-fuse: {}", .{location, location, mask, new_mask});
var addresses = try generate_address_list(map.allocator, new_mask[0..]);
defer addresses.deinit();
for (addresses.items) |address| {
std.log.warn("Wrote {} to address {}", .{value, address});
try map.put(address, value);
}
}
// Caller is responsible for freeing this
// This function takes the "fused mask", where the only thing left to resolve
// if the 'X' bits.
fn generate_address_list(allocator: *std.mem.Allocator, mask: []const u8) !std.ArrayList(u64) {
var masks = std.ArrayList(u64).init(allocator);
var i : u64 = 0;
// Store the offsets of the locations of the X character
var x_locations = std.ArrayList(usize).init(allocator);
defer x_locations.deinit();
for (mask) |c, k| {
if (c == 'X') {
try x_locations.append(k);
}
}
var n_variants = std.math.pow(u64, 2, x_locations.items.len);
//std.log.warn("{} Xs in mask '{}', {} variants", .{x_locations.items.len, mask, n_variants});
while (i < n_variants) : (i += 1) {
var m = try allocator.alloc(u8, mask.len);
std.mem.copy(u8, m, mask);
var bit_index : u6 = 0;
while (bit_index < x_locations.items.len) : (bit_index += 1) {
// At 0, all Xs become zero,
// At 1, last X becomes one, otherwise Xs are zero
// ...
m[x_locations.items[bit_index]] = switch(kth_bit(i, bit_index)) {
0 => '0',
1 => '1',
else => {
unreachable;
},
};
}
var value = try std.fmt.parseUnsigned(u64, m, 2);
//std.log.warn("\nFrom: {:64}\nGot: {b:64}", .{m, value});
try masks.append(value);
allocator.free(m);
}
return masks;
}
// @see https://www.geeksforgeeks.org/find-value-k-th-bit-binary-representation/
fn kth_bit(value: u64, k: u6) u64 {
//std.debug.warn("\nKey: {}, V: {}\nOrig: {b:64}\n", .{k, value, value});
var one: u64 = 1;
var shifted: u64 = 0;
var overflowed = @shlWithOverflow(u64, one, k, &shifted);
if (overflowed) {
std.log.warn("OVERFLOWED", .{});
}
//std.debug.warn("Shft: {b:64}\n", .{shifted});
//std.debug.warn("Andd: {b:64}\n", .{value & shifted});
//std.debug.warn("Rslt: {b:64}\n", .{(value & shifted) >> k});
return (value & shifted) >> k;
}
fn write_memory(map: *std.hash_map.AutoHashMap(u64, u64), location: u64, value: u64, and_mask: u64, or_mask: u64) !void {
// Mask
var new_value = value;
new_value &= and_mask;
new_value |= or_mask;
try map.put(location, new_value);
std.log.debug("Wrote '{}' to '{}' (pre-masked: '{}')",
.{new_value, location, value});
//std.log.warn("\npre_mask: {b:64}\nand_mask: {b:64}\nor_mask :{b:64}\npst_mask: {b:64}",
// .{value, and_mask, or_mask, new_value});
}
//const maskWidth : u64 = 36;
fn set_masks(line: []const u8, and_mask: *u64, or_mask: *u64) void {
and_mask.* = std.math.maxInt(u64);
or_mask.* = 0;
var one: u64 = 1;
for (line) |c, k| {
var offset = @intCast(u6, line.len - k - 1);
switch(c) {
'1' => {
// Only need to tweak the or_mask
or_mask.* |= (one << offset);
},
'0' => {
and_mask.* &= ~(one << offset);
},
'X' => {
continue;
},
else => unreachable,
}
}
std.log.debug("and mask:{b:64}", .{and_mask});
std.log.debug("or mask:{b:64}", .{or_mask});
}
test "mask_setting" {
var and_mask : u64 = 0;
var or_mask : u64 = 0;
var l = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X";
set_masks(l, &and_mask, &or_mask);
}
test "memory_writing" {
var and_mask : u64 = 0;
var or_mask : u64 = 0;
var l = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X";
set_masks(l, &and_mask, &or_mask);
var map = std.hash_map.AutoHashMap(u64, u64).init(std.testing.allocator);
defer map.deinit();
try write_memory(&map, 8, 11, and_mask, or_mask);
try write_memory(&map, 7, 101, and_mask, or_mask);
try write_memory(&map, 8, 0, and_mask, or_mask);
if (map.get(8)) |v| {
std.testing.expectEqual(v, 64);
}
else {
unreachable;
}
if (map.get(7)) |v| {
std.testing.expectEqual(v, 101);
}
else {
unreachable;
}
}
test "kth_bit" {
var value : u64 = 13;
// 0000 1101
var expected = [_]u64 {
// goes from LSB to MSB
1, 0, 1, 1,
0, 0, 0, 0,
};
for (expected) |v, k| {
var key : u6 = @intCast(u6, k);
std.testing.expectEqual(kth_bit(value, key), expected[k]);
}
}
test "generate_address_list" {
var mask = "000000000000000000000000000000X1101X";
var addresses = try generate_address_list(std.testing.allocator, mask[0..]);
defer addresses.deinit();
//std.log.warn("\n26: {b:64}\n27: {b:64}\n58: {b:64}\n59: {b:64}\n", .{26, 27, 58, 59});
std.testing.expectEqual(addresses.items.len, 4);
std.testing.expectEqual(addresses.items[0], 26);
std.testing.expectEqual(addresses.items[1], 58);
std.testing.expectEqual(addresses.items[2], 27);
std.testing.expectEqual(addresses.items[3], 59);
}
test "part2" {
var map = std.hash_map.AutoHashMap(u64, u64).init(std.testing.allocator);
defer map.deinit();
try write_memory_address_masked(&map, 42, 100, "000000000000000000000000000000X1001X");
try write_memory_address_masked(&map, 26, 1, "00000000000000000000000000000000X0XX");
var map_it = map.iterator();
var sum : u64 = 0;
while (map_it.next()) |entry| {
sum += entry.value;
}
std.testing.expectEqual(sum, 208);
}