10
\$\begingroup\$

For the purpose of this challenge, arguments are things you pass to a function at the call site, while parameters are what the function uses in its implementation. Or, more succinctly: arguments = external, parameters = internal.

While there are several modern languages that have support for argument labels for functions at the call site, Swift's implementation of argument labels is unique. In essence, the argument label (external) and the parameter name (internal) are not necessarily related to each other. (There's also the fact that argument labels are required to be used at the call site, but that's unimportant for this challenge.)

The Challenge

Write a program or function that receives two strings as input (an argument label, and a parameter name); and outputs (or returns) a single string containing a valid Swift function parameter declaration (sans the type annotation).

Requirements

Here's the official documentation for Swift parameter declarations, if you’re curious. You only have to implement a very small subset of this.

  • If argumentLabel and parameterName are equal, simply output their shared value.
  • If argumentLabel and parameterName are not equal, output argumentLabel, followed by a space, followed by parameterName.
  • If argumentLabel and/or parameterName are empty, replace the empty value(s) with an underscore (_), then follow the rules above.

Here's an example implementation in (what else?) Swift.

func parameterDeclaration(
  label argumentLabel: String,
  name parameterName: String
) -> String {
  switch (argumentLabel, parameterName) {
  case ("", ""):
    "_"
  case ("", _):
    "_ \(parameterName)"
  case (_, ""):
    "\(argumentLabel) _"
  case _ where argumentLabel == parameterName:
    parameterName
  default:
    "\(argumentLabel) \(parameterName)"
  }
}

Rules

  • All the usual IO methods are allowed.
  • Standard loopholes are, of course, forbidden.
  • You may assume that both input strings consist exclusively of ASCII letters (uppercase and lowercase) and digits. (That is, they match this regex: /[a-zA-Z0-9]*/.) You may not assume, however, that the strings will be nonempty.
  • You may take input as a tuple, a list, two separate arguments, a single string with a separator, or any other method that allows you to receive two separate strings as input.
    • Please mention your input method in your answer, as well as the order of inputs (argument label before parameter name, or vice versa).

Test Cases

In these test cases, the first item is the argument label, the second is the parameter name, and the third is the expected output.

("do",     "body")   -> "do body"
("a123",   "b456")   -> "a123 b456"
("count",  "count")  -> "count"
("arg1",   "arg1")   -> "arg1"
("",       "number") -> "_ number"
("unused", "")       -> "unused _"
("",       "")       -> "_"

Scoring

This is , so, as per usual, shortest answer in bytes wins.

\$\endgroup\$
1
  • \$\begingroup\$ FWIW OCaml also doesn't require the argument label to match the parameter name, though it does provide a convenient shorthand for that case \$\endgroup\$ Mar 28 at 15:18

14 Answers 14

5
\$\begingroup\$

Haskell, 40 bytes

f""="_"
f x=x
a#b=unwords$f a:[f b|a/=b]

Try it online! I borrowed the test suite from totallyhuman.

\$\endgroup\$
3
\$\begingroup\$

Vyxal 3, 6 bytes

₉'_ru„

Trivial implementation.
Try it Online!

₉'_ru„­⁡​‎⁠⁠⁠‎⁡⁠⁤‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢‏⁠‎⁡⁠⁣‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏‏​⁡⁠⁡‌­
   r    # ‎⁡Replace
₉       # ‎⁢empty string by
 '_     # ‎⁣underscore
    u„  # ‎⁤Uniquify and join on spaces
💎

Created with the help of Luminespire.

\$\endgroup\$
3
\$\begingroup\$

Python, 41 bytes

lambda a,b:(a!=b)*f"{a or'_'} "+(b or"_")

Attempt This Online!

\$\endgroup\$
2
\$\begingroup\$

JavaScript (V8), 37 bytes

x=>y=>(x||'_')+(x==y?'':y?' '+y:' _')

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Haskell, 45 bytes

""#b="_"#b
a#""=a#"_"
a#b|a==b=a|1>0=a++' ':b

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Jelly, 6 bytes

ȯ€”_QK

Try It Online!

Explanation

ȯ€”_QK    Main Link
ȯ         logical OR (flat)
 €        each
  ”_      with "_"
    Q     uniquify
     K    join on space
\$\endgroup\$
0
2
\$\begingroup\$

Java 8, 66 65 bytes

a->b->(a.isEmpty()?"_":a)+(a.equals(b)?"":b.isEmpty()?" _":" "+b)

-1 byte porting @l4m2's JavaScript answer.

Try it online.

Original answer:

(a,b)->(a=a.isEmtpy()?"_":a).equals(b=b.isEmtpy()?"_":b)?a:a+" "+b

Try it online.

Explanation:

a->b->                 // Method with two String parameters & String return-type
  (a.isEmpty()?        //  If `a` is "":
    "_"                //   Start with "_" instead
   :                   //  Else:
    a)                 //   Start with `a`
      +                //  And append:
       (a.equals(b)?   //   If `a` and `b` are the same:
         ""            //    Append nothing more
        :b.isEmpty()?  //   Else-if `b` is "":
         " _"          //    Append a space and "_"
        :              //   Else (`a` and `b` are different, and `b` is not ""):
         " "+b)        //    Append a space and `b`
(a,b)->                 // Method with two String parameters & String return-type
  (a=                   //  Overwrite `a` with:
     a.isEmtpy()?       //   If `a` is "":
      "_"               //    Replace it with "_"
     :                  //   Else:
      a)                //    Keep `a` the same
        .equals(        //  Check whether it equals:
   b=b.isEmtpy()?"_":b) //   Overwrite `b` in a similar matter
  ?                     //  If the modified `a` and `b` are the same:
   a                    //   Simply return the modified `a` as result
  :                     //  Else (they are different):
   a+" "+b              //   Return `a` and `b` joined by a space
\$\endgroup\$
2
\$\begingroup\$

APL+WIN, 25 bytes

Prompts for a nested vector of the argument name followed by the parameter name.

(≡/m)↓m←(ר⍴¨m)↓¨'_',¨m←⎕

Try it online! Thanks to Dyalog Classic

\$\endgroup\$
2
\$\begingroup\$

Uiua 0.10.0, 21 bytes

/$"_ _"⍚⍥⋅@_=0⍚⧻.◴⊂∩□

Explanation + See it in action

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 8 bytes

Ùõ¸'_‡ðý

Input as a pair of strings.

Try it online or verify all test cases.

Explanation:

Ù         # Uniquift the (implicit) input-pair
 õ¸       # Push [""]
   '_    '# Push "_"
     ‡    # Replace all "" items with "_"
      ðý  # Join the list with " " delimiter
          # (after which the result-string is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Swift, 54 bytes

Well of course I needed to golf my own Swift answer, this is the language I speak.

let u={$0>"" ?$0:"_"},f={u($0)+($0==$1 ?"":" "+u($1))}

Try it online!

f(_:_:) is the closure you’re looking for. Argument label comes first, parameter label comes second.

This ended up being in the same vein as @l4m2's JS answer. I bind a closure to u up front that replaces an empty string with an underscore, before calling it with the first parameter, checking if the parameters are equal, and then calling it again (prepending a space) if they're not.

\$\endgroup\$
1
\$\begingroup\$

Retina 0.8.2, 17 bytes

%`^$
_
D`
G`.
¶
 

Try it online! Takes input on separate lines but link is to test suite that splits on commas for convenience. Explanation:

%`^$
_

Replace empty lines with _s.

D`
G`.

Deduplicate and remove any resulting trailing empty line.

If there are still two lines, join them with a space.

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 16 bytes

⪫…⟦∨θ_∨η_⟧⊕¬⁼θη 

Try it online! Link is to verbose version of code. Explanation:

    θ               First input
   ∨                Logical Or
     _              Literal string `_`
       η            Second input
      ∨             Logical Or
        _           Literal string `_`
  ⟦      ⟧          Make into list
 …                  Truncate to length
             θ      First input
            ⁼       Equals
              η     Second input
           ¬        Logical Not
          ⊕         Incremented
⪫                   Join on spaces
                    Implicitly print
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -pl, 37 bytes

$_=($;=<>||"_")ne($_||="_")?"$_
$;":$

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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