这些标识符是否等效?


20

Nim语言中,用于区分标识符的规则比大多数其他语言稍微宽松一些。如果两个标识符遵循以下规则,则它们是等效的或寻址相同的变量:

  • 两者的第一个字符相同 (区分大小写)
  • 两个字符串相同(壳体敏感)除去后的所有实例的字符-_

挑战

编写一个程序/函数,该程序/函数接受两个表示Nim标识符的字符串,并根据上述规则是否等效来输出真值或假值。

技术指标

  • 适用标准I / O规则
  • 标准的漏洞禁止
  • 字符串将仅包含ASCII可打印内容。你并不需要检查它是否是一个有效的标识符。
  • 字符串可以作为两个单独的输入,字符串列表等(您知道练习)
  • 空字符串无需处理。
  • 真值和假值的输出必须一致
  • 挑战不是要找到所有语言中最短的方法,而是要找到每种语言中最短的方法
  • 除非另有说明,否则您的代码通常以UTF-8编码形式以字节计分
  • 允许执行此任务的内置函数,但鼓励使用不依赖内置函数的解决方案。
  • 鼓励甚至对“实用”语言进行解释。

测试用例

Input                                    Output

count, Count                             falsey
lookMaNoSeparator, answer                falsey
_test, test                              falsey
test, tset                               falsey
aVariableName, a_variable_name           truthy
numbers_are_cool123, numbersAreCool123   truthy
symbolsAre_too>_>, symbols_areTOO>>      truthy

未引用的参考实现

这是用Nim编写的。

import strutils, re

proc sameIdentifier(a, b: string): bool =
  a[0] == b[0] and
    a.replace(re"_|–", "").toLower == b.replace(re"_|–", "").toLower

3
我建议一个测试用例f("_test", "test")
门把手

@Doorknob添加了。
完全人类

1
我建议添加f("test", "tset"),因为我认为一个答案会带来意想不到的结果。
与Orjan约翰森

@ØrjanJohansen完成。
完全人类

等等,所以输入的是“代表Nim标识符”的字符串,我们“不需要检查它是否是有效的标识符”,但是其中一个示例包含>
aschepler '17

Answers:


7

JavaScript(ES6),62 61字节

@JohanKarlsson节省了1个字节

以currying语法接受输入(a)(b)。返回一个布尔值。

a=>b=>(r=s=>s[0]+s.replace(/-|_/g,'').toUpperCase())(b)==r(a)

测试用例


1
/-|_/g保存一个字节
Johan Karlsson


4

实际上,15个字节

⌠p"-_"(-Σùo⌡M═Y

在线尝试!

有趣的事实:这适用于任意数量的输入(对于少于2个输入,它总是返回true)。

说明:

⌠p"-_"(-Σùo⌡M═Y
⌠p"-_"(-Σùo⌡M    for each input:
 p                 separate the first character
  "-_"(-           remove all dashes and underscores from the rest of the string
        Σù         concatenate the list from the last operation and lowercase the string
          o        append it to the first character
             ═Y  are none of the elements unique?

3

Pyth,13个字节

qFm[hd-r0d"-_

在线尝试!

说明

qFm[hd-r0d"-_
  m              For each value in the input (which is a list of two strings):
   [             Create a list consisting of
    hd               the first character of each value
      -r0d"-_        and the lowercase version of the value without "-" or "_"
qF               Fold over equivalence; checks to see if both lists are the same

3

05AB1E,12个字节

εćs„-_SKl«}Ë

在线尝试!

-1感谢Adnan

从理论上讲,εćs„-_-«}Ë应该已经使用了10个字节,但是不幸的是,现在不建议使用此行为。


哦,是的,我仍然需要解决该问题。您可以使用„-_SK代替来保存一个字节'-K'_K
阿德南

@Adnan而且我知道有办法。谢谢!
暴民埃里克(Erik the Outgolfer)'17年

如果更改SK为11个字节м
凯文·克鲁伊森

@KevinCruijssen嗯,我将更新此答案。我认为м当时不存在。:P
暴民埃里克(Erik the Outgolfer)'18年

3

果冻,11字节

ḟ⁾-_Œl,Ḣµ€E

在线尝试!

-2个字节感谢Outgolfer的Erik
-1个字节感谢Jonathan Allan


取两个像这样的字符串的列表,["symbolsAre_too>_>", "symbols_areTOO>>"]Ḣ;ḟ⁾-_Œl$µ€E代之以-2。击败那个Pyth!
暴民埃里克(Erik the Outgolfer)

...甚至只是ḟ⁾-_Œl,Ḣµ€E11个字节。
乔纳森·艾伦

没问题,也许Erik可以给我2分,我可以给1分:)
乔纳森·艾伦

@乔纳森·艾伦 好主意; 我会做的:)
HyperNeutrino

3

Ruby86 64 63 61 51字节

f=->x{x[0]+x.upcase.delete("-_")}
->x,y{f[x]==f[y]}

在线尝试!

感觉真的很长,仍然感觉有点长。我将感谢任何Ruby专家的帮助,使它至少短一些。


不是专家,但我得到启发去检查String方法列表.delete("_-")更短。
与Orjan约翰森

f[x]f.call(x)当涉及稳定的lambda时,始终是有效的替代方法。
价值墨水

@ValueInk谢谢!我一直在尝试根据Stack Overflow答案找出如何在Ruby中打高尔夫球,所以我不知道这是一个选择。
小麦巫师

3

C ++,288个 248字节

-5个字节,感谢Zacharý

#include<string>
#include<algorithm>
#define E(a,v)a.erase(std::remove(a.begin(),a.end(),v),a.end());
#define F(a)for(auto&c:a)c=toupper(c);
int e(std::string&a,std::string&b){if(a[0]!=b[0])return 0;E(a,45)E(b,45)E(a,95)E(b,95)F(a)F(b)return a==b;}

Thanks you, Preprocessor. Also, this code takes advantage of the fact that in C++ the rule to cast int to bool is int_var!=0


Add a ; after the definition of F. Then, change the first return statement to return 0;E(a,45)E(b,45)E(a,95)E(b,95)F(a)F(b).
Zacharý

2

CJam, 20 bytes

{_"-_"f-:el:=\:c:=*}

Takes input in the form of ["string1","string2"].

Try it Online (testing version)

{
_      e# make copy of input
"-_"f- e# remove all "-" and "_" from both words in copy
:el    e# convert words in copy to lowercase
:=     e# 1 if both words in copy are equal, 0 if not
\      e# move original version of input to top of stack
:c     e# convert each word in original input to only 1st character
:=     e# 1 if both characters from original input are equal, 0 if not
*      e# multply the two numbers we obtained. If and only if both are 1 (true) we return 1 (true)
}

2

Haskell, 85 78 76 71 68 bytes

2 bytes saved thanks to Ørjan Johansen

import Data.Char
s(a:x)=a:[toLower a|a<-x,all(/=a)"-_"]
x!y=s x==s y

Try it online!

Errors on the empty string.


all(/=a)"-_". Also after your latest edit, f needs to become an operator.
Ørjan Johansen

@ØrjanJohansen Ah thanks. I thought there was a shorter way to do notElem but I couldn't remember it for the life of me.
Wheat Wizard

2

Python 2, 72 bytes

lambda x,y:r(x)==r(y)
r=lambda x:x[0]+x[1:].lower().translate(None,"-_")

Try it online!

Won't work with Python 3 because of the new translate syntax.


2

Excel, 105 bytes

=AND(CODE(A1)=CODE(B1),SUBSTITUTE(SUBSTITUTE(A1,"_",""),"-","")=SUBSTITUTE(SUBSTITUTE(B1,"_",""),"-",""))

CODE() returns numeric code of first character.

String comparison in Excel is case insensitive.


2

Husk, 13 bytes

¤=§,←(m_ω-"-_

Try it online!

Builds for each string a pair consisting of the first character of the string and the whole string lowercased and with all occurrences of -/_ removed. Then checks if the two pairs are equal.

A particularity is that - in Husk is set difference (i.e. it removes only the first occurrence found): in order to remove all occurrences, the fixed point of -"-_ is found with ω-"-_.


2

Japt, 14 25 bytes

g ¥Vg ©Uu k"_-" ¥Vu k"_-"

Checks case-insensitive string equality by removing all characters in word 2 from word 1, and removing the -_ characters; that results in an empty string ("") if the words are equal.
Thanks Ørjan Johansen for pointing out the problem with this.

Checks first-char equality and if the uppercased inputs are equal after removing _-.

Try it online!

Explanation

Implicit input: U and V are input strings

g ¥Vg

Check if first letter of U (implicit) equals (¥) the first char of V.

©Uu k"_-" ¥Vu k"_-"

And (©) check if U, uppercased (u) and with _- removed (k), equals (¥) the same for V. Implicitly return the boolean result.


I cannot get the link to work, but that explanation sounds like it does the wrong thing. What does it give for test vs. tset?
Ørjan Johansen

@ØrjanJohansen Good point... it'll fail for that case. As for the link, I've tested it and it works fine.
Justin Mariner

Yeah the link is my own fault - one of these days I need to change to a modern browser. I had better luck with Try it online!
Ørjan Johansen

@ØrjanJohansen Could I ask what browser you're using? I'm in the process of improving that CodePen and would like to make it as compatible as TIO.
Justin Mariner

cough still using Internet Explorer.
Ørjan Johansen


1

Perl 5, 67 bytes

s/.//,push@a,$&,y/_-//dr for<>;say($a[0]eq$a[2]&&lc$a[3]eq lc$a[1])

Try it online!

Takes the identifiers as input on separate lines.

Explanation:

s/.//,             # remove the first character
push@a,            # storage space, even positions are first character
                   # odd positions are remainder
$&,                # implicit variable holding last matched pattern (first char)
y/_-//dr           # Remove _ and - from remainder of input
for<>;             # iterate over all input lines
say                # output
($a[0]eq$a[2]&&    # check that first character is identical and
lc$a[3]eq lc$a[1]) # so is the lowercase version of the rest


1

Charcoal, 29 bytes

∧⁼§θ⁰§η⁰⁼↧⪫⪪⪫⪪θ_ω-ω↧⪫⪪⪫⪪η_ω-ω

Try it online!

This prints a - for truthy and nothing for falsey.

Link to the verbose version. It first compares the first character of both input strings (⁼§θ⁰§η⁰) and then compares the rest of both strings after removing the underscores and the hyphens (⪫⪪⪫⪪θ_ω-ω) and converting to lowercase ().


1

C#, 101 89 bytes

string g(string s)=>string.Concat(s.ToUpper().Split('-','_'));f=>s=>f[0]==s[0]&g(f)==g(s)

Saved 12 bytes thanks to @kusi581.


if you use a local function for string.Concat(...) you can save 2 bytes ;)
kusi581

1
@kusi581 Thanks, saved 12 bytes.
TheLethalCoder



1

C (gcc), 126 114 bytes

#define p(s)do++s;while(*s==45||*s==95);*s>95?*s-=32:0;
f(char*a,char*b){while(*a&&*a==*b){p(a)p(b)}return*a==*b;}

Try it online!

With whitespace and comments:

#define p(s)                   // Define helper macro p           \
    do ++s;                    // Increment pointer at least once \
    while (*s==45 | *s==95);   // and past any '-' or '_'         \
    *s>95 ? *s -= 32 : 0;      // If lowercase letter, convert to upper

f(char* a, char* b) {          // Define main function f
    while (*a && *a == *b) {   // Loop until end of either string
                               // or a difference found
        p(a)                   // Transform pointer and one char
        p(b)                   // via helper p above
    }
    return *a==*b;             // Test chars equal (on success, both '\0')
}

The question specifies ASCII printables, so (1) The first while test can be shortened to *s%50==45. (2) However, the lowercasing is wrong, e.g. it fails on t~ vs. t^.
Ørjan Johansen

@ØrjanJohansen I thought we could assume the inputs were both valid identifiers. But then that example with > was added, hmm.
aschepler

Huh. I was going by that example too. Looking now in the Nim manual, even - isn't actually allowed, but the algorithm still includes it...
Ørjan Johansen

@ØrjanJohansen Yeah, I noticed - isn't in the grammar description of identifier - but then other parts of that document imply it is allowed.
aschepler

1

Dyalog APL, 47 32 28 27 26 22 bytes

-4 bytes thanks to Kritixi Lithos

{(=/⊃¨⍵)∧≡/819⌶⍵~'-_'}   

Takes input as a list of the strings.

Try it online!

How?

{(=/⊃¨⍵)∧≡/819⌶⍵~'-_'}
               ⍵~'-_'   Remove '-' and '_'
           819⌶         Lowercase
         ≡/             Equality between elements
        ∧               And
 (=/⊃¨⍵)                The first element of each element is equal

I think you can do ⊃⍺=⍵ instead instead of ⍺[1]=⍵[1]
Kritixi Lithos

No, because the arguments could be of a different length!
Zacharý

1
In that case, ⊃⍵ instead of ⍵[1] should work
Kritixi Lithos

1
Maybe even ⊃⍺=⊃⍵ instead of ⍺[1]=⍵[1]
Kritixi Lithos

1

Common Lisp, 98 bytes

(lambda(x y)(and(eql(elt x 0)(elt y 0))(string-equal(#1=remove #\-(#1##\_ y))(#1##\-(#1##\_ x)))))

Try it online!

Ungolfed (super straightforward!) version:

(defun f(x y)
  (and (eql (elt x 0) (elt y 0))         ; check if initial characters are identical
       (string-equal                     ; string comparison (case insensitive)
         (remove #\- (remove #\_ y))     ; remove from both strings the unwanted chars
         (remove #\- (remove #\_ x)))))

1

R, 76 bytes

function(l)(g=substr(l,1,1))[1]==g[2]&(h=tolower(gsub('-|_','',l)))[1]==h[2]

Anonymous function that takes input as a list of two strings. Takes advantage of the fact that R's string operations, while quite long in # of characters, are vectorized. Additionally wrapping an assignment in parentheses will bind the variable, so (g=substr(l,1,1)) retains a variable to be reused later in the line and similarly for h.

R returns the last evaluated expression as function output.

Ungolfed:

function(l){
  g <- substr(l,1,1)
  h <- tolower(gsub("_|-","",l))
  (g[1]==g[2])&(h[1]==h[2])
}

Try it online! (all test cases)


1

Brachylog, 17 bytes

hᵛ&{{¬∈"_-"&ụ}ˢ}ᵛ

Try it online!

Outputs through predicate success/failure.

h                    The first element
 ᵛ                   is the same for each element of the input,
  &                  and
   {           }ᵛ    for each element of the input the following are the same:
    {      &ụ}ˢ      every element uppercased which satisfies the condition that
     ¬∈              it is not an element of
       "_-"          the string "_-".

0

Erlang 113 bytes

A=fun(L)->string:to_lower(lists:flatten(string:tokens(L,"-_")))end,fun([C|D],[C|E])->A(D)==A(E);(_,_)->a==b end.

a pair of anonymous functions that compare the two lists. meant to be pasted in the erlang shell.

more readable:

A=fun(L) ->
    string:to_lower( % case insensitive
        lists:flatten( % squash all characters back into one list
            string:tokens(L,"-_") % return a list of list of characters
        )
    )
end.
fun([C|D],[C|E]) -> % are the first characters exactly the same?
    A(D)==A(E); % does the rest compare correctly?
   (_,_) -> % first chars not the same
    a==b % shorter than 'false'
end.

0

Clip, 25 bytes

&=(x(y=AxAy[Aa--m.L`a'-'_

Explanation:

x, y and z may be referenced in a Clip program to implicitly take up to three inputs. Since this program only references x and y, it takes two inputs which are assigned to x and y.

 =(x(y                    First characters of x and y are equal
&                         And
      =AxAy               A(x) == A(y)
           [Aa            Function A, takes parameter a
                m.L`a     Map all elements of a to lower case
              --     '-'_ Remove all occurrences of '-' and '_'

Takes two strings from standard input, outputs 1 and 0 for true and false respectively.

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.