Calcular caracteres promedio de cadena


24

Tarea

Su tarea es producir una cadena que contenga caracteres promedio de cadena. El primer carácter del resultado sería el carácter promedio del primer carácter (que es el primer carácter) y el promedio del segundo carácter de los dos primeros caracteres y así sucesivamente.

¿Qué es el personaje promedio?

Las cadenas son matrices de bytes. El carácter promedio de la cadena se puede encontrar calculando el promedio de los valores ASCII de los caracteres en la cadena y tomando el carácter ASCII correspondiente.

Por ejemplo, la cadena "Hello!"se puede escribir como secuencia de bytes 72 101 108 108 111 33. El promedio de los valores ascii es 533/6 = 88.833 ... y cuando se redondea al entero más cercano obtenemos 89, que es el código ascii para la letra cautiva Y.

Reglas

  • Puede suponer que la entrada contiene solo caracteres ASCII imprimibles
  • La entrada se puede leer desde stdin o como argumentos de línea de comando o como argumentos de función
  • La salida debe ser estándar. Si su programa es funcional, también puede devolver la cadena que de lo contrario imprimiría.
  • Debe ser un programa o función completa, no un fragmento
  • Se aplican lagunas estándar
  • Los enteros se redondean por función floor(x+0.5)o función similar.

¿Cómo gano?

Este es el , por lo que la respuesta más corta (en bytes) en victorias.

Ejemplos

  • Hello!HW^adY
  • testtmop
  • 4243
  • StackExchangeSdccd_ccccddd

Pregunta editada Ahora debería estar claro: tienes que redondear las mitades hacia arriba.
Hannes Karppila

1
"La entrada se puede leer desde stdin o como argumentos de línea de comando ": o como argumentos de función (ya que permite funciones), ¿verdad?
Luis Mendo

Por supuesto, editado de nuevo.
Hannes Karppila

2
Lamento molestarlo una vez más, pero ¿las funciones realmente tienen que imprimir el resultado en STDOUT o pueden devolver la cadena deseada?
Dennis

Lo siento, olvidé editar eso antes. Ahora debería estar bien.
Hannes Karppila

Respuestas:


11

Brainfuck 106 bytes

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

Esta es mi primera participación en un código de golf, ¡sé gentil! Funciona, pero Brainfuck no puede manejar flotantes (no que yo sepa), por lo que el valor redondeado siempre es el inferior (podría arreglar mi algoritmo más adelante).

Además, el algoritmo promedia los valores 2 por 2, lo que significa que podría ser inexacto en algunos puntos. Y también necesito corregir un error que está imprimiendo un número al final de la salida.


9

Pyth, 16 bytes

smCs+.5csaYCdlYz

Muy claro. Usar en s+.5lugar de redondear, porque por alguna razón round(0.5, 0)es 0 en Python.


1
Python 3 redondea la mitad hacia el par, lo que introduce menos sesgo. La pregunta no especifica explícitamente cómo se deben redondear las mitades, por lo que solicité una aclaración al OP.
Dennis

Pregunta editada 0.5redondeado debe ser 1.
Hannes Karppila

7

Q, 15 12 bytes

12 bytes como una expresión

"c"$avgs"i"$

q)"c"$avgs"i"$"Hello!"
"HW^adY"
q)"c"$avgs"i"$"test"
"tmop"
q)"c"$avgs"i"$"42"
"43"
q)"c"$avgs"i"$"StackExchange"
"Sdccd_ccccddd"

o 15 bytes como una función

{"c"$avgs"i"$x}

q){"c"$avgs"i"$x} "Hello!"
"HW^adY"
q){"c"$avgs"i"$x} "test"
"tmop"
q){"c"$avgs"i"$x} "42"
"43"
q){"c"$avgs"i"$x} "StackExchange"
"Sdccd_ccccddd"

aprovecha

  1. el "i" $ cast para convertir una cadena (lista de caracteres) en una lista de enteros
  2. la función avgs, que calcula el promedio de ejecución de una lista como una lista de flotantes
  3. el "c" $ cast para convertir una lista de flotantes en una lista de caracteres, y que redondea automáticamente cada flotante al entero más cercano antes de hacerlo [es decir ("c" $ 99.5) = ("c" $ 100) y ("c "$ 99.4) = (" c "$ 99)]

¿Q requiere la función wrapper aquí o puede salirse con la simple expresión tácita "c"$avgs"i"$? No creo que una solución pueda ser mucho más sencilla que eso. :)
JohnE

estás en lo correcto: no necesitas el envoltorio de funciones, como "c" $ avgs "i" $ "¡Hola!" funciona bien
scottstein37

Creo que puede guardar 2 bytes cambiando "c"a `c y "i"a` i.
kirbyfan64sos

desafortunadamente, no creo que eso funcione. Para usar la representación de tipo de símbolo para la conversión, tendría que usar `char e` int según code.kx.com/wiki/JB:QforMortals2/… . Considere usar 10h y 6h en lugar de "c" e "i" pero eso no ahorraría ningún byte: 10h tiene la misma longitud que "c" y sustituir 6h por "i" requiere un espacio final, lo que hace que tengan la misma longitud también.
scottstein37


4

Perl: 31 30 caracteres

(Código de 29 caracteres + opción de línea de comando de 1 carácter).

s!.!chr.5+($s+=ord$&)/++$c!ge

Ejecución de muestra:

bash-4.3$ perl -pe 's!.!chr.5+($s+=ord$&)/++$c!ge' <<< 'StackExchange'
Sdccd_ccccddd

3

C # 189135134106 Bytes

var x=s.Select((t,i)=>Math.Round(s.Select(a=>(int)a).Take(i+1).Average())).Aggregate("",(m,c)=>m+(char)c);

Se puede ver aquí

Golfista por primera vez


2

K, 36 bytes

`0:_ci_.5+{(+/x)%#x}'.0+1_|(-1_)\_ic

Uso:

  `0:_ci_.5+{(+/x)%#x}'.0+1_|(-1_)\_ic"Hello!"
HW^adY
  `0:_ci_.5+{(+/x)%#x}'.0+1_|(-1_)\_ic"test"
tmop
  `0:_ci_.5+{(+/x)%#x}'.0+1_|(-1_)\_ic"42"
43
  `0:_ci_.5+{(+/x)%#x}'.0+1_|(-1_)\_ic"StackExchange"
Sdccd_ccccddd

_ciy _icconvertir ascii a caracteres y viceversa, respectivamente. {(+/x)%#x}es un modismo clásico de K para calcular una media. Bastante sencillo en general.

Editar: oh, leí mal la especificación. `0: es necesario para imprimir el resultado en stdout. Esperando aclaraciones sobre la entrada re. La pregunta de Dennis.


Si utiliza K5, esto se puede acortar a 35 bytes: {[s]`0:`c${_.5+(+/u)%#u:x#s}'1+!#s}.
kirbyfan64sos

O 30:`0:`c$_.5+{(+/x)%#x}'1_|(-1_)\
JohnE

`c$_.5+{(+\x)%+\~^x}`i$para 24. Podría ser más corto ( `c$`i${(+\x)%+\~^x}`i$), pero su REPL ( johnearnest.github.io/ok/index.html ) no se redondea correctamente al pasar de float a int. Dudaría en llamar a esta solución ak desde entonces _ciy _icno estoy en ninguna parte de la especificación K5 por lo que puedo decir, mientras 0:que no imprime en stdout sino que lee un archivo txt del disco.
tmartin

@tmartin: correcto- _ciy _icse reemplazan por completo en K5 con las formas similares `c$. La solución original que publiqué es compatible con Kona, que se basa en K2 / K3. Generalmente trato de no publicar soluciones con oK específicamente porque la semántica todavía está cambiando y es parcialmente inexacta.
JohnE

1
Ah ya veo, tiene sentido para mí. Pensé que esta era otra solución de K5. Aquí hay una solución de 28 char kona`0:_ci_0.5+{(+\x)%1.+!#x}_ic
tmartin

2

Mathematica, 75 bytes

FromCharacterCode@Floor[.5+Accumulate@#/Range@Length@#]&@ToCharacterCode@#&

2

Julia, 85 81 bytes

s->(i=[int(c)for c=s];print(join([char(iround(mean(i[1:j])))for j=1:length(i)])))

Esto crea una función sin nombre que acepta una cadena y crea un vector de sus puntos de código ASCII. Las medias se toman para cada grupo secuencial, se redondean a enteros, se convierten en caracteres, se unen en una cadena y se imprimen en STDOUT.


2

Ruby, 46

s=0.0
$<.bytes{|b|s+=b;$><<'%c'%(0.5+s/$.+=1)}

ideona .

Con disculpas, mi respuesta terminó siendo lo suficientemente diferente como para que valiera la pena publicarla.

$<.bytesitera sobre cada byte en stdin, por lo que imprimimos el promedio móvil en cada ciclo. '% c' convierte un flotador en un personaje redondeando hacia abajo y tomando el ASCII, por lo que todo lo que tenemos que hacer es agregar 0.5 para que se redondee correctamente. $.es una variable mágica que comienza inicializada en 0; se supone que almacena el recuento de líneas, pero dado que aquí queremos el recuento de bytes, simplemente lo incrementamos manualmente.


2

Mathcad, 60 "bytes"

ingrese la descripción de la imagen aquí

Mathcad es una aplicación matemática basada en hojas de trabajo 2D compuestas de "regiones", cada una de las cuales puede ser texto, una expresión matemática, un programa, un diagrama o un componente con guión.

Una instrucción matemática o de programación se selecciona de una barra de herramientas de paleta o se ingresa usando un atajo de teclado. Para fines de golf, se considera que una operación ("byte") es el número de operaciones de teclado necesarias para crear un nombre o expresión (por ejemplo, para establecer la variable a en 3, escribiríamos un: = 3. El operador de definición : = es una sola pulsación de tecla ":", al igual que ay 3 que dan un total de 3 "bytes". La programación para el operador requiere escribir ctl-shft- # (o un solo clic en la barra de herramientas de programación) así que de nuevo es equivalente a 1 byte

En Mathcad, el usuario ingresa comandos de lenguaje de programación utilizando métodos abreviados de teclado (o seleccionándolos de la barra de herramientas de programación) en lugar de escribirlos en texto. Por ejemplo, al escribir ctl-] se crea un operador de bucle while que tiene dos "marcadores de posición" para ingresar la condición y una sola línea del cuerpo, respectivamente. Escribir = al final de las expresiones de Mathcad hace que Mathcad evalúe la expresión.

(Cuente bytes) Al mirarlo desde una perspectiva de entrada del usuario y equiparar una operación de entrada de Mathcad (por lo general, hacer clic con el mouse en la barra de herramientas si no hay un acceso directo de kbd) a un carácter e interpretar esto como un byte. csort = 5 bytes, ya que se escribe char-by-char al igual que otros nombres de variables / funciones. El operador for es una construcción especial que ocupa 11 caracteres (incluidos 3 "marcadores de posición" en blanco y 3 espacios) pero se ingresa mediante ctl-shft- #, por lo tanto = 1 byte (similar a los tokens en algunos idiomas). Escribir '(cita) crea paréntesis equilibrados (generalmente), por lo que cuenta como 1 byte. Indexación v = 3 bytes (tipo v [k).


2

Python 3, 66 bytes

Si lo uso en round()lugar de int(.5+etc., guarda un personaje, pero técnicamente no cumple con el desafío: las round()mitades de las rondas de Python al entero par más cercano, no hacia arriba. Sin embargo, funciona correctamente en todas las entradas de muestra.

También me siento un poco sucio por no terminar la salida con una nueva línea, pero el desafío no requiere que ...

n=t=0
for c in input():n+=1;t+=ord(c);print(end=chr(int(.5+t/n)))

1
Si incrementa n antes de imprimir, puede evitar ajustarlo en 1.
xnor

1
@xnor: cara, palma. Cara de decepción. Gracias por señalar eso.
Tim Pederick

hacer print(end=chr(int(...))para guardar algunos bytes
FlipTack

@ Flp.Tkc: ¡Gracias! Respuesta actualizada
Tim Pederick

2

JavaScript (ES6), 75 bytes

let f =
s=>s.replace(/./g,x=>String.fromCharCode((t+=x.charCodeAt())/++i+.5),i=t=0)
<input oninput="O.value=f(this.value)" value="Hello!"><br>
<input id=O value="HW^adY" disabled>

No puedo creer que todavía no haya una respuesta JS con esta técnica ...


1

Pitón 2, 71

i=s=0
r=''
for c in input():s+=ord(c);i+=1.;r+=chr(int(s/i+.5))
print r

Con cada nuevo personaje, actualiza la suma de caracteres sy el número de caracteres ipara calcular y agregar el carácter promedio.


Casi exactamente el mismo enfoque que el mío, solo Python 2 en lugar de 3, y publicado horas antes: +1. (Además, descubrí que guardé unos pocos bytes imprimiendo cada carácter tal como vino en lugar de almacenarlos para una final print. ¿Funcionará eso con Python 2? Olvidé ahora cómo suprimir las nuevas líneas en la printdeclaración ... la coma hace un espacio en cambio, ¿verdad?)
Tim Pederick

Python 2 puede hacer print _,para dejar un espacio en lugar de una nueva línea, pero no hay una buena manera de omitir el espacio. Buena decisión con el endargumento de Python 3 , me había olvidado de eso.
xnor

@TimPederick Tal vez el control de retroceso podría justificarse para un terminal que lo usa, como un truco para eliminar el espacio:print'\b'+_,
xnor


1

Java, 100

Al igual que muchas otras respuestas aquí, estoy sumando y promediando en un bucle. Solo aquí para representar a 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];}

Mi código original es un 97, pero solo devuelve el modificado en char[]lugar de imprimirlo:

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

Ahora, es lo suficientemente largo para que aparezcan barras de desplazamiento para mí, así que aquí hay una versión con algunos saltos de línea, solo porque:

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

Interesante. ¿Nos puede mostrar una muestra de llamada también? Mi Java está muy oxidado.
manatwork

¿Como en cómo llamarlo? Suponiendo que testes una matriz de caracteres, solo úsela f(test);. Si es un objeto String, entonces lo usarías f(test.toCharArray());. Los literales de cadena también están bien así:f("Hello!".toCharArray());
Geobits

Oh. Seguro. toCharArray()Yo estúpido, traté de violarlo con un poco de casting. Gracias.
manatwork

Sería demasiado fácil lanzarlo. Los dioses de Java estarían furiosos: P
Geobits

1

C, 62 bytes

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

(enlace ideone)

Los resultados son ligeramente diferentes de los ejemplos del OP, pero solo porque este código redondea 0.5 hacia abajo en lugar de hacia arriba. ¡Ya no!


1

R, 135 127 Bytes

Esto se hizo largo muy rápido y realmente me equivoqué la primera vez :) Necesito leer las preguntas correctamente.

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

Prueba de funcionamiento

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

alguien publicó un desafío de engaño en el sandbox, así que encontré esto ... Esto fue hace mucho tiempo, ¡pero utf8ToIntayudará! Tengo un golf de 68 bytes de esto si quieres actualizarlo.
Giuseppe

@Giuseppe Siga adelante y publíquelo usted mismo si lo desea. Sospecho que es significativamente diferente a lo que hice aquí.
MickyT

1

Perl 5, 41 bytes

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

correr como

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

1

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

Caracteres que vuelven verticales

S
d
c
c
d
_
c
c
c
c
d
d
d

1

> <> , 30 bytes

i:0(?v
v &l~<
\+l2(?
\&,12,+o;
  • La primera línea lee de stdin y pone los caracteres en la pila
  • El segundo eliminará el EOL char, tomará el tamaño de la pila y lo colocará en el &registro
  • La tercera línea agregará números en la pila mientras haya dos o más.
  • La cuarta línea dividirá el número resultante por el valor del registro, luego agregará 1/2, generará el valor como un carácter y se detendrá. Cuando se enfrenta a un valor flotante cuando se muestra un carácter,> <> lo colocará en el piso, por lo que agregamos 1/2

Puede probarlo en el intérprete en línea, pero luego debe usar la siguiente versión, porque el intérprete en línea rellena el cuadro de código en un rectángulo y se aplica ?a los espacios.

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


1

Japt , 13 bytes (no competidor)

£T±Xc)/°Y r d

¡Pruébalo en línea!

Cómo funciona

£   T± Xc)/° Y r d
mXY{T+=Xc)/++Y r d}
                     // Implicit: U = input string, T = 0
mXY{              }  // Replace each char X and index Y in the string by this function:
    T+=Xc            //   Add X.charCodeAt() to T.
         )/++Y       //   Take T / (Y + 1).
               r d   //   Round, and convert to a character.
                     // Implicit: output result of last expression

Ah, nueces; Pensé que el filtro "no competidor" había sido eliminado de la tabla de clasificación, así que no vi esto antes de publicar esto .
Shaggy


1

PHP , 176 bytes

<?=(implode('',array_reduce(str_split($argv[1]),function($c,$k){array_push($c[1],chr(floor(((ord($k)+$c[0])/(count($c[1])+1))+0.5)));return[ord($k)+$c[0],$c[1]];},[0,[]])[1]));

Ejemplo:

>php cg.php Hello!
HW^adY
>php cg.php test  
tmop
>php cg.php 42
43

La solución más grande hasta ahora, pero creo que basada en php no puede ser mucho más corta. Se pueden guardar 2 bytes eliminando las nuevas líneas.


Hmm, buen punto. Pensé que podría dejarlos en la publicación para una mejor legibilidad. Pero sí, este es el código de golf. Los eliminaré;)
cb0

1
Siempre puede incluir una versión adicional con relleno para facilitar la lectura junto con la versión corta. A menudo hago esto cuando mi código es demasiado largo para ser completamente visible en la mayoría de los monitores.
Wheat Wizard

0

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

Casi todo está sucediendo en este momento

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

El resto es bucle / conversión de código de caracteres

Separar:

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

Si las funciones no están permitidas:

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


Fragmento de ES5:

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>


0

Python 2, 106 bytes

No es lo suficientemente corto. Como es Python, es demasiado detallado, incluso puedes leer lo que hace buscando código. Pero está funcionando.

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

1
"Dado que es Python es demasiado detallado" ... no se compara con Java. Y no estoy de acuerdo. Algo menos detallado y no sería tan bueno como es. Use Pyth si quiere menos detallado.
mbomb007

0

Matlab, 43

Usando una función anónima:

f=@(s)char(round(cumsum(+s)./(1:numel(s))))

Ejemplos:

>> f=@(s)char(round(cumsum(+s)./(1:numel(s))))
f = 
    @(s)char(round(cumsum(+s)./(1:numel(s))))

>> f('Hello!')
ans =
HW^adY

>> f('test')
ans =
tmop

>> f('42')
ans =
43

>> f('StackExchange')
ans =
Sdccd_ccccddd

0

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

Esto es molestamente largo gracias, en parte, a las funciones String.fromCharCodey charCodeAtfunciones largas de JavaScript . El fragmento de pila contiene código no comprobado, comentado y comprobable.

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>


0

Factor, 80 bytes

[ cum-sum [ dup zero? 1 0 ? + / ] map-index [ .5 + floor >fixnum ] map >string ]
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.