我叫什么名字?


30

注意:获奖答案将在17年412日选定,当前获奖者为Jolf,1个字节

令我感到惊讶的是,我们在此站点上还没有遇到我的中间名挑战。我做了很多搜索,但一无所获。如果这是一个重复项,请照此标记。

你的挑战

解析一个看起来像的字符串Jo Jean Smith并返回Jean

测试用例

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 

(从技术上讲,最后一个是不正确的,但是要解决这个问题太难了。)

笔记:

  • 名称将始终至少包含2个以空格分隔的部分,中间没有无限的中间名,或者可以是字符串列表/字符串数组。
  • 名称可能包含字母(不区分大小写)和-(0x2d
  • 您可以输出尾随换行符。
  • 您可能需要输入才能包含尾随换行符。
  • 允许从STDIN,函数参数或命令行参数输入,但不允许对其进行硬编码。
  • 禁止使用标准漏洞。
  • 输出可能是函数返回值,STDOUT,STDERR等。
  • 输出中允许尾随空格/换行符/制表符。
  • 任何问题?在下面发表评论!

这是,因此最短的字节为准!


2
输出可以是字符串列表吗?
Anthony Pham

5
如果允许使用除空格分隔的字符串以外的其他格式,请在规范中进行编辑。
Martin Ender

5
@ programmer5000:如果输入可以是字符串列表,那么输出如何?是["John", "Jacob", "Jingleheimer", "Schmidt"]-> ["Jacob", "Jingleheimer"]有效的解决方案?
nimi

3
是否允许前导空格?
betseg

2
@DJ因为“ Van”不是他的中间名,所以它是他的姓氏的一部分。大卫·劳埃德·乔治(David Lloyd George)是一个特别令人烦恼的案例,他的名字叫大卫(David),姓氏(Lloyd George)。像这样解析任何真实的人的名字的尝试都是注定的。实际上,您甚至无法分辨名字和姓氏(想想李石)。
戴维·康拉德

Answers:



44

欧姆,2个字节(CP437)

接受并返回字符串列表。

()

说明:

()   Main wire, arguments: a

(    Remove the first element of a
 )   ...and then the last element of that
     Implicit output

10
我猜这是工作的正确工具
Rohan Jhunjhunwala

15

Vim,6个 5字节

dW$BD

在线尝试!

(带有尾随空格的输出)

由于Vim与V反向兼容,因此我包括了V的TIO链接。

说明

dW                      " Delete up to the next word (removes the first name)
$                       " Go to the end of the line
B                       " Go back one word
D                       " Delete it

德拉特,你击败了我。dWWD为您节省一个字节。
DJMcMayhem

5
@DJMcMayhem仅适用于一个中间名。
Martin Ender

dW和dw有什么区别?
Duncan X Simpson

1
@DuncanXSimpson dW删除直到空格。dw删除直到非单词字符。
Fund Monica的诉讼

14

Python,24字节

lambda n:n.split()[1:-1]

尝试在线输入字符串!

输入格式:字符串


Python 2,16个字节

lambda n:n[1:-1]

尝试在线列表输入!

输入格式:清单


您应该使用Python而不是来编辑标题Python 2,因为它也适用Python 3,正好要发布它。
Xcoder先生17年

@ L3viathan因为OP没有提及输出格式must be a string,并且由于允许输入格式为列表,所以打印列表不能被认为是错误的结果!
Keerthana Prabhakaran

根据对问题的评论,您可以输入和输出字符串列表。节省一堆字节lambda n:n[1:-1]
Luke Sawczak

1
由于您可以从STDIN中读取内容,因此可以将lambda替换为input()(仅适用于Python 3)
BallpointBen

你是对的。谢谢。我已经添加了修改!
Keerthana Prabhakaran

13

Brain-Flak,133字节

{{}((((()()()()){}){}){}[{}](<()>)){{}{}(<(())>)}{}}{}{({}<>)<>}<>{{}((((()()()()){}){}){}[{}](<()>)){{}{}(<(())>)}{}}{}{({}<>)<>}<>

在线尝试!

132个字节的代码,外加1个字节的-c标志(允许ASCII输入和输出)。

不幸的是,它包含许多重复的代码,但实际上很难重用。我稍后再研究。这是一个解释:

#While True
{
    #Pop
    {}

    #Not equals 32
    ((((()()()()){}){}){}[{}](<()>)){{}{}(<(())>)}{}

#Endwhile
}

#Pop the 0
{}

#Reverse Stack
{({}<>)<>}<>

#While True
{
    #Pop
    {}

    #Not equals 32
    ((((()()()()){}){}){}[{}](<()>)){{}{}(<(())>)}{}

#Endwhile
}

#Pop the 0
{}

#Reverse Stack
{({}<>)<>}<>

删除注释时为86个字节。我添加了前两行和最后一行。TIO
Riley's

@riley酷解决方案。随时自己发布!
DJMcMayhem


12

Haskell中,2317 9个字节

init.tail

获取并返回字符串列表。在线尝试!

删除第一个字符串,删除最后一个字符串。

编辑:@Generic显示名称,请注意,输入可以是字符串列表,节省了6个字节。

编辑II:返回字符串列表,而不是单个字符串


看起来像输入列表一样,所以将其删除为-5个字节
通用显示名称

@GenericDisplayName:哦,没有注意到。谢谢!
nimi

我的Ohm答案和Mathematica都回答了字符串的两个输出列表,因此您可能丢弃unwords.-8个字节。
尼克·克利福德

@NickClifford:是的,我看到了自己,并要求OP进行澄清。
nimi

11

Mathematica,10个字节

Rest@*Most

接受并返回字符串列表的未命名函数。

Rest丢弃最后一个元素,Most丢弃第一个元素,@*是函数组合。交换Rest和/ Most或使用正确的构图/*也可以。这比索引少#[[2;;-2]]&了一个字节。


10

Brain-Flak,86个字节

(()()){({}[()]<{{}((((()()()()){}){}){}[{}](<()>)){{}{}(<(())>)}{}}{}{({}<>)<>}<>>)}{}

在线尝试!

此代码大部分来自此答案。如果您喜欢我的解决方案,则也应该赞成该解决方案。

#Push 2
(()())

#Loop twice
{({}[()]<

  #While not a space
  {
      #Pop
      {}

      #Not equals 32
      ((((()()()()){}){}){}[{}](<()>)){{}{}(<(())>)}{}

  #Endwhile
  }

  #Pop the 0
  {}

  #Reverse Stack
  {({}<>)<>}<>

#End loop twice
>)}{}

做得好!我本来不想为以后推送而设计数器,所以我花了太长时间考虑如何在不同的堆栈之间循环。
DJMcMayhem

8

Java 7,74字节

String f(String s){return s.substring(s.indexOf(' '),s.lastIndexOf(' '));}

Java 8,49字节

s->s.substring(s.indexOf(' '),s.lastIndexOf(' '))

识别空格字符的第一个出现和最后一个出现并提取中间字符的函数。结果字符串以一个空格字符作为前缀(在发布时,OP尚不清楚是否允许使用前导空格),可以通过.trim()在代码中添加7字节的额外开销来消除该字符。

与C#相比,Java具有指定结束索引而不是子字符串长度的优点,这减少了字节数。


7

JavaScript(ES6),22个字节

接收并输出一个字符串数组。

([_,...a])=>a.pop()&&a

测试用例

字符串版本(27字节)

接收并输出一个字符串。如果找不到中间名,则输出字符串可以是单个空格,也可以是带有前导和尾随空格的中间名。

s=>(/ .* /.exec(s)||' ')[0]


/./.exec.bind(/ .* /)似乎模仿#2,但null没有模仿
dandavis '17

7

AWK17 10字节

感谢@steve,节省了7个字节!

$NF=$1=x;1

在线尝试!

说明:

$NF=    set last word to
$1=     set first word to
x       an empty variable, ie empty string
1       default action, ie print everything

可以减少到11个字节,$NF=$1="";1
Steve

3
或使用10个$NF=$1=x;1
steve

1
@steve怎么1办?我不太擅长AWK :)
betseg

1仅表示采取默认操作,即打印$ 0。
史蒂夫·

6

Groovy,19个字节

{it.split()[1..-2]}

说明:

{        
 it                  all closures have an implicit argument called "it"
   .split()          splits by spaces by default. Returns an array of words
           [1..-2]   take the whole array from the second index (1) to the penultimate index (-2). Implicitly return
                  }

一个闭包/匿名函数


1
欢迎来到PPCG!您可以将字符串列表作为输入来跳过.split()吗?
Martin Ender'4

Martin Ender是的,如果您假设输入将始终是字符串列表,则{it [1 ..- 2]}将起作用。
staticmethod

5

PHP,37字节

<?=join(" ",array_slice($argv,2,-1));

-4字节用于数组输出

print_r(array_slice($argv,2,-1));

PHP,42字节

echo trim(trim($argn,join(range("!",z))));

PHP,50字节

echo preg_filter("#(^[^\s]+ |[^\s]+$)#","",$argn);


4

Perl 5中27 18个字节

需要与-n选项一起运行。

/ (.+) /&&print$1

在线尝试!

想要先在sed中执行类似的操作,但不幸的是,它不支持非贪婪量词。如果中间名超过一个单词,则需要它。

编辑

-9个字节感谢Dada

除其他外,不再需要非贪婪量词。


/ (.+) /&&print$1 should be sorter. Great to see some new people golfing with Perl!
Dada

@Dada Thanks for the tip! It's actually my first time ever writing in Perl. Do you know why print if s| (.+) |\1| doesn't work? To me it looks similar to what you wrote.
Maxim Mikhaylov

print if s| (.+) |\1|用...中间部分代替中间部分!(减去前后的空格),因此它不起作用。另一方面,我建议的内容仅中间部分匹配,并且仅打印中间部分($1)。
Dada's

4

Javascript(ES6)49 16 bytes

编辑:

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

在线尝试!

松散:

function(name) {
  return a.slice(1, -1); //start at the second item and end at the second to last item
};

我忘记了一些简单的属性 slice, and that the input can be an array. Thanks to @Neil and @fəˈnɛtɪk I was able to remove 27 bytes. Still not really competing.

原版的:

这并不是真正的竞争,但这是一个Javascript解决方案:

a=>{a=a.split(' ');return a.slice(1, a.length-1)}

这将创建一个等于以下内容的匿名函数:

function(name) {
  let name = name.split(' '); //first middle last -> [first, middle, last]
  return name.slice(1, name.length - 1); //get the second item to the second to last item in the array.
}

我如何打高尔夫球

这是一个非常简单的高尔夫。我把功能变成了箭头功能。然后我“缩小”了代码。这包括重命名name为单个字符(a在本例中为该字符),并删除let对变量的取消复制。

片段

Hope this helps anyone who is stuck on the challenge.


The length - is unnecessary, as slice already accepts negative lengths as being relative to the end. This means that you no longer need the intermediate variable, so you can turn your arrow function from a block into an expression.
Neil

Actually the way it works is that -1 is the last but one that you need here.
Neil

It is also slice(1,-1). slice(1,-2) removes two from the end.
fəˈnɛtɪk

You can also assume that you were passed an array to begin with, which lets you just perform slice and you are done.
fəˈnɛtɪk

I'm 99% sure that was changed since I started it. Thanks again.
David Archibald

3

Röda, 9 bytes

{_[1:-1]}

Try it online!

Not a very interesting solution. Takes a list from the stream and returns the middle names.

21 bytes and I/O:

{[(_/" ")[1:-1]&" "]}

Try it online!

This uses / (split) and & (join).


3

Jelly, 2 bytes

ḊṖ

Try it online!

This works as a non-inline link (i.e. function), not a full program.

'John','Jacob','Jingleheimer','Schmidt''Jacob','Jingleheimer'

As a full program, it would be 3 bytes: ḊṖK, which prints a space-separated middle name.



3

C#, 67 bytes

s=>s.Substring(s.IndexOf(' ')+1,s.LastIndexOf(' ')-s.IndexOf(' '));

Anonymous function which identifies the first occurrence of the space character and the last one and extracts the middle. It also extracts a trailing space, which can be removed at the cost of 2 bytes.

Full program with test cases:

using System;

namespace WhatsMyMiddleName
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string, string> f =
            s=>s.Substring(s.IndexOf(' ')+1,s.LastIndexOf(' ')-s.IndexOf(' '));

            Console.WriteLine(f("Jo Jean Smith"));          // "Jean"
            Console.WriteLine(f("Samantha Vee Hills"));     // "Vee"
            Console.WriteLine(f("Bob Dillinger"));          // ""
            Console.WriteLine(f("John Jacob Jingleheimer Schmidt"));// "Jacob Jingleheimer"
            Console.WriteLine(f("Jose Mario Carasco-Williams"));    // "Mario"
            Console.WriteLine(f("James Alfred Van Allen")); // "Alfred Van"
        }
    }
}


3

VBA, 69 bytes

Sub m(n)
f=InStr(1,n," ")
Debug.?Mid(n,f+1,InStrRev(n," ")-f)
End Sub

3

R, 30 27 22 bytes

Current solution due to user11599!

head(scan(,''),-1)[-1]

Takes input from stdin, returns each middle name as a separate string. Returns character() in the case of no middle name; that is, a vector of class character of length 0.

Explanation:

Read stdin into a list of strings, separated by spaces

     scan(,'')

Remove the last element. head returns the first n elements of a list, with n defaulting to 6. If n is -1 it returns all but the last element.

head(scan(,''),-1)

Now, remove the first element of this list.

head(scan(,''),-1)[-1]

This yields the middle name(s).


1
Even shorter: head(scan(,''),-1)[-1] 22 bytes. Note that '' are two single quotes.
user11599

If you don't want each name quoted, use, at 27 bytes, cat(head(scan(,''),-1)[-1])
user11599

Explanation: scan(,'') breaks the string into words, head(...,-1) drops the last word, head(...,-1)[-1] then drops the first word, cat() formats the output dropping the quotes. For no middle name, result isn't perfect, it's character(0), the empty string.
user11599

@user11599 Wow, thanks! I had played around with head() and tail(), but I didn't know you could pass a negative number as the second argument. Nice!
rturnbull

Your use of scan(,'') inspired me. I didn't think of approaching that way.
user11599

3

Ruby, 24 13 bytes

p ARGV[1..-2]

Saved 11 bytes thanks to Piccolo pointing out that array-like output is allowed.

Takes the name as separate command line arguments, e.g.:

$ ruby script.rb John Jacob Jingleheimer Schmidt

or

$ ruby -e 'p ARGV[1..-2]' John Jacob Jingleheimer Schmidt

Previous code (outputs a proper string):

puts ARGV[1..-2].join" "

@Jordan Good idea - however with $><<ARGV[1..-2].join" " it complains about the " " being unexpected, so I'd have to add parentheses - which would add 1 byte in the end.
Flambino

Ah, of course. My bad.
Jordan

The original poster said that the output can be an array, so you can shave some characters off by just changing your code to puts ARGV[1..-2], just so you know.
Piccolo

@Piccolo Huh? I don't see that anywhere? If true; p ARGV[1..-2] for 13 bytes - just looks nothing like the output in OPs challenge
Flambino


3

Golang, 152 81 bytes

import ."strings"
func f(x string)[]string{var k=Fields(x);return k[1:len(k)-1];}

It takes input as "Samantha Vee Hills" (with double quotes) and return the middle name to the stdout.

Try it Online!

Edit: @Dada, note that the "function as answer is allowed" shorten my code 71 bytes. a big thanks!


Welcome on the site. Submitting a function as answer is allowed, so you could shorten your code by doing something like this: Try it online!. Have a look at the Tips for Golfing in Go!
Dada

thank you @Dada for tips and shorten my code. It was my first code entry.
ersinakyuz

3

Matlab, 81, 79, 78, 55 Bytes

function x=a(s)
s=strsplit(s);x=strjoin(s(2:end-1));end

Takes in an input string, s, is split (by the default delimiter, whitespace char) into a cell array, from which the middle element is accessed. Then the middle elements are concatenated, or an empty string is returned.

Edit: thanks to Luis Mendo for saving 3 bytes!

Edit 2: Better solution from Ankit!


I am not a smart man! edited.
Owen Morgan

You can't use nnz on a cell array, but I did the other two changes :)
Owen Morgan

Suggested Edit by Ankit, who doesn't have enough rep to comment. (55 bytes): function x=a(s) s=strsplit(s);x=strjoin(s(2:end-1));end
mbomb007

3

C, 42 bytes

f(char**b){for(;b[2];printf("%s ",*++b));}

The parameter is a NULL terminated array of pointers to char.

See it work here.

The command line arguments may also be used with the same function.

C, 51 bytes

main(a,b)char**b;{for(;b[3];printf("%s ",b++[2]));}

A full program. Input is done through command line arguments.

See it work here.

C, 54 bytes

f(char**b){*strrchr(*b=strchr(*b,32),32)=0;*b+=!!**b;}

The parameter is an in/out parameter.

See it work here.


Welcome to PPCG!
Martin Ender

I'm receiving the following error when compiling with Visual Studio 2012:error C2100: illegal indirection
Johan du Toit

@JohanduToit VS is not C11 or even C99 conforming. My code is. As practical proof, both gcc and clang compile a valid program.
2501

2

Python 2, 42 19 16 Bytes

lambda n:n[1:-1]

Try it online! Thanks to @Kritixi Lithos for saving 23 bytes! Thanks @math_junkie for saving 3 more bytes. For input, put each part of the name as a string within a list like so:

["Samantha", "Vee", "Hills"]

And yes, the OP has approved a list to be a valid input.

Explanation

lambda n:n[1:-1]    # Returns only the middle elements... pretty literal here

1
print input()[1:-1] is shorter
Kritixi Lithos

Spring slicing sure is tricky
Anthony Pham

lambda n:n[1:-1] is even shorter
math junkie

1
I may have tried with a wrong input. But when I tried, with Samantha Vee Hills as input in repl.it link that you've shared, this just prints amantha Vee Hill which is definitely not the output required.
Keerthana Prabhakaran

2
Names will always have at least 2 space-separated parts is the first point of the question right.
Keerthana Prabhakaran

2

C++, 91 bytes

#import<list>
#import<string>
void f(std::list<std::string>&n){n.pop_front();n.pop_back();}

Takes input as a reference to a list of strings and modifies the list directly.

Try it online!

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.