找到中心


24

给定一串ASCII字符,输出中间的字符。如果没有中间字符(当字符串的长度为偶数时),则输出ASCII字符,其序号为两个中心字符的下限平均值。如果字符串为空,则应输出一个空字符串。

测试用例:

12345 => 3

Hello => l

Hiya => q

(empty input) => (empty output)

以字符中最短的程序为准。(不是字节。)

排行榜

这篇文章底部的堆栈摘录从答案a)生成排行榜,答案是每种语言的最短解决方案列表,b)则是总体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N characters 

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

## Ruby, <s>104</s> <s>101</s> 96 characters 

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 characters 

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 characters 


15
通常我们以字节计分,这样人们就无法压缩他们的整个代码,因为这会导致无聊的解决方案。您确定要这个吗?
Downgoat

1
@Vɪʜᴀɴ我认为这里不会有问题,因为解决方案无论如何都是很短的,所以压缩是不值得的。
Ypnypn

9
欢迎来到PPCG!伟大的第一个挑战!
Conor O'Brien

2
我们可以编写函数吗?
Downgoat

10
专业提示:将您的答案编码为UTF-32。每个字符4个字节。或者,也许OP应该摆脱角色得分。
Mego 2015年

Answers:


9

Pyth,15个字节

Cs.O@R/lz2_BCMz

示范

以“ Hiya”开头作为输入:

              z    "Hiya"                                      Input
            CM     [72, 105, 121, 97]                          Character values
          _B       [[72, 105, 121, 97], [97, 121, 105, 72]]    Pair with reversal
      /lz2         2                                           Halfway index
    @R             [121, 105]                                  That element in each
  .O               113.0                                       Average
 s                 113                                         Floor
C                  "q"                                         Cast to character
                   q                                           Print implicitly

请注意,这会因空输入错误而崩溃,并且不向STDOUT输出任何内容,这是按代码高尔夫默认值输出空字符串的有效方法。


Bifurcate再次显示其效用。
lirtosiast 2015年

哇,太棒了。
Maltysen 2015年

@KenanRhoton为了响应您建议的编辑,请检查添加了C地板功能的提交:github.com/isaacg1/pyth/commit/0baf23ec注意添加日期,即询问该问题的同一天。那是因为这个问题启发了我添加功能,使其不符合该问题的使用条件。
isaacg

8

Brainf ***,61个字节

中文,16个字符

这要求输入的ASCII范围是1-127,并且必须为空值。它从字符串的开头和结尾删除成对的字符,直到剩下一个或两个字符。如果有两个,它将它们加在一起,然后除以2,四舍五入。剩余字符被打印。

,[>,]<<<[[<]>[-]>[>]<[-]<<<]>[[->+<]>[-[-<+<]>>]<[>]<[>]<<]>.

此解释器上尝试。

解剖:

,[>,]         Get the null terminated input
<<<           Move to the second last character
[             While there are at least 3 characters
  [<]>           Move to the first character
  [-]            Delete it
  >[>]<          Move to the last character
  [-]            Delete it
  <<<            Move the the third last character
]
>              Move to the second last character
[              If there are two characters remaining
  [->+<]         Add the two characters together
  >[-[-<+<]>>]   Divide the character by 2 rounding down
  <[>]<[>]<<     Move to before the character to exit the if loop
]
>.             Print the remaining character

*鉴于每条指令可以压缩到3位并以UTF-32编码,因此整个程序在技术上可以用6个字符表示。

编辑:感谢Jan Dvorak向我介绍了中文,该语言将其压缩为16个字符,与Dennis的 CJam答案相当

蜐蕈帑聿纂胯箩悚衅鹊颂鹛拮拮氰人

5
Given each instruction could be compressed to 3 bits and encoded in UTF64, the whole program could technically be expressed in 3 characters.你赢了。互联网。还有其他一切。

1
我认为这是不正确的。Brainfuck源代码是字符 +-<>,.[](采用任何编码方式),而不是其二进制表示形式。我们有一个共识,即现有解释器无法使用的编码无效。
lirtosiast 2015年

2
@ThomasKwa,因此我主要以未编码字节为单位给出了分数。字符编码只是加入了可以滥用字符评分的想法。
Hand-E-Food

4
@ThomasKwa:我们中的一些人应该做这样的口译员,以用于未来的挑战。想象一下,BF击败了最好的golfscript解决方案!:)
vsz


6

CJam,16个字节

q:i_W%.+_,2/=2/c

在线尝试!

怎么运行的

q                e# Read all input.
 :i              e# Cast each character to integer.
   _W%           e# Push a reversed copy.
      .+         e# Perform vectorized addition.
        _,2/     e# Get the length, divided by 2.
            =    e# Select the corresponding sum.
             2/c e# Divide by 2 and cast to character.

9
为什么无论难度如何,几乎任何CJam / Pyth高尔夫球都需要10到30个字符?Oo
Zereges 2015年

1
困难?这是一个简单的中位数计算,不包括排序...
Dennis

4
@丹尼斯,我认为这就是他的意思。对于较简单和较难的问题,长度可以相同。
geokavel 2015年

@Zereges不是。10-30通常代表容易出现的问题。如果您想要一个示例来查找更复杂的内容,请参见此代码codegolf.stackexchange.com/a/64086/32852
Reto Koradi 2015年

6

TeaScript,23 个字节 25 30 31 33

²(x[t=xn/2]c+xv[t]c)/2)

使用@isaacg反转字符串的想法。

在线尝试

测试所有情况

取消&&说明

TeaScript仍然是JavaScript,因此其功能也非常类似于JavaScript。

C((x[t=xn/2]c+xv[t]c)/2)

C((           // Char code to char
   x[t=xn/2]c // Floored center
   +          // Add to
   xv[t]c     // Ceil'd center
  ) / 2)      // Divide by 2

5
那个
字眼

10
那头是拉德。我想要每种该死的语言的标题。

是的,除了字距调整。

@sysreq大声笑,这与我使用另一种固定字体有关。
Downgoat


5

Matlab,39 37字节

floor((end+[1,2])/2) 如果长度为偶数,则返回字符串的中间两个索引;如果长度为奇数,则返回中间索引两次。

mean只需返回这些值的平均值并char自动对其进行下限。

@(s)char(mean(s(floor(end/2+[.5,1]))))

5

8086机器代码+ DOS,31个字节

十六进制转储:

BA 1E 01 B4 0A CD 21 8B F2 46 8A 1C D0 EB 8A 50
01 72 06 74 08 02 10 D0 EA B4 02 CD 21 C3 FF

汇编源代码(可以用tasm汇编):

    .MODEL TINY

    .CODE
    org 100h

    MAIN PROC

    mov dx, offset buf
    mov ah, 10      ; DOS function "read string"
    int 21h

    mov si, dx
    inc si          ; si now points to the length of the string
    mov bl, [si]    ; 
    shr bl, 1       ; divide the length by 2
    mov dl, [si+bx+1] ; load the middle char
    jc calc_done    ; if length was odd - done
    jz output_done  ; if length was zero - exit
    add dl, [si+bx] ; add the other middle char
    shr dl, 1       ; divide by 2
calc_done:
    mov ah, 2       ; DOS function "output char"
    int 21h
output_done:
    ret

buf db 255          ; maximum bytes to input

    MAIN ENDP
    END MAIN

这里有一些FLAGS寄存器的微妙用法。在将字符串的长度右移1位(等效于2分)后,两个标志存储了其他信息:

  • 进位标志:包含移出的位。如果该位为1,则长度为奇数。
  • 零标记:显示结果是否为零。如果进位标志为0,零标志为1,则长度为零,并且不打印任何内容。

通常,应该立即检查标志,但是这里我使用了mov指令不会更改标志的事实。因此,可以在加载中间字符后对其进行检查。


4

Python 3,61 59 57 55字节

我尽量不要与我使用的语言打高尔夫球,但这并不太邪恶。

感谢@xsot 2个字节!

lambda x:chr((ord(x[len(x)//2])+ord(x[~len(x)//2]))//2)

完整的程序为59个字节:

x=input()
l=len(x)//2
print(chr((ord(x[l])+ord(x[~l]))//2))

在这里尝试。


啊,您击败了我,我的下一个任务将是什么(如果我没有找到10个要刮掉的字节)
2015年

不,不,要删除我的166字节Go解决方案需要 10个字节。但是,您的优雅得多。
2015年

@sysreq啊,我误会了。谢谢你
lirtosiast

-1-len(x)//2之所以等效于,~len(x)//2是因为底数除法如何对负整数进行运算。
xsot

@xsot谢谢,尽管它使代码更加邪恶:)
lirtosiast 2015年

4

Prolog,111个字节

p(X):-atom_codes(X,L),length(L,N),I is N//2,J is(N-1)//2,nth0(I,L,A),nth0(J,L,B),Q is(A+B)//2,writef('%n',[Q]).

解释

p(X):-atom_codes(X,L),       % Convert to list of charcodes
      length(L,N),           % Get length of list
      I is N//2,             % Get mid index of list
      J is(N-1)//2,          % Get 2nd mid index of list if even length
      nth0(I,L,A),           % Get element at mid index
      nth0(J,L,B),           % Get element at 2nd mid index
      Q is(A+B)//2,          % Get average of elements at mid indices
      writef('%n',[Q]).      % Print as character

例子

>p('Hello').
l

>p('Hiya').
q

4

R,73字节

function(x,y=utf8ToInt(x),n=sum(1|y))if(n)intToUtf8(mean(y[n/2+c(1,.5)]))

在线尝试!

非常感谢@ngm提出了这种非递归的想法-允许打高尔夫球20个字节。

旧解决方案:

R101 95字节

"!"=function(x,n=sum(1|x))"if"(n<3,mean(x),!x[-c(1,n)])
try(intToUtf8(!utf8ToInt(scan(,""))),T)

在线尝试!

递归解决方案。已以2字节的价格更正了一个问题:

  • 添加try(expr, silent = TRUE)以正确管理输入为空的情况。

感谢Giusppe 4个字节!


不会intToUtf8截断非整数吗?
朱塞佩

@Giuseppe,您一如既往的正确:)
JayCe '18

92字节的非递归解决方案。
ngm

82个字节我希望您将它作为一个单独的答案发布-与我的答案完全不同!
JayCe '18年

好吧,除非您付出了最初的努力,否则我不会想出来的。我的回答是票数最高的Pyth回答。我们有很多技巧,我们R人来了。然后您将其缩短。因此,请以明确的良心进行编辑!
ngm

4

外壳,11个字节

c½S¤+öc→←½↔

在线尝试!

说明

一路走来,美味可口的组合器。ö是“组成这四个函数”,¤是“将第一个参数应用于将第二个参数分别应用于两个其他参数的结果”,S是“将此函数(应带有两个参数)应用于S第三个参数和结果”将S'的第二个参数应用于第三个参数”。因此,

   Function       Type                Semantics
     öc→←½        [TChar]->TInt       ASCII code of middle (floored) char in string
   ¤+öc→←½        [TC]->[TC]->TI      Sum of ASCII codes of middle of two strings
  S¤+öc→←½↔       [TC]->TI            Sum of ASCII codes of the middle of a string and its reverse
c½S¤+öc→←½↔       [TC]->TC            ASCII character represented by half the above, QEF

编辑添加:严格来说,这有点不符合问题规范,在输入为空的情况下要求输入字符串,在其他情况下要求使用字符。

由于Husk的严格输入,因此无法定义可以返回两种类型之一的函数/程序。我选择在所有情况下都返回单个字符,对于Husk,单个字符代表空字符串的最合理选择是'(space)'因为这是“默认”值(事实上,这就是该程序返回它的原因;默认值)取空列表的最后一项()时使用值。

我还可以合理地选择返回零个或一个字符的字符串,这将在另一个方向上使规范失败,但是我没有这样做,因为它添加了四个字节:Ṡ&ö;c½S¤+öc→←½↔;将字符转换为一个字符的字符串,另一个ö明确组成需要的内容,Ṡ&如果输入错误,则为快捷方式。


3

C ++ 14,56个字节

[](auto s){int l=s.size();return(s[(l-1)/2]+s[l/2])/2;};

匿名lambda,将string作为参数并返回int作为char代码。对于"",它返回0。不确定输入和输出的外观如何(问题中未指定)。

松开,使用

#include <string>
int main()
{
    auto lmbd = [](auto str)
    {
        int len = str.size();
        return (str[(len - 1) / 2] + str[len / 2]) / 2;
    };

    std::cout << (char) lmbd("Hiya"s) << std::endl; // outputs q
}

@CᴏɴᴏʀO'Bʀɪᴇɴ做完了。
Zereges

我认为您无法使用字符代码进行输出,也无法0针对“”进行输出。
lirtosiast

有明显的规则会很好。
Zereges


3

JavaScript(ES6),83字节89 91

@CᴏɴᴏʀO'Bʀɪᴇɴ节省了2个字节

@ETHproductions节省了6个字节

s=>String.fromCharCode((s[~~(t=s.length/2-.5)][q='charCodeAt']()+s[0|t+.9][q]())/2)

JavaScript对于所有这些字符串char代码都不是很好。


你击败了我。哦,好吧,至少我能帮您忙;)s=>String.fromCharCode((s[~~(t=s.length/2-.5)][r="charCodeAt"]()+s[Math.ceil(t)][r])/2)短了5个字节。
Conor O'Brien 2015年

@CᴏɴᴏʀO'Bʀɪᴇɴ甜。我需要()周围的东西,charCodeAt所以实际上是3个字符,但是还是谢谢你!
Downgoat

@ןnɟuɐɯɹɐןoɯif t是不能工作的整数
Downgoat 2015年

Math.ceil(t)可以更改为0|t+.9
ETHproductions 2015年

@ETHproductions谢谢,节省了6个字节!
Downgoat


2

Minkolang 0.1323 20个字节

$oI2$%d$z,-Xz3&+2:O.

在这里尝试。

说明

$o        Read in the whole stack as characters
I2$%      Push I,2, then pop them and push I//2,I%2
d$z       Duplicate top of stack (I%2) and store in register (z)
,-X       <not> the top of stack, subtract, and dump that many off the top of stack
z3&       Retrieve value from register and jump 3 spaces if this is not zero
   +2:    Add and then divide by 2
O.        Output as character and stop.

1
hiya返回i而不是q
Downgoat

@Vɪʜᴀɴ:哦。我看错了 我以为问题是要问中间的字符,如果长度是均匀的,则要移到下限平均位置
El'endia Starman 2015年

@ThomasKwa:固定。
El'endia Starman

@Vɪʜᴀɴ:^固定。
El'endia Starman 2015年

2

Japt40 29 23 21 20字节

感谢@ןnɟuɐɯɹɐןo,节省了4个字节

现在只有原来长度的一半!我喜欢打高尔夫球。:-D

UcV=K*Ul)+Uw cV)/2 d

在空字符串上正常工作。在线尝试!

怎么运行的

          // Implicit: U = input string, K = 0.5
Uc        // Take the char-code at position
 V=K*Ul   //  V = 0.5 * length of U
+         //  (auto-floored), plus
Uw cV     //  the char-code at position V (auto-floored) in the reversed string,
/2 d      //  divide by 2, and turn back into a character (auto-floored).
          // Implicit: output last expression

如您所见,它使用了大量自动填充功能。(感谢JavaScript!)欢迎提出建议!


相反的事情是辉煌的+1
Downgoat

你不能做V=Ul /2;((UcV +Uw cV )/2 d吗?
Mama Fun Roll

@ןnɟuɐɯɹɐןoɯ好吧,h:P我已经使用了c无数次争论,以至于我忘了它接受了一个。谢谢!
ETHproductions 2015年

2

围棋,166个 156 153字节

围棋可能不是打高尔夫球的最佳语言……但是我非常喜欢它,而且我正在学习,所以在那里。

此实现接受空白(\n)输入,并且可能会因非ASCII / ASCII扩展输入而中断。但是,OP没有指定输入/输出编码,因此我明确支持所有ASCII。

编辑:原来,if/ else 比较短的switch。我想,现在我知道了。

打高尔夫球:

package main;import ."fmt";func main(){a:="";_,_=Scanln(&a);if b:=len(a);b>0{x:=b/2;if b%2==0{Printf("%c",(a[x]+a[x+1])/2)}else{Println(string(a[x]))}}}

取消高尔夫:

package main # everything in go is a package.

import . "fmt" # the dot allows for absolute package method references 
# (think "from string import *" in python)

func main() {
    a := ""
    _, _ = Scanln(&a) # a pointer to a
    if b := len(a); b > 0 { # if statements allow local assignment statements
        x := b / 2
        if b%2 == 0 { # modulo 2 is the easiest way to test evenness
#in which case, average the charcodes and print the result
            Printf("%c", (a[x]+a[x+1])/2)
        } else {
# else just find the middle character (no rounding needed; integer division in Go always results in an integer)
            Println(string(a[x]))
        }
    }
}


2

C#,77个字节

s=>{int n=s.Length;return n<1?' ':(char)(n%2>0?s[n/2]:(s[n/2-1]+s[n/2])/2);};

它实际上并不返回字符串,而且如果输入字符串为空,则将得到一个空格字符,因为该函数必须始终返回一个值。返回字符串还需要2个字节。

完整的测试用例程序:

using System;

namespace FindTheCenter
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string,char>f= s=>{int n=s.Length;return n<1?' ':(char)(n%2>0?s[n/2]:(s[n/2-1]+s[n/2])/2);};   //77 bytes
            Console.WriteLine(f(""));
            Console.WriteLine(f("Hello"));
            Console.WriteLine(f("Hiya"));
        }
    }
}

Alternatively, a full program which reads user input and prints the center of the entered string:

C#, 144 bytes

using C=System.Console;class P{static void Main(){var s=C.ReadLine();int n=s.Length;C.Write(n<1?' ':(char)(n%2>0?s[n/2]:(s[n/2-1]+s[n/2])/2));}}

Again, it uses the same trick of printing a space character, which the user will not notice, and not an empty string, otherwise the solution is 2 bytes longer.


2

Vim, 38 24 23击键

由于vim具有内置功能来查找中间而不是中间 字符,因此我们首先使用substitute,查找中间行,然后删除其前后的所有内容,将每个字符分隔在单独的行上。

:s/\./\0\r/g<cr>ddMjdGkdgg

如果要运行此命令,请注意.vimrc可能会更改.(magic regex)和g (gdefault). Note that it actually saves me 3 keystrokes on my machine :)

先前的答案

:exe 'norm '.(virtcol('$')/2).'|d^ld$'

将一行缓冲区作为输入,并使用中间字符更新当前缓冲区。我以为在vim中会有这个捷径!

注意:一个可能更短的解决方案似乎会导致无限循环...如果某人有一个主意:qq^x$x@qq@qp(12次击键)-它可以<c-c>在最后一次之后使用@q...


1

Mathematica, 118 99 chars

Floor
If[#=="","",FromCharacterCode[%@Mean@#[[Ceiling[l=Length@#/2];;%[l+1]]]&@ToCharacterCode@#]]&

Mma character code manipulation is pricey...


This function only works once, unless you repeat the entire code each time you want to call it. The point of function submissions is for them to be reusable. Calling your function breaks the value of the global % which it relies on.
Martin Ender

1
Why not use the shortened forms of Floor and Ceiling?
DavidC

1

VBA, 130 Bytes

Function a(q)
h=Len(q):a=Mid(q,(h)/2,2)
If h Mod 2=0 Then:a=Chr((Asc(Left(a,1))+Asc(Right(a,1)))\2):Else:a=Right(a,1)
End Function

Finds the Middle 2 Characters.
If number of Characters is Odd then get the Right of the Middle 2 which will be the true middle as we rounded down.
If not sum the ASCII asc() values of the 2 Characters divided by 2 and return the ASCII Character chr() based on that value.

I think I can golf away one of the asc() calls, but couldn't get it to work shorter.



1

><>, 24 + 3 (for -s) = 27 bytes

l1+l4(*9$.~{~
;
o;
+2,o;

Old solution (Doesn't work for empty input):

l3(?v~{~
?vo;>l2=
;>+2,o

Both take input on the stack through -s. Both are 24 bytes.

Try it online here.


1

pb, 83 bytes

^<b[1]>>>w[B!0]{<w[B!0]{t[B]<b[T]>>}<b[0]<b[0]<[X]>>}w[B=0]{<}t[B]<[X]t[B+T]vb[T/2]

While there are at least 3 characters in the input string, the first and last are removed. This leaves either 1 character (should be printed unmodified) or 2 (should be averaged and printed). To handle this, the first and last characters of the string are added together and divided by two. If there was only one character, (a+a)/2==a. If there was two, (a+b)/2 is the character that needs to be printed. pb "borrows" Python's expression evaluation (def expression(e): return eval(e, globals())) so this is automatically floored.

Handling empty input costs me 5 bytes. Specifically, <b[1]> on the first line. Earlier, when I said "string", that was a total lie. pb doesn't have strings, it has characters that happen to be close to each other. Looking for the "last character of a string" just means moving the brush to the left until it hits a character. When no input is provided, the "while there are at least 3 characters" loop is skipped entirely and it starts looking for the last character. Without that <b[1]>, it would keep looking forever. That code puts a character with a value of 1 at (-1, -1) specifically to be found when the input is empty. After finding the "last character" of the string the brush assumes the first one is at (0, -1) and goes there directly, finding a value of 0. (1+0)/2 is 0 in pb, so it prints a null character.

But monorail, that's still printing! The challenge specification says (empty input) => (empty output)! Isn't printing a null character cheating? Also, this is unrelated, but you are smart and handsome.

Thanks, hypothetical question-asker. Earlier, when I said "print", that was a total lie. In pb, you don't really print values, you just place them on the canvas. Rather than "a way to output", it's more accurate to imagine the canvas as an infinitely large 2D array. It allows negative indices in either dimension, and a lot of programming in pb is really about making sure the brush gets to the location on the canvas that you want it. When the program finishes executing, anything on the canvas with non-negative X and Y coordinates is printed to the appropriate location on the console. When the program begins, the entire canvas is filled with values of 0. In order to not have to print an infinite number of lines, each with an infinite number of null bytes, each line of output is only printed up to the last nonzero character, and lines are only printed up to the last one with a nonzero character in it. So putting a 0 at (0, 0) is still an empty output.

Ungolfed:

^<b[1]>                # Prevent an infinite loop on empty input

>>w[B!0]{              # While there are at least 3 chars of input:

    <w[B!0]{              # Starting at the second character:
            t[B]<b[T]>>         # Copy all characters one position to the left
                                # (Effectively erasing the first character)
    }

    <b[0]<b[0]            # Delete both copies of the last character

    <[X]>>                # Get in place to restart loop
}

w[B=0]{<}                 # Go to last character of remaining string
t[B]<[X]t[B+T]            # Find it plus the first character
vb[T/2]                   # Divide by 2 and print

1

Seriously, 22 20 bytes

,O3 >WXXaXa3 >WXkæ≈c

Thanks @Mego for being great at your language

Try it online or whatever


1
This fails for empty input. I have a deleted 20-byte solution which I'm also trying to fix for empty input.
lirtosiast

,;``@(lIƒ will leave you with the input value on the stack if its len is > 0, or terminate the program otherwise. Note that there's an unprintable in the backticks - character 127.
Mego

@Mego This doesn't seem to be working.
phase

@phase You gotta quote strings for input. This works.
Mego

@Mego What is the ƒ supposed to do?
phase

1

CoffeeScript, 104 103 bytes

f=(x)->((y=x.length)%2&&x[y//2]||y&&String.fromCharCode (x[y/=2][z='charCodeAt']()+x[y-1][z] 0)//2)||''

1

Ruby, 43 42 41 bytes

->a{s=a.size;puts s<1?'':s%2<1??q:a[s/2]}

42 bytes

->a{s=a.size;puts s==0?'':s%2<1??q:a[s/2]}

43 bytes

->a{s=a.size;puts s==0?'':s%2<1?'q':a[s/2]}

Usage:

->a{s=a.size;puts s<1?'':s%2<1??q:a[s/2]}['12345']
=> 3

1

Java 7, 152 bytes

String c(String s){char[]a=s.toCharArray();int l=a.length,x,y;return l<2?s:""+(l%2>0?a[l/2]:(char)((x=a[l/2])>(y=a[(l/2)-1])?y+((x-y)/2):x+((y-x)/2)));}

Ungolfed & test cases:

Try it here.

class M{
  static String c(String s){
    char[] a = s.toCharArray();
    int l = a.length,
            x,
            y;
    return l < 2
            ? s
            : "" + (l%2 > 0
                     ? a[l/2]
                     : (char)((x = a[l/2]) > (y = a[(l/2)-1])
                                ? y + ((x-y)/2)
                                : x + ((y-x)/2)));
  }

  public static void main(String[] a){
    System.out.println(c("12345"));
    System.out.println(c("Hello"));
    System.out.println(c("Hiya"));
    System.out.println(c(""));
    System.out.println(c("x")); // Additional test case that will fail on some other answers
  }
}

Output:

3
l
q
(empty output)
x

1

PHP, 147 93 bytes

Credits and special thanks to Jörg Hülsermann for golfing my answer 54 bytes down!

<?=($l=strlen($s=$argv[1]))%2?$s[($l-1)/2]:chr(floor((ord($s‌​[$l/2])+ord($s[$l/2-‌​1]))/2));

Previous version:

$s=$argv[1];$l=strlen($s);echo($l%2!=0?substr($s,$n=($l-1)/2,-$n):chr(floor(abs((ord($x=substr($s,$l/2-1,1))-ord(substr($s,$l/2,1)))/2))+ord($x)));

Testing code:

$argv[1] = 'Hiya';
$s=$argv[1];
$l=strlen($s);
echo($l%2!=0?substr($s,$n=($l-1)/2,-$n):chr(floor(abs((ord($x=substr($s,$l/2-1,1))-ord(substr($s,$l/2,1)))/2))+ord($x))); 

Test online

I have the feeling that this can be improved, but not enough time for it...


<?=($l=strlen($s=$argv[1]))%2?$s[($l-1)/2]:chr(floor((ord($s[$l/2])+ord($s[$l/2-1]))/2)); is my proposal
Jörg Hülsermann

@JörgHülsermann Brilliant golfing! You should post it as your own answer. If I have time I will golf my answer more with your nice solutions. Thanks.
Mario

Feel free to take it as your answer
Jörg Hülsermann

1

Excel, 122 79 bytes

Actually @Sophia Lechner's answer now:

=IFERROR(CHAR(CODE(MID(A8,LEN(A8)/2+.5,1))/2+CODE(MID(A8,LEN(A8)/2+1,1))/2),"")

-5 bytes from initial solution thanks to @Taylor Scott.

=IFERROR(IF(ISODD(LEN(A1)),MID(A1,LEN(A1)/2+1,1),CHAR((CODE(MID(A1,LEN(A1)/2,1))+CODE(MID(A1,LEN(A1)/2+1,1)))/2)),"")

12 bytes needed for Empty String.


Drop Average(...,...) and use (...+...)/2 for -5 bytes. =IFERROR(IF(ISODD(LEN(A1)),MID(A1,LEN(A1)/2+1,1),CHAR((CODE(MID(A1,LEN(A1)/2,1))+CODE(MID(A1,LEN(A1)/2+1,1)))/2)),"")
Taylor Scott

Excel will accept (and floor) a non-integer second argument to MID, so you don't have to split it into cases - =IFERROR(CHAR(CODE(MID(A1,LEN(A1)/2+1,1))/2+CODE(MID(A1,LEN(A1)/2+.5,1))/2),"") for 79 bytes
Sophia Lechner
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.