14
\$\begingroup\$

Briefing

Given a Fully Qualified Java Class/ Package name, you must shorten it as such:

Each part of the dot separated package will be shortened to its first letter, apart from the last section and the class (if it exists).

package names will be all lower case, and the class (if it exists) will start with a capital letter and be UpperCamelCase. packages come in the form of:

foo.bar.foo

and

foo.bar.foo.Class

Examples

(No Class)
Input com.stackoverflow.main
Output c.s.main

(Class)
Input com.google.parser.Gson
Output c.g.parser.Gson

(Class)
Input com.google.longer.package.TestClass
Output c.g.l.package.TestClass

Rules

  • Shortest code in bytes wins
  • Standard loopholes apply
\$\endgroup\$
10
  • 1
    \$\begingroup\$ Does the class name always come last? \$\endgroup\$
    – Shaggy
    May 5, 2017 at 10:46
  • \$\begingroup\$ @Shaggy yes it does \$\endgroup\$
    – Shaun Wild
    May 5, 2017 at 10:59
  • \$\begingroup\$ Related \$\endgroup\$ May 5, 2017 at 11:11
  • \$\begingroup\$ Would fantastic.foo.func.bar become f.f.f.bar or is it guaranteed that 2 packages can't start with the same letter? \$\endgroup\$
    – Emigna
    May 5, 2017 at 11:11
  • 1
    \$\begingroup\$ f.f.f.bar would be correct. \$\endgroup\$
    – Shaun Wild
    May 5, 2017 at 12:36

15 Answers 15

10
\$\begingroup\$

Retina, 17 bytes

\B\w+(\.[a-z])
$1

Try it online!

Explanation

\B         # Start from a position that isn't a word boundary. This ensures that
           # the first letter of the package name is skipped.
\w+        # Match one or more word characters. This is the remainder of the
           # package name which we want to remove.
(          # Capture the next part in group 1, because we want to keep it...
  \.[a-z]  #   Match a period and a lower-case letter. This ensures that we
           #   don't match the package that precedes the class, or the package or
           #   class at the end of the input.
)

This is replaced with $1, which is the period and lower case letter which shouldn't be removed.

\$\endgroup\$
1
  • \$\begingroup\$ I wanted to try my first Retina answer but the Retina god Martin showed up. Way to go, Me! \$\endgroup\$ May 6, 2017 at 0:33
4
\$\begingroup\$

JavaScript (ES6), 68 53 bytes

s=>s.split`.`.map((x,y,z)=>z[y+1]>"["?x[0]:x).join`.`
  • 15 bytes saved thanks to Arnauld.

See my other solution here.


Try it

f=
s=>s.split`.`.map((x,y,z)=>z[y+1]>"["?x[0]:x).join`.`
i.addEventListener("input",_=>o.innerText=f(i.value))
console.log(f("com.stackoverflow.main"))
console.log(f("c.g.parser.Gson"))
console.log(f("com.google.longer.package.TestClass"))
<input id=i><pre id=o>

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Could it be simplified to s=>s.split`.`.map((x,y,z)=>z[y+1]>"["?x[0]:x).join`.` ? \$\endgroup\$
    – Arnauld
    May 5, 2017 at 14:27
  • \$\begingroup\$ Seems like it can, thanks, @Arnauld. \$\endgroup\$
    – Shaggy
    May 5, 2017 at 14:33
  • \$\begingroup\$ Innovative solution but only 2 upvotes. But I will upvote this! \$\endgroup\$
    – Arjun
    May 6, 2017 at 14:09
3
\$\begingroup\$

Python 2, 88 81 bytes

f=lambda s,d=".":s.count(d)>(s.split(d)[-1]<"[")and s[0]+d+f(s[s.find(d)+1:])or s

Try it online!

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

Java 8, 66 41 bytes

s->s.replaceAll("\\B\\w+(\\.[a-z])","$1")

Port from @MartinEnder's amazing Retina answer.

Try it online.

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

Mathematica, 75 bytes

#[[;;-3]]~StringTake~1~Join~#[[-2;;]]~StringRiffle~"."&[#~StringSplit~"."]&

Anonymous function. Takes a string as input and returns a string as output.

\$\endgroup\$
3
  • \$\begingroup\$ JS scoring lower than, Mathematica?! That can't be right - I've done something wrong, haven't I? \$\endgroup\$
    – Shaggy
    May 5, 2017 at 11:26
  • \$\begingroup\$ @Shaggy Java 7 scoring lower than JS and Mathematica?! That can't be right - I've done something wrong, haven't I? (Couldn't resist it. ;) All credit goes to MartinEnder's Retina's port btw). \$\endgroup\$ May 5, 2017 at 11:38
  • 1
    \$\begingroup\$ @KevinCruijssen, thanks for drawing my attention to Martin's answer - I've now fixed the problem of Java out-scoring JS! :D \$\endgroup\$
    – Shaggy
    May 5, 2017 at 11:48
2
\$\begingroup\$

Japt, 30 27 25 bytes

¡Y>Zl -('[>ZgJ)-2?X:Xg}'.

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Nice one! I think you can save two bytes with ('[>ZgJ) \$\endgroup\$ May 5, 2017 at 11:44
  • \$\begingroup\$ I just realised that as well ;-) \$\endgroup\$
    – Luke
    May 5, 2017 at 11:45
2
\$\begingroup\$

Python 2, 76 73 bytes

q=input().split('.')
i=~(q[-1]<'_')
q[:i]=zip(*q[:i])[0]
print'.'.join(q)

Try it online! or Try all test cases

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

V, 9 bytes

Í쓃…®õÀ!

Try it online!

Hexdump:

00000000: cdec 9383 85ae f5c0 21                   ........!

This is a wonderful example of V's signature regex compression.

Explanation:

Í          " Remove every match on every line:
 ì         " A lower case letter
  “ …      "   *ONLY MATCH THIS PART:*
   ƒ       "   As few characters as possible
      ®    " Followed by a dot
       õÀ! " Not followed by an uppercase letter
\$\endgroup\$
2
\$\begingroup\$

Haskell, 58 bytes

f s|[(a:t,p:x:r)]<-lex s=a:concat[t|x<'a']++p:f(x:r)|1<3=s

Try it online! Usage: f "some.string".

lex parses a string as Haskell tokens, so lex "some.string" returns [("some",".string")]. f recurses over the tokens in the string and always appends the first char a of the current token, but the rest t of the token only if the remaining string after the colon p starts with an uppercase char, that is x<'a'. If the pattern match failed, we have reached the last token and simply return s.

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

JavaScript (ES6), 36 bytes

Another port of Martin's Retina answer. See my other solution here.

s=>s.replace(/\B\w+(\.[a-z])/g,"$1")

f=
s=>s.replace(/\B\w+(\.[a-z])/g,"$1")
i.addEventListener("input",_=>o.innerText=f(i.value))
console.log(f("com.stackoverflow.main"))
console.log(f("c.g.parser.Gson"))
console.log(f("com.google.longer.package.TestClass"))
<input id=i><pre id=o>

\$\endgroup\$
1
  • \$\begingroup\$ A good solution but no upvotes. It deserves more than a 0 score. I will turn it into 1! :) \$\endgroup\$
    – Arjun
    May 6, 2017 at 14:10
1
\$\begingroup\$

sed, 57 22 bytes

I expected sed solution to be a little shorter than this...

Edit:

The shorter solution uses regex from Martin Ender's answer.

21 bytes sourcecode + 1 byte for -r flag (or -E flag for BSD sed).

s|\B\w+(\.[a-z])|\1|g
\$\endgroup\$
2
  • \$\begingroup\$ Can't you also use the substitution from my Retina answer? s|\B\w+(\.[a-z])|\1|g? \$\endgroup\$ May 5, 2017 at 18:44
  • \$\begingroup\$ @MartinEnder I spent quite some time trying to come up with one-liner without looking at anyone's answers first but failed. I don't think there is a shorter way to do it, so I will use yours. Thank you! \$\endgroup\$ May 5, 2017 at 19:03
1
\$\begingroup\$

Python 2, 108 97 89 bytes

i=input().split(".")
for x in range(len(i)+~(i[-1][0]<"[")):i[x]=i[x][0]
print".".join(i)

Try it online!

-8 with many thanks to @ovs for the tip

\$\endgroup\$
1
  • \$\begingroup\$ for x in range(len(i)+~(i[-1][0]<"[")):i[x]=i[x][0] for -8 \$\endgroup\$
    – ovs
    May 5, 2017 at 15:04
1
\$\begingroup\$

Go, 101 bytes

import."regexp"
func f(B string)string{return MustCompile(`\B\w+(\.[a-z])`).ReplaceAllString(B,`$1`)}

Attempt This Online!

Port of Martin's Retina answer.

\$\endgroup\$
1
+100
\$\begingroup\$

Pip, 22 19 bytes

aR`\B\w+(\.[a-z])`B

-3 thanks to DLosc!

Yet another port of Martin's Regex.

Try It Online!


First Attempt(Non-Competing)

Pip, 45 bytes

d:"."c:dNae:XU Na?c-1ca:a^dFi,e{a@i:a@i@0}aJd

Try It Online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Instead of using a pattern for the replacement, you can use a callback function. Within the function, group 1 is bound to the local variable b, so for this replacement you can use {b} or just B for short: Try it online! \$\endgroup\$
    – DLosc
    Dec 2, 2022 at 16:30
1
\$\begingroup\$

05AB1E, 20 15 bytes

ΔA3ãvy'.«ÀDõ1ǝ:

Try it online or verify all test cases. (Extremely slow, so the A has been replaced with Dálê (duplicate; keep letters; convert to lowercase; sorted-uniquify) in the TIO-links.)

Original 20 bytes approach:

'.©¡Rć¬.uisć}s€н`r®ý

Try it online or verify all test cases.

Explanation:

I basically keep replacing every ab.c to a.c, where abc are any combination of lowercase letter including duplicates:

Δ                 # Loop until the result no longer changes,
                  # using the (implicit) input-string in the first iteration
 A                #  Push the lowercase alphabet
  3ã              #  Create all possible triplets of lowercase letters with the
                  #  cartesian power of 3
    v             #  Loop over each triplet `y`:
     y'.«        '#   Append a "." to the triplet
         À        #   Rotate it once towards the right: "abc." to "ab.c"
          D       #   Duplicate it
           õ1ǝ    #   Replace the character at index 1 with "": "ab.c" to "a.c"
              :   #   Replace all "ab.c" in the string to "a.c"
                  # (after which the resulting string is output implicitly)
'.               '# Push "."
  ©               # Store it in variable `®` (without popping)
   ¡              # Pop and split the (implicit) input by this "."
    R             # Reverse this list
     ć            # Extract head; pop and push remainder-list and first item separated
                  # to the stack
      ¬           # Get the first character (without popping the string)
       .ui        # Pop, and if it's uppercase:
          s       #  Swap so the remainder-list is at the top of the stack
           ć      #  Extract its head again
         }        # Close the if-statement
          s       # Swap so the remainder-list is at the top of the stack
           €      # Map over each string in this list:
            н     #  Pop and only leave its first character
             `    # Pop and dump these characters to the stack
              r   # Reverse the stack
               ®ý # Join the stack by the "."-delimiter from variable `®`
                  # (after which the result is output implicitly)
\$\endgroup\$

Your Answer

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

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