Вычислить средние символы строки


24

задача

Ваша задача - создать строку, содержащую средние символы строки. Первый символ результата будет средним символом первого символа (который является первым символом) и вторым символом среднего двух первых символов и так далее.

Что такое средний характер?

Строки - это массивы байтов. Средний символ строки можно найти, рассчитав среднее значение ASCII символов в строке и приняв соответствующий символ ASCII.

Например, строка "Hello!"может быть записана как последовательность байтов 72 101 108 108 111 33. Среднее значение ascii равно 533/6 = 88.833 ... и когда оно округляется до ближайшего целого числа, мы получаем 89, что является кодом ascii для заглавной буквы Y.

правила

  • Вы можете предположить, что ввод содержит только печатные символы ASCII
  • Входные данные могут быть прочитаны из стандартного ввода или как аргументы командной строки или как аргументы функции
  • Выход должен быть стандартным. Если ваша программа является функцией, вы также можете вернуть строку, которую вы иначе напечатаете.
  • Это должна быть целая программа или функция, а не фрагмент
  • Применяются стандартные лазейки
  • Целые числа округляются по функции floor(x+0.5)или аналогичной функции.

Как мне победить?

Это , поэтому самый короткий ответ (в байтах) за выигрыш.

Примеры

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

Отредактированный вопрос. Теперь должно быть понятно: нужно округлять половинки вверх.
Ханнес Карппила

1
« Входные данные могут быть прочитаны из стандартного ввода или как аргументы командной строки »: или как аргументы функции (так как вы разрешаете функции), верно?
Луис Мендо

Конечно, отредактировано снова.
Ханнес Карппила

2
Извините, что беспокою вас еще раз, но действительно ли функции должны печатать вывод в STDOUT или они могут вернуть нужную строку?
Деннис

Извините, забыл отредактировать это раньше. Теперь все должно быть в порядке.
Ханнес Карппила

Ответы:


11

Brainfuck 106 байт

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

Это мое первое участие в код-гольфе, пожалуйста, будьте осторожны! Это работает, но brainfuck не может обрабатывать числа с плавающей точкой (не то, что я знаю), поэтому округленное значение всегда является нижним (может исправить мой алгоритм позже).

Кроме того, алгоритм усредняет значения 2 на 2, что означает, что он может быть неточным в некоторых местах. И мне нужно исправить ошибку, которая печатает число в конце вывода тоже.


9

Pyth, 16 байт

smCs+.5csaYCdlYz

Довольно просто. Используется s+.5вместо округления, потому что по какой-то причине round(0.5, 0)0 в Python.


1
Python 3 округляет половину до четного, что вносит меньший уклон. Вопрос не указывает явно, как следует округлять половинки, поэтому я попросил разъяснений у ОП.
Деннис

Отредактированный вопрос. 0.5округлено должно быть 1.
Ханнес Карппила

7

Q, 15 12 байт

12 байтов как выражение

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

или 15 байт как функция

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

использует в своих интересах

  1. «i» $ приведение для преобразования строки (списка символов) в список целых чисел
  2. функция avgs, которая вычисляет скользящее среднее для списка в виде списка с плавающей точкой
  3. преобразование "c" $ для преобразования списка с плавающей точкой в ​​список символов, которое автоматически округляет каждое число с плавающей точкой до ближайшего целого числа перед тем, как это сделать [т.е. ("c" $ 99.5) = ("c" $ 100) и ("c" "99,4 $) = (" C "99 $)]

Требует ли Q здесь обёртка функции или вы можете оставить только молчаливое выражение "c"$avgs"i"$? Я не думаю, что решение может стать намного более простым, чем это. :)
JohnE

вы правы - вам не нужен упаковщик функций, так как "c" $ avgs "i" $ "Hello!" отлично работает
scottstein37

Я думаю, что вы можете сохранить 2 байта, изменив "c"`c "i"и` i.
kirbyfan64sos

к сожалению, я не думаю, что это работает. Чтобы использовать представление типа символа для приведения, я должен был бы использовать `char и` int согласно code.kx.com/wiki/JB:QforMortals2/… Я решил использовать 10h и 6h вместо "c" и "i", но это не спасло бы ни одного байта - 10h такой же длины, как «c», а замена 6h на «i» требует конечного пробела, что делает их такой же длины.
scottstein37


4

Perl: 31 30 символов

(29 символов кода + 1 символ командной строки.)

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

Образец прогона:

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

3

C # 189 135 134 106 байт

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

Можно увидеть здесь

Первый раз игрок в гольф


2

К, 36 байт

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

Использование:

  `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

_ci а также _ic преобразовать ASCII в символы и наоборот, соответственно. {(+/x)%#x}это классическая идиома для вычисления среднего. Довольно просто в целом.

Редактировать: о, неправильно прочитал спецификацию. `0: необходимо для вывода результата в стандартный вывод. Жду разъяснений по поводу ввода ре. Вопрос Денниса


Если вы используете K5, это может быть сокращено до 35 байт: {[s]`0:`c${_.5+(+/u)%#u:x#s}'1+!#s}.
kirbyfan64sos

Или 30:`0:`c$_.5+{(+/x)%#x}'1_|(-1_)\
Иоанна

`c$_.5+{(+\x)%+\~^x}`i$для 24. Это может быть короче ( `c$`i${(+\x)%+\~^x}`i$), но ваш REPL ( johnearnest.github.io/ok/index.html ) не округляется правильно при приведении от float к int. С тех пор я бы не стал называть это решением ak, _ciи _ic, насколько я могу судить, нигде в спецификации K5 0:нигде не печатается на стандартный вывод, а вместо этого читает txt-файл с диска.
tmartin

@tmartin: правильно - _ciи _icполностью заменены в K5 такими формами `c$. Изложенное мной оригинальное решение совместимо с Kona, основанным на K2 / K3. Я обычно стараюсь не публиковать решения с помощью ОК, потому что семантика все еще меняется и частично неточна.
JohnE

1
Ах, я вижу, имеет смысл для меня. Я подумал, что это было еще одно решение K5. Вот решение 28 char `0:_ci_0.5+{(+\x)%1.+!#x}_ic
kona

2

Mathematica, 75 байт

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

2

Юлия, 85 81 байт

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

Это создает безымянную функцию, которая принимает строку и создает вектор ее кодовых точек ASCII. Средство берется для каждой последовательной группы, округляется до целых чисел, преобразуется в символы, объединяется в строку и печатается в STDOUT.


2

Руби, 46

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

ideone .

С извинениями перед w0lf мой ответ оказался настолько отличным, что казалось, что его стоит опубликовать.

$<.bytesперебирает каждый байт в stdin, поэтому мы печатаем скользящее среднее в каждом цикле. «% c» преобразует число с плавающей точкой в ​​символ, округляя и беря ASCII, поэтому все, что нам нужно сделать, это добавить 0,5, чтобы сделать его округленным правильно.$.это магическая переменная, которая начинается с нуля - она ​​должна хранить счетчик строк, но, поскольку здесь нам нужно количество байтов, мы просто увеличиваем его вручную.


2

Mathcad, 60 "байтов"

введите описание изображения здесь

Mathcad - это математическое приложение, основанное на двухмерных рабочих листах, состоящих из «областей», каждая из которых может быть текстом, математическим выражением, программой, графиком или компонентом со скриптом.

Математическая или программная инструкция выбирается из панели инструментов палитры или вводится с помощью сочетания клавиш. В целях игры в гольф под операцией («байтом») понимается количество операций клавиатуры, необходимых для создания имени или выражения (например, чтобы установить для переменной a значение 3, мы бы написали a: = 3. Оператор определения : = это одно нажатие клавиши «:», а являются и 3 дает в общей сложности 3 «байт» программированию. для оператора требует ввода CTL-shft- # (или одним нажатием кнопки на панели инструментов программирования) , чтобы снова эквивалентно 1 байт

В Mathcad пользователь вводит команды языка программирования, используя сочетания клавиш (или выбирая их на панели инструментов программирования), а не записывая их в тексте. Например, при вводе ctl-] создается оператор цикла while, который имеет два «заполнителя» для ввода условия и одну строку тела соответственно. Тип = в конце выражения Mathcad заставляет Mathcad вычислить выражение.

(Количество байтов). Рассматривая его с точки зрения пользовательского ввода и приравнивая одну операцию ввода Mathcad (обычно клавиатура, щелчок мыши на панели инструментов, если нет ярлыка kbd) к символу и интерпретируя его как байт. csort = 5 байт, поскольку он набирается символ за символом, как и другие имена переменных / функций. Оператор for - это специальная конструкция, которая занимает 11 символов (включая 3 пустых "заполнителя" и 3 пробела), но вводится с помощью ctl-shft- #, следовательно, = 1 байт (аналогично токенам в некоторых языках). Ввод '(цитата) создает сбалансированные скобки (обычно), поэтому считается 1 байт. Индексирование v = 3 байта (тип v [k).


2

Python 3, 66 байт

Если я использую round()вместо int(.5+и т. Д., Он сохраняет один символ, но технически не соответствует задаче: Pythonround() раунды делятся пополам до ближайшего четного числа, а не вверх. Тем не менее, он работает правильно на всех входах образца.

Я также чувствую себя немного грязно из-за того, что не заканчиваю вывод новой строкой, но для этого не нужно ...

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

1
Если вы увеличите значение n перед печатью, вы можете избежать его настройки на 1.
xnor

1
@xnor: Лицо, ладонь. Рука-лицо. Спасибо что подметил это.
Тим Педерик

сделать, print(end=chr(int(...))чтобы сохранить несколько байтов
FlipTack

@ Flp.Tkc: Спасибо! Ответ обновлен.
Тим Педерик

2

JavaScript (ES6), 75 байт

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>

Я не могу поверить, что пока нет ответа JS с этой техникой ...


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

С каждым новым символом обновляется сумма символов sи количество символов iдля вычисления и добавления среднего символа.


Практически точно такой же подход, как у меня, только Python 2 вместо 3, и размещен часами ранее: +1. (Кроме того, я обнаружил, что я сохранил несколько байтов, печатая каждый символ в том виде, в каком он был, вместо того, чтобы сохранять их для одного финала print. Будет ли это работать с Python 2? Я только сейчас забыл, как подавить переносы в printвыражении ... запятая делает его пробелом вместо этого, верно?)
Тим Педерик

Python 2 может print _,оставить пробел, а не перевод строки, но нет хорошего способа пропустить пробел. Хороший вызов с endаргументом Python 3 , я забыл об этом.
xnor

@TimPederick Может быть, контроль возврата был бы оправдан для терминала, который его использует, в качестве хака для удаления пробела:print'\b'+_,
xnor


1

Ява, 100

Как и многие другие ответы здесь, я суммирую и усредняю ​​в цикле. Просто здесь, чтобы представлять 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];}

Мой оригинальный код 97, но он возвращает только измененный, char[]а не распечатывает его:

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

Теперь это просто достаточно долго для скроллинга появляться для меня, так вот версия с некоторыми разрывами строк, только потому , что:

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

Интересный. Можете ли вы показать нам пример звонка тоже? Моя ява очень ржавая.
Манатворк

Как в том, как это назвать? Предполагая, testчто это массив символов, просто используйте f(test);. Если это объект String, то вы бы использовали f(test.toCharArray());. Строковые литералы в порядке , как это тоже:f("Hello!".toCharArray());
Geobits

Ой. Конечно. toCharArray()Я глупый, я пытался нарушить это с некоторым кастингом. Спасибо.
Манатворк

Было бы слишком просто просто разыграть его. Боги Java будут в ярости: P
Geobits


1

R 135 127 байт

Это стало очень быстро, и я действительно ошибся с первого раза :) Нужно правильно прочитать вопросы.

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

Тестовый забег

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

кто-то разместил в песочнице дурацкий вызов, так что я нашел это ... Это было давно, но utf8ToIntпоможет! У меня есть 68-байтовый гольф этого, если вы хотите обновить его.
Джузеппе

@ Giuseppe Иди и напиши это сам, если хочешь. Я подозреваю, что это значительно отличается от того, что я сделал здесь.
MickyT

1

Perl 5, 41 байт

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

беги как

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

1

TSQL, 118 байт

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

Возвращение символов по вертикали

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

1

> <> , 30 байт

i:0(?v
v &l~<
\+l2(?
\&,12,+o;
  • Первая строка читает из stdin и помещает символы в стек
  • Второй удалит EOL char, возьмет размер стека и поместит его в &регистр
  • Третья строка добавит числа в стек, в то время как их два или более
  • Четвертая строка разделит полученное число на значение регистра, затем прибавит 1/2, выведет значение в виде символа и остановится. Если перед отображением символа указано значение с плавающей запятой,> <> будет иметь значение, поэтому мы добавили 1/2

Вы можете попробовать его на онлайн-переводчике, но затем вам нужно будет использовать следующую версию, потому что онлайн-переводчик помещает поле кода в прямоугольник и применяется ?к пробелам.

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

1

05AB1E , 15 байт [Не конкурирует?]

.pvyDSÇOsg/îç}J

Попробуйте онлайн!


-2 байта, удаляя Dи }, и заменяя sна y.
Кевин Круйссен

1
@KevinCruijssen за то, сколько лет этот ответ, есть намного больше, чем это: P. .pтеперь тоже 1 байт
Волшебная урна осьминога

Ах, лол, забыл про ηxD
Кевин Круйссен

1

Japt , 13 байт (не конкурирует)

£T±Xc)/°Y r d

Проверьте это онлайн!

Как это работает

£   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

Ах, орехи; Я думал, что «неконкурентный» фильтр был удален из списка лидеров, поэтому я не видел этого до публикации этого .
Лохматый


1

PHP , 176 байт

<?=(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]));

Пример:

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

Самое большое решение на данный момент, но я думаю, что на основе php оно не может быть намного короче. 2 байта можно сохранить, удалив символы новой строки.


Хм, хорошая мысль. Я думал, что мог бы оставить их в посте для лучшей читаемости. Но да, это код гольф. Я их
уберу

1
Вы всегда можете включить дополнительную версию с отступами для удобства чтения рядом с короткой. Я часто делаю это, когда мой код слишком длинный, чтобы быть полностью видимым на большинстве мониторов.
Пшеничный волшебник

0

JavaScript ES7, 122 байта

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

В основном все происходит в этом бите

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

Остальное зацикливание / преобразование кодов символов

Разделить:

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

Если функции не разрешены:

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 байта


Фрагмент 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 байт

Это не достаточно коротко. Поскольку это python, он слишком многословен, вы даже можете прочитать, что он делает, посмотрев код. Но это работает.

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
«Так как это python, он слишком многословен» ... по сравнению с Java. И я не согласен. Немного менее многословно, и это было бы не так здорово, как есть. Используйте Pyth, если вы хотите меньше многословия.
mbomb007

0

Матлаб, 43

Использование анонимной функции:

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

Примеры:

>> 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 байт

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

Это очень долго, отчасти благодаря JavaScript String.fromCharCodeи charCodeAtфункциям JavaScript . Фрагмент стека содержит некомментированный, прокомментированный, тестируемый код.

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

Фактор, 80 байтов

[ cum-sum [ dup zero? 1 0 ? + / ] map-index [ .5 + floor >fixnum ] map >string ]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.