Calcular caracteres médios da string


24

Tarefa

Sua tarefa é produzir uma sequência que contenha caracteres médios da sequência. O primeiro caractere do resultado seria o caractere médio do primeiro caractere (que é o primeiro caractere) e a média do segundo caractere de dois primeiros caracteres e assim por diante.

O que é caráter médio?

Strings são matrizes de bytes. O caractere médio da sequência pode ser encontrado calculando a média dos valores ASCII dos caracteres na sequência e utilizando o caractere ASCII correspondente.

Por exemplo, a string "Hello!"pode ser escrita como sequência de bytes 72 101 108 108 111 33. A média dos valores ascii é 533/6 = 88.833 ... e quando é arredondado para o número inteiro mais próximo, obtemos 89, que é o código ascii para a letra captial Y.

Regras

  • Você pode assumir que a entrada contém apenas caracteres ASCII imprimíveis
  • A entrada pode ser lida no stdin ou como argumentos de linha de comando ou como argumentos de função
  • A saída deve estar em stdout. Se o seu programa estiver funcionando, você também poderá retornar a string que, de outra forma, imprimiria.
  • Deve ser um programa ou função inteira, não um trecho
  • Aplicam-se brechas padrão
  • Os números inteiros são arredondados por função floor(x+0.5)ou função semelhante.

Como eu ganho?

Este é o , a resposta mais curta (em bytes) em vitórias.

Exemplos

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

Pergunta editada. Agora deve ficar claro: você precisa arredondar as metades para cima.
Hannes Karppila

11
"A entrada pode ser lida no stdin ou como argumentos da linha de comando ": ou como argumentos da função (desde que você permita funções), certo?
Luis Mendo

Claro, editado novamente.
Hannes Karppila

2
Desculpe incomodá-lo mais uma vez, mas as funções realmente precisam imprimir a saída em STDOUT ou elas podem retornar a string desejada?
Dennis

Desculpe, esqueci de editar isso antes. Agora deve ficar tudo bem.
Hannes Karppila

Respostas:


11

Brainfuck 106 bytes

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

Esta é a minha primeira participação em um código de golfe, por favor, seja gentil! Ele funciona, mas o cérebro não pode lidar com carros alegóricos (não que eu saiba), então o valor arredondado é sempre o mais baixo (pode corrigir meu algoritmo posteriormente).

Além disso, o algoritmo calcula a média dos valores 2 por 2, o que significa que pode ser impreciso em alguns pontos. E também preciso corrigir um erro que está imprimindo um número no final da saída.


9

Pitão, 16 bytes

smCs+.5csaYCdlYz

Bem direto. Usando em s+.5vez de arredondamento, porque, por algum motivo, round(0.5, 0)é 0 no Python.


11
O Python 3 arredonda a metade para o par, o que introduz menos viés. Como a pergunta não especifica explicitamente como as metades devem ser arredondadas, solicitei esclarecimentos ao OP.
Dennis

Pergunta editada. 0.5arredondado deve ser 1.
Hannes Karppila

7

Q, 15 12 bytes

12 bytes como uma expressão

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

ou 15 bytes como uma função

{"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"

tira proveito de

  1. o "i" $ cast para converter uma string (lista de caracteres) em uma lista de números inteiros
  2. a função avgs, que calcula a média de execução de uma lista como uma lista de flutuadores
  3. o "c" $ convertido para converter uma lista de carros alegóricos em uma lista de caracteres e que arredonda automaticamente cada carro alegórico para o número inteiro mais próximo antes de fazer isso [ou seja, ("c" $ 99,5) = ("c" $ 100) e ("c "$ 99,4) = (" c "$ 99)]

Q requer o wrapper de função aqui ou você pode se safar apenas da expressão tácita "c"$avgs"i"$? Não acho que uma solução possa ser muito mais direta do que isso. :)
JohnE 24/07

você está correto - não há necessidade do wrapper de função, como "c" $ avgs "i" $ "Hello!" funciona bem
scottstein37

Eu acho que você pode salvar 2 bytes mudando "c"para `c e "i"para` i.
kirbyfan64sos

infelizmente, acho que não funciona. Para usar a representação do tipo de símbolo na transmissão, eu teria que usar `char e` int conforme code.kx.com/wiki/JB:QforMortals2/…. Eu considerei usar 10h e 6h em vez de "c" e "i", mas que não salvariam bytes - 10h tem o mesmo comprimento que "c" e substituir 6h por "i" requer um espaço à direita, tornando-os também com o mesmo comprimento.
precisa


4

Perl: 31 30 caracteres

(Código de 29 caracteres + opção de linha de comando de 1 caractere.)

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

Exemplo de execução:

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

3

C # 189 135 134 106 106 bytes

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

Pode ser visto aqui

Jogador de golfe pela primeira 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

_cie _icconverta ascii em chars e vice-versa, respectivamente. {(+/x)%#x}é um idioma K clássico para calcular uma média. Bem simples em geral.

Edit: oh, interpretou mal as especificações. `0: é necessário para imprimir o resultado em stdout. À espera de esclarecimentos sobre a entrada re. A pergunta de Dennis.


Se você usar K5, este pode ser reduzido para 35 bytes: {[s]`0:`c${_.5+(+/u)%#u:x#s}'1+!#s}.
kirbyfan64sos

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

`c$_.5+{(+\x)%+\~^x}`i$para 24. Poderia ser mais curto ( `c$`i${(+\x)%+\~^x}`i$), mas o seu REPL ( johnearnest.github.io/ok/index.html ) não está arredondando corretamente ao transmitir de float para int. Eu hesitaria em chamar essa solução ak desde então _cie _icnão está na especificação do K5, tanto quanto eu posso dizer, enquanto 0:não imprime no stdout, mas lê um arquivo txt do disco.
22415 Tmartin

@martin: correto - _cie _icsão totalmente substituídos no K5 pelos formulários como `c$. A solução original que publiquei é compatível com o Kona, que é baseado no K2 / K3. Geralmente, tento não postar soluções com oK especificamente porque a semântica ainda está mudando e é parcialmente imprecisa.
Johne

11
Ah, entendo, faz sentido para mim. Achei que essa era outra solução do K5. Aqui está uma solução de 28 caracteres 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)])))

Isso cria uma função sem nome que aceita uma string e cria um vetor de seus pontos de código ASCII. As médias são obtidas para cada grupo seqüencial, arredondadas para números inteiros, convertidas em caracteres, unidas em uma sequência e impressas em STDOUT.


2

Ruby, 46

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

ideone .

Pedindo desculpas ao w0lf, minha resposta acabou sendo diferente o suficiente para parecer valer a pena ser postada.

$<.bytesitera sobre cada byte em stdin, por isso imprimimos a média móvel em cada loop. '% c' converte um float em um caractere arredondando para baixo e pegando o ASCII, então tudo o que precisamos fazer é adicionar 0,5 para torná-lo arredondado corretamente. $.é uma variável mágica que começa inicializada como 0 - deve armazenar a contagem de linhas, mas como aqui queremos a contagem de bytes, apenas a incrementamos manualmente.


2

Mathcad, 60 "bytes"

insira a descrição da imagem aqui

O Mathcad é um aplicativo matemático baseado em planilhas 2D compostas de "regiões", cada uma das quais pode ser texto, uma expressão matemática, programa, plotagem ou componente com script.

Uma instrução matemática ou de programação é selecionada em uma barra de ferramentas da paleta ou inserida usando um atalho de teclado. Para fins de golfe, uma operação ("byte") é considerada o número de operações do teclado necessárias para criar um nome ou expressão (por exemplo, para definir a variável a como 3, escreveríamos a: = 3. O operador de definição : = é um único pressionamento de tecla ":", como são ae 3, fornecendo um total de 3 "bytes". A programação para o operador requer digitar ctl-shft- # (ou um único clique na barra de ferramentas de programação) para que novamente seja equivalente a 1 byte.

No Mathcad, o usuário digita comandos da linguagem de programação usando atalhos de teclado (ou escolhendo-os na barra de ferramentas de programação) em vez de escrevê-los em texto. Por exemplo, digitar ctl-] cria um operador while-loop que possui dois "espaços reservados" para inserir a condição e uma única linha do corpo, respectivamente. Digitar = no final de uma expressão do Mathcad faz com que o Mathcad avalie a expressão.

(Contagem de bytes) Analisando-o da perspectiva de entrada do usuário e equiparando uma operação de entrada do Mathcad (teclado normalmente, clique com o mouse na barra de ferramentas se não houver atalho do kbd) a um caractere e interprete-o como um byte. csort = 5 bytes, pois é digitado char-by-char, assim como outros nomes de variáveis ​​/ funções. O operador for é uma construção especial que ocupa 11 caracteres (incluindo 3 "espaços reservados" em branco e 3 espaços), mas é inserida por ctl-shft- #, portanto = 1 byte (semelhante aos tokens em alguns idiomas). Digitar '(aspas) cria parênteses balanceados (geralmente) e conta como 1 byte. Indexação v = 3 bytes (tipo v [k).


2

Python 3, 66 bytes

Se eu usar em round()vez de int(.5+etc., ele salvará um caractere, mas tecnicamente não está de acordo com o desafio: as round()rodadas do Python são divididas pela metade até o número par mais próximo, e não para cima. No entanto, ele funciona corretamente em todas as entradas de amostra.

Também me sinto um pouco suja por não terminar a saída com uma nova linha, mas o desafio não exige isso ...

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

11
Se você incrementar n antes da impressão, poderá evitar ajustá-lo em 1.
xnor

11
@xnor: rosto, palma. Palm, cara. Obrigado por apontar isso.
Tim Pederick

fazer print(end=chr(int(...))para salvar alguns bytes
FlipTack 11/11

@ Flp.Tkc: Obrigado! Resposta atualizada.
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>

Eu não posso acreditar que ainda não há resposta JS com esta técnica ...


1

Python 2, 71

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

A cada novo caractere, atualiza a soma se o número de caracteres ipara calcular e acrescentar o caractere médio.


Quase exatamente a mesma abordagem que a minha, apenas Python 2 em vez de 3, e postado horas antes: +1. (Além disso, descobri que salvei alguns bytes imprimindo cada caractere como veio, em vez de armazená-los para uma final print. Isso funcionará com o Python 2? Agora esqueço como suprimir novas linhas na printdeclaração ... a vírgula torna um espaço em vez disso, à direita)?
Tim Pederick

O Python 2 pode fazer print _,para deixar um espaço em vez de nova linha, mas não há uma boa maneira de omitir o espaço. Boa ligação com o endargumento do Python 3 , eu tinha esquecido disso.
Xnor

@TimPederick Talvez o controle de retrocesso poderia ser justificada por um terminal que usa, como um hack para excluir o espaço:print'\b'+_,
xnor


1

Java, 100

Bem como muitas outras respostas aqui, estou somando e calculando a média em um loop. Apenas aqui para representar 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];}

Meu código original é 97, mas retorna apenas o modificado em char[]vez de imprimi-lo:

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

Agora, é apenas o tempo suficiente para as barras de rolagem aparecerem para mim, então aqui está uma versão com algumas quebras de linha, apenas 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];
}

Interessante. Você pode nos mostrar uma amostra de chamada também? Meu Java está muito enferrujado.
24515 manatwork

Como em como chamá-lo? Assumindo que testé uma matriz de caracteres, basta usar f(test);. Se for um objeto String, você usaria f(test.toCharArray());. Os literais de string também são bons assim:f("Hello!".toCharArray());
Geobits

Oh. Certo. toCharArray()Me estúpido, tentei violá-lo com algum elenco. Obrigado.
24515 manatwork

Seria fácil demais lançá-lo. Os deuses de Java ficariam furiosos: P
Geobits

1

C, 62 bytes

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

(link ideone)

Os resultados são ligeiramente diferentes dos exemplos do OP, mas apenas porque esse código arredonda 0,5 para baixo em vez de para cima. Não mais!


1

R, 135 127 bytes

Isso ficou muito rápido e eu realmente entendi errado da primeira vez :) Preciso ler as perguntas corretamente.

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

Execução de teste

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

alguém postou um desafio idiota na caixa de areia, então eu achei isso ... Isso foi há muito tempo, mas utf8ToIntajudará! Eu tenho um golfe de 68 bytes disso, se você quiser atualizar para ele.
Giuseppe

@ Giuseppe Vá em frente e publique você mesmo, se desejar. Suspeito que seja significativamente diferente do que fiz aqui.
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

Retornando caracteres na vertical

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

1

> <> , 30 bytes

i:0(?v
v &l~<
\+l2(?
\&,12,+o;
  • A primeira linha lê stdin e coloca os caracteres na pilha
  • O segundo removerá o caractere EOL, pegará o tamanho da pilha e o colocará no &registro
  • A terceira linha adicionará números na pilha enquanto houver dois ou mais deles
  • A quarta linha dividirá o número resultante pelo valor do registrador, depois adicionará 1/2, exibirá o valor como um caractere e parará. Quando confrontado com um valor flutuante ao exibir um caractere,> <> o pavimenta, e é por isso que adicionamos 1/2

Você pode experimentá-lo no intérprete online, mas precisará usar a versão a seguir, porque o intérprete online encaixa a caixa de código em um retângulo e aplica ?- se a espaços.

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


1

Japt , 13 bytes (não concorrente)

£T±Xc)/°Y r d

Teste online!

Como 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, nozes; Eu pensei que o filtro "não concorrente" havia sido removido da tabela de classificação, então não o vi antes de postar isso .
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]));

Exemplo:

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

A maior solução até agora, mas com base no php, não pode ficar muito menor, eu acho. 2 bytes podem ser salvos removendo as novas linhas.


Hmm, bom ponto. Eu pensei que poderia deixá-los no cargo para melhor legibilidade. Mas sim, isso é código de golfe. Vou removê-los;)
cb0

11
Você sempre pode incluir uma versão adicional com preenchimento para facilitar a leitura ao lado da versão curta. Costumo fazer isso quando meu código é muito longo para ficar totalmente visível na maioria dos monitores.
Assistente de trigo

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

Principalmente tudo está acontecendo neste pouco

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

O resto é loop / conversão de código de caracteres

Dividir:

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

Se as funções não forem 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


Snippet 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

Não é curto o suficiente. Como é python, é muito detalhado, você pode até ler o que faz procurando código. Mas 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))])

11
"Como é python, é muito detalhado" ... não comparado ao Java. E eu discordo. Menos detalhado e não seria tão bom quanto é. Use Pyth se quiser menos detalhado.
mbomb007

0

Matlab, 43

Usando uma função anônima:

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

Exemplos:

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

Isso é irritantemente longo, em parte graças ao longo String.fromCharCodee às charCodeAtfunções do JavaScript . O snippet da pilha contém código testado não comentado, comentado.

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

Fator, 80 bytes

[ cum-sum [ dup zero? 1 0 ? + / ] map-index [ .5 + floor >fixnum ] map >string ]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.