Сбалансированное кодирование Zero-One

12

задача

Кодируйте строку, которая полностью состоит из прописных букв ( A-Z), используя только нули и единицы, используя вашу собственную любимую схему. Но правило не так просто!

правила

  1. Ваша программа / функция должна правильно обрабатывать любую допустимую строку ввода длиной 8 .
  2. Результаты должны иметь одинаковую длину для всех входных данных.
  3. Результаты должны отличаться для разных входов.
  4. Результаты должны быть максимально короткими.
  5. Результаты должны быть равны нулю (иметь количество единиц, сходных с нулями). Они не должны быть равными (то есть идеально сбалансированными), но ваш счет будет оштрафован за это.

Вам не нужно предоставлять программу / функцию, которая декодирует вашу кодировку.

Вход и выход

  • Вы можете принять любой набор из 26 различных печатаемых символов ASCII вместоA-Z .
  • Вы можете решить вывести любую пару различных печатаемых символов ASCII вместо 0и 1.
  • Вам не разрешено выводить целое число вместо битовой строки, так как оно может иметь начальные нули, и неясно, действительно ли вы выполнили правило 2.
  • Если вы решили отклониться от значения по умолчанию ( A-Zввод и 01вывод), вы должны указать наборы символов ввода / вывода в своем представлении.

счет

  • Базовая оценка: размер кода или 1, если ваша программа пуста.
  • Штрафы
    • Штраф за длину: умножить 1.5 ** (encoded length - 42)
    • Там нет бонуса за то, что короче; 42 - минимальная длина для идеально сбалансированного кодирования строк длиной 8 с размером алфавита 26.
    • Штраф за несбалансированность: умножить 2 ** max(abs(ones - zeros) for every valid input of length 8), где onesи zeros- это числа 1 и 0 в каждом выходе соответственно.
    • Ваша заявка должна содержать либо пример наихудшего случая (вход / выход), либо теоретическое объяснение значения штрафа.
  • Самый низкий балл побеждает.

Пример представления

Гипотетический esolang, 0 байт, оценка 74733,8906

Вот гипотетический esolang, где пустая программа печатает все ASCII-коды символов ввода в двоичном виде.

 

Например, если вы дадите в AAAAAAAAкачестве ввода, программа будет печатать 10000018 раз подряд, т.е.10000011000001100000110000011000001100000110000011000001 .

Входной алфавит выбран, чтобы быть CEFGIJKLMNQRSTUVXYZabcdefh . Таким образом, все символы конвертируются в семизначные числа в двоичном виде, а счетчики с нулем один отличаются только на единицу на символ (все они имеют три единицы и четыре нуля или наоборот при преобразовании в двоичную форму).

Длина выхода всегда равна 56, и на входах возникает дисбаланс в худшем случае, например CCCCCCCC, где нули появляются в 8 раз чаще, чем единицы.

Таким образом, оценка этого представления 1.5 ** (56 - 42) * 2 ** 8 == 74733.8906.

фонтанчик для питья
источник
Песочница: codegolf.meta.stackexchange.com/a/14908/78410
Bubbler
могу ли я использовать свой гипотетический esolang, в котором пустая программа принимает число N в 26-буквенном коде и выдает N-ую возможную 42-битную последовательность суммы 21?
августа
@ngn - Ваш гипотетический язык соответствует нашим принятым критериям ? - РЕДАКТИРОВАТЬ ах ввод всегда [АЗ] - Я думаю, это достаточно просто ... :)
Джонатан Аллан
1
Можем ли мы вывести список единиц и нулей или это должна быть строка?
Деннис
1
Весь вопрос сводится к тому, что «не должно быть дисбаланса, должно быть в 42 цифрах, кому важно реальное время бега»
l4m2

Ответы:

4

Stax , 11 байт, 0 пенальти, оценка 11

Эта программа использует [0-9A-P]для ввода и [01]для вывода.

ö■▄←·ï↨≡⌐╠H

Запустите и отладьте его онлайн - нажмите кнопку « Выполнить» , чтобы начать. Первые четыре теста выполняются за миллисекунды. Пятое за секунды. Шестой в тысячелетиях.

Соответствующее ascii представление этой программы таково.

A$21*,26|bD|N

Он сильно опирается на |Nинструкцию, которая получает последующую перестановку массива.

A$21*           "10" repeated 21 times
     ,26|b      get input and decode it as a base 26 number
          D|N    ... that many times get the next lexicographic permutation

Все выходы являются перестановками исходной строки. Имеет 21 ноль и 21 единицу. Поэтому все выходы имеют 42 символа и идеально сбалансированы.

рекурсивный
источник
3

Желе , 19 байт

O_65ḅ26ị2Ḷ¤x21¤Œ!Q¤

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

объяснение

O_65ḅ26ị2Ḷ¤x21¤Œ!Q¤  Main Link
O                    Take the character code of each character
 _65                 Subtract 65 (the code of "A")
    ḅ26              Convert to base 26
       ị             Get the <left-arg>th element of:
        2Ḷ¤x21¤Œ!Q¤  All balanced strings of length 42:
        2Ḷ           range(2) == [0, 1]
           x21       stretch 21 ([0, 0, ..., 0, 1, 1, ..., 1])
               Œ!    all permutations
                 Q   deduplicate
HyperNeutrino
источник
E x p l a n a t i o n?
Esolanging Fruit
@EsolangingFruit добавил
HyperNeutrino
3

Pyth, 20 19 14 байтов, Макс. Разность: 0, длина: 64, оценка: 149636,5528 142154,7251 104745,5869

sm@S.{.p*`T4xG

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

Использует строчные буквы алфавита ( [a-z]) вместо прописных. Можно использовать прописные путем замены Gс rG1ценою 2 байта.

Я мог бы перевести ответ HyperNeutrino на Python 3 для лучшего результата, но, честно говоря, я хочу получить ответ, который действительно работает.

hakr14
источник
2

Python 2 , 779 645 байт, Макс (разность) = 0, длина = 48, оценка = 7346,95

def f(s):
 a,b=0,""
 for i in s:a=a*26+ord(i)-65
 a+=56*252**4
 for i in range(5):b=bin((int("4lnk28t9vtqgfrpfda9uyfrjhcjwjvno6aec2nwegi0g4mnublc05dher8fjm4s5gh55lu87a4itmc74t6tozcsfdbxkg82frwljy0wam1jht98g2j0bma021v5d48pwq0fklv0n1ltrxft1fpk5gt5mx5fj4p2mjqqpvcylt1xayxf1iwdmyoxgfvl7oui1oo6147bm9rqpqut9ns8hhjc77t3pqy48otovrsm1t4mmleumspkuef66ma1vi0l4mtkwaeeizuvvds9fro3vhc0mrn6ox17rdpk7xw747qf28934u5jci5q1qj81i7dyf7rf0x7hb19xm93xhxsgh4w8ifs6fhynsddbo9j938ewfvhjlbpiz50n5hanmno6c89blyx50e89z7vjq2ho2r2u2wwyu4q18kv4fi1nhmfbgjbnkdayr5kblaped4fo5u97bi9a67d89irxa0r9cinmnohfgjmh5fhkcr33",36)>>a%252*10)&1023)[2:].rjust(10,"0")+b;a/=252
 return b[2:]

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

Магическое число 4lnk28t9vtqgfrpfda9uyfrjhcjwjvno6aec2nwegi0g4mnublc05dher8fjm4s5gh55lu87a4itmc74t6tozcsfdbxkg82frwljy0wam1jht98g2j0bma021v5d48pwq0fklv0n1ltrxft1fpk5gt5mx5fj4p2mjqqpvcylt1xayxf1iwdmyoxgfvl7oui1oo6147bm9rqpqut9ns8hhjc77t3pqy48otovrsm1t4mmleumspkuef66ma1vi0l4mtkwaeeizuvvds9fro3vhc0mrn6ox17rdpk7xw747qf28934u5jci5q1qj81i7dyf7rf0x7hb19xm93xhxsgh4w8ifs6fhynsddbo9j938ewfvhjlbpiz50n5hanmno6c89blyx50e89z7vjq2ho2r2u2wwyu4q18kv4fi1nhmfbgjbnkdayr5kblaped4fo5u97bi9a67d89irxa0r9cinmnohfgjmh5fhkcr33(в базе 36) или его десятичный эквивалент 382136276621246556626597379364678993894472503063952720559883124988542417847157286833446006767955087631166943136913765901237281892296575754126024183763829277879554548743231384272055945084065681774297483130020386641869860456147616177702938121538230311395513497506285733567467605871232294046704309941152721616618474501854355102646152223338484615876165254236449912858255665248186687952137487016925761633237335983620006273901509768720506129789443353730706676483647298576692613113269388239830925662977837917272690235355742330377154505179476767457756888107428475384947712227312747517748632498691058764154580934614231152483398774630508576533263098942260213967880819240793990219283490212843120923539516962682466148372296338428497778127570401190309339992457562121354271кодирует все 252 перестановки по 5 0с и 5 1с.

Алгоритм сначала конвертируется A-Zв 0-25и обрабатывает его как число с основанием 26, а затем добавляет 56*252**4.

Затем число преобразуется в 5-значное число с основанием 252 и заменяется соответствующей перестановкой 5 0с и 5 1с.

После этого удалите первые 2 бита, что гарантированно будет 01. Затем мы закодировали строку в 48-битную строку, которая состоит ровно из 24 0с и 24 1с.

Сиеру Асакото
источник
Уверен, что штрафы должны быть умножены (т. Е. Ваш счет 7346.953125).
HyperNeutrino
@HyperNeutrino О, я думаю, что это дополнение; P Отредактировано
Shieru Asakoto
2

JavaScript (ES8), оценка 22186,623779296875

f=
s=>s.replace(/./g,(c,i)=>(i%2*127^c.charCodeAt()).toString(2).padStart(7,0))
<input oninput=o.textContent=f(this.value)><pre id=o>

При вводе четной длины всегда выводится 3,5 * нулей и единиц, поэтому он платит только штраф 1,5 ** 14. Поддерживаемые символы: '+-.3569:<GKMNSUVYZ\cefijlqrtx.

Нил
источник
2

Желе , 16 байт

42ɠO%ḅ26ịœcH$ạ‘Ṭ

Используется +,-./0123456789:;<=>?@ABCDдля ввода и возвращает список единиц и нулей.

Это попытается создать список из 538 257 874 440 комбинаций в памяти, поэтому вам потребуется большой объем оперативной памяти, чтобы запустить его как есть ...

Попробуйте онлайн! (тестируемый; длина ввода 3, длина вывода 18)

Как это устроено

42ɠO%ḅ26ịœcH$ạ‘Ṭ  Main link. No arguments.

42                Set the argument and the return value to 42.
  ɠ               Read one line from STDIN.
   O              Ordinal; map ['+', ..., 'D'] to [43, ..., 69].
    %             Take the code points modulo 42, mapping [43, ..., 69] to
                  [1, ..., 26].
     ḅ26          Convert the result from base 26 to integer.
            $     Combine the two links to the left into a monadic chain.
           H          Halve; yield 21.
         œc           Generate all 21-combinations of [1, ..., 42].
                  There are 538,257,874,440 of these combinations. The first
                  269,128,937,220 begin with a 1.
        ị         Retrieve the combination at the index to the left.
                  [26, 26, 26, 26, 26, 26, 26, 26] in bijective base 26 equals
                  217,180,147,158 in decimal, so the retrieved combination will
                  begin with a 1.
              ‘   Increment; yield 43.
             ạ    Absolute difference; map [1, ..., 42] to [42, ..., 1].
                  The combination now begins with a 42.
               Ṭ  Untruth; turn the combination into a Boolean list, with 1's
                  at the specified indices and 0's elsewhere.
                  Since the maximum of the combination is 42, this list will have
                  exactly 42 items, 21 of which will be 1's.
Деннис
источник
2

Python 3 , 985 135 байтов, Max Diff 0, длина 42, оценка 135

lambda s:C(int(s,26),21,20)
B=lambda x,y:y<1or-~x*B(x+1,y-1)//y
def C(n,o,z):p=B(o,z);x=n>=p;return z+1and[x]+C(n-p*x,o-x,z-1+x)or[1]*o

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

Предоставлено Bubbler

Код Ungolfed:

import math

def binomial(x, y):
    return math.factorial(x) // math.factorial(y) // math.factorial(x - y)

def string_to_int(input_str):
    result = 0
    for i in range(0,8):
        result += (ord(input_str[i])-65)%26 * pow(26,i)
    return result

def counting_function(target, ones, zeros):
    if zeros > 0:
        position = binomial(ones+zeros-1,zeros-1)
    else:
        position = 1
    if target > position:
        if ones > 0:
            print("1", end='')
            ones -= 1
            counting_function(target-position,ones,zeros)
    else:
        if zeros > 0:
            print("0", end='')
            zeros -= 1
            counting_function(target,ones,zeros)
        elif ones > 0:
            print("1", end='')
            ones -= 1
            counting_function(target,ones,zeros)

input_str = input("Input string (A-Z): ")
input_int = string_to_int(input_str)+1
target = input_int
ones = 21
zeros = 21
counting_function(target, ones, zeros)
print("")

Поскольку другие подходы кажутся совершенно неэффективными, я попытался сделать оптимальный по времени. Это просто O (N) в N битах кодирования, что является оптимальным для big-O.

Подсказка: попробуйте подумать о треугольнике Паскаля для этого ( эта диаграмма показывает это)

Пример выходов:

Input:  AAAAAAAA
Output: 000000000000000000000111111111111111111111

 

Input:  ZZZZZZZZ
Output: 011001000000011010011000111010110110111110

Время выполнения: <0,013 с (примерно постоянно для всех входов)

реальный
источник
@Bubbler Невероятно, я не обладал навыками, чтобы достичь этого
Реал
Но вы должны приложить некоторые усилия, чтобы свести к минимуму ваш счет. Все материалы должны прилагать серьезные усилия для оптимизации оценки, в противном случае она недействительна.
user202729
@ user202729 Тогда я изменил версию Bubbler, которая сведена к минимуму. Я действительно старался минимизировать свой счет, но не с помощью размера кода.
Реальный
По поводу последнего пункта ... правильно.
user202729
2

Perl 5 , 55 байтов, max diff 0, длина 42, оценка 56 55

Это работает, но займет много времени, но выполнимо ( ZZZZZZZZна моем компьютере это заняло 2,5 дня). Память не проблема.

Используется A-Zкак ввод и 1и Aкак кодировка символов. Они всегда идеально сбалансированы. Пропускает первые 26^7 = 8031810176сбалансированные комбинации, представляющие строку длиной менее 8 символов, но это нормально, так как они 538257874440доступны, и я использую 208827064575и208827064575 + 8031810176 < 538257874440 .

Однако на самом деле он «рассчитывает» до целевой комбинации, которая займет очень много времени. Вот почему в ссылке TIO я использовал только слишком короткую входную строку (которая также поддерживается), чтобы продемонстрировать, что вывод правильный. Будет работать чуть больше, чем AAAAAAдо истечения времени ожидания TIO. ZZZZZZZZдолжно быть примерно в 26^3 = 17576разы медленнее.

#!/usr/bin/perl -ap
$_=1x21 .($i=A)x21;s/(A*)(1*)1A/$2$1A1/ until"@F"eq$i++

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

Декодер почти такой же:

#!/usr/bin/perl -ap
$_=1x21 .($\=A)x21;s/(A*)(1*)1A/$2$1A1/,$\++until"@F"eq$_}{

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

Тон Хоспел
источник
1

> <> , 75 байтов, Макс. Разность 0, длина 42, оценка 75

0i:0(?v'A'-$dd+*+!
.")1+.\1+:0$:2%:}:@-2,@+$bl"
[ab+-?\$:?vv~3
~~]>n<v$-1<>

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

Честное предупреждение, это займет очень очень очень много времени, чтобы завершить даже для тривиального AAAAAAAAслучая. Выполняется через каждое двоичное представление счетчика, пока не 1будет достигнуто ( двоичное представление входа 26) двоичное число с 21 с. Если вы хотите немного протестировать программу, вы можете заменить ab+строку в третьей строке, 1которая будет возвращать n-ное двоичное число всего одним 1, попробуйте онлайн!

Джо Кинг
источник
1

Python 3 , 75 байт, Max Diff 0, длина 42, счет 112

lambda s:sorted({*permutations("01"*21)})[int(s,26)]
from itertools import*

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

Это работает только в теории из-за ограничений памяти. Существуют 538257874440четкие сбалансированные ноль-единичные строки длиной 42 и208827064575 возможные входы, поэтому некоторые из возможных выходов не будут использоваться.

-37 байт благодаря @recursive

HyperNeutrino
источник
Вы можете использовать int(s,26)для своего индекса значение, а не sum(...)если вы измените свой набор символов ввода.
рекурсивный
@ рекурсивный, который требует непечатных. уже пробовал
HyperNeutrino
Непечатные? Это использует [0-9A-P], не так ли? На моей машине,int("123ABC",26) == 12855114
рекурсивный
@ recursive, о, да, ты прав IDK, что я думал LOL. Благодарность!
HyperNeutrino
1

C ++, 146 байт, 42 maxlength, 0 дисбаланс, оценка 146

#include<algorithm>
long long i,s;int f(char*I,char*O){for(O[i=42]=s=0;i--;i<8?s=s*26+I[i]:0)O[i]=i%2|48;for(;s--;)std::next_permutation(O,O+42);}

Работает для любого непрерывного 26 символов, но предупреждает, что оно работает недопустимо

l4m2
источник
Похоже, что вам требуется дополнительно передать пустой массив. Я не думаю, что это действительно. / Если вы используете GCC, вы можете заменить #include<algorithm>на #import<regex>.
user202729
Я изменю это, когда GCC решит прекратить использовать данный указатель в качестве вывода
l4m2
... так это указатель на вывод? Выглядит действительным тогда. Но вы должны явно указать формат ввода / вывода.
user202729