Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- $filename = "14.txt";
- open(FILE, $filename);
- @data = <FILE>;
- close(FILE);
- $currentmask = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
- %mems = ();
- %memsp2 = ();
- foreach $line (@data) {
- $line =~ s/\n//sgi;
- $line =~ s/\t//sgi;
- $line =~ s/\r//sgi;
- # If line is a mask setting line - change current mask
- if ($line =~ m/^mask = (X|0|1){36}$/) {
- $line =~ s/mask = //;
- $currentmask = $line;
- }
- # If line is a memory setting line, execute it.
- if ($line =~ m/^mem\[(\d+)\] = (\d+)$/) {
- $memaddr = $1;
- $value = $2;
- $bin = sprintf("%036b", $value); # *Part1* Convert value to 36bit binary
- $addrbinp2 = sprintf("%036b", $memaddr); # *Part2* Convert adress to 36 bit binary
- @inmask = split("", $currentmask);
- @inbin = split("", $bin);
- @addrbin = split("", $addrbinp2);
- $outbin = "";
- @zerobits = ();
- @onebits = ();
- # Loop through all 36 bits
- for ($i = 0; $i < 36; $i++) {
- # If current mask bit is a zero
- if ($inmask[$i] eq "0") {
- $outbin = $outbin . "0"; # *part1* Add a 0 to result bit string
- if ($i == 0) {
- push(@zerobits, $addrbin[$i]); # *part2* If this is first bit, we need to populate @zerobits array with the current adress bit (0 = adress bit unaffected)
- }
- else
- {
- # Otherwise, add the current adress bit, to all elements in @zerobits array (this is important because for each X mask bit, @zerobits array is doubled)
- for ($z = 0; $z < $#zerobits + 1; $z++) {
- $zerobits[$z] = $zerobits[$z] . $addrbin[$i];
- }
- }
- }
- if ($inmask[$i] eq "1") {
- $outbin = $outbin . "1"; # *part1* Add a 1 to result bit string
- if ($i == 0) {
- push(@zerobits, "1"); # *part2* same as above but we add a strict "1".
- }
- else
- {
- # *part2* same as above, but we add a strict "1" to all elements.
- for ($z = 0; $z < $#zerobits + 1; $z++) {
- $zerobits[$z] = $zerobits[$z] . "1";
- }
- }
- }
- if ($inmask[$i] eq "X") {
- $outbin = $outbin . $inbin[$i]; # *part1* Add the current value binary bit to the result bit string.
- if ($i == 0) {
- # *part2* X on first place in a mask - Add 2 elements containing one of each, both one 1 and one 0.
- push(@zerobits, "1");
- push(@zerobits, "0");
- }
- else
- {
- # *part2* This is interesting. First we make a copy of the array containing all current adress bit strings possible, given the X'es.
- @onebits = @zerobits;
- for ($z = 0; $z < $#zerobits + 1; $z++) {
- # Then we add a "0" to all elements in the first array, and "1" to all elements in the second array.
- $zerobits[$z] = $zerobits[$z] . "0";
- $onebits[$z] = $onebits[$z] . "1";
- }
- # Then contcatenate both arrays into @zerobits. Effectively, this will double the amount of elements (since initially @zerobits and @onebits are copies, then all gets a 0 and 1 appended)
- push(@zerobits, @onebits);
- }
- }
- }
- $mems{$memaddr} = oct("0b".$outbin); # *part1* Set memory adress to the decimal representation of output binary
- for ($b = 0; $b < $#zerobits + 1; $b++) {
- # *part2* For all adresses in this memset (with regards to X'es in the mask) - set same value.
- $uv = oct("0b".$zerobits[$b]);
- $memsp2{$uv} = $value;
- }
- }
- }
- # *part1* Sum up everything in %mems which is part1 memory space.
- $runningsum = 0;
- foreach $memread (keys %mems) {
- $runningsum = $runningsum + int($mems{$memread});
- }
- print "P1: $runningsum\n";
- # *part2* Sum up everything in %memsp2 which is part2 memory space.
- $runningsum = 0;
- foreach $memread (keys %memsp2) {
- $runningsum = $runningsum + int($memsp2{$memread});
- }
- print "P2: $runningsum\n";
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement