Advertisement
Guest User

Untitled

a guest
Dec 14th, 2020
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 5.47 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. $filename = "14.txt";
  4.  
  5. open(FILE, $filename);
  6. @data = <FILE>;
  7. close(FILE);
  8.  
  9. $currentmask = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
  10.  
  11. %mems = ();
  12. %memsp2 = ();
  13.  
  14. foreach $line (@data) {
  15.         $line =~ s/\n//sgi;
  16.         $line =~ s/\t//sgi;
  17.         $line =~ s/\r//sgi;
  18.  
  19.         # If line is a mask setting line - change current mask
  20.         if ($line =~ m/^mask = (X|0|1){36}$/) {
  21.                 $line =~ s/mask = //;
  22.                 $currentmask = $line;
  23.         }
  24.  
  25.         # If line is a memory setting line, execute it.
  26.         if ($line =~ m/^mem\[(\d+)\] = (\d+)$/) {
  27.  
  28.                 $memaddr = $1;
  29.                 $value = $2;
  30.                 $bin = sprintf("%036b", $value); # *Part1* Convert value to 36bit binary
  31.  
  32.                 $addrbinp2 = sprintf("%036b", $memaddr); # *Part2* Convert adress to 36 bit binary
  33.  
  34.                 @inmask = split("", $currentmask);
  35.                 @inbin = split("", $bin);
  36.                 @addrbin = split("", $addrbinp2);
  37.                 $outbin = "";
  38.  
  39.                 @zerobits = ();
  40.                 @onebits = ();
  41.  
  42.                 # Loop through all 36 bits
  43.  
  44.                 for ($i = 0; $i < 36; $i++) {
  45.  
  46.                         # If current mask bit is a zero
  47.                         if ($inmask[$i] eq "0") {
  48.                                 $outbin = $outbin . "0"; # *part1* Add a 0 to result bit string
  49.  
  50.                                 if ($i == 0) {
  51.                                         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)
  52.                                 }
  53.                                 else
  54.                                 {
  55.                                         # 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)
  56.                                         for ($z = 0; $z < $#zerobits + 1; $z++) {
  57.                                                 $zerobits[$z] = $zerobits[$z] . $addrbin[$i];
  58.                                         }
  59.                                 }
  60.                         }
  61.                         if ($inmask[$i] eq "1") {
  62.                                 $outbin = $outbin . "1"; # *part1* Add a 1 to result bit string
  63.  
  64.                                 if ($i == 0) {
  65.                                         push(@zerobits, "1"); # *part2* same as above but we add a strict "1".
  66.                                 }
  67.                                 else
  68.                                 {
  69.                                         # *part2* same as above, but we add a strict "1" to all elements.
  70.                                         for ($z = 0; $z < $#zerobits + 1; $z++) {
  71.                                                 $zerobits[$z] = $zerobits[$z] . "1";
  72.                                         }
  73.                                 }
  74.  
  75.                         }
  76.                         if ($inmask[$i] eq "X") {
  77.                                 $outbin = $outbin . $inbin[$i]; # *part1* Add the current value binary bit to the result bit string.
  78.  
  79.                                 if ($i == 0) {
  80.                                         # *part2* X on first place in a mask - Add 2 elements containing one of each, both one 1 and one 0.
  81.                                         push(@zerobits, "1");
  82.                                         push(@zerobits, "0");
  83.                                 }
  84.                                 else
  85.                                 {
  86.                                         # *part2* This is interesting. First we make a copy of the array containing all current adress bit strings possible, given the X'es.
  87.                                         @onebits = @zerobits;
  88.                                         for ($z = 0; $z < $#zerobits + 1; $z++) {
  89.                                                 # Then we add a "0" to all elements in the first array, and "1" to all elements in the second array.
  90.                                                 $zerobits[$z] = $zerobits[$z] . "0";
  91.                                                 $onebits[$z] = $onebits[$z] . "1";
  92.                                         }
  93.                                         # 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)
  94.                                         push(@zerobits, @onebits);
  95.                                 }
  96.                         }
  97.                 }
  98.  
  99.                 $mems{$memaddr} = oct("0b".$outbin); # *part1* Set memory adress to the decimal representation of output binary
  100.  
  101.                 for ($b = 0; $b < $#zerobits + 1; $b++) {
  102.                         # *part2* For all adresses in this memset (with regards to X'es in the mask) - set same value.
  103.                         $uv = oct("0b".$zerobits[$b]);
  104.                         $memsp2{$uv} = $value;
  105.                 }
  106.  
  107.         }
  108.  
  109. }
  110. # *part1* Sum up everything in %mems which is part1 memory space.
  111.  
  112. $runningsum = 0;
  113. foreach $memread (keys %mems) {
  114.         $runningsum = $runningsum + int($mems{$memread});
  115. }
  116.  
  117. print "P1: $runningsum\n";
  118.  
  119. # *part2* Sum up everything in %memsp2 which is part2 memory space.
  120.  
  121. $runningsum = 0;
  122. foreach $memread (keys %memsp2) {
  123.         $runningsum = $runningsum + int($memsp2{$memread});
  124. }
  125.  
  126. print "P2: $runningsum\n";
  127.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement