34
\$\begingroup\$

Task

Your task is to produce string that contains average characters of string. First character of result would be average character of first character (which is first character) and second character average of two first characters and so on.

What is average character?

Strings are arrays of bytes. Average character of string can be found by calculating the average of the ASCII values of characters in string and taking corresponding ASCII character.

For example string "Hello!" can be written as byte sequence 72 101 108 108 111 33. Average of ascii values is 533/6 = 88.833... and when it's rounded to nearest integer we get 89 which is ascii code for captial letter Y.

Rules

  • You can assume that input contains only printable ASCII characters
  • Input can be read from stdin or as command line arguments or as function arguments
  • Output must be stdout. If your program is function, you can also return the string you would otherwise print.
  • It must be whole program or function, not snippet
  • Standard loopholes apply
  • Integers are rounded by function floor(x+0.5) or similar function.

How do I win?

This is , so shortest answer (in bytes) in wins.

Examples

  • Hello!HW^adY
  • testtmop
  • 4243
  • StackExchangeSdccd_ccccddd
\$\endgroup\$
8
  • \$\begingroup\$ Edited question. Now it should be clear: you have to round halves upwards. \$\endgroup\$ Jul 24, 2015 at 9:46
  • 1
    \$\begingroup\$ "Input can be read from stdin or as command line arguments": or as function arguments (since you allow functions), right? \$\endgroup\$
    – Luis Mendo
    Jul 24, 2015 at 12:17
  • \$\begingroup\$ Of course, edited again. \$\endgroup\$ Jul 24, 2015 at 13:36
  • 2
    \$\begingroup\$ Sorry to bother you once again, but do functions actually have to print the output to STDOUT or can they return the desired string? \$\endgroup\$
    – Dennis
    Jul 24, 2015 at 14:20
  • 1
    \$\begingroup\$ Sdcce`ccddeee and HW^bdY bugs are if you use ceil instead of round, while HV^adY bugs is if you use banker's rounding (round to even). The original asker has it right for traditional math rounding. \$\endgroup\$
    – Sandra
    Aug 20, 2022 at 8:08

58 Answers 58

1
2
1
\$\begingroup\$

Java, 100

Much like many other answers here, I'm summing and averaging in a loop. Just here to represent Java :)

void f(char[]z){float s=0;for(int i=0;i<z.length;System.out.print((char)Math.round(s/++i)))s+=z[i];}

My original code is a 97, but it only returns the modified char[] rather than printing it:

char[]g(char[]z){float s=0;for(int i=0;i<z.length;z[i]=(char)Math.round(s/++i))s+=z[i];return z;}

Now, it's just long enough for scrollbars to appear for me, so here's a version with some line breaks, just because:

void f(char[]z){
    float s=0;
    for(int i=0;
            i<z.length;
            System.out.print((char)Math.round(s/++i)))
        s+=z[i];
}
\$\endgroup\$
4
  • \$\begingroup\$ Interesting. Can you show us a call sample too? My Java is very rusty. \$\endgroup\$
    – manatwork
    Jul 24, 2015 at 13:49
  • \$\begingroup\$ As in how to call it? Assuming test is a char array, just use f(test);. If it's a String object, then you'd use f(test.toCharArray());. String literals are fine like that, too: f("Hello!".toCharArray()); \$\endgroup\$
    – Geobits
    Jul 24, 2015 at 13:53
  • \$\begingroup\$ Oh. Sure. toCharArray() Me stupid, I tried to violate it with some casting. Thank you. \$\endgroup\$
    – manatwork
    Jul 24, 2015 at 13:58
  • \$\begingroup\$ It'd be way too easy to just cast it. The Java gods would be furious :P \$\endgroup\$
    – Geobits
    Jul 24, 2015 at 13:59
1
\$\begingroup\$

C, 62 bytes

c;t;main(n){for(;(c=getchar())>0;n++)putchar(((t+=c)+n/2)/n);}

(ideone link)

The results are slightly different from the OP's examples, but only because this code rounds 0.5 down instead of up. Not any more!

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

R, 135 127 Bytes

This got long real quick and I really got it wrong the first time:) Need to read the questions properly.

cat(sapply(substring(a<-scan(,''),1,1:nchar(a)),function(x)rawToChar(as.raw(round(mean(as.integer(charToRaw(x)))+.5)))),sep='')

Test Run

cat(sapply(substring(a<-scan(,''),1,1:nchar(a)),function(x)rawToChar(as.raw(round(mean(as.integer(charToRaw(x)))+.5)))),sep='')
1: Hello!
2: 
Read 1 item
HW^adY
\$\endgroup\$
2
  • \$\begingroup\$ somebody posted a dupe challenge in the sandbox so I found this...This was a looong time ago, but utf8ToInt will help! I have a 68 byte golf of this if you want to update to it. \$\endgroup\$
    – Giuseppe
    Jan 18, 2018 at 17:31
  • \$\begingroup\$ @Giuseppe Go ahead and post it yourself if you would like. I suspect that it is significantly different to what I did here. \$\endgroup\$
    – MickyT
    Jan 18, 2018 at 18:41
1
\$\begingroup\$

Perl 5, 41 bytes

say map{$s+=ord;chr($s/++$c+.5)}pop=~/./g

run as

$ perl -E 'say map{$s+=ord;chr($s/++$c+.5)}pop=~/./g' StackExchange
Sdccd_ccccddd
\$\endgroup\$
1
\$\begingroup\$

TSQL, 118 bytes

DECLARE @ varchar(400) = 'StackExchange'

SELECT
top(len(@))char(avg(ascii(stuff(@,1,number,''))+.5)over(order by number))FROM
master..spt_values
WHERE'P'=type

Returning characters vertical

S
d
c
c
d
_
c
c
c
c
d
d
d
\$\endgroup\$
1
\$\begingroup\$

><>, 30 bytes

i:0(?v
v &l~<
\+l2(?
\&,12,+o;
  • The first line reads from stdin and puts the characters on the stack
  • The second will remove the EOL char, take the size of the stack and put it in the & register
  • The third line will add numbers on the stack while there are two or more of them
  • The fourth line will divide the resulting number by the register's value, then add 1/2, output the value as a character and stop. When faced with a float value when displaying a char, ><> will floor it, which is why we added 1/2

You can try it on the online interpreter but then you need to use the following version, because the online interpreter pads the code box to a rectangle and applies ? to spaces.

i:0(?v
v &l~<
\+l2(   ?
\&,12,+o;
\$\endgroup\$
1
\$\begingroup\$

Clojure, 69 bytes

#(for[c(map /(reductions +(map int %))(rest(range)))](char(+ c 0.5)))

Returns a sequence of characters, arguably a string-like construct. Would need an #(apply str(for[...]...)) to convert it into a string.

\$\endgroup\$
1
  • \$\begingroup\$ 81 bytes with the string conversion. \$\endgroup\$
    – Sandra
    Aug 20, 2022 at 8:19
1
\$\begingroup\$

Jelly, 8 bytes

OÆmƤ+.ḞỌ

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Husk, 10 bytes

zȯci/Nt∫mc

Try it online!

                                                    | "tuna"
         mc  -- map each character to ASCII value   | [116,117,110,97]
       t∫    -- prefix sums & drop leading 0        | [116,233,343,440]
z(   )N      -- zip the list with [1..] using       | 
    /        --   divide                            | [116/1,233/2,343/3,440/4] == [116.0,116.5,114.̅3,110.0]
   i         --   round                             | [116,117,114,110]
  c          --   convert to character              | "turn"
\$\endgroup\$
1
\$\begingroup\$

J, 23 bytes

(0.5<.@++/%#)&.(a.&i.)\

Try it online!

How it works

                      \  on prefixes
               (   i.)   index of the first occurence
               (  &  )   in
               (a.   )   the character set
            x&.y         apply y, then x, then the inverse of y,                            
(0.5        )              that is the element of a. with a given index
(       +/  )            sum
(          #)            number of elements
(         % )            division
(   <.@+    )            add, then floor 
\$\endgroup\$
1
\$\begingroup\$

SmileBASIC, 65 bytes

LINPUT S$FOR I=1TO LEN(S$)A=A-A/I+ASC(S$[I-1])/I?CHR$(A+.5);
NEXT
\$\endgroup\$
1
\$\begingroup\$

Zsh, 52 bytes

for c (${(s::)1})printf ${(#)$((.5+(n+=0.+#c)/++i))}

Try it online!

In arithmetic mode, #c gets the code of the first character of $c. The parameter expansion ${(#) } prints the character associated with the code.

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 59 bytes

-join($args|%{[char][int][Math]::Floor(($s+=+$_)/++$i+.5)})

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Dyalog APL, 25 bytes

{⎕UCS⌊.5+(+\C)÷⍳⍴C←⎕UCS⍵}
\$\endgroup\$
1
\$\begingroup\$

Jelly, 16 bytes

S÷L+.Ḟ
OµḣLR$Ç€Ọ

Try it online!

Only if there were Average and Round built-ins...

\$\endgroup\$
1
\$\begingroup\$

PARI/GP, 45 bytes

s->t=i=0;Strchr([(t+=c)\/i++|c<-Vecsmall(s)])

Attempt This Online!


PARI/GP, 52 bytes

s->Strchr(Vec(intformal(Ser(Vecsmall(s))/(1-x)))\/1)

Attempt This Online!

This one is longer, but I can't resist to do this:

  • Vecsmall(s): Converts the string to a vector of ASCII codes.
  • Ser(...): Converts the vector to a formal power series.
  • .../(1-x): Divides the result by \$1-x\$. This is equivalent to taking the cumsum.
  • intformal(...): Takes the integral with respect to \$x\$. This is equivalent to dividing the n-th term with n.
  • Vec(...): Converts the result back to a vector.
  • ...\/1: Rounds the result.
  • Strchr(...) Converts the result back to a string.
\$\endgroup\$
1
\$\begingroup\$

Burlesque, 21 bytes

)?^qavpa0.5?+)avqL[\m

Try it online!

)?^   # To codepoint
qavpa # Average on prefixes
0.5?+ # Add 0.5 to each
)av   # Floor each
qL[\m # Back to char

Should be 17 chars, but R_ (round) rounds 0.5 down, not up.

\$\endgroup\$
1
+200
\$\begingroup\$

Prolog (SWI), 59 bytes

N+X+[A|R]:-L=X+A,T is round(L/N),put(T),N+1+L+R.
+A:-1+0+A.

Try it online!

Takes a list of codepoints and outputs to STDOUT.

A little longer, but using only one predicate:

Prolog (SWI), 63 bytes

+A:-scanl(plus,A,0,Z),nth0(N,Z,E),N>0,T is round(E/N),\+put(T).

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C (clang), 55 bytes

n;t;main(c){for(;read(0,&c,1);putchar(t/++n))t+=c+n%2;}

Try it online!

How it works

n;t;           // t and n are initialized to 0
read(0,&c,1)   // Reads a character from stdin into c,
               // returns the number of characters read, 0 if EOF.
t+=c+n%2       // t is the accumulator, n%2 is used to round up.
putchar(t/++n) // increment n and use the new value to calculate the average.

C (clang), 45 bytes

Same idea, but as a function which modifies the string in-place.

n;t;f(*s){for(n=t=0;*s;*s++=t/++n)t+=*s+n%2;}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Thunno 2 B, 5 bytes

ƒ€m.+

Attempt This Online!

Explanation

ƒ€m.+  # Implicit input
       # Convert to ordinals
ƒ      # Prefixes of ordinals
 €m    # Mean of each
   .+  # Add 0.5 to each
       # Convert to string
       # Implicit output
\$\endgroup\$
1
\$\begingroup\$

Scala, 106 bytes

Port of @alephalpha's PARI/GP answer in Scala.


Golfed version. Attempt This Online!

s=>{var(t,i)=(0.0,1);s.map(c=>{t+=c;val a=math.round(t/i).toInt.max(32).min(126);i+=1;a.toChar}).mkString}

Ungolfed version. Attempt This Online!

object Main {
  def f(s: String): String = {
    val vecsmall: Array[Int] = s.map(_.toInt).toArray
    var t = 0.0
    var i = 1
    var res = new StringBuilder

    for (c <- vecsmall) {
      t += c
      val ascii = Math.round(t / i).toInt.max(32).min(126) // ensure within printable ASCII range
      res += ascii.toChar
      i += 1
    }

    res.toString()
  }

  def main(args: Array[String]): Unit = {
    val strings = List("Hello!", "test", "42", "StackExchange")
    strings.foreach(s => println(s"$s -> ${f(s)}"))
  }
}
\$\endgroup\$
0
\$\begingroup\$

JavaScript ES7, 122 bytes

s=>String.fromCharCode(...[for(i of s)i.charCodeAt()].map((l,i,a)=>Math.round(eval((t=a.slice(0,++i)).join`+`)/t.length)))

Mostly everything is happening in this bit

eval((t=a.slice(0,++i)).join`+`)/t.length)

The rest is looping / character code conversion

Split up:

s=> 
 String.fromCharCode(...                        ) // Converts average character code array to string, ... allows it to take an array
   [for(i of s)i.charCodeAt()]                    // Converts string to char code array
   .map((l,i,a)=>                             )   // Loops through each character
     Math.round(                    /t.length)    // Rounds sum of previous char codes, divides by position + 1
       eval(                       )              // evals string of char codes seperated with +
            (                ).join`+`            // joins previous char codes with +
             t=a.slice(0,++i)                     // creates an array with all the char codes

If functions aren't allowed:

alert(String.fromCharCode(...[for(i of prompt())i.charCodeAt()].map((l,i,a)=>Math.round(eval((t=a.slice(0,++i)).join`+`)/t.length))))

133 bytes


ES5 Snippet:

function _toConsumableArray(r){if(Array.isArray(r)){for(var e=0,t=Array(r.length);e<r.length;e++)t[e]=r[e];return t}return Array.from(r)}function _taggedTemplateLiteral(r,e){return Object.freeze(Object.defineProperties(r,{raw:{value:Object.freeze(e)}}))}var _templateObject=_taggedTemplateLiteral(["+"],["+"]),f,t=function t(s){return String.fromCharCode.apply(String,_toConsumableArray(function(){var r=[],e=!0,t=!1,a=void 0;try{for(var n,i=s[Symbol.iterator]();!(e=(n=i.next()).done);e=!0){var o=n.value;r.push(o.charCodeAt())}}catch(l){t=!0,a=l}finally{try{!e&&i["return"]&&i["return"]()}finally{if(t)throw a}}return r}().map(function(l,i,a){return Math.round(eval((f=a.slice(0,++i)).join(_templateObject))/f.length)})))};

// Demo
document.getElementById('go').onclick=function(){
  document.getElementById('output').innerHTML = t(document.getElementById('input').value)
};
<div style="padding-left:5px;padding-right:5px;"><h2 style="font-family:sans-serif">Average of Words Snippet</h2><div><div  style="background-color:#EFEFEF;border-radius:4px;padding:10px;"><input placeholder="Text here..." style="resize:none;border:1px solid #DDD;" id="input"><button id='go'>Run!</button></div><br><div style="background-color:#EFEFEF;border-radius:4px;padding:10px;"><span style="font-family:sans-serif;">Output:</span><br><pre id="output" style="background-color:#DEDEDE;padding:1em;border-radius:2px;overflow-x:auto;"></pre></div></div></div>

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

Python 2, 106 bytes

It's not short enough. Since it's python it's way too verbose, you can even read what it does by looking code. But it's working.

a=[.0]+[ord(i)for i in raw_input()]
print"".join([chr(int(.5+(sum(a[:i+1])/i)))for i in range(1,len(a))])
\$\endgroup\$
1
  • 1
    \$\begingroup\$ "Since it's python it's way too verbose"... not compared to Java. And I disagree. Any less verbose and it wouldn't be as great as it is. Use Pyth if you want less verbose. \$\endgroup\$
    – mbomb007
    Jul 24, 2015 at 21:39
0
\$\begingroup\$

JavaScript ES6, 111 bytes

w=>w.replace(/./g,(_,i)=>String.fromCharCode([for(f of w.slice(0,++i))f.charCodeAt()].reduce((a,b)=>a+b)/i+.5))

This is annoyingly long thanks in part to JavaScript's long String.fromCharCode and charCodeAt functions. The stack snippet contains ungolfed, commented, testable code.

f=function(w){
  return w.replace(/./g,function(e,i){
    return String.fromCharCode(w.slice(0,++i).split('').map(function(f){
      return f.charCodeAt()
    }).reduce(function(a,b){
      // Adds all numbers in the array
      return a+b
      // String.fromCharCode automatically floors numbers, so we add .5 to round up
    })/i+.5)
  })
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('input').value)};document.getElementById('run').onclick=run;run()
<input type="text" id="input" value="Hello!" /><button id="run">Run</button><br />
<pre id="output"></pre>

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

Factor, 80 bytes

[ cum-sum [ dup zero? 1 0 ? + / ] map-index [ .5 + floor >fixnum ] map >string ]
\$\endgroup\$
0
\$\begingroup\$

Jelly, 7 bytes

OÄ÷T+.Ọ
OÄ÷T+.Ọ  ~Main link
O        ~Cast to number
 Ä       ~Cumulative sum; add the values
  ÷T     ~Divide by indices
    +.   ~Add .5
      Ọ  ~Cast to characters

Attempt This Online!

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

Python, 50 bytes

f=lambda s:s and f(s[:-1])+[int(.5+sum(s)/len(s))]

Attempt This Online!

Takes in an list of UTF-8 codepoints, return a list of UTF-8 codepoints.

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

C#, 210 bytes

Saved so many bytes thanks to the comment of @ceilingcat


Golfed version. Try it online!

static string F(string s){int j=s.Length,i=j;var v=new int[j];var t=.0;var r="";for(;i-->0;)v[i]=Convert.ToInt32(s[i]);for(;++i<j;)r+=((char)Math.Min(Math.Max((int)Math.Round((t+=v[i])/-~i),32),126));return r;}

Ungolfed version. Run it on dotnetfiddle!

using System;
using System.Text;

public class Program
{
    public static string ConvertString(string s)
    {
        int[] vecsmall = new int[s.Length];
        for(int j = 0; j < s.Length; j++)
        {
            vecsmall[j] = Convert.ToInt32(s[j]);
        }
        
        double t = 0.0;
        int i = 1;
        StringBuilder res = new StringBuilder();

        foreach(int c in vecsmall)
        {
            t += c;
            int ascii = (int)Math.Round(t / i);
            ascii = Math.Max(ascii, 32); // ensure within printable ASCII range
            ascii = Math.Min(ascii, 126); // ensure within printable ASCII range
            
            res.Append((char)ascii);
            i += 1;
        }
        
        return res.ToString();
    }

    public static void Main(string[] args)
    {
        string[] strings = new string[] {"Hello!", "test", "42", "StackExchange"};

        foreach(string s in strings)
        {
            Console.WriteLine($"{s} -> {ConvertString(s)}");
        }
    }
}
\$\endgroup\$
1
1
2

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.