Win a Six Month Subscription to Interface Technical Training’s Video Collection by Solving this PowerShell Puzzle!

During the 2013 Scripting Games, I won three subscriptions, each good for six months of video training at Interface Technical Training. I have a subscription already so I asked Don Jones about re-gifting my prizes since I don’t need more than one subscription so here’s your chance to win one.

The first video training subscription that I won was given to Rohn Edwards who is the co-founder of the Mississippi PowerShell User Group. We exclude ourselves from the normal swag giveaways we have during our official meetings each month so I wanted Rohn to have one of these. Speaking of the Mississippi PowerShell User Group, our meetings are virtual so anyone from anywhere can attend. Where else can you find a PowerShell User Group whose founders are the 2012 Scripting Games advanced track winner (Rohn Edwards) and the 2013 Scripting Games advanced track winner (Mike F Robbins)?

I tweeted out a mini-competition for the second video training subscription that I won which Rob Campbell won for being the first person to find my script in one of the events where our names were no longer listed on our entries and no one had voted on that particular entry of mine yet.

That leaves me with one voucher good for a six month subscription to Interface Technical Training’s video training collection. Here’s the puzzle you need to solve with PowerShell in order to win:

Your task is to write a short PowerShell one-liner that returns a list of PowerShell cmdlet names that do not have repeating characters in them:

  • Only PowerShell commands that are classified as “Cmdlets” should be returned.
  • Return only the name of the cmdlets.
  • Non-repeating characters means the cmdlet name doesn’t contain two or more of the same characters, for example: Get-Help would not be in the results because it contains two of the letter “E” and Copy-Item would be in the results because it doesn’t contain any repeating characters.
  • For the purposes of this contest, case does not matter. “E” and “e” are considered to be the same character. (Thanks to Rob Campbell for bringing this to my attention).

The shortest answer wins! Be aware, a space is a character too. In case of a tie, the person who submits a solution first wins.

Use the “Leave a Reply” box at the bottom of this blog article and submit your solution via a comment to this blog article by 5am (GMT) on Tuesday, June 25th. The winner will be announced on Thursday, June 27th on this blog and the prize will be awarded at that time.

Note: Entries (comments) will not be made public until after the submission deadline.

Update: 6/26/13
The winner is Carlo with the following entry which was 24 characters in length and produced the desired results:

[sourcecode language=”powershell” autolinks=”false”]
gcm -c c|sls ‘(.).*1’-N
[/sourcecode]

itt-winner

Thank you to everyone who competed in this contest!

µ

58 Comments

  1. Chris H. (@LogicalDiagram)

    gcm -C Cmdlet|?{!([char[]]$_.Name.ToLower()|group|?{$_.Count -gt 1})}|Select Name

    Reply
  2. Bartek B

    Not that I want to win, but I could not resits… 😉
    gcm -ty cmdlet|?{$_.Name-notmatch'(.)(?=.*?1)’}

    not even 100% sure it is correct. 😉

    Reply
  3. Bartek Bielawski

    Not that I want to win, but I could not resits… 😉
    gcm -ty cmdlet|?{$_.Name-notmatch'(.)(?=.*?1)’}

    not even 100% sure it is correct. 😉

    Reply
  4. Bartek Bielawski

    Or better yet: gcm -ty cmdlet|?{$_.Name-notmatch'(.)(?=.*1)'}

    Reply
  5. Bartek Bielawski

    I should probably read more carefully… 😉 Final and hopefully good solution:
    gcm -ty cmdlet|%{$_.Name}|?{$_-notmatch'(.)(?=.*1)'}

    Sorry for spam. Please feel free to reject other comments. 😉
    And yes, I know in v3 I could make it shorter, but hey, I don’t want to win… 😉

    Reply
  6. rjasonmorgan

    Get-command -CommandType Cmdlet | where { $_.Name.ToCharArray().Count -eq ($_.name.ToCharArray() | select -Unique).count}

    Reply
  7. rjasonmorgan

    Get-command -CommandType Cmdlet | where { $_.Name.ToCharArray().Count -eq ($_.name.tolower().ToCharArray() | select -Unique).count}

    Reply
  8. rjasonmorgan

    Last try: Get-command -CommandType Cmdlet | where { $_.Name.ToCharArray().Count -eq ($_.name.tolower().ToCharArray() | select -Unique).count} | select name

    Reply
  9. _Emin_

    gcm -Ty:8|? Name -notmatch “^.*(.).*1.*$”

    Reply
  10. dvsit

    gcm -CommandType Cmdlet | ? {($_.name.Length) -eq ($_.Name.ToLower().ToCharArray() | select -Unique).count}

    Reply
  11. dvsit

    gcm -CommandType Cmdlet | ? {($_.name.Length) -eq ($_.Name.ToLower().ToCharArray() | select -Unique).count}

    Stupid wordpress! I don’t know if I submitted this already or not.

    Reply
  12. Jeff Smith

    (Reqires version 3)
    (gcm -C cmdlet).Name | ? {$_.length -eq ($_.toUpper() -split ” | select -U).Count -1}

    Reply
  13. Peter Kriegel

    gcm -C Cmdlet|?{$_ -match “^(?:(.)(?!.*1))*$”}

    Reply
  14. Sahal

    This is what i could cook:
    (gcm -c c|?{$_.tostring().length-eq($_.ToString().ToCharArray()|select -Unique).count}).Name

    if i knew regex then i would try something like this:
    (gcm -c c).Name|?{$_ -match “”} – but iam not good at regex 🙁
    i need a pattern for maching any thing except a new line character and no multiple occurance of characters.

    Reply
  15. Sahal Omer

    PS: not sure my previous comment attempt succeeded hence entering again.

    This is what i could cook:
    (gcm -c c|?{$_.tostring().length-eq($_.ToString().ToCharArray()|select -Unique).count}).Name

    if i knew regex then i would try something like this:
    (gcm -c c).Name|?{$_ -match “”} – but iam not good at regex 🙁
    i need a pattern for maching any thing except a new line character and no multiple occurance of characters.

    Reply
    • Sahal Omer

      This one is much shorter:
      (gcm -c c|?{$_.name.length-eq($_.name.ToCharArray()|select -Unique).count}).Name

      Reply
      • Sahal

        Oops, just now realized while comparing others solutions, this method is wrong as the Select -Unique doesn’t handle changing case “a” and “A” are two separate object. how do i avoid this with this method?

        Reply
  16. Carlo

    My powershellV3-39-chars-long-answer:
    (gcm -c c).name|?{$_-NotMatch”(.).*1″}
    Funny game, good idea!
    Carlo

    Reply
  17. stangm

    Sorry of this is a duplicate, I wasn’t logged in the first time

    (gcm -c c).Name|%{if(([char[]]$_|select -u)-join””-eq$_){$_}}

    Reply
  18. Julian Siebert

    gcm -Ty C|% Na*|sls “^(?:(.)(?!.*1))*$”

    Reply
  19. Mark Stang

    Ok, slighlty smaller, at 58 chars:
    (gcm -c c).Name|%{$_*(([char[]]$_|select -u)-join””-eq$_)}

    Reply
  20. stangm

    Slightly shorter 58 chars:

    (gcm -c c).Name|%{$_*(([char[]]$_|select -u)-join””-eq$_)}

    Reply
  21. stangm

    And now I believe neither one of my solutions work….Darn it

    Reply
  22. stangm

    Okay, here are my two solutions: Absolute shortest 45 chars:
    gcm -c c|%{$_.Name*!($_-match”(.)(?=.*?1)”)}

    Better output, at 50 chars:

    gcm -c c|%{if(!($_-match”(.)(?=.*?1)”)){$_.Name}}

    Reply
  23. Bartek Bielawski

    OK, I couldn’t resist pasting this new version here. This v3 version, and I noticed I don’t need lookahead here, so I got rid off it.. 😉
    gcm -c cmdlet|? Name -notm '(.).*1'|% Name
    43 chars is probably as good as I can get… 😉
    BTW: bummer on using -ty instead of -c. What a waste of keyboard! 😉

    Reply
  24. Bartek Bielawski

    And… you gonna hate me for that… I just realized that CommandType is actually enum.. 😀 So here it goes…:
    gcm -c 8|? Name -notm '(.).*1'|% Name

    Reply
  25. stangm

    AHA!!! I have a shorter one! 38!!!

    (gcm -c c)-notmatch”(.)(.*?1)”|% Name

    Reply
  26. Lee Holmes

    Here’s what I could come up with – 25 characters. Please don’t enter me in the draw, though:
    gcm -c 8|sls -n “(.).*1”

    Lee Holmes [MSFT]

    Reply
  27. Rohn Edwards

    I’ll exclude myself, but after getting the 25 character hint on Twitter, I was able to come up with this:

    gcm -c C|sls “(.).*1” -N

    Reply
  28. _Emin_ (@p0w3rsh3ll)

    gcm -Ty:8|? Name -notmatch “.*(.).*1”

    Reply
  29. _Emin_ (@p0w3rsh3ll)

    gcm -Ty:8|? Name -notmatch “.(.).*1”

    Reply
  30. _Emin_ (@p0w3rsh3ll)

    gcm -Ty:8|? Na* -notm “(.).*1”

    Reply
  31. _Emin_ (@p0w3rsh3ll)

    (gcm -C:8)-notmatch”(.).*1″

    Reply
  32. Bartek Bielawski

    OK, this one is slightly shorter, I guess this is similar to what Alex used:
    (gcm -c 8).Name-notmatch'(.).*1' -> 33
    I have no idea how Lee got less chars, that has to be some clever regex, or technique other than regular expression that I never seen before… 🙂

    Reply
  33. Carlo

    Mike, I see now that the doublequotes are badly interpreted when pasted in in your comment window…

    Reply
    • Mike F Robbins

      I think the double quotes are turned into those curly quotes which don’t work in PowerShell, but I’ll replace them with standard double quotes when grading the entries.

      Reply
  34. Carlo

    33…

    (gcm -c c).name-NotMatch'(.).*1′

    🙂

    Reply
  35. Carlo

    31! I need maybe to change my approach now!

    (gcm -c c).name|sls ‘(.).*1’-N

    Reply
  36. Shay LevyShay Levy

    Here’s my take on this 25 chars long.

    gcm -c 8|sls -n ‘(.).*1’

    Reply
  37. Carlo

    OMG!!! 24!!!!
    gcm -c c|sls ‘(.).*1’-N

    Reply
  38. jbs534

    (gcm -c c).Name|?{$_ -notmatch ‘^.*(.).*1.*$’}

    Reply
  39. Bartek Bielawski

    I *really* hope this is my last attempt.. 😉
    gcm -c 8|sls -n '(.).*1'
    Ha! 25 - I was sure that was not possible. :D

    Reply
  40. nohandle (@nohwnd)

    gcm -C 8|sls -n ‘(.).*1’

    Reply
  41. Matt Tilford

    Ok, so i think i’ve done the best i can. I’m sure once i’ve seen the shortest solution i’ll kick myself but here’s what i got in a nice round 100 characters:
    (gcm -ty Cmdlet).Name.ToLower()|%{diff $_ (($_.tochararray()|Sort -U)-join””)-I -Ex -Pa -Pr Length}

    Reply
  42. Carlo

    Had some spare time so went another path with Switch. Unfortunately the result is less glorious in terms of chars 😉
    switch -regex(gcm -c c){‘(.).*1′{}default{$_.name}}
    Carlo

    Reply
  43. Dave Garnar (@davotronic5000)

    This is a quick effort, fairly sure it could be a little shorter, but here we go:
    gcm -C Cmdlet|?{$_.Name -match “^(?:(.)(?!.*?1))*$”}|FL Name

    Reply
  44. Shay Levy

    24 chars
    gcm -c 8|sls ‘(.).*1’-n

    Reply
  45. stangm

    So the 24 character one is very slick. And it does return the cmdlets. But not only the cmdlets. There are extra chars included. For example: Try $a=gcm -c 8|sls “(.).*1”-n
    Then see what is in $a[0]
    it is not just Copy-item. It is;

    Copy-item

    With a blank line above and two blank lines below.

    Reply
    • Mike F Robbins

      I didn’t count off for white space since solutions by people like Lee Holmes included them as well. I also took a scripting games mentality when grading the entries and left room for interpretation, but I also tested each command to determine how many results it contained. The winning entry returns 39 items on my pc as does the ones that don’t contain the empty lines. (gcm -c c|sls ‘(.).*1’-N).count

      Reply
      • Carlo

        Hi Stangm,
        you have to keep in mind that the output of the select-string is not a collection of strings, but a collection of MatchInfo objects.

        $a.gettype()
        IsPublic IsSerial Name BaseType
        True False MatchInfo System.Object

        That’s why the number of returned cmdlets in Mikes’ test is right. It is because count returns the number of matches, not the number of lines like if they were strings.

        Using $a.tostring() removes the top and bottom epmty lines, because the matchinfo object becomes a string.

        Carlo

        Reply
  46. Carlo

    Thanks Mike! I enjoyed the contest! Keep the good work in the Powershell Community.
    Carlo

    Reply

Leave a Reply

%d bloggers like this: