7
\$\begingroup\$

Your goal is to write a hash function, that accepts morse code character and returns a hash code that you get to define.

You can be sure, passed string will be:

  • One of the Latin characters (A-Z) encoded into Morse Code using . and -, or
  • One of the digits (0-9) encoded into Morse Code using . and -, or
  • Empty

So, there could be any of 37 different strings passed to you.

Requirements:

  • The returned number should be unique for all 37 strings
  • For empty string the function should return 0

Score:

  1. Initially, you have a 100 points.
  2. You will lose
    • 1 point for every bitwise operator in your code
    • 2 points for every addition (subtraction) operator in your code (operators in loop clauses (e.g. inside for(;;) or while() don't count)
    • 4 points for every multiplication (division, modulo, etc) operator
    • 6 points for every if (else) statement
    • 8 points for every loop statement (including loops in the called functions. You can presume that any called function has no more than one loop)
    • 12 points for every conditional operator
    • 200 points for using a built-in hash function

Bonuses:

  • If all numbers, produced by your function are less than N, you will get additional 137 - N points (of course, if the bonus is positive)

Winners:

Score matters, but be creative!


Example:

Score: 100 - 5*2 - 3*4 - 8 + (137 - 134) = 73

I know, this could be improved by removing modulo operator and make a loop starts from 1, but this is just an example

#include <iostream>
#include <map>
#include <set>

std::size_t hash_morse(const std::string& s)
{
    std::size_t ans = 0;

    for(std::size_t i = 0; i < s.size(); ++i)
    {
        ans += (s.at(i) - '-' + 2) * (i + 1) * (i + 1);
    }

    return ans % 134;
}

int main()
{
    std::map<std::string, char> m
    {
        {"",     0},
        {".-",   'A'},
        {"-...", 'B'},
        {"-.-.", 'C'},
        {"-..",  'D'},
        {".",    'E'},
        {"..-.", 'F'},
        {"--.",  'G'},
        {"....", 'H'},
        {"..",   'I'},
        {".---", 'J'},
        {"-.-",  'K'},
        {".-..", 'L'},
        {"--",   'M'},
        {"-.",   'N'},
        {"---",  'O'},
        {".--.", 'P'},
        {"--.-", 'Q'},
        {".-.",  'R'},
        {"...",  'S'},
        {"-",    'T'},
        {"..-",  'U'},
        {"...-", 'V'},
        {".--",  'W'},
        {"-..-", 'X'},
        {"-.--", 'Y'},
        {"--..", 'Z'},

        {".----",    '1'},
        {"..---",    '2'},
        {"...--",    '3'},
        {"....-",    '4'},
        {".....",    '5'},
        {"-....",    '6'},
        {"--...",    '7'},
        {"---..",    '8'},
        {"----.",    '9'},
        {"-----",    '0'}
    };

    std::map<std::size_t, std::string> hashes;

    for(const auto& elem: m)
    {
        auto hash = hash_morse(elem.first);

        if(hashes.find(hash) != hashes.end())
        {
            std::cout << "Collision" << std::endl;
            std::cout << '"' << hashes[hash] << R"(" and ")" << elem.first << '"' << std::endl;
            std::cout << "Hash: " << hash << std::endl;
            std::cout << std::endl;
        }
        else
        {
            hashes[hash] = elem.first;
        }
    }

    std::cout << "Total amount of collisions: " << (m.size() - hashes.size()) << std::endl;

    return 0;
}
\$\endgroup\$
19
  • 1
    \$\begingroup\$ Although this isn't an exact duplicate of Morse code to standard output, it's close enough that most answers will be portable both ways. \$\endgroup\$ Commented Jan 31, 2014 at 12:46
  • \$\begingroup\$ Wait, does string find/replace count as a loop? \$\endgroup\$
    – Doorknob
    Commented Jan 31, 2014 at 13:24
  • \$\begingroup\$ By "binary operation" did you mean "bitwise operation"? Addition and multiplication are binary operations. \$\endgroup\$ Commented Jan 31, 2014 at 13:25
  • 2
    \$\begingroup\$ I'm pretty sure as soon as you remove loops, you remove turing completeness(recursion is still looping). \$\endgroup\$
    – Cruncher
    Commented Jan 31, 2014 at 14:10
  • 1
    \$\begingroup\$ What do you mean by "Score matters, but be creative"? I'm assuming the highest score wins, but you may want to clarify that. Is creativity solely a tie-breaker? If not, then it's not objective as is. \$\endgroup\$
    – user344
    Commented Jan 3, 2015 at 19:25

10 Answers 10

8
\$\begingroup\$

Arguably perfect score

There are some possible loopholes in the scoring system. In particular,

8 points for every loop statement (including loops in the called functions. You can presume that any called function has no more than one loop)

According to PHP documentation,

array() is a language construct used to represent literal arrays, and not a regular function.

So it's arguable that

$hash = array(
    '' => 0,
    '.-' => -1,
    ...
);
return $hash[$morse];

contains no called functions and should score a perfect 100 + (137 - 1) = 236 points.

\$\endgroup\$
4
  • \$\begingroup\$ I think this answer demonstrates that array/hash look-up either needs to be disallowed, or heavily penalized. \$\endgroup\$
    – primo
    Commented Jan 31, 2014 at 15:38
  • 15
    \$\begingroup\$ I would go further and say that it demonstrates that attempting to write scoring systems based around language constructs is doomed to fail unless you restrict people to using one language. \$\endgroup\$ Commented Jan 31, 2014 at 15:39
  • \$\begingroup\$ Does array look up implicitly use a for loop or hash? \$\endgroup\$ Commented Jan 29, 2017 at 3:43
  • 1
    \$\begingroup\$ @RohanJhunjhunwala, I don't know how it's implemented. FWIW nowadays I would cast a close vote and ask OP to sandbox the question rather than posting a protest answer, but that's a sign of how the site culture has changed. \$\endgroup\$ Commented Jan 29, 2017 at 9:02
7
\$\begingroup\$

bash — 236 points

I understand there's some griping over using negative numbers, so have revised:

echo '' '[morse code]'|grep -o ' [\.-]*'|tr -t '.-' '19'|sed 's/ /0./g'|awk '{printf("%g\n",$0)}'

Will generate codes from 0.1 to 0.99999 for valid Morse Code and 0 for empty input.

e.g.

$ echo '' '. - .. -- .-.- -.-. ..... -----'|grep -o ' [\.-]*'|tr -t '.-' '19'|sed 's/ /0./g'|awk '{printf("%g\n",$0)}'
0.1
0.9
0.11
0.99
0.1919
0.9191
0.11111
0.99999

As per specs, empty input '' returns 0:

$ echo '' ''|grep -o ' [\.-]*'|tr -t '.-' '19'|sed 's/ /0./g'|awk '{printf("%g\n",$0)}'
0

Points Calculation

Starting with 100, deduct:

  • 1 point for every bitwise operator - none
  • 2 points for every addition (subtraction) operator - none
  • 4 points for every multiplication (division, modulo, etc) operator - none
  • 6 points for every if (else) statement - none
  • 8 points for every loop statement - none
  • 12 points for every conditional operator - none
  • 200 points for using a built-in hash function - none

So still have 100 points.

Bonus Calculation

All numbers are less than 1 (largest is 0.99999 for ----- a.k.a. Morse Code Zero), so the bonus is 137 - 1 or 136 points, again for a total of 236 points.


bash — 236 points

echo '' '[morse code]'|grep -o ' [\.-]*'|tr -t '.-' '67'|sed 's/ /-0/g'|awk '{printf("%d\n",$0)}'

Will generate codes from -77777 to -6 for valid Morse Code and 0 for empty input.

e.g.

$ echo '' '. - ..--. -..- .--- .. -..-. .. -----'|grep -o ' [\.-]*'|tr -t '.-' '67'|sed 's/ /-0/g'|awk '{printf("%d\n",$0)}'
-6
-7
-66776
-7667
-6777
-66
-76676
-66
-77777

As per specs, empty input '' returns 0:

$ echo '' ''|grep -o ' [\.-]*'|tr -t '.-' '67'|sed 's/ /-0/g'|awk '{printf("%d\n",$0)}'
0

Points Calculation

Starting with 100, deduct:

  • 1 point for every bitwise operator - none
  • 2 points for every addition (subtraction) operator - none
  • 4 points for every multiplication (division, modulo, etc) operator - none
  • 6 points for every if (else) statement - none
  • 8 points for every loop statement - none
  • 12 points for every conditional operator - none
  • 200 points for using a built-in hash function - none

So still have 100 points.

Bonus Calculation

All numbers are less than 1 (largest is 0 for an empty input), so the bonus is 137 - 1 or 136 points for a total of 236 points.

\$\endgroup\$
3
  • \$\begingroup\$ You realize that every valid hash which negates its output would automatically have a bonus of 136. Clearly, the author intended the maximum bonus to be 100. \$\endgroup\$
    – primo
    Commented Jan 31, 2014 at 16:11
  • \$\begingroup\$ From the specs "Your goal is to write a hash function, that accepts Morse Code characters and returns a hash code that you get to define." Standard hash codes, e.g. from md5 or sha1 can be interpreted as negative numbers, especially in languages without unsigned types like Java or Basic. There are two requirements: the returned number should be unique for all 37 strings, and for empty strings the function should return 0. Both are met. \$\endgroup\$
    – user15259
    Commented Jan 31, 2014 at 16:22
  • \$\begingroup\$ There are 36 morse codes in this challenge. The 137-N formula should suggest that the author is referring to a positive, integer result. By skirting the requirements you are just wasting your time, because he will just write his intentions better as soon as he sees answers such as these. \$\endgroup\$
    – Tobia
    Commented Jan 31, 2014 at 23:00
6
\$\begingroup\$

Ruby 100 - 6 (one if/else) - 2 (one subtraction) = 92 + 75 (largest value is 62) = 167 (159 if string find/replace counts as looping)

code = gets.chomp
if code.empty?
  p -1
else
  p ('1' + code.gsub(/./){|c| c.ord - 45 }).to_i(2)
end

Simply does a find/replace on the string, but replaces each character with its ASCII code - 45. This turns - into 0 and . into 1. It then prepends a 1 (to handle leading zeroes) and parses this string as binary.

\$\endgroup\$
1
  • \$\begingroup\$ Same comment as to primo: 137 - 63 = 74 for the bonus. (And clarification to question says that find/replace counts as looping). \$\endgroup\$ Commented Jan 31, 2014 at 14:57
5
\$\begingroup\$

GolfScript (143 164 192 points)

I was slightly wrong about the relationship with the other Morse question: this one is much much simpler.

2base

scores 100 - 8 points for an implicit loop = 92, with no bonus.

2base 87%

scores 100 - 4 points for a modulo - 8 points for an implicit loop + (137 - 82) bonus points for a total of 143 points.

That has two parameters which can potentially be optimised to improve the bonus. The best I've found so far is

46base 62%

for N=61 and a total of 164 points.

But it's possible to do even better.

2base MAGIC_STRING=

scores 100 - 8 points for an implicit loop + (137 - 37) bonus points for a total of 192 points, where MAGIC_STRING is a suitable 1427-character string literal:

"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1E\x0F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x18\v\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x11\x15\x0E!\x1C\x1F\x1D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\e$#\r\"\f\x14\x1A\x00\x16\x00\x10 \x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\n\x00\t\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\a\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x05\x06"
\$\endgroup\$
2
  • \$\begingroup\$ @primo, that's what comes of copying the string from a command window output rather than redirecting to a file and copying from the file. = is not a looping function: it's an array indexing operation. No language that I know of implements those with a loop. \$\endgroup\$ Commented Jan 31, 2014 at 15:23
  • \$\begingroup\$ You're right. I Confused it with find. \$\endgroup\$
    – primo
    Commented Jan 31, 2014 at 15:26
2
\$\begingroup\$

Perl - score = 165

print~-oct'0b1'.<>=~y/.-/10/r

Re-interpretting morse as binary, with a 1 prepended.

Score break-down

  • -1 - bitwise inversion (~)
  • -8 - loop statement (y)
  • +74 - the largest value produced is 62
\$\endgroup\$
3
  • \$\begingroup\$ I make 137 - 63 = 74 for the bonus. \$\endgroup\$ Commented Jan 31, 2014 at 14:53
  • \$\begingroup\$ 180+ should be possible. Go go magic formula grinder. \$\endgroup\$
    – primo
    Commented Jan 31, 2014 at 14:57
  • \$\begingroup\$ Actually, yes, you're right... \$\endgroup\$ Commented Jan 31, 2014 at 14:59
2
\$\begingroup\$

Scheme:

Initial 100 points and it has no reduction since there was no mention of switch/case there and the / is part of the number not an operator..

The output is a rational number between 0 and 1. Extra score would be 137-1=136.

Total score: 236

(define (hash-morse-code code)
  (case code
    (("") 0)
    ((".-") 1)
    (("-...") 1/2)
    (("-.-.") 1/3)
    (("-..") 1/4)
    ((".") 1/5)
    (("..-.") 1/6)
    (("--.") 1/7)
    (("....") 1/8)
    (("..") 1/9)
    ((".---") 1/10)
    (("-.-") 1/11)
    ((".-..") 1/12)
    (("--") 1/13)
    (("-.") 1/14)
    (("---") 1/15)
    ((".--.") 1/16)
    (("--.-") 1/17)
    ((".-.") 1/18)
    (("...") 1/19)
    (("-") 1/20)
    (("..-") 1/21)
    (("...-") 1/22)
    ((".--") 1/23)
    (("-..-") 1/24)
    (("-.--") 1/25)
    (("--..") 1/26)
    ((".----") 1/27)
    (("..---") 1/28)
    (("...--") 1/29)
    (("....-") 1/30)
    ((".....") 1/31)
    (("-....") 1/31)
    (("--...") 1/32)
    (("---..") 1/33)
    (("----.") 1/34)
    (("-----") 1/35)))

(hash-morse-code "...") => 1/19
\$\endgroup\$
0
\$\begingroup\$

Java - 100 + 136 = 236

public static int hashMorse(String toHash) {
    switch (toHash){
        case ".-": //A
            return -36;
        case "-...": //B
            return -35;
        case "-.-.": //C
            return -34;
        case "-..": //D
            return -33;
        case ".": //E
            return -32;
        case "..-.": //F
            return -31;
        case "--.": //G
            return -30;
        case "....": //H
            return -29;
        case "..": //I
            return -28;
        case ".---": //J
            return -27;
        case "-.-": //K
            return -26;
        case ".-..": //L
            return -25;
        case "--": //M
            return -24;
        case "-.": //N
            return -23;
        case "---": //O
            return -22;
        case ".--.": //P
            return -21;
        case "--.-": //Q
            return -20;
        case ".-.": //R
            return -19;
        case "...": //S
            return -18;
        case "-": //T
            return -17;
        case "..-": //U
            return -16;
        case "...-": //V
            return -15;
        case ".--": //W
            return -14;
        case "-..-": //X
            return -13;
        case "-.--": //Y
            return -12;
        case "--..": //Z
            return -11;
        case ".----": //1
            return -10;
        case "..---": //2
            return -9;
        case "...--": //3
            return -8;
        case "....-": //4
            return -7;
        case ".....": //5
            return -6;
        case "-....": //6
            return -5;
        case "--...": //7
            return -4;
        case "---..": //8
            return -3;
        case "----.": //9
            return -2;
        case "-----": //0
            return -1;
        default:
            return 0;
    }
}

All those - signs don't count; they stand for the literal number. If you want to count them, then I'll just replace all those numbers with the binary literal (no minuses then).

Switches are free according to the question; neither an if nor an else. If you don't want switches, I'll just replace it with a HashMap

The largest possible number is 0, for the empty string or invalid strings.


Don't like negative numbers? This works (score of 200):

public static int hashMorse(String toHash) {
    switch (toHash){
        case ".-": //A
            return 36;
        case "-...": //B
            return 35;
        case "-.-.": //C
            return 34;
        case "-..": //D
            return 33;
        case ".": //E
            return 32;
        case "..-.": //F
            return 31;
        case "--.": //G
            return 30;
        case "....": //H
            return 29;
        case "..": //I
            return 28;
        case ".---": //J
            return 27;
        case "-.-": //K
            return 26;
        case ".-..": //L
            return 25;
        case "--": //M
            return 24;
        case "-.": //N
            return 23;
        case "---": //O
            return 22;
        case ".--.": //P
            return 21;
        case "--.-": //Q
            return 20;
        case ".-.": //R
            return 19;
        case "...": //S
            return 18;
        case "-": //T
            return 17;
        case "..-": //U
            return 16;
        case "...-": //V
            return 15;
        case ".--": //W
            return 14;
        case "-..-": //X
            return 13;
        case "-.--": //Y
            return 12;
        case "--..": //Z
            return 11;
        case ".----": //1
            return 10;
        case "..---": //2
            return 9;
        case "...--": //3
            return 8;
        case "....-": //4
            return 7;
        case ".....": //5
            return 6;
        case "-....": //6
            return 5;
        case "--...": //7
            return 4;
        case "---..": //8
            return 3;
        case "----.": //9
            return 2;
        case "-----": //0
            return 1;
        default:
            return 0;
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ HashMap definitely isn't free. It has loops in both put and get. \$\endgroup\$ Commented Jan 31, 2014 at 23:12
  • \$\begingroup\$ @PeterTaylor what about python's dictionaries? Can I use those? \$\endgroup\$
    – Justin
    Commented Feb 1, 2014 at 0:53
  • \$\begingroup\$ Probably, although then it's going to look very similar to my PHP answer. switch is more interesting because no-one else had done it. \$\endgroup\$ Commented Feb 1, 2014 at 7:54
0
\$\begingroup\$

Java - 100 + 136 = 236

public static int hash(String morse){
    try{
        morse.charAt(0);
    }catch (IndexOutOfBoundsException e){
        return 0;
    }
    return Integer.parseInt("-1" + help(morse), 2);
}
private static String help(String morse) {
    int a = 0;
    try {
        a = (int) morse.charAt(0);
    } catch (IndexOutOfBoundsException e) {
        return "";
    }
    a = Integer.parseInt(String.valueOf(Integer.toString(a, 2).charAt(4)));
    return a + help(morse.substring(1));
}

call hash(someString); to use this function. I'm working on a loop-free alternative to Integer.parseInt and Integer.toString.

I avoided the penalties by:

  • using recursion instead of loops
  • using Strings and String concatenation instead of numbers

So I get 100 + 136 as the largest output is 0.

\$\endgroup\$
1
  • \$\begingroup\$ They use loops. So does String.format. \$\endgroup\$ Commented Jan 31, 2014 at 23:10
0
\$\begingroup\$

JavaScript, 217pts

replace : Minus 8pts (loop)
replace : Minus 8pts (loop)
/ 100000: Minus 4pts (division)

100 - 20 = 80 + (137 - 0) = 217

function mc2(s) {
    return s.replace(/\./g,'1').replace(/-/g,'2') / 100000
}

JavaScript 199pts

for     : Minus  8pts (loop)
r+=     : Minus  2pts (addition)
(c>'-') : Minus  6pts (if)
c>'-'   : Minus 12pts (conditional operator)
:2      : Minus  6pts (else)
r/      : Minus  4pts (division)

100-38pts = 62pts + (137-0) = 199pts

function mc2(s) {
    r=''
    for(i=0;(c=s[i]);i++)r+=(c>'-')?1:2
    return r/100000
}
\$\endgroup\$
-1
\$\begingroup\$

Python, 236

Now, Peter Taylor claims to have a perfect score. But really, he's only got 200. Negative numbers all being smaller than zero, my bonus is 137-1, so this solution is 36 points better.

F = lambda s:-eval(''.join([
'12340'[s[0:].find('-')],'12340'[s[0:].find('.')],
'12340'[s[1:].find('-')],'12340'[s[1:].find('.')],
'12340'[s[2:].find('-')],'12340'[s[2:].find('.')],
'12340'[s[3:].find('-')],'12340'[s[3:].find('.')],
'12340'[s[4:].find('-')],'12340'[s[4:].find('.')]]))
\$\endgroup\$
5
  • \$\begingroup\$ Does find not contain a loop? \$\endgroup\$ Commented Jan 31, 2014 at 23:07
  • \$\begingroup\$ Ah, missed the bit on functions. \$\endgroup\$
    – boothby
    Commented Feb 1, 2014 at 0:21
  • \$\begingroup\$ Waitaminute. We can assume "no more than one"? How 'bout I assume zero, which is certainly no more than one, and don't change my answer in the least. \$\endgroup\$
    – boothby
    Commented Feb 1, 2014 at 0:23
  • \$\begingroup\$ I don't think that's a plausible interpretation. \$\endgroup\$ Commented Feb 1, 2014 at 7:24
  • \$\begingroup\$ I don't think so either, but that's what a literal reading of the rules suggests. I think I'm being generous, actually, by not updating my score to reflect an assumption of a negative number of loops in the function calls. \$\endgroup\$
    – boothby
    Commented Feb 1, 2014 at 15:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.