41
\$\begingroup\$

Note: The winning answer will be selected on 4/12/17 the current winner is Jolf, 1 byte.

I'm surprised that we haven't had a what's my middle name challenge on this site yet. I did alot of searching but found nothing. If this is a dup, please flag it as such.

Your challenge

Parse a string that looks like Jo Jean Smith and return Jean.

Test cases

Input: Samantha Vee Hills
Output: Vee

Input: Bob Dillinger
Output: (empty string or newline)

Input: John Jacob Jingleheimer Schmidt
Output: Jacob Jingleheimer

Input: Jose Mario Carasco-Williams
Output: Mario

Input: James Alfred Van Allen
Output: Alfred Van 

(That last one is incorrect technically, but fixing that would be too hard.)

Notes:

  • Names will always have at least 2 space-separated parts, with unlimited middle names between them or can be a list/array of strings.
  • Names may contain the alphabet (case-insensitive) and - (0x2d)
  • You may output a trailing newline.
  • You may require input to have a trailing newline.
  • Input from STDIN, a function parameter, or command-line argument is allowed, but hard-coding it in is not allowed.
  • Standard loopholes forbidden.
  • Output may be function return value, STDOUT, STDERR, etc.
  • Trailing spaces/newlines/tabs in the output are allowed.
  • Any questions? Comment below!

This is , so the shortest anwser in bytes wins!

\$\endgroup\$
20
  • 2
    \$\begingroup\$ Can the output be a list of strings? \$\endgroup\$ Commented Apr 2, 2017 at 14:34
  • 5
    \$\begingroup\$ If other formats than a space-separated string are allowed, please edit that into the specification. \$\endgroup\$ Commented Apr 2, 2017 at 14:46
  • 5
    \$\begingroup\$ @programmer5000: if the input can be a list of strings, how about the output? Is ["John", "Jacob", "Jingleheimer", "Schmidt"] -> ["Jacob", "Jingleheimer"] a valid solution? \$\endgroup\$
    – nimi
    Commented Apr 2, 2017 at 15:17
  • 3
    \$\begingroup\$ Are leading spaces allowed? \$\endgroup\$
    – betseg
    Commented Apr 2, 2017 at 15:32
  • 5
    \$\begingroup\$ @DJ Because "Van" isn't his middle name, it's part of his last name. A particularly vexing case is David Lloyd George, whose first name is David and last name is Lloyd George. Any attempt to parse real people's names like this is doomed. In fact, you can't even tell what the first and last names are (think Li Shi). \$\endgroup\$ Commented Apr 3, 2017 at 2:16

75 Answers 75

1 2
3
0
\$\begingroup\$

Ruby, 17 bytes

$><<$*[1..-2]*' '

Full program, takes input as command line arguments, e.g.:

$ ruby middle.rb john jacob jingleheimer shmidt
jacob jingleheimer

If we don't mind having the result wrapped in quotation marks, can just use:

p$*[1..-2]*' '
$ ruby middle2.rb john jacob jingleheimer shmidt
"jacob jingleheimer"

Of course, we can also just take a list and return a list, which can be as short as a 13 byte lambda.

->s{s[1..-2]}
# usage:
y = ->s{s[1..-2]};
y.call ["john","jacob","jingleheimer","shmidt"] #=> ["jacob", "jingleheimer"]
\$\endgroup\$
0
\$\begingroup\$

Sed, 23 20 bytes

s/\w* (.*) \w*$/\1/

Unlike my last sed entry which involved a pipeline from one sed command to another, this one is just a simple, single command, so I'm only counting the bytes of the sed script.

Edited: Plus a 1-byte penalty for the -r flag. Thank you, Krixti Lithos, for pointing that out!

\$\endgroup\$
4
  • \$\begingroup\$ Can you use the -r flag to save some bytes from escaping the groups? \$\endgroup\$
    – user41805
    Commented Apr 3, 2017 at 8:22
  • \$\begingroup\$ @Kritixi I could but I'm not sure how to score that. Does it count as 2 bytes for the -r flag or only 1 byte? \$\endgroup\$ Commented Apr 4, 2017 at 5:37
  • \$\begingroup\$ It counts as only 1 byte \$\endgroup\$
    – user41805
    Commented Apr 4, 2017 at 5:39
  • \$\begingroup\$ @Kritixi Thanks! I just found this answer on meta, too. And I see another change I can make to improve it as well. \$\endgroup\$ Commented Apr 4, 2017 at 5:44
0
\$\begingroup\$

Pushy, 17 bytes

32K-$.;@$.;.@32+"

Try it online!

32 K-    \ Take away 32 from every character.
         \ Now we have the value 0 where there were spaces.
$        \ Until we reach a zero:
 .;      \   Pop a character from the end
         \ Everything after the last space is now removed
@        \ Reverse stack
$.;      \ Do the same
.        \ Pop the leading space
32+      \ Add 32 to everything to map the numbers back to their original characters
@"       \ Reverse and print

This is the first method I thought of, and looks like the shortest.

\$\endgroup\$
0
\$\begingroup\$

C#, 72 69 bytes

Takes a string, returns a string...

s=>string.Join(" ",s.Split(' ').Skip(1).TakeWhile(n=>!s.EndsWith(n)))

C# 43 bytes

Takes a string array, returns a string array...

s=>s.Skip(1).TakeWhile((n,i)=>i<s.Length-2)
\$\endgroup\$
0
\$\begingroup\$

c, 72 bytes

g(char*p){char*e,*s=0;for(;*p;p++)*p-32?0:s?(e=p):(s=p);*e=0;puts(s+1);}

Try it online

\$\endgroup\$
0
\$\begingroup\$

Clojure, 107 bytes

(fn[f](clojure.string/join" "(map #(apply str %)(drop 1(drop-last(take-nth 2(partition-by #(= % \ )f)))))))

Unfortunately drop/drop-last was shorter than subvec.

(defn middle-name [full-name]
  ; Partition the string into a list of names split on spaces, then take every second element
  ;  since partition keeps the spaces 
  (let [sub-names (take-nth 2
                    (partition-by #(= % \ ) full-name))]

    ; ... then join the middle names together on a space.
    (clojure.string/join " "
      ; Drop returns list of chars, so turn them back into strings...
      (map #(apply str %)
           ; Drop the first and last name
           (drop 1
             (drop-last sub-names))))))
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 16 Bytes

x=>x.slice(1,-1)

Simple. Return the array passed from the second element to the second from last.

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to PPCG! Nice submission! \$\endgroup\$
    – user58826
    Commented Apr 5, 2017 at 17:30
0
\$\begingroup\$

Lua, 39 bytes

print(io.read("*l"):match(" (.+) .+$"))
\$\endgroup\$
0
\$\begingroup\$

c, 53 bytes

main(a,b)char**b;{for(++b;--a>2;printf("%s ",*++b));}

Try it online

\$\endgroup\$
0
\$\begingroup\$

Noodel, 5 bytes

Input must be an array of the names.

Ẹ⁻2¤İ

Try it:)


How it works

      # Pushes the input on implicitly.
Ẹ⁻2¤İ
Ẹ     # Takes the last item of an array and pushes it to the back.
 ⁻2   # Pop the first two items off of the array.
   ¤  # Push the string "¤" onto the stack which represents a space.
    İ # Concatenates the array elements by the "¤" string.
      # Implicitly output the top of the stack to the screen.

<div id="noodel" code="Ẹ⁻2¤İ" input='["James", "Alfred", "Van", "Allen"]' cols="10" rows="2"/>

<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>

\$\endgroup\$
0
\$\begingroup\$

Javascript ES6 23Bytes

x=>x.pop()*x.shift()||x

use * instead of && to save 1 byte

Try it online

\$\endgroup\$
0
\$\begingroup\$

Tcl, 28 bytes

proc R n {lrange $n 1 end-1}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Japt, 7 3 bytes

s1J

Try it online!

This is essentially Input.slice(1,-1). The -1 wraps around to the last item in the input.

\$\endgroup\$
0
\$\begingroup\$

Gambit Scheme (gsi), 48 bytes

(lambda(x)(if(>(length x)2)(cadr(reverse x))""))

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Arturo, 29 bytes

$->a[take drop a 1(size a)-2]

Try it

\$\endgroup\$
1 2
3

Your Answer

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