Find the center

24

1

Given a string of ASCII characters, output the character that is in the middle. If there is no middle character (when the string has an even length), output the ASCII character whose ordinal is the floored average of the two center characters. If the string is empty, an empty string should be output.

Test cases:

12345 => 3

Hello => l

Hiya => q

(empty input) => (empty output)

Shortest program in characters wins. (Not bytes.)

Leaderboard

The Stack Snippet at the bottom of this post generates the leaderboard from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N characters 

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

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

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

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

You can also make the language name a link which will then show up in the snippet:

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

<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 64599; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 47556; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>

n-o-body here

Posted 2015-11-23T23:20:44.920

Reputation: 381

15Usually we score in bytes so people can't compress their entire code, as this results in boring solutions. Are you sure you want this? – Downgoat – 2015-11-23T23:26:49.133

1@Vɪʜᴀɴ I don't think that will be a problem here, since solutions will be very short anyway, so compressing won't be worth it. – Ypnypn – 2015-11-23T23:27:29.763

Can you describe what you mean by floored average? – TanMath – 2015-11-23T23:32:47.933

@TanMath I think it means if the average is 87.8 you should always round down to 87 – Downgoat – 2015-11-23T23:33:47.463

9Welcome to PPCG! Great first challenge! – Conor O'Brien – 2015-11-23T23:56:19.520

2Can we write functions? – Downgoat – 2015-11-23T23:57:18.977

10Pro-tip: encode your answers in UTF-32. 4 bytes per character. Or maybe the OP should just get rid of the character scoring. – Mego – 2015-11-24T00:15:51.817

@Vɪʜᴀɴ Functions are allowed by default int [tag:code-golf] – flawr – 2015-11-24T11:44:01.077

@AdamDavis That only matters if your compiler/interpreter can't read the encoding. Seriously, for example, is happy with any encoding, because it's all just bytes to it anyway. – Mego – 2015-11-25T16:57:41.540

Answers

9

Pyth, 15 bytes

Cs.O@R/lz2_BCMz

Demonstration

Starting with "Hiya" as input:

              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

Note that this crashes with an error on empty input, and prints nothing to STDOUT, which is a valid way to output an empty string by code-golf defaults.

isaacg

Posted 2015-11-23T23:20:44.920

Reputation: 39 268

Bifurcate shows its utility again. – lirtosiast – 2015-11-24T03:37:14.397

whoa bifurcate is awesome. – Maltysen – 2015-11-25T00:58:25.200

@KenanRhoton In response to your proposed edit, check out the commit that added the C flooring functionality: https://github.com/isaacg1/pyth/commit/0baf23ec Notice the day it was added, the same day this question was asked. That's because this question inspired me to add that functionality, making it ineligible for use on this question.

– isaacg – 2016-09-27T15:28:03.077

8

Brainf***, 61 bytes

Chinese, 16 characters

This requires the input is in the ASCII range 1-127 and is null-terminated. It deletes pairs of characters from the start and end of the string until there are one or two characters remaining. If there are two, it adds them together, then divides by 2, rounding down. The remaining character is printed.

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

Try it on this interpreter.

Dissection:

,[>,]         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

* Given each instruction could be compressed to 3 bits and encoded in UTF-32, the whole program could technically be expressed in 6 characters.

EDIT: And thanks to Jan Dvorak for introducing me to Chinese, which compresses this into 16 characters, on par with Dennis' CJam answer.

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

Hand-E-Food

Posted 2015-11-23T23:20:44.920

Reputation: 7 912

5Given each instruction could be compressed to 3 bits and encoded in UTF64, the whole program could technically be expressed in 3 characters. You win. The internet. And everything else. – cat – 2015-11-24T04:12:00.550

1

I don't think this is valid. Brainfuck source code is the characters +-<>,.[], in whatever encoding, not their binary representations. We have a consensus that an encoding that can't be used by an existing interpreter is invalid.

– lirtosiast – 2015-11-24T05:34:03.260

2@ThomasKwa, hence I gave my score primarily in un-encoded bytes. The character encoding was just joining in the idea that scoring by characters can be abused. – Hand-E-Food – 2015-11-24T05:42:51.550

4@ThomasKwa : it's time for some of us to make such an interpreter, to be used in future challenges. Imagine BF beating the best golfscript solution! :) – vsz – 2015-11-24T07:25:39.627

1@vsz, I think I now have something to keep me busy tonight... ;-) – Hand-E-Food – 2015-11-24T08:34:52.790

1I can't find a description of UTF64 anywhere; did you mean UTF-32? – anatolyg – 2015-11-24T22:42:02.243

@anatolyg No, he meant UTF-64, with twice the codepoints as UTF-32 as a joke. – cat – 2015-11-25T00:23:13.443

1Then I do UTF-9000! I win :) – anatolyg – 2015-11-25T00:24:39.093

@anatolyg, whoops. Yeah, I guess I meant UTF-32. That's what I get for not compiling my super-encoded code. – Hand-E-Food – 2015-11-25T02:01:11.583

2

@vsz https://esolangs.org/wiki/Chinese

– John Dvorak – 2015-11-25T11:35:08.843

6

CJam, 16 bytes

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

Try it online!

How it works

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.

Dennis

Posted 2015-11-23T23:20:44.920

Reputation: 196 637

9Why almost any CJam/Pyth golf is 10-30 chars no matter the difficulty? O.o – Zereges – 2015-11-23T23:37:12.640

1Difficulty? This is a simple median calculation, minus the sorting... – Dennis – 2015-11-24T00:37:50.340

4@Dennis I think that's what he means. It can be about the same length for both easier and harder questions. – geokavel – 2015-11-24T01:12:23.530

@Zereges Not really. 10-30 is typical for easy problems. See this if you want an example of how it looks for something more complex: http://codegolf.stackexchange.com/a/64086/32852.

– Reto Koradi – 2015-11-24T04:32:26.423

6

TeaScript, 23 bytes 25 30 31 33

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

Uses @isaacg's idea of reversing the string.

Try it online

Test all of the cases

Ungolfed && Explanation

TeaScript is still JavaScript so it functions a lot like JavaScript too.

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

Downgoat

Posted 2015-11-23T23:20:44.920

Reputation: 27 116

5That kerning... – lirtosiast – 2015-11-24T00:30:55.553

10That header is rad. I want that header for every goddamn language. – cat – 2015-11-24T00:31:15.970

Yeah, except the kerning. – cat – 2015-11-24T00:31:36.160

@sysreq lol, it had to do with the fact I'm using a different font, fixed. – Downgoat – 2015-11-24T00:39:36.650

12Please tell me will work. – phase – 2015-11-24T02:13:12.483

Now I get TypeError: x.G is not a function even though there is no xG??? – ETHproductions – 2015-11-24T02:24:46.193

@ETHproductions huh, weird, try it now – Downgoat – 2015-11-24T02:25:53.897

Yep, it's better :) – ETHproductions – 2015-11-24T02:27:17.440

@ThomasKwa The default for my computer is ISO-8859, or Latin-1. In UTF-8 encoding this is 24 bytes but in Latin-1, it is 23.

– Downgoat – 2015-11-24T03:56:02.873

5

Matlab, 39 37 bytes

floor((end+[1,2])/2) returns the middle two indices of the string if the length is even, and returns the middle indice twice if the length is odd.

mean just returns the mean of those values and char automatically floors it.

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

flawr

Posted 2015-11-23T23:20:44.920

Reputation: 40 560

5

8086 machine code + DOS, 31 bytes

Hexdump:

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

Assembly source code (can be assembled with 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

There is some delicate usage of the FLAGS register here. After it shifts the length of the string right by 1 bit (which is equivalent to division by 2), two flags store additional information:

  • Carry flag: contains the bit that was shifted out. If the bit is 1, the length was odd.
  • Zero flag: shows whether the result is zero. If the carry flag is 0 and the zero flag is 1, the length was zero, and nothing should be printed.

Normally, the flags should be checked immediately, but here I use the fact that the mov instruction doesn't change flags. So they can be examined after loading the middle char.

anatolyg

Posted 2015-11-23T23:20:44.920

Reputation: 10 719

4

R, 73 bytes

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

Try it online!

Many thanks to @ngm for coming up with this non-recursive idea - allowed to golf 20 bytes.

Old solution:

R, 101 95 bytes

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

Try it online!

Recursive solution. Corrected one issue at the price of 2 bytes:

  • added try(expr, silent = TRUE) to properly manage the case where the input is empty.

thanks Giusppe for 4 bytes !

JayCe

Posted 2015-11-23T23:20:44.920

Reputation: 2 655

doesn't intToUtf8 truncate non-integers? – Giuseppe – 2018-08-09T14:57:19.873

@Giuseppe you are right as always :) – JayCe – 2018-08-09T15:04:29.023

92 bytes non-recursive solution. – ngm – 2018-08-09T16:24:41.847

82 bytes I'd rather you post it as a separate answer - it's totally different from my answer! – JayCe – 2018-08-09T16:33:20.530

Well, I wouldn't have come up with it unless you had put the original effort in. And my answer was a port of the top vote-getting Pyth answer. With a bunch of tricks we R people have come up. And then you made it shorter. So go ahead and make the edit with a clear conscience! – ngm – 2018-08-09T16:47:18.990

@ngm Many thanks, will do. I have found some more bytes though :) – JayCe – 2018-08-09T16:57:06.463

4

Husk, 11 bytes

c½S¤+öc→←½↔

Try it online!

Explanation

Delicious, delicious combinators all the way down. ö is "compose these four functions", ¤ is "apply the first argument to the results of applying the second argument to two additional arguments separately", S is "apply this function (which should take two arguments) to S's third argument and to the result of applying S's second argument to its third". Therefore,

   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

Edited to add: Strictly speaking, this fails slightly to conform to the problem specification, which requests a string in the case of an empty input and a character in other cases.

Due to Husk's strict typing, it's just not possible to define a function/program that can return either of two types. I chose to return a single character in all cases, and for Husk, the most reasonable choice for a single character to represent the empty string is '(space)' because that's the "default" value (and in fact, that's why this program returns it; the default value is used when taking the last () item of an empty list).

I could have also reasonably chosen to return strings of zero or one characters, which would fail the specification in the other direction, but I didn't because it adds four bytes: Ṡ&ö;c½S¤+öc→←½↔, with the ; converting the character to a one-character string, another ö to explicitly compose the needful, and a Ṡ& to shortcut in the case of falsy input.

Sophia Lechner

Posted 2015-11-23T23:20:44.920

Reputation: 1 200

4

Python 3, 61 59 57 55 bytes

I try not to golf with languages I work in, but this isn't too evil.

Thanks to @xsot for 2 bytes!

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

The full program is 59 bytes:

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

Try it here.

lirtosiast

Posted 2015-11-23T23:20:44.920

Reputation: 20 331

Ah, you beat me to what my next task was going to be (had I not found 10 bytes to shave off) – cat – 2015-11-24T02:00:59.977

No, no, 10 bytes to shave off my 166 byte Go solution. Yours is far more elegant, however. – cat – 2015-11-24T02:05:08.510

@sysreq Ah, I misunderstood. And thanks. – lirtosiast – 2015-11-24T02:06:15.613

-1-len(x)//2 is equivalent to ~len(x)//2 because of how floor division works on negative integers. – xsot – 2015-11-24T04:43:11.093

@xsot Thanks—it makes the code a little more evil though :) – lirtosiast – 2015-11-24T05:28:40.327

4

Prolog, 111 bytes

Code

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]).

Explained

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

Examples

>p('Hello').
l

>p('Hiya').
q

Emigna

Posted 2015-11-23T23:20:44.920

Reputation: 50 798

3

O, 44 34 bytes

Crossed out 44 is still regular 44 :(

ise.eJ;2/m[(\($L;dJ{#\#+2/c}L;?o];

Bytes wasted on:

  • Checking if the input's length is even/odd
  • Getting the middle character(s)

phase

Posted 2015-11-23T23:20:44.920

Reputation: 2 540

7I'm sure you posted an ungolfed version to say that ;) – Conor O'Brien – 2015-11-24T00:12:22.400

4@CᴏɴᴏʀO'Bʀɪᴇɴ I just got lucky :D – phase – 2015-11-24T00:13:30.527

3

JavaScript (ES6), 83 bytes 89 91

Saved 2 bytes thanks to @Cᴏɴᴏʀ O'Bʀɪᴇɴ

Saved 6 bytes thanks to @ETHproductions

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

JavaScript's not too good at all this string char code.

Downgoat

Posted 2015-11-23T23:20:44.920

Reputation: 27 116

You beat me to it. Oh well, least I can do is help you ;) s=>String.fromCharCode((s[~~(t=s.length/2-.5)][r="charCodeAt"]()+s[Math.ceil(t)][r])/2) is 5 bytes shorter. – Conor O'Brien – 2015-11-24T00:10:39.593

@CᴏɴᴏʀO'Bʀɪᴇɴ Sweet. I need the () around charCodeAt so it's really 3 chars,but thanks anyway! – Downgoat – 2015-11-24T00:14:32.333

@ןnɟuɐɯɹɐןoɯ if t is an integer that won't work – Downgoat – 2015-11-24T00:36:29.933

Math.ceil(t) can be changed to 0|t+.9 – ETHproductions – 2015-11-24T01:37:08.207

@ETHproductions thanks, That saved 6 bytes! – Downgoat – 2015-11-24T01:40:00.417

I get TypeError: s[~(~((intermediate value)))] is undefined for an empty string – rink.attendant.6 – 2015-11-25T09:14:58.593

3

C++14, 56 bytes

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

Anonymous lambda taking string as an argument and returning int as char code. For "", it returns 0. Not sure how exactly the input and output should look like (is not specified in the question).

Ungolfed, with usage

#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
}

Zereges

Posted 2015-11-23T23:20:44.920

Reputation: 1 165

@CᴏɴᴏʀO'Bʀɪᴇɴ done. – Zereges – 2015-11-24T00:15:23.577

I don't think you can output with the character code, and I don't think you can output 0 for "" either. – lirtosiast – 2015-11-24T17:46:29.573

It would be nice to have apparent rules. – Zereges – 2015-11-24T19:17:58.063

54 bytes – ceilingcat – 2019-06-19T03:38:00.293

2

Minkolang 0.13, 23 20 bytes

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

Try it here.

Explanation

$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.

El'endia Starman

Posted 2015-11-23T23:20:44.920

Reputation: 14 504

1hiya returns i instead of q – Downgoat – 2015-11-24T00:02:49.670

@Vɪʜᴀɴ: OH. I misread it. I thought the question was asking for the character in the middle, going to the floored average position if the length was even. – El'endia Starman – 2015-11-24T00:27:26.850

@ThomasKwa: Fixed. – El'endia Starman – 2015-11-24T00:51:19.383

@Vɪʜᴀɴ: ^ Fixed. – El'endia Starman – 2015-11-24T00:52:09.123

2

, 23 chars

a=ïꝈ/2,ϚĎ((ïüa+ᴙïüa)/2)

Try it here (Firefox only).

Thanks to @ETHProductions for the idea!

Mama Fun Roll

Posted 2015-11-23T23:20:44.920

Reputation: 7 234

2Lucky, a challenge measured in chars instead of bytes ;) – ETHproductions – 2015-11-24T02:51:13.060

Oh yay! We're all tied. – Mama Fun Roll – 2015-11-24T03:34:18.630

Whoever downvoted this, could I please get an explanation? – Mama Fun Roll – 2015-11-24T14:21:12.530

2

Japt, 40 29 23 21 20 bytes

Saved 4 bytes thanks to @ןnɟuɐɯɹɐןoɯ

Now only half the original length! I love code golf. :-D

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

Works properly on the empty string. Try it online!

How it works

          // 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

As you can see, it uses a lot of auto-flooring. (Thanks, JavaScript!) Suggestions welcome!

ETHproductions

Posted 2015-11-23T23:20:44.920

Reputation: 47 880

The reverse thing is brilliant +1 – Downgoat – 2015-11-24T01:33:25.133

Couldn't you just do V=Ul /2;((UcV +Uw cV )/2 d? – Mama Fun Roll – 2015-11-24T01:53:57.357

@ןnɟuɐɯɹɐןoɯ Well, duh :P I've used c so many times without an argument that I forgot it accepted one. Thanks! – ETHproductions – 2015-11-24T02:19:53.337

2

Go, 166 156 153 bytes

Go may not be the best language for golfing... but I love it, so so much, and I'm learning it, so there.

This implementation accepts blank (\n) input and will probably break with non-ASCII/ASCII-extended input. However, OP has not specified input/output encoding thus ASCII is all I've explicitly supported.

Edit: turns out if/else is shorter than switch. Now I know, I suppose.

Golfed:

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]))}}}

Ungolfed:

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]))
        }
    }
}

cat

Posted 2015-11-23T23:20:44.920

Reputation: 4 989

2

C#, 77 bytes

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

It doesn't actually return a string, and you'll get a space character if the input string is empty because the function must always return a value. 2 more bytes would be needed to return a string.

Full program with test cases:

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.

adrianmp

Posted 2015-11-23T23:20:44.920

Reputation: 1 592

2

Vim, 38 24 23 keystrokes

Because vim has a built in function to find the middle line but not the middle char, we split every character on a separate line first using substitute, find the middle line, then delete everything after and before it.

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

If you want to run this, beware of .vimrc files which may change the behavior of . (magic regex) and g (gdefault). Note that it actually saves me 3 keystrokes on my machine :)

Previous answer

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

Takes a one line buffer as input, updates the current buffer with the middle character. I thought there would have been a shortcut for this in vim!

Note: a potentially shorter solution seems to cause an infinite loop... If someone has an idea: qq^x$x@qq@qp (12 keystrokes) - it works with <c-c> after the last @q...

Christian Rondeau

Posted 2015-11-23T23:20:44.920

Reputation: 301

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.

Wernisch

Posted 2015-11-23T23:20:44.920

Reputation: 2 534

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 – 2018-08-08T11:01:08.223

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 – 2018-08-09T21:12:50.463

1

Haskell, 87 bytes

A nice recursive solution is possible here:

import Data.Char
f[]=[]
f[c]=[c]
f[c,d]=[chr(ord c+div(ord d-ord c)2)]
f(c:s)=f$init s

AlexJ136

Posted 2015-11-23T23:20:44.920

Reputation: 251

chr and ord are not in Prelude, so according to our golfing rules you need to include the import Data.Char in your byte count. In better news, you can drop f[]=[];f[c]=[c] and add f e=e as last line to save some bytes. – Laikoni – 2018-08-11T13:45:54.707

Wait, you can only shorten f[]=[] to f e=e, otherwise init throws an error. – Laikoni – 2018-08-11T13:53:04.727

1

Mathematica, 118 99 chars

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

Mma character code manipulation is pricey...

LegionMammal978

Posted 2015-11-23T23:20:44.920

Reputation: 15 731

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 – 2015-11-30T12:26:15.710

1Why not use the shortened forms of Floor and Ceiling? – DavidC – 2016-09-27T14:42:46.537

1

Seriously, 22 20 bytes

,O3 >WXXaXa3 >WXkæ≈c

Thanks @Mego for being great at your language

Try it online or whatever

phase

Posted 2015-11-23T23:20:44.920

Reputation: 2 540

1This fails for empty input. I have a deleted 20-byte solution which I'm also trying to fix for empty input. – lirtosiast – 2015-11-24T05:25:25.413

,;\`@(lIƒwill leave you with the input value on the stack if itslen` is > 0, or terminate the program otherwise. Note that there's an unprintable in the backticks - character 127. – Mego – 2015-11-24T15:46:39.467

@Mego This doesn't seem to be working.

– phase – 2015-11-24T19:36:50.247

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

– Mego – 2015-11-24T19:42:28.260

@Mego What is the ƒ supposed to do? – phase – 2015-11-24T19:56:02.627

@phase It calls the \`` (terminate program function) if the length is falsely, or tries (and fails) to call the string input. – Mego – 2015-11-24T20:05:37.597

The code you have also doesn't work for odd-length strings.

– Mego – 2015-11-25T02:16:57.237

This, however, does work. If I had noticed that I screwed up the implementation of the median function before this challenge was posted, this would also work. ,║ is now valid as well, because I extended median to work with strings. – Mego – 2015-11-25T02:40:38.313

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.

cole

Posted 2015-11-23T23:20:44.920

Reputation: 3 526

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.

JimmyJazzx

Posted 2015-11-23T23:20:44.920

Reputation: 691

1

K, 40 bytes

{(*|r;`c$_(+/r:2#l_x)%2)@l=_l:-1+(#x)%2}

kirbyfan64sos

Posted 2015-11-23T23:20:44.920

Reputation: 8 730

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

undergroundmonorail

Posted 2015-11-23T23:20:44.920

Reputation: 5 897

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)||''

rink.attendant.6

Posted 2015-11-23T23:20:44.920

Reputation: 2 776

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

Vasu Adari

Posted 2015-11-23T23:20:44.920

Reputation: 941

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

Kevin Cruijssen

Posted 2015-11-23T23:20:44.920

Reputation: 67 575

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...

Mario

Posted 2015-11-23T23:20:44.920

Reputation: 3 043

<?=($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 – 2016-09-27T23:10:42.217

@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 – 2016-09-28T14:17:04.330

Feel free to take it as your answer – Jörg Hülsermann – 2016-09-28T14:23:46.263

0

C (gcc), 54 51 bytes

-3 bytes thanks to vazt.

Returns a NULL char for empty strings.

l;f(char*s){l=strlen(s);s+=l/2;s=*s+s[l%2-!!l]>>1;}

Try it online!

gastropner

Posted 2015-11-23T23:20:44.920

Reputation: 3 264

l%2-!!l instead of -!(!l+l%2) for 51 bytes – vazt – 2018-08-08T15:29:45.130

Suggest s=s[l/2]+s[~-l/2+!l]>>1 instead of s+=l/2;s=*s+s[l%2-!!l]>>1 – ceilingcat – 2018-12-21T02:58:17.240

0

Excel VBA, 101 81 bytes

Immediate window function that takes input from cell [A1] and outputs to the VBE immediate window

l=[Len(A1)]/2:s=[A1]&" ":If l Then?Chr((Asc(Mid(s,l+.5))+Asc(Mid(s,l+1)))\2)Else?

Taylor Scott

Posted 2015-11-23T23:20:44.920

Reputation: 6 709

0

Lua, 128 bytes

p=...i=math.ceil(#p/2)s=string b=s.byte a=p:sub(i,i)io.write(#p==0 and""or#p/2%1~=0 and a or s.char((b(a)+b(p:sub(i+1,i+1)))/2))

Try it online!

Visckmart

Posted 2015-11-23T23:20:44.920

Reputation: 151

0

05AB1E, 11 15 bytes

Dg≠iÇÂ)øDg;èO;ç

+4 bytes to fix an input of length 1.

Try it online or verify all test cases.

Explanation:

Dg              # Duplicate the input, and get it's length
  ≠i            # If this length is not exactly 1:
    Ç           #  Convert each letter to its ordinal value
                #   i.e. 'Hiya' → [72,105,121,97]
     Â          #  Bifurcate (short for Duplicate and Reverse)
                #   [72,105,121,97] → [72,105,121,97] and [97,121,105,72]
      )         #  Wrap both lists in a list
                #   [72,105,121,97] and [97,121,105,72] → [[72,105,121,97],[97,121,105,72]]
       ø        #  Zip the lists with each other, creating pairs
                #   i.e. [[72,105,121,97],[97,121,105,72]]
                #    → [[72,97],[105,121],[121,105],[97,72]]
        Dg      #  Duplicate it, and get it's length
                #   i.e. [[72,97],[105,121],[121,105],[97,72]] → 4
          ;     #  Halve this length
                #   i.e. 4 → 2
           è    #  Index (0-indexed) it in the pairs
                #   i.e. [[72,97],[105,121],[121,105],[97,72]] and 2 → [121,105]
            O   #  Take the sum of the indexed pair
                #   i.e. [121,105] → 226
             ;  #  Halve it
                #   i.e. 226 → 113.0
              ç #  Convert it from this ordinal value to a character
                #   i.e. 113.0 → 'q'
                # (Implicit else: output the 1-char input itself)

Old 11 bytes version which works for all given test cases, but fails for inputs of length 1:

ÇÂ)øDg;èO;ç

Try it online or verify all test cases.

Kevin Cruijssen

Posted 2015-11-23T23:20:44.920

Reputation: 67 575