他们叫我莫尔斯探长


20

您的任务(如果您选择接受它)是确定给定的输入字符串是点重还是Dash重。

当字符串的摩尔斯表示形式包含的点多于破折号时,则表示该点很重。例如,字母E是单个点,这意味着它是点重的。

输入值

  • 输入字符串仅包含[a-z]或范围内的字符[A-Z]。您可以决定它们应该全部为大写还是全部为小写。AAA很好,aaa很好,aAa不是。
  • 输入字符串的长度始终至少为1个字符。
  • 您可能会假设输入字符串永远不会有相同数量的点和破折号。

输出量

对于包含更多点字符的输入,您应该返回Truthy
对于包含更多破折号的输入,应返回Falsy。
编辑:我也将允许点的正值和破折号的负值。

测试用例

| input | morse representation | result          |
|------------------------------------------------|
| S     | ...                  | Truthy          |
| k     | -.-                  | Falsy           |
| HELLO | .... . .-.. .-.. --- | Truthy          |
| code  | -.-. --- -.. .       | Falsy           |

参考

国际摩尔斯电码

这是。以字节为单位的最短代码获胜。



4
对于dotheavy,我们能否返回大于0的值,对于dash-heavy,是否可以返回负值?
无知的体现

@EmbodimentofIgnorance对我有效,只要您在帖子中指定即可。我认为它通常不会通过真实的虚假测试,但是在这种情况下,它感觉像是一个不错的解决方案,因此我将允许它
Bassdrop Cumberwubwubwub

Answers:


5

APL(Dyalog扩展)24  15 字节SBCS

-9感谢Ven

以大写字母为参数的匿名默认前缀函数。

>/'.-'⍧∊∘⌂morse

在线尝试!

⌂morse 转换为莫尔斯弦列表,
 然后
ϵ nlist(展平)
'.-'⍧ 计算点中的点数和破折号
>/ 多于破折号?(大于减少量)


为什么默认情况下没有扩展预加载dfns?
ngn

@ngn它现在的内置
亚当

7

IBM PC DOS,8088组件, 54 35字节

-19字节使用差异法

ac2c 41d0 d8d7 7206 51b1 04d2 e859 240f 2c03 02e0 e2ea 3534 4527 4125 1303 1462 4523 13

未组装:

; compare dashes and dots in a morse code string
; input:
;   I: pointer to input string (default SI)
;   IL: length of input string (default CX)
;   TBL: pointer to data table (default BX)
; output:
;   Sign/OF flags: Dot-heavy: SF == OF (JGE), Dash-heavy: SF != OF (JL)
MORSE_DD    MACRO   I, IL, TBL
            LOCAL   LOOP_LETTER, ODD
        IFDIFI <I>,<SI>     ; skip if S is already SI
    MOV  SI, I              ; load string into SI 
        ENDIF
        IFDIFI <IL>,<CX>    ; skip if IL is already CX
    MOV  CX, IL             ; set up loop counter
        ENDIF
        IFDIFI <TBL>,<BX>   ; skip if TBL is already BX
    MOV  BX, OFFSET TBL     ; load letter table into BX
        ENDIF
LOOP_LETTER:
    LODSB                   ; load next char from DS:SI into AL, advance SI
    ;AND  AL, 0DFH           ; uppercase the input letter (+2 bytes)
    SUB  AL, 'A'            ; convert letter to zero-based index
    RCR  AL, 1              ; divide index by 2, set CF if odd index
    XLAT                    ; lookup letter in table
    JC   ODD                ; if odd index use low nibble; if even use high nibble
    PUSH CX                 ; save loop counter (since SHR can only take CL on 8088)
    MOV  CL, 4              ; set up right shift for 4 bits
    SHR  AL, CL             ; shift right
    POP  CX                 ; restore loop counter
ODD:
    AND  AL, 0FH            ; mask low nibble
    SUB  AL, 3              ; unbias dash/dot difference +3 positive
    ADD  AH, AL             ; add letter difference to sum (set result flags)
    LOOP LOOP_LETTER
        ENDM

TBL DB 035H, 034H, 045H, 027H, 041H, 025H, 013H, 003H, 014H, 062H, 045H, 023H, 013H

说明

仅使用8088兼容指令,以Intel / MASM语法作为MACRO(基本上是函数)实现。输入为大写字符串(或+2个字节以允许使用大小写混合),输出Truthy / Falsy结果为SF == OF(使用JGJL测试)。

字母差异表的值存储为二进制半字节,因此总共只需要13个字节。

原始文件(54个字节):

; compare dashes and dots in a Morse code string
; input:
;   I: pointer to input string (default SI)
;   IL: length of input string (default CX)
;   TBL: pointer to data table
; output:
;   Carry Flag: CF=1 (CY) if dot-heavy, CF=0 (NC) if dash-heavy
MORSE_DD    MACRO   I, IL, TBL
            LOCAL   LOOP_LETTER
        IFDIFI <I>,<SI>     ; skip if S is already SI
    MOV  SI, I              ; load string into SI 
        ENDIF
        IFDIFI <IL>,<CX>    ; skip if IL is already CX
    MOV  CX, IL             ; set up loop counter
        ENDIF
    MOV  BX, OFFSET TBL     ; load score table into BX
    XOR  DX, DX             ; clear DX to hold total score
LOOP_LETTER:
    LODSB                   ; load next char from DS:SI into AL, advance SI
    ;AND  AL, 0DFH           ; uppercase the input letter (+2 bytes)
    SUB  AL, 'A'            ; convert letter to zero-based index
    XLAT                    ; lookup letter in table
    MOV  AH, AL             ; examine dot nibble
    AND  AH, 0FH            ; mask off dash nibble
    ADD  DH, AH             ; add letter dot count to total
    PUSH CX                 ; save loop counter (since SHR can only take CL)
    MOV  CL, 4              ; set up right shift for 4 bits
    SHR  AL, CL             ; shift right
    POP  CX                 ; restore loop counter
    ADD  DL, AL             ; add letter dash count to total
    LOOP LOOP_LETTER
    CMP  DL, DH             ; if dot-heavy CF=1, if dash-heavy CF=0
        ENDM

; data table A-Z: MSN = count of dash, LSN = count of dot
TBL DB 011H, 013H, 022H, 012H, 001H, 013H, 021H, 004H, 002H 
    DB 031H, 021H, 013H, 020H, 011H, 030H, 022H, 031H, 012H
    DB 003H, 010H, 012H, 013H, 021H, 022H, 031H, 022H

说明

仅使用8088兼容指令,以Intel / MASM语法作为MACRO(基本上是函数)实现。作为字符串输入,在进位标志中输出“真/假”结果。分数表包含每个字母的破折号和点数。

输入为大写。添加2个字节以采用小写或混合大小写。

示例测试程序(作为IBM PC DOS独立COM可执行文件)

    SHR  SI, 1              ; point SI to DOS PSP
    LODSW                   ; load arg length into AL, advance SI to 82H
    MOV  CL, AL             ; set up loop counter in CH
    DEC  CX                 ; remove leading space from letter count

    MORSE_DD SI, CX, TBL    ; execute above function, result is in CF

    MOV  DX, OFFSET F       ; default output to "Falsy" string
    JA   DISP_OUT           ; if CF=0, result is falsy, skip to output
    MOV  DX, OFFSET T       ; otherwise CF=1, set output to "Truthy" string
DISP_OUT:
    MOV  AH, 09H            ; DOS API display string function
    INT  21H
    RET

T   DB "Truthy$"
F   DB "Falsy$"

示例输出:

在此处输入图片说明

下载测试程序DD.COM

或在线尝试! 我不知道在线TIO可以直接链接到DOS可执行文件,但是您只需几个步骤即可使用它:

  1. DD.COM下载为ZIP文件
  2. 转到https://virtualconsoles.com/online-emulators/DOS/
  3. 上载刚刚下载的ZIP文件,然后单击“开始”。
  4. 输入DD HelloDD code输入您的内心内容

我可能会丢失一些东西,但是该宏在进入时是否不假定AH = 0?当然,该假设在使用测试程序时有效。
gastropner

1
好眼睛!该假设基于DOS执行的初始启动寄存器值,几乎所有版本的DOS都0000h用于AX源:fysnet.net/yourhelp.htm
640KB

从一个组装高尔夫球手到另一个高尔夫球手:太好了!使用纯粹的8088兼容指令的额外样式点。那是一个平台,代码打高尔夫球在很大程度上等同于优化,而这确实是一种失落的艺术。很好地使用,XLAT可以精确地执行其意图。如果您实际上是针对速度进行优化,则希望进行WORD大小的查找。即使在具有贫乏的8位外部总线的8088上,这仍然是速度上的胜利,因为您可以在不增加代码大小的情况下将吞吐量提高一倍,只需节省一条XCHG指令即可。
科迪·格雷

@CodyGray谢谢!当挑战与平台和指令集很好地结合在一起时,总是很有趣。此外XLAT,即使您需要6个字节向右移4位(在)中,也可以在1字节的原始PC上完成8088上的原始操作(例如),这很巧妙LOOP
640KB

对。为了提高性能,您肯定希望通过1进行4个单独的换档,以消除推压和弹出声。甚至没有更多的字节数(+2),因此总体来说是净赢球,但不利于打高尔夫球。当挑战符合ISA的要求时,真正的乐趣就来了,您必须全神贯注地寻找新的,创新的方法来应用现有的构建基块。1字节的字符串指令对于8088的性能和打高尔夫球确实非常有用。我在真实代码中使用它们。我猜XLAT并不是我经常使用的东西,我想是因为现代架构使我偏向于LUT。
科迪·格雷

7

的Java(JDK) 131 124 110 84 64个字节

有趣的是,“点”是重点,而“破”是点重。

将所有大写形式作为输入IntStream(向下滚动以获得实际String8个字节的版本)。我已经有相当多的帮助,这个高尔夫球之一:由于过期数据为高尔夫20个字节,以尼尔打高尔夫球26个字节,以奥利维尔格雷打高尔夫球18个字节和凯文Cruijssen打高尔夫球2个字节。

在双引号中包含26个不可打印的字符。

c->c.map(a->"".charAt(a-65)-4).sum()>0

在线尝试!

取消高尔夫:

c -> // lambda taking input as an IntStream in upper case and returning a boolean
  c.map(a -> "" // map each character's ASCII value to its net dot impact (unprintable characters here)
    .charAt(a - 65) // translate the ASCII code into a zero-based index into the above string (65 is 'A')
    - 4) // unprintables are > 0, this restores the proper values
  .sum() > 0 // add up all the values, positive sum indicates a dot-heavy input string

的Java(JDK) 131 124 110 84 72个字节

对于纯粹主义者;将输入作为String。感谢Expired Data高尔夫球20字节,Neil高尔夫球26字节,OlivierGrégoire高尔夫球10字节。

s->s.chars().map(a->"".charAt(a-65)-4).sum()>0

在线尝试。

取消高尔夫:

s -> // lambda taking input as a String in upper case and returning a boolean
  s.chars() // convert to a stream of characters
  .map(a -> "" // map each character's ASCII value to its net dot impact (unprintable characters here)
    .charAt(a - 65) // translate the ASCII code into a zero-based index into the above string (65 is 'A')
    - 4) // unprintables are > 0, this restores the proper values
  .sum() > 0 // add up all the values, positive sum indicates a dot-heavy input string



2
为什么不使用"35344527512513031462452313".charAt(a-65)-51
尼尔


1
@OlivierGrégoire您的66字节实际上是65字节,因为您忘记删除结尾的分号。但是,使用不可打印的字符可以再节省1个字节:64个字节
Kevin Cruijssen

4

果冻,21 字节

Oị“ÆġwıMƥ)ɠịṙ{’D¤Æm>4

在线尝试!

怎么样?

Oị“ÆġwıMƥ)ɠịṙ{’D¤Æm>4 - Link: list of characters ([A-Z]), S
                ¤     - nilad followed by link(s) as a nilad:
  “ÆġwıMƥ)ɠịṙ{’       -   base 250 integer = 14257356342446455638623624
               D      -   to decimal digits
                      -   -- that is the number of dots less the number of dashes plus 4
                      -      ... for each of OPQRSTUVWXYZABCDEFGHIJKLMN
O                     - ordinals of S   e.g. "ATHROUGHZ" -> [65,84,72,82,79,85,71,72,90]
 ị                    - index into (1-indexed & modular, so O gets the 79%26 = 1st item
                      -                                  or A gets the 65%26 = 13th item
                 Æm   - arithmetic mean
                   >4 - greater than 4?

4

05AB1E22 21字节

由于节省了一个字节 Kevin Cruijssen,

SA•U(Õþć6Δ
»›I•‡3-O.±

在线尝试!

说明

•U(Õþć6Δ
»›I•

35344527512513031462452313压缩到基体255。

S              # split input into list of chars
       ‡       # transliterate
 A             # the lowercase alphabet
  •...•        # with the digits from the compressed string
        3-     # subtract 3 from each              
          O    # then sum the result
           .±  # and take the sign

您可以通过将地图替换为来保存字节S
凯文·克鲁伊森

@KevinCruijssen:谢谢!我确定我已经尝试过,但是显然没有:)
Emigna

3
usdgpsahsoaboutlopezgbidolCv = ord(c)*3%83%8

@ Arnauld:有趣!您是怎么发现的?我希望不要用手:P
Emigna

1
我把所有单词对都用蛮力了,最长的匹配是aboutlopez。然后,我用相同的乘数和模寻找其他匹配项。(因此,绝对不能保证它是最佳的。)
Arnauld




3

Python 2中73个 70 69字节

lambda s:sum(int(`0x21427b563e90d7783540f`[ord(c)%25])-3for c in s)>0

在线尝试!

仅大写

-3个字节,感谢Outgolfer的Erik


大写和小写版本:

Python 2中73 71个字节

lambda s:sum(int(oct(0x1d7255e954b0ccca54cb)[ord(c)%32])-3for c in s)>0

在线尝试!



2

Stax,20 个字节

ÉBÜ◙ƒ╣<Hf6─òɼsäS╗◄↔

运行并调试

拆开包装,松开包装并进行评论,看起来像这样。

"45D.J57KBJa`"I"    string literal with code points [52 53 68 46 74 53 55 75 66 74 97 34 73]
$                   flatten to string "52536846745355756674973473"
;                   push input
@                   get string characters at indices 
                    (using input codepoints as indices; lookups wrap around)
:V                  arithmetic mean
53>                 is greater than 53

运行这个


2

红宝石,64字节

->s{n=0;s.bytes{|i|n+=("[E[LduRgmQSMK"[i%13].ord>>i%2*3)%8-3};n}

在线尝试!

使用13字节的魔术字符串,0..7每个字节编码2个数字。在范围内减去3-3..4

A(也是N)以13为模的ASCII码是零。


1

视网膜0.8.2,51字节

T`L`35344527412513031462452313
.
$*<>>>
+`<>|><

^<

在线尝试!链接包括测试用例。仅接受大写(混合大小写为+6字节)。无耻地窃取@Arnauld的字符串,但是我还是要使用相同的算法。说明:

T`L`35344527412513031462452313
.

将每个字母更改为点和破折号之差,再加上三个,即O=0H=7

$*<>>>

将差异表示为<s和3 >s的数量。(可悲的是我不能使用点,因为它们在正则表达式中很特殊。)

+`<>|><

删除配对的<s和>s。

^<

检查是否还剩下点。


1

Bash + coreutils, 64个  60字节

tr a-z 35344526512513031462452313|sed s/./\&z-+/g|dc -eIK?^p

在线尝试!

接受小写的字符串,对于falsy输出零,对于true则输出非零

说明

使用tr和sed创建一个看起来像的dc程序(对于示例输入'hello'):

IK6z-+4z-+5z-+5z-+0z-+^p

IK     Push 10, then 0 to the stack
6z-+  Push 6 (three more than the dots minus dashes in 'h'), subtract 3, and accumulate
...    Do the same for all other letters, so the stack now has the total dots minus dashes
^      Raise 10 to this power - precision is zero so this turns negative/positive to falsy/truthy
p      Print result

通过仅将dc放在管道中而不是使用命令替换来获取两个字节,然后通过替换<space>3为另一个字节z(方便的是,此时我在堆栈上有3个项!),另一个字节通过替换sed程序周围的引号一个反斜杠即可逃脱&
Sophia Lechner


1

TI-BASIC(TI-84),111字节

:Ans→Str1:"ABCDEFGHIJKLMNOPQRSTUVWXYZ→Str2:"35344527512513031462452312→Str3:0<sum(seq(expr(sub(Str3,inString(Str2,sub(Str1,X,1)),1)),X,1,length(Str1))-3

我使用了与其他答案相同的字符串来确定点重。如果输入字符串是点重的,
程序将返回true(1),否则返回falsy()0
输入字符串必须大写。
输入存储在中Ans。输出存储在Ans程序完成后,并自动打印出来。

取消高尔夫:

:Ans→Str1
:"ABCDEFGHIJKLMNOPQRSTUVWXYZ→Str2 
:"35344527512513031462452312→Str3
:0<sum(seq(expr(sub(Str3,inString(Str2,sub(Str1,X,1)),1)),X,1,length(Str1))-3

例:

"HELLO
HELLO
prgmCDGF3
           1
"CODE
CODE
prgmCDGF3
           0

说明:
(TI-BASIC没有评论,假设有评论;

:Ans→Str1                          ;store the input into Str1
:"ABCDEFGHIJKLMNOPQRSTUVWXYZ→Str2  ;store the uppercase alphabet into Str2
:"35344527512513031462452312→Str3  ;store dot-dash+3 for each letter into Str3

:0<sum(seq(expr(sub(Str3,inString(Str2,sub(Str1,X,1)),1)),X,1,length(Str1))-3 ;full logic

   sum(                                                                       ;sum the elements of
       seq(                                                               )    ;the list evaluated by
                sub(                                    )                       ;the substring of
                    Str3,                                                        ;Str3
                         inString(                  ),                           ;at the index of
                                       sub(        )                              ;the substring of
                                           Str1,                                   ;Str1
                                                X,                                 ;starting at X
                                                  1                                ;of length 1
                                  Str2,                                           ;in Str2
                                                      1                          ;of length 1
           expr(                                        ),                       ;converted to an integer
                                                          X,                    ;using X as the increment variable
                                                            1,                  ;starting at 1
                                                              length(Str1)      ;ending at the length of Str1
                                                                           -3   ;then subtract 3 from all elements in the list
  0<                                                                           ;then check if the sum is greater than 0
                                                                               ;implicitly output the result

注意: 使用[MEM] > [2] > [7](124个字节)中的值,然后减去程序名称的长度,可以评估程序的字节数,CDGF3,(5个字节)和用于额外8个字节存储程序:

124-5-8 = 111字节




0

C ++(与Visual Studio 2017编译)171bytes

int f(string i){const char*c="1322131421130102123023121211210120032121323101112232";int j=0,h[2]={0};while(j<sizeof(i)/28)*h+=c[i[j]-97],h[1]+=c[i[j++]-71];return*h>h[1];}

如果我们考虑到出于测试目的而存在的主程序及其更多内容。

这是无高尔夫球的“整洁”变体

#include "stdafx.h"
int main()
{
    const int dotCount[] = {1,3,2,2,1,3,1,4,2,1,1,3,0,1,0,2,1,2,3,0,2,3,1,2,1,2};
    const int dashCount[] = {1,1,2,1,0,1,2,0,0,3,2,1,2,1,3,2,3,1,0,1,1,1,2,2,3,2};
    std::cout << "Enter String:\n";
    std::string input;
    std::cin >> input;
    int inputsHeavyness[2] = { 0 };
    for(int i = 0;i < sizeof(input)/sizeof(std::string);i++)
    {
        inputsHeavyness[0] += dotCount[input[i] - 'a'];
        inputsHeavyness[1] += dashCount[input[i] - 'a'];
    }
    if (inputsHeavyness[0] > inputsHeavyness[1])
    {
        std::cout << "Dot Heavy\n";
    }
    else
    {
        std::cout << "Dash Heavy or Neutral\n";
    }
    return 0;
}

假设所有小写


1
您可能要添加一个TIO链接。(此外,我认为您在非高尔夫代码中有错别字:22应该是2。)
Arnauld

是的,这很可能是错字。我想我在高尔夫版本中解决了这个问题。tio好,我对这些东西一无所知(我想我只看了一次,它没有使用编译器即时消息,因此vs2017和tio之间的结果可能会有所不同吗?一点也不好)
der benter

1
145个字节。结果在VS和TIO之间确实可能有所不同。有时对我来说也会有所不同,实际上我正在使用GCC(尽管是MinGW)。
gastropner

1
@ceilingcat调整了131个字节
gastropner

1
在@gastropner上构建111个字节将两个数组组合为一个;"132...并且"112...成为"353...并且513
ceilingcat

0

c(118个字符)对 正点返回正值,对负点返回负值

int n(char* c){int v=25124858,d=3541434,i=0,o=0;for(;c[i]!=0;i++)o=(1&(v>(c[i]-65)))>0?(1&(d>>(c[i]-65)))>0?o+1:o-1:o;return o;}

未打高尔夫球

int n(char* c)
{
  // Bitwise alpha map: 
  // more dots = 1
  // more dashes or equal = 0
  int d=3541434;  
  // validation bit map.
  // dot/dash heavy = 1
  // even = 0
  int v=25124858;
  int i=0,o=0;
  for(;c[i]!=0;i++)   // iterate through all values
  {
    // There is no way to make this pretty
    // I did my best.
    // If the little endian validation bit corresponding
    // to the capitol letter ascii value - 65 = 0,
    // the output does not increment or decrement.
    // If the value is one it increases or decreases based
    // on the value of the d bitmap.
    o=(1& ( v > (c[I] - 65))) > 0 ?
      (1 & (d >> (c[I] - 65))) > 0 ?
        o + 1 :
        o - 1 :
      o;
  }
  return o;
}


我必须承认,我没有完全理解比较1& ( v > (c[I] - 65)),它与相同v > c[I] - 65,我无法想象它是错误的,因此我们可以在对@ceilingcat进行56字节
遍历

0

MathGolf,22字节

{▄="Yⁿ∩┐↑rⁿ¼~<↔"$▒3-§+

在线尝试!

使用与许多其他答案相同的方法,其中ⁿ∩┐↑rⁿ¼~<↔"表示幻数35344527512513031462452313


0

python 2,90 86字节

import morse
s=''.join(morse.string_to_morse(input()))
print s.count('.')>s.count('-')

在本地工作 莫尔斯图书馆。-4字节。感谢@JoKing的提示!

另外,如果在Python 3中,则增加1个字节。

Python 3,87个字节

import morse
s=''.join(morse.string_to_morse(input()))
print(s.count('.')>s.count('-'))

尽管问题假设“。”和“-”的数量不相等;如果它们相等,则此代码将返回True。


我的意思是,你可以使用input,而不是raw_input如果你想...
乔金

@JoKing我尝试过。它引发了错误,因此不得不求助于raw_input
Koishore Roy

您只需要在字符串input两边加上引号,因为在将STDIN传递给程序之前先评估STDIN
Jo King

这是很公平的一点。我错过了!:3
Koishore Roy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.