Розшифруйте порожнечу


25

Недійсний список - це список, який на жодному рівні не містить об'єктів, які не є списком. Або якщо ви віддаєте перевагу рекурсивному визначенню

  • Порожній список недійсний

  • Список, що містить лише інші списки недійсних, недійсний

Усі недійсні списки мають кінцеву глибину.

Ось кілька прикладів недійсних списків (використовуючи синтаксис python):

[]
[[]]
[[],[]]
[[[]]]
[[[]],[]]
[[],[[]]]

Ось кілька прикладів речей, які не є недійсними списками:

["a"]
[[...]]
[1]
2
[[],([],[])]

Завдання

Напишіть дві окремі функції (або програми, якщо бажаєте). Потрібно взяти додаткове ціле число (ви можете також включити нуль, якщо хочете) як аргумент та повернути список недійсних, а інший повинен взяти список недійсних та повернути йому ціле число. Ці дві функції завжди повинні бути оберненими одна до одної. Тобто, якщо ви передасте висновок fв, gви повинні отримати оригінальний вхід fв результаті g. Це означає, що відображення повинно бути 1: 1, тобто для кожного цілого числа може існувати лише один список недійсних, який gдає це ціле число, а для кожного списку недійсностей має бути саме одне ціле число, яке fдає цей список недійсних.

Ви по суті створюєте Bijection

Ви можете використовувати рядкове подання недійсного списку (з комами або без пробілів) замість вашого рідного списку мов.

Оцінка балів

Ваш результат буде тривати дві функції разом. Це тому ви повинні прагнути мінімізувати цю суму.



1
Це питання вимагає двох функцій, тоді як дублікат задається лише для першого тайму.
Ян Міллер

3
Щури Я ледве не опублікував найкращу відповідь, яку я написав досі, і це не відповідає іншій проблемі.
Калеб Клеветер

2
@IanMiller Я хотів би сказати, що інша проблема має різні вказівки щодо кодування, ніж ця.
Калеб Клеветер

1
Можливо, було б більше сенсу для цього питання бути просто декодером? Тому що вже є питання щодо кодера.

Відповіді:


7

Pyth, 27 + 29 = 56 байт

f:

L?bol`NS{sm[d+d]Y]d)ytb]Y@y

Тестовий набір

g:

L?bol`NS{sm[d+d]Y]d)ytb]Yxyl`

Тестовий набір

Система дуже проста: я генерую всі можливі списки з не більше певної кількості [s. Потім я сортую їх таким чином, щоб списки, які я ще не створив, були б наприкінці кінця. Це все робиться за допомогою функції y, однакової в обох програмах. Він написаний як

L?bol`NS{sm[d+d]Y]d)ytb]Y

Потім я індексую цей список для fта шукаю йогоg .

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

Програми дозволяють / повертати 0 як опцію.


5

Python 2 , 96 байт

Спробуйте в Інтернеті! перевірити біекцію.

f=lambda l:len(l)and f(l[0])*2+1<<f(l[1:])

Позначає недійсні списки до невід’ємних цілих чисел. 42 байти

g=lambda n:n*[g]and[g(n/(n&-n)/2)]+g(len(bin(n&-n))-3)

Недійсні цілі числа приймає до недійсних списків. 54 байти Більш рекурсивна спроба дала однакову довжину.

g=lambda n,i=0:n*[g]and[g(n/2,i+1),[g(n/2)]+g(i)][n%2]

1

Java 7, 725 байт

f(int)( 325 байт ):

String f(int i){String s="";for(int j=0,e=0;e<i;e+=v(s))s=Integer.toBinaryString(j++);return"["+s.replace("1","[").replace("0","]")+"]";}int v(String s){for(;!s.isEmpty();s=s.replaceFirst("1","").replaceFirst("0",""))if(s.replace("1","").length()!=s.replace("0","").length()|s.charAt(0)<49|s.endsWith("1"))return 0;return 1;}

g(String)( 75 + 325 байт ):

int g(String s){int r=0;for(String i="10";!i.equals(s);i=f(++r));return r;}

Оскільки метод gвикористовує метод fдля обчислення результату, перебираючи можливий список пустот, поки він не знайде той, який дорівнює введеному, байти fпідраховуються вдвічі (оскільки обидва способи повинні мати можливість працювати без іншого для цього завдання).

Пояснення:

Взагалі метод fпросто перетинає всі бінарні рядкові представлення цілих чисел і збільшує лічильник щоразу, коли знайдеться дійсне. Дійсні бінарні рядки для цього виклику відповідають таким правилам: Вони починаються з a 1, а закінчуються з a 0; вони мають рівну кількість 1s і 0s; і кожен раз, коли ви видаляєте перше 1і 0ще раз підтверджуєте те, що залишилося, ці два правила все ще діють. Після того, як лічильник дорівнює вводу, він перетворює цей двійковий-String в список Stid void-list, замінюючи всі 1на [і всі 0на] .

Що стосується методу g: ми починаємо з "[]"(представляє void-list 0), а потім продовжуємо використовувати метод f, збільшуючи ціле число, до тих пір, поки воно не збігатиметься з input-String.

String f(int i){         // Method `f` with integer parameter and String return-type
  String s="";           //  Start with an empty String
  for(int j=0,e=0;e<i;   //  Loop as long as `e` does not equal the input
      e+=v(s))           //    And append increase integer `e` if String `s` is valid
    s=Integer.toBinaryString(j++);
                         //   Change `s` to the next byte-String of integer `j`
                         //  End of loop (implicit / single-line body)
  return"["+             //  Return the result String encapsulated in "[" and "]"
    s.replace("1","[").replace("0","]")+"]";
                         //  after we've replaced all 1s with "[" and all 0s with "]"
}                        // End of method `f`

int v(String s){         // Separate method with String parameter and integer return-type
  for(;!s.isEmpty();     //  Loop as long as String `s` isn't empty
      s=s.replaceFirst("1","").replaceFirst("0",""))
                         //    After each iteration: Remove the first "1" and "0"
    if(s.replace("1","").length()!=s.replace("0","").length()
                         //   If there isn't an equal amount of 1s and 0s
       |s.charAt(0)<49   //   or the String doesn't start with a 1
       |s.endsWith("1")) //   or the String doesn't end with a 0
      return 0;          //    Return 0 (String is not valid)
                         //  End of loop (implicit / single-line body)
  return 1;              //  Return 1 (String is valid)
}                        // End of separate method

int g(String s){         // Method `g` with String parameter and integer return-type
  int r=0;               // Result integer
  for(String i="[]";!i.equals(s);
                         //  Loop as long as `i` does not equal the input String
      i=f(++r));         //   After each iteration: Set `i` to the next String in line
  return r;              //  Return the result integer
}                        // End of method `g`

Приклади випадків введення та виведення:

Спробуйте тут. (ПРИМІТКА. Останні кілька тестових випадків досить повільні. На всі вони знадобиться приблизно 10-15 сек.)

0   <-> []
1   <-> [[]]
2   <-> [[][]]
3   <-> [[[]]]
4   <-> [[][][]]
5   <-> [[][[]]]
6   <-> [[[]][]]
7   <-> [[[][]]]
8   <-> [[[[]]]]
9   <-> [[][][][]]
10  <-> [[][][[]]]
11  <-> [[][[]][]]
12  <-> [[][[][]]]
13  <-> [[][[[]]]]
14  <-> [[[]][][]]
50  <-> [[[][[[]]]]]
383 <-> [[[][]][[[][]]]]

1
Я не думаю, що [][]це список. Можливо, я нерозумію те, як Java робить все, що завгодно. Додавши [...]все до них і маючи 0 карт, []слід зробити трюк.
Пшеничний майстер

@WheatWizard Ах, гарний дзвінок. Спробую це виправити. У мене все одно було недостатньо байтів. ; P
Кевін Круїссен

@WheatWizard Добре, це слід виправити зараз. Жорсткий, але веселий виклик btw. Минув деякий час, перш ніж я зрозумію, що ти мав на увазі, і ще довше написати цю відповідь, але це було весело. :)
Кевін Кройсейсен



0

Python 3 - знак / абс, 73 байти

f=lambda n:[[[]]*(n<0),[[]]*abs(n)]
g=lambda l:[-1,1][not l[0]]*len(l[1])

Спробуйте в Інтернеті!

Пряма реалізація вперед, підтримує негативні числа.

Ціле число iкодується [sign(i), abs(i)], де sign(i)=[] if i > 0 else [[]]і abs(i)=[[]] * i, тобто список порожніх списків з довжиною abs (i).

Python 3 - двійковий, 126 байт

Це більш досконала версія (і набагато довше ...), де абсолютне значення кодується у поданні бінарного списку.

f=lambda n:[[[]]*(n<0),[[[]]*int(i)for i in f"{n:+b}"[1:]]]
g=lambda l:[-1,1][not l[0]]*int(''.join(map(str,map(len,l[1]))),2)

Спробуйте в Інтернеті!


1
Не працює для складніших недійсних списків: спробуйте в Інтернеті!
Jitse

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

0

Stax , 33 усього байт

Ці програми є оберненими один до одного. Вони перетворюються на та з усіх недійсних списків і всіх невід’ємних цілих чисел, так що включає 0. Це здається, що це, можливо, відома функція з якоїсь алгебри, яку я не знаю. Для того, щоб обернути голову навколо цього, я спершу реалізував програми як функції в python.

def convert_to_void(n):
    lst = []
    while n > 0:
        n -= 1
        choices = len(lst) + 1
        choice = n % choices
        cutpoint = len(lst) - choice
        n //= choices
        newgroup = lst[cutpoint:]
        del lst[cutpoint:]
        lst.append(newgroup)
    return lst

def convert_from_void(lst):
    n = 0
    while lst != []:
        newgroup = lst.pop()
        n *= len(lst) + len(newgroup) + 1
        n += len(newgroup) + 1
        lst.extend(newgroup)
    return n

Програми stax мають таку саму поведінку.

Невід’ємне ціле число → Список недійсних, 15 байт

ƒâ₧~└3BI─¿-rÅ;ì

Запустіть і налагоджуйте його

Список недійсних → Невід’ємне ціле число, 18 байт

Çäê[!σ`c↑Ö§░NR╥ç=Æ

Запустіть і налагоджуйте його

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