Война - это мир. Свобода - это рабство. Невежество это сила

69

Как Джордж Оруэлл написал в 1984 году :

Война - это мир.
Свобода - это рабство.
Невежество - это сила.

Напишите программу или функцию, которая берет одно из шести основных слов из цитаты Оруэлла и выводит свой аналог.

В частности:

[input] -> [output]
war -> peace
peace -> war
freedom -> slavery
slavery -> freedom
ignorance -> strength
strength -> ignorance

Никаких других пар ввода / вывода не требуется.

Вы должны предполагать, что слова всегда полностью строчные, как указано выше. В качестве альтернативы, вы можете считать , что слова всегда полностью в верхнем регистре: WAR -> PEACE, PEACE -> WARи т.д.

Самый короткий код в байтах побеждает.

Кальвин Хобби
источник
10
Связанный :-)
xnor
2
@ Денис Да. Либо все строчные, либо все прописные.
Увлечения
3
Не знаю, может ли кто-нибудь использовать это для более сильного сжатия своих строк (это не улучшило мою оценку в Пипе), но начальные буквы этих слов ( w p f s i) больше нигде не встречаются ни в одном из слов. Интригующая собственность.
DLosc
13
Это двойной вызов
Jojodmo
3
Почти никто не любит эту книгу. Это полно лжи! Грустный.
Питер - Восстановить Монику

Ответы:

58

05AB1E , 30 байтов

05AB1E использует CP-1252 .

“ignorance¤í‡î—™šÔÃÒry“#DIk1^è

Попробуйте онлайн! или как тестовый набор

объяснение

Прямой подход

  • Нажмите на строку ignorance strength war peace freedom slavery
  • Сплит на пространствах
  • Получить индекс ввода в списке
  • XOR индекс с 1
  • Получить элемент в списке по этому индексу
Emigna
источник
42
14 байт короче длины всех слов. Что вообще это за язык?
DJMcMayhem
65
> Толкни струну,ignorance strength war peace freedom slavery я чувствую, что пропустил около десятка шагов!
Боб
31
i.imgur.com/vI4ZIfW.jpg
Павел
10
Кто-нибудь может объяснить, откуда взялись остальные слова, помимо «невежества»?
Carcigenicate
36
05AB1E имеет встроенный словарь слов, каждый из которых представлен двумя байтами: github.com/Adriandmen/05AB1E/blob/master/dictionary.py
Роберт Фрейзер,
47

JavaScript (ES6), 80 байт

s=>'freedom,,war,,strength,,slavery,peace,ignorance'.split`,`[s.charCodeAt(1)%9]

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

Мы используем небольшую таблицу поиска, основанную на коде ASCII 2-го символа каждого слова, возвращая индекс его аналога.

Word      | 2nd char. | ASCII code | MOD 9
----------+-----------+------------+------
war       | a         | 97         | 7
peace     | e         | 101        | 2
freedom   | r         | 114        | 6
slavery   | l         | 108        | 0
ignorance | g         | 103        | 4
strength  | t         | 116        | 8

В качестве примечания, если бы разрешался смешанный регистр, использование war PEACE FREEDOM slavery IGNORANCE strengthс модулем 6 привело бы к идеальному хешу.

Контрольная работа

Arnauld
источник
2
Это классный подход. Никогда бы не подумал об этом.
Carcigenicate
Очень хорошо. Остатки не различимы для 6, 7, 8, поэтому вам нужно 9.
ShreevatsaR
Использование разделителя, как zи сжатие строки с atobсохранением 8 байтов?
вниз
@ Downgoat Разве это не потребует большого количества экранирования для символов за пределами диапазона 32-126?
Арно
используя atobвы получите строку, которая в основном является допустимым javascript - в конце концов вам нужно экранировать только `\` и заключительную кавычку. Может быть трудно разместить его на этом сайте, но это не лишает законной силы ответ. Смотрите ответ perl от smis
edc65
32

Желе , 24 байта

“Ñ=ƘḊ¹ƥ¹Ƙ⁷ṅ8cøGị»Ḳµiɠ^1ị

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

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

Во-первых, токен

“Ñ=ƘḊ¹ƥ¹Ƙ⁷ṅ8cøGị»

индексы в словарь желе, чтобы создать строку

strength war peace freedom slavery ignorance

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

["strength", "war", "peace", "freedom", "slavery", "ignorance"]

µ начинается новая монадическая цепочка с этим строковым массивом в качестве аргумента, который также является текущим возвращаемым значением.

ɠчитает одну строку ввода из STDIN и iнаходит его индекс предыдущего возвращаемого значения, то есть сгенерированного массива строк.

Теперь, ^1принимает побитовый XOR этого индекса и 1 . Для четных индексов - помните , что индексы Желе являются 1 -А и модульным, поэтому сила имеет индекс 1 и невежество имеет индекс 6 / 0 - это увеличивает индекс; для нечетных индексов это уменьшает их.

Наконец, извлекает строку с этим индексом из аргумента цепочки.

Деннис
источник
16

Mathematica, 84 байта

(x="war""peace")(y="freedom""slavery")(z="ignorance""strength")/#/.x->1/.y->1/.z->1&

объяснение

Больше "арифметики" со строками! Как и в связанном ответе, это основано на том факте, что вы можете «умножать» строки в Mathematica, что оставит их неоцененными (аналогично умножению двух неназначенных переменных x*y), но Mathematica будет применять базовые упрощения, такие как факторы отмены в делении.

Таким образом , мы начинаем хранить три пары в качестве продуктов в x, y, z, соответственно , и умножить их все вместе:

(x="war""peace")(y="freedom""slavery")(z="ignorance""strength")

Это оценивает

"freedom" "ignorance" "peace" "slavery" "strength" "war"

(Mathematica автоматически сортирует факторы, но нас не волнует порядок.)

Мы делим это на вход, чтобы удалить слово, которое нам не нужно .../#, так как Mathematica отменяет факторы. Например, если бы ввод был, "peace"мы бы в итоге:

"freedom" "ignorance" "slavery" "strength" "war"

Наконец, мы избавляемся от пар , мы не заинтересованы, путем замены каждого из x, yи zс 1. Опять же, упрощение Mathematica в этом 1*aвсегда a. Эта часть сделана с:

/.x->1/.y->1/.z->1

Хорошая вещь заключается в том, что Mathematica знает, что умножение Orderlessтаково, что он найдет два фактора независимо от того, являются ли они смежными в продукте или нет. Только слово, противоположное входу, больше не соединено в продукте, поэтому оно не будет удалено и останется единственным выходом.

Мартин Эндер
источник
Ах, молодец! Я проигрываю на 7 байтов с WordList[][[<|"l"->14007,"t"->17083,"a"->25105,"r"->32106,"g"->33790,"e"->39048|>@#[[2]]]]&.
Грег Мартин
@GregMartin О, WordListхорошо. Взять список символов в качестве входных данных и вернуть строку, хотя и немного странно. ;) Тем не менее, вы можете сделать 4 байта лучше с x[[7-Position[x={"war","slavery","ignorance","strength","freedom","peace"},#][[1,1]]]]&.
Мартин Эндер
Меня заинтересует ваше мнение, но мне кажется, что это хитроумно санкционировано PP & CG :)
Грег Мартин
также <|#->#2&~MapThread~{x={"war","slavery","ignorance","strength","fre‌edom","peace"},Reverse@x}|>для 94 байтов
Грег Мартин
13

Vim, 60 байт

D3iwar freedom ignorance peace slavery strength <esc>2?<C-r>"
3wdwVp

Попробуйте онлайн! в обратно совместимом V-интерпретаторе.

Конечно, если бы мы переключились на V, мы могли бы сохранить один байт , используя более удобный метод ввода. Но так как это такая небольшая разница, я бы предпочел использовать версию без игры в гольф.

Объяснение:

D                       " Delete this whole line
 3i...<esc>             " Insert the text three times
           2?           " Search backwards twice
             <C-r>"     " For the words we deleted
3w                      " Move three words forward
  dw                    " Delete a word
    V                   " Select this whole line
     p                  " And paste the word we deleted over it
DJMcMayhem
источник
10

C (gcc) , 120 107 байтов

f(long*s){long r[2]={0};strcpy(r,s);s=*r>>40?*r>>56?"\n":"":"CE";*r^=*s;r[1]^=69;puts(r);}

Максимальное злоупотребление указателем! Требуется машина с прямым порядком байтов и 64-битные значения.

Код содержит несколько непечатных документов, но копирование должно работать.

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

Деннис
источник
8

Python, 81 байт

l='war peace freedom slavery ignorance strength'.split()
lambda s:l[l.index(s)^1]

Или той же длины:

l='war slavery ignorance strength freedom peace'.split()
dict(zip(l,l[::-1])).get
XNOR
источник
Разрешены ли определения переменных за пределами лямбы при использовании лямбды вместо полной программы?
Смс
1
@smls Да, посмотрите эту мета-дискуссию . Обратите внимание, что даже в противном случае можно ввести контрабанду в lкачестве необязательного аргумента.
xnor
8

Perl 6 , 61 байт

С непечатными символами, обозначенными как Sta (потому что StackExchange удаляет их в противном случае):

{first {s/^\w+<(\0*$//},["���ce","�������","���
����e"X~^$_]}

Вот xxdшестнадцатеричный дамп:

00000000: 7b66 6972 7374 207b 732f 5e5c 772b 3c28  {first {s/^\w+<(
00000010: 5c30 2a24 2f2f 7d2c 5b22 0704 1363 6522  \0*$//},["...ce"
00000020: 2c22 151e 0413 011d 1422 2c22 1a13 1c0a  ,".......","....
00000030: 1c06 1a0b 6522 587e 5e24 5f5d 7d0a       ....e"X~^$_]}.

Расширенная версия (непечатные символы заменены на escape-последовательности, добавлены пробелы и комментарии):

{    # A Lambda.
    first {                   # Return first element which:
        s/ ^ \w+ <( \0* $ //  #   after stripping \0 has only word characters left.
    },
    [                                                  # The array to search:
        "\x[7]\x[4]\x[13]ce",                          #   "war" xor "peace"
        "\x[15]\x[1e]\x[4]\x[13]\x[1]\x[1d]\x[14]",    #   "freedom" xor "slavery"
        "\x[1a]\x[13]\x[1c]\n\x[1c]\x[6]\x[1a]\x[b]e"  #   "ignorance" xor "strength"
        X~^ $_                                         #   each xor'ed with the input.
    ]
}
SMLS
источник
8

Баш , 100 87 86 78 байт

a=peace;e=war;r=slavery;l=freedom;g=strength;t=ignorance;x=${1:1:1};echo ${!x}

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

2-я буква каждого слова однозначно идентифицирует это слово, поэтому я использую этот символ в качестве имени переменной; значение этой переменной является соответствующим другим словом.

Например, 2-я буква peaceis e, и слово, соответствующее peaceis war, поэтому я установил e=war.

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

Митчелл Спектор
источник
8

TI-Basic, 103 84 77 байт

Сокращение до одной строки сэкономило много байтов! Ха-ха, как иронично было это утверждение ...

inString("EALRGT",sub(Ans,2,1
sub("WAR  PEACE FREEDOMSLAVERY STRENGTH IGNORANCE ",9Ans+1,4+Ans
Timtech
источник
7

Perl , 63 байта

62 байта + -pфлаг.

$_=(slavery,freedom,ignorance,strength,war,peace)[(ord)%6+/h/]

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

ordвозвращает код символа первого символа входного слова.
После %6мы имеем:

- свобода => ord = 102 =>% 6 = 0  
- рабство => ord = 115 =>% 6 = 1  
- невежество => ord = 105 =>% 6 = 3  
- прочность => ord = 115 =>% 6 = 1  
- война => орд = 119 =>% 6 = 5  
- мир => ord = 112 =>% 6 = 4  

Таким образом , у нас есть slaveryи strengthкак возвращение 1 (так как они оба начинаются с той же буквы), и никто не возвращался 2. Таким образом, мы добавим 1к strength(это единственное слово , которое будет соответствовать /h/), и мы имеем каждое слово переведенный с индексом от 0 до 5.

папа
источник
6

R 86 87 92 байта

Изменено на безымянную функцию и gsubна subнесколько байтов. В grepопределяет , какая из 3 -х строк используются , и входной удаляются из этой строки с sub.

function(v)sub(v,'',(l=c("warpeace","freedomslavery","ignorancestrength"))[grep(v,l)])
MickyT
источник
5

PHP, 70 байт

<?=[ignorance,peace,slavery,strength,freedom,war][md5("^$argv[1]")%7];
user63956
источник
5

Befunge, 89 88 байт

<>_00g1v2+%7~%2~"slavery"0"war"0"freedom"0"ignorance"0"strength"0"peace"
 |p00:-<
@>:#,_

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

объяснение

Исходный код с выделенными путями выполнения

*Мы начинаем с того, что помещаем в стек все возможные выходные строки с нулевым завершением. Эта последовательность выполняется справа налево, поэтому значения перемещаются в обратном порядке, поскольку в этом порядке символы будут необходимы, когда они в конечном итоге будут выведены.
*Затем мы читаем первые два символа из stdin, и это все, что нам нужно для идентификации входной строки. Если мы возьмем значение ASCII первой буквы mod 2 плюс вторую букву mod 7, мы получим уникальное число в диапазоне от 2 до 7.

Input         ASCII      %2 %7   Sum
[fr]eedom     102 114    0  2    2
[pe]ace       112 101    0  3    3
[sl]avery     115 108    1  3    4
[st]rength    115 116    1  4    5
[ig]norance   105 103    1  5    6
[wa]r         119 97     1  6    7

*Этот номер может затем использоваться как своего рода индекс в списке строк в стеке. Мы итеративно уменьшаем индекс (в первый раз на 2), и для каждой итерации мы очищаем одну строку из стека с последовательностью >_.
*Как только индекс достигнет нуля, у нас останется правильная выходная строка в верхней части стека, поэтому мы используем простую последовательность выходных строк, чтобы записать результат в стандартный вывод.

Джеймс Холдернесс
источник
2
Мне нравится использование :-<и @>:#«смайлики» здесь :)
Тобиас Кинцлер
5

Пайк, 29 байт

.d⻌૽ɦڷࠛ⯤dci@1.^iR@

Попробуй это здесь!

.d⻌૽ɦڷࠛ⯤           -     "war peace freedom slavery ignorance strength"
         dc         -     ^.split(" ")
           i        -    i=^
            @       -   ^.find(input)
             1.^    -  ^ xor 1
                iR@ - input[^]
синий
источник
5

С, 93

@ Ответ Арно, портированный на C

#define F(w)(char*[]){"freedom",0,"war",0,"strength",0,"slavery","peace","ignorance"}[w[1]%9]
edc65
источник
4

C (gcc) , 113 108 байтов

f(char*s){char*t="5WAR\0+PEACE\09FREEDOM\0'SLAVERY\0;IGNORANCE\0%STRENGTH";while(strcmp(s,++t));puts(t+*--t-47);}

Все экземпляры \0могут быть заменены фактическими байтами NUL для целей оценки.

t+*--t-47неопределенное поведение; это может / не будет работать с другими компиляторами.

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

Деннис
источник
4

JavaScript (ES6), 71 78

Так скучно, как ответ Арно, но и короче.

Теперь я добавил кодировку с btoa. В закодированной строке есть 4 байта, которые я не могу опубликовать на этом сайте, даже если они являются допустимыми символами в строке javascript. Поэтому я использовал шестнадцатеричный escape в форме \xHH. Каждое из этих побегов считается за 1 байт.

Закодированная строка strength0ignorance0peace0war0slavery0freedom

x=>(w=btoa`²ÚÞ\x9e\x0baÒ('¢¶§qí)y§\x1eÓ\x06«ÒÉZ½êòÑúÞyÚ&`.split(0))[w.indexOf(x)^1]

Это 82 и без учета регистра

x=>',,strength,,slavery,war,,,ignorance,peace,freedom'.split`,`[parseInt(x,36)%15]

Контрольная работа

F=
x=>(w=btoa`²ÚÞ\x9e\x0baÒ('¢¶§qí)y§\x1eÓ\x06«ÒÉZ½êòÑúÞyÚ&`.split(0))[w.indexOf(x)^1]

;['freedom','slavery','war','peace','ignorance','strength']
.forEach(w=>console.log(w + ' -> ' + F(w)))

edc65
источник
3

CJam, 52 (только ASCII)

"/.|Mv
DO'y    EK{ {:nBct'Pt}d4sE"144b26b'af+'j/_ra#1^=

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

Примечание: космические объекты - это символы табуляции (один до и один после "EK {")

Объяснение:

Часть до «+» распаковывает строку «slaveryjfreedomjwarjpeacejignorancejstrength», используя базовое преобразование:
строка (обрабатывается как массив кодов символов) → (базовое 144) число → (базовое 26) массив чисел → (добавление «a» к каждому число) строка

'j/    split around 'j' characters
_      duplicate the resulting word array
ra     read the input and wrap in array
#      find the index of the input in the word array
1^     XOR with 1
=      get the word at the new index
aditsu
источник
3

> <> (Рыба), 84 78 байт

0i~ia%.
v'raw'
>ol?!;
^'htgnerts'
^'yrevals'

^'ecnarongi'
^'ecaep'
^'modeerf'

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

Мы начинаем плавать сверху слева, направляясь вправо. Сначала мы загружаем стек с 0. Затем мы читаем первую букву input ( i), отбрасываем его ( ~), читаем вторую букву ( i) и уменьшаем его значение ASCII по модулю 10 ( a%). Это отображает a, e, r, l, g и t на 7, 1, 4, 8, 3 и 6 соответственно - давайте назовем это число N. .Выдвинем два значения из стека - N и 0 - и перейдем к строка N, символ 0.

После прыжка рыба выполняет один такт перед выполнением инструкций, поэтому игнорирует первый символ и пересекает строку N, которая загружает соответствующее слово в стек. Наконец, мы переходим к строке 2, которая выводит весь стек и завершает работу.

  • Сэкономили шесть байтов, используя переход, вместо того, чтобы использовать классную модификацию кода, которую я использовал ранее. Ну что ж.
Ник Маттео
источник
3

JavaScript, 78 байт

w=>(a="war slavery ignorance strength freedom peace".split` `)[5-a.indexOf(w)]

Это своего рода порт моего ответа на Python . Мы храним слова в строке, где каждое находится в противоположной позиции по отношению к своему аналогу. Мы находим индекс данного слова wи получаем этот индекс с конца, чтобы вернуть результат.

Тестовый фрагмент:

f = w=>(a="war slavery ignorance strength freedom peace".split` `)[5-a.indexOf(w)]

console.log(f("peace"))
console.log(f("ignorance"))
console.log(f("war"))

FlipTack
источник
2

Par / GP, 86 байт

Pari / GP - интерактивный интерпретатор, нам не нужен «print» -cmd для вывода; однако для утилиты Try-It_Online требуется "print" -cmd, поэтому я разделил ее на "нижний колонтитул".
Мы определяем «объект-функцию» (буква O мне очень напоминает функцию Оруэлла ... ;-)):

x.O=s=[war,freedom,ignorance,strength,slavery,peace];for(k=1,6,if(x==s[k],i=7-k));s[i]

После этого позвоните

print(war.O)   \\ input to Pari/GP with the O-rwell-member of "war"
       peace   \\ output by Pari/GP

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

(Обратите внимание, что в Pari / GP приведенные здесь токены являются не строками, а допустимыми именами переменных! Этим переменным никогда не должно назначаться какое-либо значение)

Готфрид Хелмс
источник
2

С накоплением, 70 байт

@x'war
strength
freedom
slavery
ignorance
peace'LF split:x index\rev\#

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

'war'

@x'war
strength
freedom
slavery
ignorance
peace'LF split:x index\rev\#

out

Этот код довольно понятен. Немного изменен для запуска всех тестовых случаев:

('war' 'slavery' 'ignorance')
{x:'war
strength
freedom
slavery
ignorance
peace'LF split:x index\rev\#x\,}"!
disp
Конор О'Брайен
источник
1
что делает 'LF?
вниз
1
@Downgoat Хорошо, @xустанавливает переменную, '...'является строкой и LFявляется переменной перевода строки
Конор О'Брайен
1
Ах, я вижу, поэтому аргумент функции стоит перед именем функции?
вниз
1
@ Downgoat Точно. С накоплением, ну, на основе стека.
Конор О'Брайен
1
теперь я чувствую себя глупо, не осознавая такой очевидный факт: |
вниз
2

Джольф, 35 байт

.γG"ΞΠΞ¦ΞpΞsΞΈΞ3I"-5 iγ

Есть много непечатных. Вот hexdump, хотя он не принесет много пользы:

00000000: 2ece b347 22ce 9e07 cea0 c28e ce9e 07c2  ...G"...........
00000010: 8ac2 a6ce 9e06 c28e 70ce 9e07 73c2 8fce  ........p...s...
00000020: 9e06 ce88 c280 ce9e 0133 4922 052d 3520  .........3I".-5
00000030: 69ce b3                                  i..

Вот онлайн-ссылка.

В основном код выглядит так:

.γG"..."♣-5 iγ
  G"..."♣        split uncompressed string on spaces
 γ               set gamma to this
            iγ   index of the input in gamma
.γ       -5      and get 5 - this from gamma
Конор О'Брайен
источник
2

На самом деле 56 байтов

' "war peace freedom slavery ignorance strength"s;)í1^@E

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

К сожалению, без каких-либо встроенных функций сжатия короче не сжимать строку и не распаковывать ее вручную.

Объяснение:

' "war peace freedom slavery ignorance strength"s;)í1^@E
' "war peace freedom slavery ignorance strength"s         split the string on spaces
                                                 ;)       make a copy, push it to the bottom of the stack
                                                   í      index of input in list
                                                    1^    XOR with 1
                                                      @E  that element in the list
Мего
источник
2

Haskell, 104 111 байтов

data O=WAR|FREEDOM|IGNORANCE|PEACE|SLAVERY|STRENGTH deriving(Show,Enum)
f s=toEnum$mod(3+fromEnum s)6::O

Идея:

  • Перечислите ключевые слова так, чтобы их аналог находился на 3 позиции
  • Возьмите ключевое слово, найдите его позицию fromEnum, переместите 3 шага вправо (модуль 6) и преобразуйте обратно в ключевое слово
  • ::OНеобходимо потому , что определение типа имеют некоторые проблемы. Предоставление fподписи f :: O -> Oбудет иметь тот же эффект , но это не то, что короткий.

Редактировать:

Заменены

f s=toEnum$mod(3+fromEnum s)6

по

f=toEnum.(`mod`6).(+3).fromEnum

спасибо @Laikoni.

user3389669
источник
2
Использование точечной нотации для fкороче:f s=toEnum$mod(3+fromEnum s)6
Laikoni
2

Дьялог АПЛ , 66 байт

Любой из них:

'slavery' 'freedom' 'ignorance' 'strength' 'war' 'peace'⊃⍨6|⎕UCS⊃⍞использует этот метод (требуется, ⎕IO←0который используется по умолчанию во многих системах).

'strength' 'freedom' 'war' 'peace' 'slavery' 'ignorance'(⍳⊃(⌽⊣))⊂⍞ выполняет поиск, а затем выбирает соответствующий элемент из обращенного списка.

Адам
источник
2

Qbasic, 138 99 байт

D$="ignorancefreedom  peace    strength slavery  war      ":INPUT A$:?MID$(D$+D$,INSTR(D$,A$)+27,9)

D$хранит все слова с левой стороны мантры, а затем все слова с правой стороны. Каждое слово дополняется пробелами до 9 букв на слово. D$затем добавляется к себе.

Затем instrиспользуется для поиска индекса слова, введенного пользователем. Другая часть мантры всегда хранится точно в 9 * 3 позициях далее в строке, поэтому мы печатаем подстроку, начинающуюся с этой позиции, принимая 9 символов.

steenbergh
источник
2

SmileBASIC, 92 байта

A$="PEACE
E$="WAR
R$="SLAVERY
L$="FREEDOM
G$="STRENGTH
T$="IGNORANCE
INPUT I$?VAR(I$[1]+"$")
12Me21
источник
2

Python , 80 байт

Каким-то образом обошел кснор!

Это безымянная лямбда-функция, которая возвращает результат.

lambda w,a="war slavery ignorance strength freedom peace".split():a[~a.index(w)]

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

Список слов организован так, что каждое из них находится в противоположной позиции по отношению к своему аналогу. По данному слову wмы находим его индекс в списке слов, а затем поразрядно НЕ ( ~) его. Это переворачивает все биты, которые вычисляются n => -n-1. Из-за отрицательной индексации Python получает противоположный индекс в списке.

В качестве своего рода непреднамеренного бонуса вы можете передать любой список слов противоположностей этой функции в качестве второго аргумента.

FlipTack
источник