Recursive range iteration [D]











up vote
1
down vote

favorite












I decided to do Advent of Code this year in D, and the following is my solution to day8.



Algorithm aside, I was specifically wondering if there was a better way to use ranges in a recursive manner here. I feel like I should be able to do write the functions in a more generic way (not just int, avoiding the .array in main), and without destroying the original array in the process - avoiding the temporary variable p1.



My use of the header variable seems suspect to me as well - basically I want a popFront that returns a value, I think, but have been unable to find anything like that



I'm also happy to hear general advice about usual best practices and efficiencies



import std.algorithm;
import std.conv;
import std.file;
import std.range;
import std.stdio;
import std.string;

int count_metadata(ref int r)
{
auto header = r.take(2);
int num_child = header.front;
int num_metadata = header.back;
r = r.drop(2);
int count;
for (int i; i < num_child; i++) {
count += r.count_metadata;
}
count += r.take(num_metadata).sum;
r = r.drop(num_metadata);
return count;
}

int node_value(ref int r)
{
auto header = r.take(2);
int num_child = header.front;
int num_metadata = header.back;
r = r.drop(2);
int child_values;
for (int i; i < num_child; i++) {
child_values ~= node_value(r);
}
int count;
if (num_child == 0) {
count = r.take(num_metadata).sum;
} else {
// ignore out of range
count = r.take(num_metadata).filter!(a => 0 < a && a <= child_values.length).map!(a => child_values[a - 1]).sum;
}
r = r.drop(num_metadata);
return count;
}

void main(string args)
{
// integers separated by spaces
auto input = readText(args[1]).split.map!(a => to!int(a)).array;
//auto input = [2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2];
auto p1 = input.dup;
writeln("Metadata total: ", count_metadata(p1));
writeln("Node value: ", node_value(input));
}


(args[1] is a file with integers separated by spaces, sample input is commented out below it)










share|improve this question




























    up vote
    1
    down vote

    favorite












    I decided to do Advent of Code this year in D, and the following is my solution to day8.



    Algorithm aside, I was specifically wondering if there was a better way to use ranges in a recursive manner here. I feel like I should be able to do write the functions in a more generic way (not just int, avoiding the .array in main), and without destroying the original array in the process - avoiding the temporary variable p1.



    My use of the header variable seems suspect to me as well - basically I want a popFront that returns a value, I think, but have been unable to find anything like that



    I'm also happy to hear general advice about usual best practices and efficiencies



    import std.algorithm;
    import std.conv;
    import std.file;
    import std.range;
    import std.stdio;
    import std.string;

    int count_metadata(ref int r)
    {
    auto header = r.take(2);
    int num_child = header.front;
    int num_metadata = header.back;
    r = r.drop(2);
    int count;
    for (int i; i < num_child; i++) {
    count += r.count_metadata;
    }
    count += r.take(num_metadata).sum;
    r = r.drop(num_metadata);
    return count;
    }

    int node_value(ref int r)
    {
    auto header = r.take(2);
    int num_child = header.front;
    int num_metadata = header.back;
    r = r.drop(2);
    int child_values;
    for (int i; i < num_child; i++) {
    child_values ~= node_value(r);
    }
    int count;
    if (num_child == 0) {
    count = r.take(num_metadata).sum;
    } else {
    // ignore out of range
    count = r.take(num_metadata).filter!(a => 0 < a && a <= child_values.length).map!(a => child_values[a - 1]).sum;
    }
    r = r.drop(num_metadata);
    return count;
    }

    void main(string args)
    {
    // integers separated by spaces
    auto input = readText(args[1]).split.map!(a => to!int(a)).array;
    //auto input = [2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2];
    auto p1 = input.dup;
    writeln("Metadata total: ", count_metadata(p1));
    writeln("Node value: ", node_value(input));
    }


    (args[1] is a file with integers separated by spaces, sample input is commented out below it)










    share|improve this question


























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I decided to do Advent of Code this year in D, and the following is my solution to day8.



      Algorithm aside, I was specifically wondering if there was a better way to use ranges in a recursive manner here. I feel like I should be able to do write the functions in a more generic way (not just int, avoiding the .array in main), and without destroying the original array in the process - avoiding the temporary variable p1.



      My use of the header variable seems suspect to me as well - basically I want a popFront that returns a value, I think, but have been unable to find anything like that



      I'm also happy to hear general advice about usual best practices and efficiencies



      import std.algorithm;
      import std.conv;
      import std.file;
      import std.range;
      import std.stdio;
      import std.string;

      int count_metadata(ref int r)
      {
      auto header = r.take(2);
      int num_child = header.front;
      int num_metadata = header.back;
      r = r.drop(2);
      int count;
      for (int i; i < num_child; i++) {
      count += r.count_metadata;
      }
      count += r.take(num_metadata).sum;
      r = r.drop(num_metadata);
      return count;
      }

      int node_value(ref int r)
      {
      auto header = r.take(2);
      int num_child = header.front;
      int num_metadata = header.back;
      r = r.drop(2);
      int child_values;
      for (int i; i < num_child; i++) {
      child_values ~= node_value(r);
      }
      int count;
      if (num_child == 0) {
      count = r.take(num_metadata).sum;
      } else {
      // ignore out of range
      count = r.take(num_metadata).filter!(a => 0 < a && a <= child_values.length).map!(a => child_values[a - 1]).sum;
      }
      r = r.drop(num_metadata);
      return count;
      }

      void main(string args)
      {
      // integers separated by spaces
      auto input = readText(args[1]).split.map!(a => to!int(a)).array;
      //auto input = [2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2];
      auto p1 = input.dup;
      writeln("Metadata total: ", count_metadata(p1));
      writeln("Node value: ", node_value(input));
      }


      (args[1] is a file with integers separated by spaces, sample input is commented out below it)










      share|improve this question















      I decided to do Advent of Code this year in D, and the following is my solution to day8.



      Algorithm aside, I was specifically wondering if there was a better way to use ranges in a recursive manner here. I feel like I should be able to do write the functions in a more generic way (not just int, avoiding the .array in main), and without destroying the original array in the process - avoiding the temporary variable p1.



      My use of the header variable seems suspect to me as well - basically I want a popFront that returns a value, I think, but have been unable to find anything like that



      I'm also happy to hear general advice about usual best practices and efficiencies



      import std.algorithm;
      import std.conv;
      import std.file;
      import std.range;
      import std.stdio;
      import std.string;

      int count_metadata(ref int r)
      {
      auto header = r.take(2);
      int num_child = header.front;
      int num_metadata = header.back;
      r = r.drop(2);
      int count;
      for (int i; i < num_child; i++) {
      count += r.count_metadata;
      }
      count += r.take(num_metadata).sum;
      r = r.drop(num_metadata);
      return count;
      }

      int node_value(ref int r)
      {
      auto header = r.take(2);
      int num_child = header.front;
      int num_metadata = header.back;
      r = r.drop(2);
      int child_values;
      for (int i; i < num_child; i++) {
      child_values ~= node_value(r);
      }
      int count;
      if (num_child == 0) {
      count = r.take(num_metadata).sum;
      } else {
      // ignore out of range
      count = r.take(num_metadata).filter!(a => 0 < a && a <= child_values.length).map!(a => child_values[a - 1]).sum;
      }
      r = r.drop(num_metadata);
      return count;
      }

      void main(string args)
      {
      // integers separated by spaces
      auto input = readText(args[1]).split.map!(a => to!int(a)).array;
      //auto input = [2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2];
      auto p1 = input.dup;
      writeln("Metadata total: ", count_metadata(p1));
      writeln("Node value: ", node_value(input));
      }


      (args[1] is a file with integers separated by spaces, sample input is commented out below it)







      recursion interval d






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 15 hours ago

























      asked 15 hours ago









      LordAro

      1616




      1616



























          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209268%2frecursive-range-iteration-d%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209268%2frecursive-range-iteration-d%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Morgemoulin

          Scott Moir

          Souastre