Обчисліть середні символи рядка


24

Завдання

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

Що таке середній характер?

Рядки - це масиви байтів. Середній символ рядка можна знайти, обчисливши середнє значення ASCII символів у рядку та взявши відповідний символ ASCII.

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

Правила

  • Можна припустити, що вхід містить лише символи для друку ASCII
  • Вхід може бути прочитаний з stdin або як аргументи командного рядка або як аргументи функції
  • Вихід повинен бути stdout. Якщо ваша програма функціонує, ви також можете повернути рядок, який ви інакше надрукували.
  • Це має бути ціла програма або функція, а не фрагмент
  • Застосовуються стандартні лазівки
  • Цілі числа округляються за функцією floor(x+0.5)або подібною функцією.

Як я виграю?

Це , тому найкоротша відповідь (у байтах) у виграші.

Приклади

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

Відредаговане питання. Тепер має бути зрозуміло: ви повинні округлити половинки вгору.
Ханнес Карппіла,

1
" Введення можна читати з stdin або як аргументи командного рядка ": або як аргументи функції (оскільки ви дозволяєте функції), правда?
Луїс Мендо

Звичайно, відредаговано ще раз.
Hannes Karppila

2
Вибачте, що вас ще раз турбували, але чи дійсно функції повинні надрукувати вихід у STDOUT чи вони можуть повернути потрібний рядок?
Денніс

Вибачте, раніше забув редагувати це. Тепер має бути гаразд.
Ханнес Карппіла,

Відповіді:


11

Brainfuck 106 байт

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

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

Крім того, алгоритм усереднює значення 2 на 2, тобто це може бути неточним в деяких місцях. І мені потрібно виправити помилку, яка друкує номер наприкінці виводу.


9

Pyth, 16 байт

smCs+.5csaYCdlYz

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


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" $ cast для перетворення рядка (списку символів) у список цілих чисел
  2. функція avgs, яка обчислює середнє значення поточного списку у вигляді списку плавців
  3. "c" $ cast для перетворення списку поплавків у список символів, який автоматично округляє кожен поплавок до найближчого цілого числа перед цим [тобто ("c" $ 99.5) = ("c" $ 100.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: потрібен для друку результату для stdout. Чекаю роз'яснення щодо введення даних. Питання Денніса.


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

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

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

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

1
Ах бачу, для мене це має сенс. Я подумав, що це ще одне рішення K5. Ось 28- `0:_ci_0.5+{(+\x)%1.+!#x}_ic
річне

2

Математика, 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)}

ідеоне .

З вибаченнями для w0lf, моя відповідь закінчилася досить різною, що здавалося, що варто опублікувати.

$<.bytesітераціює над кожним байтом у stdin, тому ми друкуємо середнє кочення в кожному циклі. '% c' перетворює поплавок на персонаж шляхом округлення вниз і взяття ASCII, тому все, що нам потрібно зробити, - це додати 0,5, щоб правильно зробити його круглим. $.є магічною змінною, яка починається з ініціалізації до 0 - вона повинна зберігати кількість рядків, але оскільки ми хочемо підрахунок байтів, ми просто збільшуємо її вручну.


2

Mathcad, 60 "байт"

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

Mathcad - це математичне додаток, засноване на 2D робочих аркушах, що складається з "регіонів", кожен з яких може бути текстом, математичним виразом, програмою, графіком або сценарієм.

Математична інструкція або інструкція з програмування вибирається з панелі інструментів палітри або вводиться за допомогою комбінації клавіш. Для цілей гольфу операцією ("байт") вважається кількість операцій на клавіатурі, необхідних для створення імені або виразу (наприклад, для встановлення змінної a на 3, ми запишемо: = 3. Оператор визначення : = - це одне натискання клавіш ":", як і 3 і дають усього 3 "байти". Програмування для оператора вимагає ввести ctl-shft- # (або один натискання на панелі інструментів програмування), тому знову еквівалентно 1 байт.

У Mathcad користувач вводить команди мови програмування, використовуючи комбінації клавіш (або вибираючи їх на панелі інструментів програмування), а не записуючи їх у тексті. Наприклад, введення ctl-] створює оператор циклу while, який має два "заповнювачі" для введення умови та одну лінію тіла відповідно. Введення тексту = в кінці виразів Mathcad змушує Mathcad оцінити вираз.

(Підрахунок байтів) Переглядаючи це з точки зору введення користувача та прирівнюючи одну операцію введення Mathcad (зазвичай клавіатура, клацніть мишею на панелі інструментів, якщо немає ярлика kbd), до символу та інтерпретуючи це як байт. csort = 5 байт, як це вводиться char-by-char, як і інші назви змінних / функцій. Оператор for - це спеціальна конструкція, яка займає 11 символів (включаючи 3 порожні «заповнювачі» та 3 пробіли), але вводиться ctl-shft- #, отже = 1 байт (подібно до лексем у деяких мовах). Введення тексту (цитата) створює збалансовані дужки (зазвичай), тому вважається 1 байт. Індексація v = 3 байти (тип v [k).


2

Python 3, 66 байт

Якщо я використовую round()замість int(.5+etc., це зберігає один символ, але технічно не відповідає виклику: Python round()округляє половинки до найближчого парного цілого числа, а не вгору. Однак він працює правильно на всіх вхідних зразках.

Я також відчуваю себе трохи брудним за те, що не закінчувати вихід новим рядком, але це не викликає вимагає цього ...

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

Пітон 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];
}

Цікаво. Чи можете ви також показати нам зразок дзвінків? Моя Java дуже іржава.
манатура

Як у тому, як це назвати? Припустимо test, що це масив char, просто використовуйте f(test);. Якщо це об'єкт String, тоді ви використовуєте f(test.toCharArray());. f("Hello!".toCharArray());
Лінійні рядки

Ой. Звичайно. toCharArray()Мене дурне, я намагався порушити це деяким кастингом. Дякую.
манатура

Це було б занадто просто, щоб просто кинути його. Яви боги були б розлючені: П
Геобіт


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

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, виведе значення як символ і зупинить. Якщо ви зіткнетесь із значенням float при відображенні знака,> <> буде заливати його, тому ми додали 1/2

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

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


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 байти можна зберегти, видаливши нові рядки.


Хм, хороший момент. Я думав, що можу залишити їх на посаді для кращої читабельності. Але так, це кодовий гольф. Я їх зніму;)
cb0

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

Це дратівливо довго завдяки частково тривалості 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.