For names sake - Project Euler 22











up vote
2
down vote

favorite












Project Euler - 22



Names scores




Using names.txt (right click and 'Save Link/Target As...'), a 46K text
file containing over five-thousand first names, begin by sorting it
into alphabetical order. Then working out the alphabetical value for
each name, multiply this value by its alphabetical position in the
list to obtain a name score.



For example, when the list is sorted into alphabetical order, COLIN,
which is worth $3 + 15 + 12 + 9 + 14 = 53$, is the 938th name in the
list. So, COLIN would obtain a score of $938 × 53 = 49714$.



What is the total of all the name scores in the file?






While being fairly comfortable with the zen of Python, Julia is very new to me. Is the following code in line with Julia's vision?



In particular I feel my handling of the dictionary is sub-optimal and especially the way i hard-code remove the parenthesis in names.



Every hint on how to improve the code is welcome.





ALPHABET_INDEX = Dict( letter => index for (index, letter) in enumerate('A':'Z'))

function namescore(name)
return sum(ALPHABET_INDEX[letter] for letter in name[2:end-1])
end


function sort_file(filename)
file = open(filename)
sort(split(readstring(filename),","))
end


function PE_022(filename="p022_names.txt")

total = 0
for (index, name) in enumerate(sort_file(filename))
total += index*namescore(name)
end
total
end

println(PE_022())









share|improve this question




























    up vote
    2
    down vote

    favorite












    Project Euler - 22



    Names scores




    Using names.txt (right click and 'Save Link/Target As...'), a 46K text
    file containing over five-thousand first names, begin by sorting it
    into alphabetical order. Then working out the alphabetical value for
    each name, multiply this value by its alphabetical position in the
    list to obtain a name score.



    For example, when the list is sorted into alphabetical order, COLIN,
    which is worth $3 + 15 + 12 + 9 + 14 = 53$, is the 938th name in the
    list. So, COLIN would obtain a score of $938 × 53 = 49714$.



    What is the total of all the name scores in the file?






    While being fairly comfortable with the zen of Python, Julia is very new to me. Is the following code in line with Julia's vision?



    In particular I feel my handling of the dictionary is sub-optimal and especially the way i hard-code remove the parenthesis in names.



    Every hint on how to improve the code is welcome.





    ALPHABET_INDEX = Dict( letter => index for (index, letter) in enumerate('A':'Z'))

    function namescore(name)
    return sum(ALPHABET_INDEX[letter] for letter in name[2:end-1])
    end


    function sort_file(filename)
    file = open(filename)
    sort(split(readstring(filename),","))
    end


    function PE_022(filename="p022_names.txt")

    total = 0
    for (index, name) in enumerate(sort_file(filename))
    total += index*namescore(name)
    end
    total
    end

    println(PE_022())









    share|improve this question


























      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      Project Euler - 22



      Names scores




      Using names.txt (right click and 'Save Link/Target As...'), a 46K text
      file containing over five-thousand first names, begin by sorting it
      into alphabetical order. Then working out the alphabetical value for
      each name, multiply this value by its alphabetical position in the
      list to obtain a name score.



      For example, when the list is sorted into alphabetical order, COLIN,
      which is worth $3 + 15 + 12 + 9 + 14 = 53$, is the 938th name in the
      list. So, COLIN would obtain a score of $938 × 53 = 49714$.



      What is the total of all the name scores in the file?






      While being fairly comfortable with the zen of Python, Julia is very new to me. Is the following code in line with Julia's vision?



      In particular I feel my handling of the dictionary is sub-optimal and especially the way i hard-code remove the parenthesis in names.



      Every hint on how to improve the code is welcome.





      ALPHABET_INDEX = Dict( letter => index for (index, letter) in enumerate('A':'Z'))

      function namescore(name)
      return sum(ALPHABET_INDEX[letter] for letter in name[2:end-1])
      end


      function sort_file(filename)
      file = open(filename)
      sort(split(readstring(filename),","))
      end


      function PE_022(filename="p022_names.txt")

      total = 0
      for (index, name) in enumerate(sort_file(filename))
      total += index*namescore(name)
      end
      total
      end

      println(PE_022())









      share|improve this question















      Project Euler - 22



      Names scores




      Using names.txt (right click and 'Save Link/Target As...'), a 46K text
      file containing over five-thousand first names, begin by sorting it
      into alphabetical order. Then working out the alphabetical value for
      each name, multiply this value by its alphabetical position in the
      list to obtain a name score.



      For example, when the list is sorted into alphabetical order, COLIN,
      which is worth $3 + 15 + 12 + 9 + 14 = 53$, is the 938th name in the
      list. So, COLIN would obtain a score of $938 × 53 = 49714$.



      What is the total of all the name scores in the file?






      While being fairly comfortable with the zen of Python, Julia is very new to me. Is the following code in line with Julia's vision?



      In particular I feel my handling of the dictionary is sub-optimal and especially the way i hard-code remove the parenthesis in names.



      Every hint on how to improve the code is welcome.





      ALPHABET_INDEX = Dict( letter => index for (index, letter) in enumerate('A':'Z'))

      function namescore(name)
      return sum(ALPHABET_INDEX[letter] for letter in name[2:end-1])
      end


      function sort_file(filename)
      file = open(filename)
      sort(split(readstring(filename),","))
      end


      function PE_022(filename="p022_names.txt")

      total = 0
      for (index, name) in enumerate(sort_file(filename))
      total += index*namescore(name)
      end
      total
      end

      println(PE_022())






      programming-challenge file julia






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Oct 16 '17 at 4:05









      Phrancis

      14.7k646139




      14.7k646139










      asked Oct 16 '17 at 3:43









      N3buchadnezzar

      2,5251332




      2,5251332






















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          0
          down vote













          the only change I would make is to remove your use of the Dict. Dicts are great when you need mutability, but here there is the much simpler solution Int(letter)-Int('A'). With this change, namescore becomes



          function namescore(name)
          return sum(Int(char)-Int('A') for letter in name[2:end-1])
          end


          This, however is not ideal, as we can take out the subtraction, yielding



          function namescore(name)
          return sum(Int(char) for letter in name[2:end-1]) - (lenth(name)-2) * Int('A')
          end


          I haven't done performance testing, but this should be a fair bit faster, as I would expect Int to be faster than a dictionary lookup.






          share|improve this answer





















          • I just used 'BenchmarkTools' , and saw no noticable change in performance. Here are the results, and here are the functions tested. However I do agree that using 'Int(letter)' is much cleaner. Perhaps dictionaries in Julia are fairly optimized compared to Python?
            – N3buchadnezzar
            Oct 16 '17 at 12:40












          • Pretty sure you want Int(char) - Int('A') + 1, and a similar change for your second version, since 'A' should evaluate to 1, not 0.
            – AJNeufeld
            Oct 23 at 18:18




















          up vote
          0
          down vote













          I solved the same problem a few months ago, here's the code I used:



          name_scores_total() = name_scores_total(@__DIR__()*"/022data_names.txt")
          name_scores_total(names_file::String) = name_scores_total(vec(readdlm(names_file, ',', String)))

          function name_scores_total(names_list::Array{String})
          sort!(names_list)
          alphabet_order = Dict((c, UInt8(c) - UInt8('A') + 1) for c in 'A':'Z')

          total_score = 0
          for (pos, name) in enumerate(names_list)
          try
          name_score = pos * sum(alphabet_order[c] for c in name)
          total_score += name_score
          catch er
          er isa KeyError && error("Only CAPITAL English letters are allowed in the file ($(name) has $(er.key) in it)")
          rethrow()
          end
          end

          total_score
          end

          if !isinteractive()
          println(name_scores_total())
          end


          Pretty similar to what your code does when it comes down to it (the main loop), but uses multiple dispatch to allow different types of input, and uses readdlm to read the file, which automatically strips the quotes around the input fields.



          I can't say for sure that this is a "better" way of doing things since I'm also still getting a feel for the language, but at the least it just offers a different approach.






          share|improve this answer





















            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%2f178003%2ffor-names-sake-project-euler-22%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            0
            down vote













            the only change I would make is to remove your use of the Dict. Dicts are great when you need mutability, but here there is the much simpler solution Int(letter)-Int('A'). With this change, namescore becomes



            function namescore(name)
            return sum(Int(char)-Int('A') for letter in name[2:end-1])
            end


            This, however is not ideal, as we can take out the subtraction, yielding



            function namescore(name)
            return sum(Int(char) for letter in name[2:end-1]) - (lenth(name)-2) * Int('A')
            end


            I haven't done performance testing, but this should be a fair bit faster, as I would expect Int to be faster than a dictionary lookup.






            share|improve this answer





















            • I just used 'BenchmarkTools' , and saw no noticable change in performance. Here are the results, and here are the functions tested. However I do agree that using 'Int(letter)' is much cleaner. Perhaps dictionaries in Julia are fairly optimized compared to Python?
              – N3buchadnezzar
              Oct 16 '17 at 12:40












            • Pretty sure you want Int(char) - Int('A') + 1, and a similar change for your second version, since 'A' should evaluate to 1, not 0.
              – AJNeufeld
              Oct 23 at 18:18

















            up vote
            0
            down vote













            the only change I would make is to remove your use of the Dict. Dicts are great when you need mutability, but here there is the much simpler solution Int(letter)-Int('A'). With this change, namescore becomes



            function namescore(name)
            return sum(Int(char)-Int('A') for letter in name[2:end-1])
            end


            This, however is not ideal, as we can take out the subtraction, yielding



            function namescore(name)
            return sum(Int(char) for letter in name[2:end-1]) - (lenth(name)-2) * Int('A')
            end


            I haven't done performance testing, but this should be a fair bit faster, as I would expect Int to be faster than a dictionary lookup.






            share|improve this answer





















            • I just used 'BenchmarkTools' , and saw no noticable change in performance. Here are the results, and here are the functions tested. However I do agree that using 'Int(letter)' is much cleaner. Perhaps dictionaries in Julia are fairly optimized compared to Python?
              – N3buchadnezzar
              Oct 16 '17 at 12:40












            • Pretty sure you want Int(char) - Int('A') + 1, and a similar change for your second version, since 'A' should evaluate to 1, not 0.
              – AJNeufeld
              Oct 23 at 18:18















            up vote
            0
            down vote










            up vote
            0
            down vote









            the only change I would make is to remove your use of the Dict. Dicts are great when you need mutability, but here there is the much simpler solution Int(letter)-Int('A'). With this change, namescore becomes



            function namescore(name)
            return sum(Int(char)-Int('A') for letter in name[2:end-1])
            end


            This, however is not ideal, as we can take out the subtraction, yielding



            function namescore(name)
            return sum(Int(char) for letter in name[2:end-1]) - (lenth(name)-2) * Int('A')
            end


            I haven't done performance testing, but this should be a fair bit faster, as I would expect Int to be faster than a dictionary lookup.






            share|improve this answer












            the only change I would make is to remove your use of the Dict. Dicts are great when you need mutability, but here there is the much simpler solution Int(letter)-Int('A'). With this change, namescore becomes



            function namescore(name)
            return sum(Int(char)-Int('A') for letter in name[2:end-1])
            end


            This, however is not ideal, as we can take out the subtraction, yielding



            function namescore(name)
            return sum(Int(char) for letter in name[2:end-1]) - (lenth(name)-2) * Int('A')
            end


            I haven't done performance testing, but this should be a fair bit faster, as I would expect Int to be faster than a dictionary lookup.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Oct 16 '17 at 4:29









            Oscar Smith

            2,698922




            2,698922












            • I just used 'BenchmarkTools' , and saw no noticable change in performance. Here are the results, and here are the functions tested. However I do agree that using 'Int(letter)' is much cleaner. Perhaps dictionaries in Julia are fairly optimized compared to Python?
              – N3buchadnezzar
              Oct 16 '17 at 12:40












            • Pretty sure you want Int(char) - Int('A') + 1, and a similar change for your second version, since 'A' should evaluate to 1, not 0.
              – AJNeufeld
              Oct 23 at 18:18




















            • I just used 'BenchmarkTools' , and saw no noticable change in performance. Here are the results, and here are the functions tested. However I do agree that using 'Int(letter)' is much cleaner. Perhaps dictionaries in Julia are fairly optimized compared to Python?
              – N3buchadnezzar
              Oct 16 '17 at 12:40












            • Pretty sure you want Int(char) - Int('A') + 1, and a similar change for your second version, since 'A' should evaluate to 1, not 0.
              – AJNeufeld
              Oct 23 at 18:18


















            I just used 'BenchmarkTools' , and saw no noticable change in performance. Here are the results, and here are the functions tested. However I do agree that using 'Int(letter)' is much cleaner. Perhaps dictionaries in Julia are fairly optimized compared to Python?
            – N3buchadnezzar
            Oct 16 '17 at 12:40






            I just used 'BenchmarkTools' , and saw no noticable change in performance. Here are the results, and here are the functions tested. However I do agree that using 'Int(letter)' is much cleaner. Perhaps dictionaries in Julia are fairly optimized compared to Python?
            – N3buchadnezzar
            Oct 16 '17 at 12:40














            Pretty sure you want Int(char) - Int('A') + 1, and a similar change for your second version, since 'A' should evaluate to 1, not 0.
            – AJNeufeld
            Oct 23 at 18:18






            Pretty sure you want Int(char) - Int('A') + 1, and a similar change for your second version, since 'A' should evaluate to 1, not 0.
            – AJNeufeld
            Oct 23 at 18:18














            up vote
            0
            down vote













            I solved the same problem a few months ago, here's the code I used:



            name_scores_total() = name_scores_total(@__DIR__()*"/022data_names.txt")
            name_scores_total(names_file::String) = name_scores_total(vec(readdlm(names_file, ',', String)))

            function name_scores_total(names_list::Array{String})
            sort!(names_list)
            alphabet_order = Dict((c, UInt8(c) - UInt8('A') + 1) for c in 'A':'Z')

            total_score = 0
            for (pos, name) in enumerate(names_list)
            try
            name_score = pos * sum(alphabet_order[c] for c in name)
            total_score += name_score
            catch er
            er isa KeyError && error("Only CAPITAL English letters are allowed in the file ($(name) has $(er.key) in it)")
            rethrow()
            end
            end

            total_score
            end

            if !isinteractive()
            println(name_scores_total())
            end


            Pretty similar to what your code does when it comes down to it (the main loop), but uses multiple dispatch to allow different types of input, and uses readdlm to read the file, which automatically strips the quotes around the input fields.



            I can't say for sure that this is a "better" way of doing things since I'm also still getting a feel for the language, but at the least it just offers a different approach.






            share|improve this answer

























              up vote
              0
              down vote













              I solved the same problem a few months ago, here's the code I used:



              name_scores_total() = name_scores_total(@__DIR__()*"/022data_names.txt")
              name_scores_total(names_file::String) = name_scores_total(vec(readdlm(names_file, ',', String)))

              function name_scores_total(names_list::Array{String})
              sort!(names_list)
              alphabet_order = Dict((c, UInt8(c) - UInt8('A') + 1) for c in 'A':'Z')

              total_score = 0
              for (pos, name) in enumerate(names_list)
              try
              name_score = pos * sum(alphabet_order[c] for c in name)
              total_score += name_score
              catch er
              er isa KeyError && error("Only CAPITAL English letters are allowed in the file ($(name) has $(er.key) in it)")
              rethrow()
              end
              end

              total_score
              end

              if !isinteractive()
              println(name_scores_total())
              end


              Pretty similar to what your code does when it comes down to it (the main loop), but uses multiple dispatch to allow different types of input, and uses readdlm to read the file, which automatically strips the quotes around the input fields.



              I can't say for sure that this is a "better" way of doing things since I'm also still getting a feel for the language, but at the least it just offers a different approach.






              share|improve this answer























                up vote
                0
                down vote










                up vote
                0
                down vote









                I solved the same problem a few months ago, here's the code I used:



                name_scores_total() = name_scores_total(@__DIR__()*"/022data_names.txt")
                name_scores_total(names_file::String) = name_scores_total(vec(readdlm(names_file, ',', String)))

                function name_scores_total(names_list::Array{String})
                sort!(names_list)
                alphabet_order = Dict((c, UInt8(c) - UInt8('A') + 1) for c in 'A':'Z')

                total_score = 0
                for (pos, name) in enumerate(names_list)
                try
                name_score = pos * sum(alphabet_order[c] for c in name)
                total_score += name_score
                catch er
                er isa KeyError && error("Only CAPITAL English letters are allowed in the file ($(name) has $(er.key) in it)")
                rethrow()
                end
                end

                total_score
                end

                if !isinteractive()
                println(name_scores_total())
                end


                Pretty similar to what your code does when it comes down to it (the main loop), but uses multiple dispatch to allow different types of input, and uses readdlm to read the file, which automatically strips the quotes around the input fields.



                I can't say for sure that this is a "better" way of doing things since I'm also still getting a feel for the language, but at the least it just offers a different approach.






                share|improve this answer












                I solved the same problem a few months ago, here's the code I used:



                name_scores_total() = name_scores_total(@__DIR__()*"/022data_names.txt")
                name_scores_total(names_file::String) = name_scores_total(vec(readdlm(names_file, ',', String)))

                function name_scores_total(names_list::Array{String})
                sort!(names_list)
                alphabet_order = Dict((c, UInt8(c) - UInt8('A') + 1) for c in 'A':'Z')

                total_score = 0
                for (pos, name) in enumerate(names_list)
                try
                name_score = pos * sum(alphabet_order[c] for c in name)
                total_score += name_score
                catch er
                er isa KeyError && error("Only CAPITAL English letters are allowed in the file ($(name) has $(er.key) in it)")
                rethrow()
                end
                end

                total_score
                end

                if !isinteractive()
                println(name_scores_total())
                end


                Pretty similar to what your code does when it comes down to it (the main loop), but uses multiple dispatch to allow different types of input, and uses readdlm to read the file, which automatically strips the quotes around the input fields.



                I can't say for sure that this is a "better" way of doing things since I'm also still getting a feel for the language, but at the least it just offers a different approach.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jun 25 at 13:53









                sundar

                1485




                1485






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f178003%2ffor-names-sake-project-euler-22%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

                    List directoties down one level, excluding some named directories and files

                    list processes belonging to a network namespace

                    list systemd RuntimeDirectory mounts