Is this string a palindrome (in Morse Code)?

16

Challenge

Inspired by this video

As you may know, a palindrome is a word that is spelled the same forward as it is backward. The word "PULP" is not a palindrome, but when translated into Morse Code (with the spacing between letters removed), "PULP" becomes ".--...-.-...--." which is a palindrome. Your task is to write a program or function which takes a string and returns whether that word is a palindrome in International Morse Code.

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: --..

Rules

Input

Input can be taken in any reasonable format. The input string will contain only letters in any case you prefer. The string will not contain spaces, numbers, or punctuation.

Output

Your program should output 1 of 2 constant distinct results based on whether the input is a palindrome, e.g. True/False, 1/0, HOTDOG/NOTHOTDOG

Scoring

This is so shortest answer in bytes wins. Standard loopholes are forbidden.

Test Cases

Input => Output

"PULP"       => True
"RESEARCHER" => True
"HOTDOGS"    => True
""           => True
"A"          => False
"RACECAR"    => False
"PROGRAMMING"=> False
"PUZZLES"    => False

Cowabunghole

Posted 2018-10-19T18:47:17.750

Reputation: 1 590

related – Luis felipe De jesus Munoz – 2018-10-19T18:57:44.240

4Only my vote is a hammer, I'd VTC this as a dupe of the challenge Luis linked; the bulk of most solutions is going to be converting the input to Morse code. – Shaggy – 2018-10-19T19:12:49.960

1It looks like all the solutions are just a Morse code mappings with a "same as reverse" check tacked on, so I'm closing as a duplicate. – xnor – 2018-10-20T04:05:36.520

2It's a shame this is closed as a duplicate, since the duplicate-target has specified (a) that input is from the standard input (disallowing functions) and (b) one must leave non [A-Z]|[A-z]|[0-9] as they are in the input. Together these make some answers here less than trivial to port. – Jonathan Allan – 2018-10-20T13:06:23.113

Oh man - it looks like I hammer open too! I thought I just made a single vote. I've hammered it closed again, but feel maybe it shouldn't be. – Jonathan Allan – 2018-10-20T13:08:42.553

(c) the digits have a pattern to exploit. – Jonathan Allan – 2018-10-20T13:31:32.663

I went ahead and ported my answer here to the target (here). It was not all that trivial, but porting back would be I guess.

– Jonathan Allan – 2018-10-20T14:43:16.767

Answers

7

Jelly,  35 32 27  25 bytes

-2 thanks to Dennis (shift the permutation to avoid %32)

Oị“¡\ḣḶɼz3ç³ƝMƒ§’Œ?¤ḃ2FŒḂ

Takes input in upper-case; output is 1 for true, 0 for false.

Try it online! Or see the test-suite.

How?

Oị“...’Œ?¤ḃ2FŒḂ - Link: list of characters (in [A-Za-z]), S   e.g. 'FoOl'
O               - to ordinals                                      [70,111,79,108]
 %32            - modulo by 32 (A->1, a->1, ...)                   [6,15,15,12]
         ¤      - nilad followed by link(s) as a nilad:
  “...’         -   base 250 literal = 41482574787853596522350494865
       Œ?       -   first permutation of [1,N] which resides at that
                -   index when all permutations of [1,N] are sorted
                -   = [8,16,10,24,26,27,18,20,4,23,25,11,1,17,13,15,3,22,12,19,6,5,14,21,28,9,7,2]
                - index into (modular-indexing & vectorises)       [17,14,14,19]
          ḃ2    - to bijective base 2 (vectorises)                 [[1,1,2,1],[2,2,2],[2,2,2],[1,2,1,1]]
            F   - flatten                                          [1,1,0,1,0,0,0,0,0,0,1,0,1,1]
             ŒḂ - is palindromic?                                  1

Previous 35 byte solution (also takes input in upper-case)...

ØẠḣ29“...’œ?iⱮ⁸d⁴BnⱮ/€FŒḂ - Link: list of characters (in [A-Z] only), S
ØẠ                        - alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
  ḣ29                     - head to index 29 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabc'
     “...’                - base 250 literal = 1222276956185766767980461920692
          œ?              - permutation at index = 'EAIWRUSJPaLbFVHcTNMDKGOBXCYZQ'
              ⁸           - chain's left argument = S       e.g. 'FOOL'
             Ɱ            - map with:
            i             -   first index of (char in 'EAI...')  [13,23,23,11]
                ⁴         - literal 16                           16
               d          - divmod                               [[0,13],[1,7],[1,7],[0,11]]
                 B        - to binary (vectorises)               [[[0],[1,1,0,1]],[[1],[1,1,1]],[[1],[1,1,1]],[[0],[1,0,1,1]]]
                     €    - for each:
                    /     -   reduce by:
                   Ɱ      -     map with:
                  n       -       not equal                      [[1,1,0,1],[0,0,0],[0,0,0],[1,0,1,1]]
                      F   - flatten                              [1,1,0,1,0,0,0,0,0,0,1,0,1,1]
                       ŒḂ - is palindromic?                      1

Jonathan Allan

Posted 2018-10-19T18:47:17.750

Reputation: 67 804

7

Jelly, 28 bytes

ØAŻŻ“¡9o|çṫ¡X1ỴỌġQ’œ?iⱮḃ2FŒḂ

Try it online!

ØA                             The uppercase alphabet.
  ŻŻ                           Prepend two zeroes.
    “¡9o|çṫ¡X1ỴỌġQ’œ?          Get the 73540211105102870315464559332nd permutation.
                                  (= “ETIANMSURWDKGOHVF0L0PJBXCYZQ”)
                     iⱮ        Find indices of input letters in this list.
                       ḃ2      Bijective base 2: map [1,2,3,4,5…] to
                                 [1], [2], [1,1], [1,2], [2,1], …
                         F     Flatten.
                          ŒḂ   Is palindrome?

I wrote this answer looking at one of these (read the rows from right-to-left, and you get my magic string!):

enter image description here

Lynn

Posted 2018-10-19T18:47:17.750

Reputation: 55 648

73,540,211,105,102,870,315,464,559,332nd... what?! How did you find that number? Also how does that not take *forever* to run? – Magic Octopus Urn – 2018-11-02T17:34:01.150

@MagicOctopusUrn Basically, it's an encoding of the order of the letters in that string relative to the order 00ABCDEFGHIJKLMNOPQRSTUVWXYZ. Jelly has built-ins to convert a permutation into such a number, and such a number back into the permutation. See factorial number base on Wikipedia.

– Lynn – 2018-11-02T17:54:47.080

1That is the coolest thing I've seen in a long time! So basically with factorials you can "know" where the permutation will lie, because the permutations are done in a specific order. Is that a constant time access? Linear? Log? Something else entirely? – Magic Octopus Urn – 2018-11-02T18:48:08.530

3

Dyalog APL, 24 bytes

⎕CY'dfns'
⎕←(⌽≡⊢)∊morse⍞

Try it online!

dfns never ceases to amaze

Zacharý

Posted 2018-10-19T18:47:17.750

Reputation: 5 710

2

MBASIC, 325 bytes

First attempt, before the big guns get here :-)

1 DATA .-,-...,-.-.,-..,.,..-.,--.,....,..,.---,-.-,.-..,--,-.,---,.--.,--.-,.-.,...,-,..-,...-,.--,-..-,-.--,--..
2 DIM C$(26):FOR I=1 TO 26:READ C$(I):NEXT:INPUT T$:FOR I=1 TO LEN(T$):N=ASC(MID$(T$,I,1))-64:S$=S$+C$(N):NEXT:L=LEN(S$):FOR I=1 TO L:IF MID$(S$,I,1)<>MID$(S$,(L+1)-I,1) THEN 4
3 NEXT:PRINT"True":END
4 PRINT"False

Output

? PULP
True

? RESEARCHER
True

? HOTDOGS
True

?
True

? A
False

? RACECAR
False

? PROGRAMMING
False

? PUZZLES
False

wooshinyobject

Posted 2018-10-19T18:47:17.750

Reputation: 171

2

JavaScript (Node.js), 111 bytes

x=>(u=[...x.replace(/./g,_=>"**ETIANMSURWDKGOHVF*L*PJBXCYZQ".indexOf(_).toString(2).slice(1))])+''==u.reverse()

Try it online!

l4m2

Posted 2018-10-19T18:47:17.750

Reputation: 5 985

2

Perl 6, 87 bytes

{$_ eq.flip}o*.trans(/./=>{S/.//}o{'  ETIANMSURWDKGOHVF L PJBXCYZQ'.index($/).base(2)})

Try it online!

Converts the word to a series of 1s and 0s and checks if it is palindromic.

Explanation:

             *.trans(/./=>  # Translate each letter of the input to
                                   '...'.index($/)   # The index of the letter in the lookup string
                                                  .base(2)  # Converted to binary
                          {S/.//}o{                       } # With the first digit removed
{$_ eq.flip}o   # Return if the string is equal to its reverse

Jo King

Posted 2018-10-19T18:47:17.750

Reputation: 38 234

2

Python 3, 172 148 104 bytes

First code golf ever. Please be kind and offer any help :)

This is based off the C# answer: https://codegolf.stackexchange.com/a/175126/83877. I took the same ideas and applied it to Python 3. I tried my best to golf-ify the code, but I am sure there is a lot more I can do.

EDIT 1: Thanks @Stephen and @Cowabunghole for helping me remove some whitespace and unnecessary code.

EDIT 2: Thanks @JoKing for the suggestion to do it in binary. This is a really neat trick where '-' and '.' are not even necessary. This led to a huge byte decrease.

Solution

def b(w):x=''.join(map(lambda c:bin('  ETIANMSURWDKGOHVF L PJBXCYZQ'.index(c))[3:],w));return x==x[::-1]

Try it online!

pwaivers

Posted 2018-10-19T18:47:17.750

Reputation: 21

1

Welcome to PPCG! Here's 152 bytes with whitespace golfed off: Try it online!

– Stephen – 2018-11-05T20:43:12.660

1A couple of tips to save a few characters: Remove whitespace everywhere you can. For example, you can change while i > 0: to while i>0: to save 2 bytes. Also, I could be wrong but I think you can do away with the > 0 altogether and just use while i:. Second, the statement in the while loop can go on the same line as the while, saving the newline and indentation. Last, this is terrible advice everywhere except when code golfing, but if you use Python 2 instead of Python 3, you can save 1 byte from using / instead of // for division. – Cowabunghole – 2018-11-05T20:43:36.137

1Oh, also, you can use ~-i instead of i-1. This is the same number of bytes, but you can then omit the parentheses which saves 2 bytes. – Cowabunghole – 2018-11-05T20:47:21.650

Thank you @Stephen. – pwaivers – 2018-11-05T20:50:41.310

Thank you @Cowabunghole. Two very useful suggestions. – pwaivers – 2018-11-05T20:51:05.350

1

You could do binary instead of using - and .. 105 bytes

– Jo King – 2018-11-05T21:04:59.877

Wow @JoKing, that is awesome! You should post that one instead. It so much more clever, that I don't want to take credit for it. – pwaivers – 2018-11-05T21:51:21.230

1

Nah, I've already got a Perl 6 answer that uses the technique. Feel free to use the technique

– Jo King – 2018-11-06T02:53:35.027

1

Pyth, 35 33 bytes

The code contains unprintable characters, so here's a hexdump.

00000000: 5f49 7358 7a47 632e 2207 0901 3f08 82ee  _IsXzGc."...?...
00000010: bd3f c256 9d54 c381 7dac 6590 37d3 c8f5  .?.V.T..}.e.7...
00000020: 52                                       R

Try it online. Test suite.

Explanation

Starting from ." the end of the code generates the Morse alphabet, with dots as \x08 and dashes as \x07, and separated by tabs.

c splits the string by the tabs.

XzG translates (X) the input (z) from the alphabet (G) to this "Morse alphabet".

s sums (joins) the Morse symbols together. For empty inputs, returns 0, but this is not a problem.

_I checks if the result does not change (I) when reversed (_). For empty input, checks if 0 does not change when negated.

PurkkaKoodari

Posted 2018-10-19T18:47:17.750

Reputation: 16 699

0

Retina 0.8.2, 87 bytes

[B-ILNPRSZ]
$&.
[AJKMOQT-Y]
$&-
}T`L`\EDKN_UMS\EWNRTTMWGAI_ISADKG
+`^(.)(.*)\1$
$2
^.?$

Try it online! Link includes test cases. Explanation:

[B-ILNPRSZ]
$&.

All the Morse codes for the letters in this set end with ..

[AJKMOQT-Y]
$&-

All the Morse codes for the letters in this set end with -.

T`L`\EDKN_UMS\EWNRTTMWGAI_ISADKG

Replace each letter with the letter whose Morse code is the prefix of that letter (here E and T are simply deleted via the unescaped _, but normally they would be turned into spaces). For instance, P is the Morse code for W with an extra . on the end; we added the . above so now all that remains is to decode the W.

}

Repeat the above stages until there are no letters left.

^(.)(.*)\1$
$2

If the first and last characters are the same, delete them both.

+`

Repeat for as many characters that match.

^.?$

If this was a palindrome, then there is at most one character left.

Neil

Posted 2018-10-19T18:47:17.750

Reputation: 95 035

0

Wolfram Language (Mathematica), 107 bytes

PalindromeQ[##2&@@@(IntegerDigits[Tr@StringPosition[" ETIANMSURWDKGOHVF L PJBXCYZQ",#],2]&/@Characters@#)]&

Try it online!

Similar to this Jelly answer: we think of Morse code as binary, and write down a string " ETIANMSURWDKGOHVF L PJBXCYZQ" where the position of a character, in binary, gives us its Morse code. But with an extra 1 prepended because we want to distinguish S = 000 and H = 0000, for instance. Then ##2&@@@ simultaneously gets rid of this leading 1 and flattens.

Misha Lavrov

Posted 2018-10-19T18:47:17.750

Reputation: 4 846

Huh, I would've expected Wolfram Language to have a Morse code built-in. Or does it have one, but it's too verbose? – Jack Brounstein – 2018-10-22T18:20:41.900

1I couldn't find one. (And the documentation includes example code for some audio commands which hard-codes Morse code, which I wouldn't expect if a built-in existed.) – Misha Lavrov – 2018-10-22T18:31:30.553

0

05AB1E, 37 bytes

v•1êÿµµÈ∞Ƶipδ8?a¡š%=тîδ/•3B0¡Aykè}JÂQ

Try it online!


Encodes the alphabet in base 3, converted to base 255:

12021110212102110101121022101111011012220212012110220210222012210221201210111020112011120122021120212202211

Base 255:

•1êÿµµÈ∞Ƶipδ8?a¡š%=тîδ/•

Then basically, I break it apart on the 0's, construct the string by position and check for palindrome.

Magic Octopus Urn

Posted 2018-10-19T18:47:17.750

Reputation: 19 422

0

C# (.NET Core), 191 bytes

a=>{var s="";int r=1,x=0,i;foreach(var t in a){var c="";for(i=" ETIANMSURWDKGOHVF L PJBXCYZQ".IndexOf(t);i>0;i/=2)c="-."[i--%2]+c;s+=c;}i=s.Length;for(;x<i;x++)r=s[x]==s[i-x-1]?r:0;return r;}

Try it online!

Part of this answer was adapted from Nick Larsen's morse code golf. Based on the comments on the answer, this could potentially be golfed further.

Ungolfed:

a => {
    var s = "";                 // initialize s
    int r = 1, x = 0, i;        // initialize r, x, and i

    /*
        This portion was adapted from Nick Larsen. He described it as follows:
            -- The string of characters is a heap in which the left child is a dot and the right child is a dash.
            -- To build the letter, you traverse back up and reverse the order.
        I have edited it to remove number support, which saves 34 bytes.
    */
    foreach(var t in a)
    {
        var c = "";
        for(i = " ETIANMSURWDKGOHVF L PJBXCYZQ".IndexOf(t); i > 0; i /= 2)
            c = "-."[i-- % 2] + c;
        s += c;
    }

    i = s.Length;               // reuse i and set to the length of the morse code string
    for(; x < i; x++)           // increment x until x reaches i
        r = s[x] == s[i - x - 1] ?      // if the xth character on the left side of s is equal to the xth character on the right side of s
                                    r :     // true: do not change r
                                        0;  // false: set r to zero (set to false)

    return r;
}

Meerkat

Posted 2018-10-19T18:47:17.750

Reputation: 371

0

PowerShell, 204 187 bytes

param($a);$a|% t*y|%{$b+=[convert]::ToString("  ETIANMSURWDKGOHVF L PJBXCYZQ".IndexOf($_),2).substring(1)};$c=($b=($b|% *ce 0 .|% *ce 1 -)).ToCharArray();[array]::Reverse($c);$b-eq-join$c

Try it online!

Errors on null string... Can anyone help with this?

Test code (After wrapping the code in a Script Block and assigned to variable $Z...):

$tests = @(
    "PULP", "True"
    "RESEARCHER", "True"
    "HOTDOGS", "True"
    "A", "False"
    "RACECAR", "False"
    "PROGRAMMING", "False"
    "PUZZLES", "False"
)
$outputs = @()
for($i = 0; $i -lt $tests.length/2; $i++){
    $output = New-Object "PSObject"
    $output  | Add-Member -MemberType NoteProperty -Name Name -Value "`"$($tests[2*$i])`""
    $output | Add-Member -MemberType NoteProperty -Name Expected -Value $tests[2*$i + 1]
    $output | Add-Member -MemberType NoteProperty -Name Result -Value $(&$Z -a $tests[2*$i])
    $outputs += $output 
}
$outputs | Format-Table

Output:

Name          Expected Result
----          -------- ------
"PULP"        True       True
"RESEARCHER"  True       True
"HOTDOGS"     True       True
"A"           False     False
"RACECAR"     False     False
"PROGRAMMING" False     False
"PUZZLES"     False     False

KGlasier

Posted 2018-10-19T18:47:17.750

Reputation: 211

Welcome to PPCG. It will be useful for you to look Tips for golfing in PowerShell

– mazzy – 2018-11-05T18:05:36.507

Thanks, @mazzy! – KGlasier – 2018-11-05T18:21:00.357