Розрахуйте вагу забивання з низькою вагою


19

Створіть програму, яка обчислює вагу струну струни. Переможець - програма з найнижчою вагою кування.

Правила:

  • Вага забивання для символу ASCII визначається як загальна кількість бітів, встановлених 1у його бінарному поданні.
  • Припустимо, що вхідне кодування є 7-бітним ASCII, що передається через будь-який механізм введення, нормальний для вашої мови (наприклад, stdin, args тощо)
  • Виведіть результат, як число, для stdout або будь-якого механізму виводу за замовчуванням / нормального виводу, який використовує ваша мова.
  • Це само собою зрозуміло, але ви повинні мати можливість реально запускати програму в реальному житті, щоб вона була правильним рішенням.
  • Переможець - це рішення, код якого має найменшу вагу забивання.
  • Вибачте, для цього не знайдено жодного рішення у просторі ! Гаразд, ви можете кодувати у пробілі зараз я розібрав правила :)

Приклади персонажів:

char |  binary  | weight
-----+----------+-------
a    | 01100001 | 3
x    | 01111000 | 4
?    | 00111111 | 6
\x00 | 00000000 | 0
\x7F | 01111111 | 7

якщо взяти 0x20/ ASCII 32 як опорний, чи не гучна вага hello world10, а не 11?
Крістіан Лупаску

Чому вага hello world11? Тільки 10 символів відрізняються від пробілу. Також - вага програми Хеммінга, здається, становить лише її довжину, виключаючи пробіли. Не так відрізняється від звичайного коду гольфу.
ugoren

Вибачте, я цілком накрутив це. Стаття щодо вагомості у Вікіпедії є досить оманливою, і я цілком дотримувався правил. Перепишіть зараз. Оновлення: Гаразд, переписаний, щоб визначити його як кількість бітів, встановлених на 1 у рядку ASCII, вибачте за завершення роботи.
Поліном

@ugoren Рішення з меншими значеннями ASCII символів має меншу вагу.
Поліном

1
Тепер це все має сенс. ВИКОРИСТАННЯ ВЕРХНІЙ, БЕРЕЖІТЬСЯ ~AND o.
ugoren

Відповіді:



8

J, вага 34

+/,#:a.i.

Використання - розмістіть рядок, що вимірюється в лапках, в кінці:

   +/,#:a.i.'+/,#:a.i.'
34

Як варіант, взявши введення з клавіатури (вага 54):

   +/,#:a.i.1!:1[1
hello
21

Є лише один спосіб написати це :)
ефемія

Немає ... Я знайшов рішення, яке має вагу нарізання нижче.
ɐɔıʇǝɥʇuʎs

Не намагаються бути buzzkill, але правила запитують програму, а не фрагмент.
FUZxxl

5

J , 39

+/,#:a.i:]

Це функція, що бере один аргумент. (Або замініть ]рядок безпосередньо; як зазначає Гарет, це знижує вартість до 34.)

   + /, #: ai:] "привіт, світ"
45
   + /, #: ai:] '+ /, #: ai:]'
39

Великі уми мислять однаково. :-)
Гарет

5

Пітон, 189

print sum(bin(ord(A)).count("1")for A in raw_input())

2
Еквівалент Python 3 print(sum(bin(ord(A)).count('1')for A in input())), має оцінку 180.
dan04

4
@ dan04: Використовуйте подвійні лапки замість одиничних на 176.
Кіт Рендалл

5

QBasic, 322 311 286 264

H$=COMMAND$
FOR A=1 TO LEN(H$)
B=ASC(MID$(H$,A,1))
WHILE B>0
D=D+B MOD 2
B=B\2
WEND
NEXT
?D

Якийсь правильний інструмент для роботи, звичайно все-таки смокче.


1
+1 за використання однієї з моїх улюблених мов усіх часів. Це перша мова, яку я навчився кодувати на ПК.
Поліном

5

Унарний 0

Ви всі знали, що це буде. Перша програма BrainFuck:

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

Я додав нові рядки, щоб зробити його "читабельним", але він має вагу Хеммінга 4066. Він працює, багаторазово отримуючи коефіцієнт / залишки вхідного рядка та додаючи всі залишки. Звичайно, якщо запустити його на собі, ви отримаєте: 226 (4066% 256) (технічно \ xe2), так чітко, що він визначає себе переможцем.

Тепер ми конвертуємо його в Unary і отримуємо

000 ... 9*google^5.9 0's ... 000

Ми використовуємо одинарну реалізацію з NULL символами \ x00 для '0' і буму, маючи вагу 0.

Питання про бонус : для яких символів ASCII cви можете запустити цю програму на рядку, що складається з Nповторень, і вивести цей символ. (EG рядок з 32 пробілів дає пробіл). Які значення Nроботи (або нескінченна кількість їх буде працювати, або жодна не буде).


1
Я не впевнений, що розумію це рішення. Програма "мозковий ебан" має величезну вагу. Чи приймає Unary нульові байти як програму, чи вам потрібно буде повторно реалізувати Unary? Якщо це останнє, це насправді не є правильним рішенням - кожен може просто сказати "Я визначаю мову програмування, де будь-який байт введення дає {результат}", і виграти кожну проблему з кодом для гольфу на сайті.
Поліном

1
Нульовий символ Унарний буде добре. Все, що вам потрібно - це EOF, щоб сказати, перестаньте рахувати. Насправді ось якийсь псевдо-C для читання цього файлу: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }зовсім не має значення, що ви вирішили стати вашим Unar Char (поки це не EOF).
проходити

1
Ну ось унарний компілятор C, який добре працює з нульовими символами: ideone.com/MIvAg . Звичайно, файл, необхідний для створення цієї програми, не вміститься у Всесвіті, але ми маємо можливість запустити її.
пройти

3
Якщо ви не можете реально запустити його, це насправді не рішення.
Поліном

4
Як казав Карл Саган одного разу: "Якщо ви хочете обчислити вагу струни струни, спочатку винайдіть 10 ^ 500 всесвітів". (мільярди та мільярди, навіть)
пройдуть

4

C, вага 322 263 256

Чи враховується вага забивання ваги ковзання?

main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))D+=*A%2;printf("%d",D-2);}

Використовуються здебільшого стандартні методи для гольфу.
Один цикл обчислює вагу (зміщення вправо і додавання до нуля) і сканує рядок (просуває вказівник, коли нуль досягнуто).
Припущення Dініціалізовано до 2 (один параметр).

Оптимізація ваги забивання:
1. ABDHЗ масою 2, кожна використовується для імен.
2. *++Hпереважний над H[1].


Так, я досі не зрозумів ваше перше речення.
хлібопічка

Ви можете знизити рахунок до 230, вивівши результат як одинарне число:main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
schnaader

@schnaader, я ніколи не знав, що @це цифра в одинарній системі. Я думав , що він використовує лише 0.. 0. Але якщо ви хочете піти цим шляхом, шлях printf("@"+*a%2)коротший.
угорен

@ugoren: Залежить від конвенції / визначення унарного. Наприклад, система en.wikipedia.org/wiki/Unary_numeral_system використовує підкреслені позначки і каже: "Не існує явного символу, який би представляв нуль унарному, як це є в інших традиційних базах".
шнадер

@schnaader, гаразд, але я думаю, що це занадто далеко розтягує вимогу "як число".
ugoren

4

Гольфскрипт 84 72 58

{2base~}%{+}*

(дякую Говарду та Пітеру Тейлору за допомогу)

Введення: рядок введення повинен бути в стеці (передається як аргумент командного рядка або просто розміщується в стеку).

Якщо ви запускаєте його з командного рядка, переконайтеся, що ви використовуєте echo -n, інакше останній рядок також буде врахований.

Вихід: виводить на консоль значення ваги забивання

Програму можна перевірити тут .


1
Чи чутливий до регістру Golfscript? Якщо ні, ви можете зберегти кілька біт, використовуючи BASEзамість base. Оновлення: Щойно перевірено, BASEне працює. Гарне рішення :)
Поліном

@Polynomial Я спробував це, побачивши ваш TEST/ testкоментар :) Але це не працює.
Крістіан Лупаску

Позбутися {...}2*можна, застосувавши 2base~в першу чергу. Отримує рахунок до 72.
Говард

@Howard дякую за цю чудову пораду! Я застосував це у своїй відповіді.
Крістіан Лупаску

Ваш тестовий механізм невірний, тому що ви забули важливе обмеження сторінки веб-GolfScript. Ви повинні мати ;рядок перед рядком, який ви замінюєте на stdin, так що (;це зайве. Потім спостереження Говарда зменшує його до 65.
Пітер Тейлор

2

Perl, 80 (22 символи)

Готово:

perl -0777nE 'say unpack"%32B*"'

Або ось альтернативна версія вагою 77 (21 символ):

perl -0777pE '$_=unpack"%32B*"'

Мені ця версія не дуже подобається, тому що її вихід не відповідає остаточному новому рядку.

Для підрахунку ваги я припускаю, що я рахую символи звичайним чином (виключаючи perl -e/ -E, але включаючи інші символи опції). Якщо люди чомусь скаржаться на це, то найкраще, що я можу зробити без варіантів, це 90 (26 символів):

$/=$,,say unpack"%32B*",<>

Використання зразка:

$ perl -0777nE 'say unpack"%32b*"' rickroll.txt
7071

Бум.


2

Піт - 15

Відмова: Ця відповідь не може виграти, оскільки Pyth молодший за цей виклик.

Використовує .Bдля двійкового представлення і підраховує кількість "1"s.

/.BQ\1

Бере введення в рядку для економії на zпорівнянні Q.

Спробуйте його онлайн тут .


1

Scala 231

readLine().map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum

Код самотестування:

"""readLine().map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum""".map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum

з модифікацією самотестування.


Це вага 495, а не 231. Ви не можете набрати вагу 231 із 126 символів - це в середньому менше 2, а всі друковані символи (крім @місця та місця, якими ви не користуєтесь) мають вагу 2 принаймні.
ugoren

1
@ugoren: Але це лише 65 символів. Програма друкується майже вдвічі: Один раз код для обчислення ваги забивання, і другий раз як статичний вхід для його обчислення для програми. Але в обчислювальній частині відсутня "readLine ()" попереду, тому що вона займає буквальний ввід. Я спробував уточнити саму відповідь.
користувач невідомий

1

Ява, вага 931 774 499 454

Я думаю, що це єдина відповідь на даний момент з вагою понад 300.

class H{public static void main(String[]A){System.out.print(new java.math.BigInteger(A[0].getBytes()).bitCount());}}

Очікує введення як аргумент командного рядка.


1

ГНУ sed -r, 467 + 1

(+1 для використання -r- або це має бути +4?)

Виводи у вигляді одинарного значення на вихідний рядок; перетворити в десятковий загальний, перенаправити вихід у | tr -d "\n" | wc -c. Підраховує всі друковані символи ASCII (32-126), плюс передачу рядків (10).

s@[a-z]@\U& @g
s@[?{}~]@      @g
s@[][/7;=>OW|^]@     @g
s@[-'+.3569:<GKMNSUVYZ\\]@    @g
s@[#%&)*,CEFIJL1248ORTX]@   @g
s@$|[!"$(ABDH0P`]@  @g
y! @!11!

Важко уникнути перерахування всіх символів, але ми можемо зменшити це, спостерігаючи, що малі літери мають вагу Хеммінга на одну більше, ніж відповідні великі літери. Ми віддаємо перевагу новому рядку (бал 2) над крапкою з комою (оцінка 5) як роздільник висловлювань; ми вважаємо за краще @(оцінка 1) або !(оцінка 2) над /(оцінка 5) як роздільник візерунка.

Примітка - щоб отримати правильні набори символів, я створив цю таблицю з таблиці в man ascii, відсортовану за вагою. Просто додайте бали праворуч і нижче, щоб отримати загальну вагу кожного персонажа:

   2 4   3 5 6   7 
   ---  ------   - 
0:   @   0 P `   p |0

1: ! A   1 Q a   q | 
2: " B   2 R b   r |1
4: $ D   4 T d   t | 
8: ( H   8 X h   x | 

3: # C   3 S c   s | 
5: % E   5 U e   u | 
6: & F   6 V f   v |2
9: ) I   9 Y i   y | 
A: * J   : Z j   z | 
C: , L   < \ l   | | 

7: ´ G   7 W g   w | 
B: + K   ; [ k   { |3
D: - M   = ] m   } | 
E: . N   > ^ n   ~ | 

F: / O   ? _ o     |4
   ---  ------   -  
    1      2     3

Це може виявитися корисним для інших.


0

Юлія 262 268

Модифікована версія використовує зручну функцію 'count_ones' для економії 6 (262)

show(mapreduce(x->count_ones(x),+,map(x->int(x),collect(ARGS[1]))))

Стара версія з використанням вбудованої функції підрахунку (268)

show(mapreduce(x->int(x)-48,+,mapreduce(x->bits(x),*,collect(ARGS[1]))))

Використовує аргумент командного рядка для введення.


0

CJam 52 або 48

Якщо введення вже не є стеком (52)

q:i2fbs:s:i:+

Якщо вхід є стеком (48)

:i2fbs:s:i:+

Наприклад

"Hello World":i2fbs:s:i:+

0

Юлія, HW 199

H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))

З

A="H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))"

або безпосередньо вставивши рядок:

julia> H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect("H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))")))
199

Негольована версія (HW 411) виглядає так:

bitstring=mapreduce(x->bits(x),*,collect(teststring[:]))
mapreduce(checkbit->checkbit=='1',+,bitstring)

І для задоволення, ось оптимізована версія (вага Hamming 231 ) проблеми бейкерга:

A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))

з

H="A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))"

0

HPPPL (Мова основного програмування HP), 74

sum(hamdist(ASC(a),0))

Графічний калькулятор HP Prime має вбудовану функцію hamdist (). Вага забивання кожного символу така ж, як відстань забивання від 0.

ASC (рядок) створює масив значень ASCII кожного символу в рядку.

hamdist (значення, 0) обчислює відстань забивання від 0 для кожного значення ASCII

sum () підсумовує всі значення.

Розрахунок ваги забивання власного вихідного коду:

Вага Хемінга HPPPL


0

05AB1E , вага 17 (4 байти )

ÇbSO

Спробуйте в Інтернеті або перевірте ще кілька тестових випадків .

Пояснення:

Ç       # Convert the characters in the (implicit) input to their ASCII decimal values
        #  i.e. "Test" → [84,101,115,116]
 b      # Convert those values to binary
        #  i.e. [84,101,115,116] → ["1010100","1100101","1110011","1110100"]
  S     # Split it into a list of 0s and 1s (implicitly flattens)
        #  i.e. ["1010100","1100101","1110011","1110100"]
        #   → [1,0,1,0,1,0,0,1,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0]
   O    # Sum those (and output implicitly)
        #  i.e. [1,0,1,0,1,0,0,1,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0] → 16

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.