Битфлип и отрицание


42

Если задано целое число, создайте выражение, которое создает его из 0унарного отрицания -и побитового дополнения ~( ~n= -n-1), причем операторы применяются справа налево.

...
-3  = ~-~-~0
-2  = ~-~0
-1  = ~0
 0  = 0
 1  = -~0
 2  = -~-~0
 3  = -~-~-~0
...

Ваше выражение должно быть как можно короче, что означает отсутствие избыточных частей ~~, --, -0или 00. Выведите или напечатайте выражение в виде строки или последовательности символов.



1
пробелы между ~ и 0 разрешены?
Адам

Нет, выведите строки точно.
xnor

2
Обязательный xkcd.com/153
Джаред Смит

Ответы:


17

Python, 32 байта

lambda x:("-~"*abs(x))[x<0:]+"0"

Анонимная лямбда-функция. Учитывая, что целое число x записывает «- ~» abs (x) раз и удаляет первый символ, если x отрицательно, то в конце добавляется ноль.


Ой, бей меня к этому.
mbomb007

Я тоже написал тоже самое - nвместо xи 'вместо ":)
Джонатан Аллан

2
@JonathanAllan Тогда ты можешь смело считать это обманом.
Эрик Outgolfer

16

JavaScript (ES6), 33 31 байт

f=x=>x<0?"~"+f(~x):x&&"-"+f(-x)

Рекурсия <встроенные <циклы (по крайней мере, в этом случае). В основном не оценивает входные данные:

  • если оно меньше 0, переверните его и добавьте ~к строке;
  • если оно больше 0, отрицайте его и добавьте -к строке;
  • если это точно 0, верните 0.

Использует преимущества этого шаблона:

 0         = 0
-1 = ~( 0) = ~0
+1 = -(-1) = -~0
-2 = ~(+1) = ~-~0
+2 = -(-2) = -~-~0
-3 = ~(+2) = ~-~-~0
+3 = -(-3) = -~-~-~0
etc.

11

Pyth, 14 13 12 байт

_<>0Q+0sm"~-

-2 байта благодаря @StevenH.

тестирование

Решил попробовать Pyth, так что я перевел свой ответ на Python . Любая помощь приветствуется!

Объяснение:

_<>0Q+0sm"~-     
        m"~-     # Map "~-" onto the input (= a list of n times "~-").
       s         # Join the list to a string.
     +0          # Add "0" in front. 
 <>0Q            # Slice off the last char if the input is negative.
_                # Reverse the whole thing.

Используйте неявный ввод в конце, чтобы сохранить один байт: >0вместо<Q0
Стивен Х.

@StevenH. Спасибо! Теперь мы находимся в связи с кратчайшим ответом!
КарлКастор

2
Совсем другое решение (которое, к сожалению, не сохраняет байты):tW>0Q_+0sm"~-
Стивен Х.

2
@StevenH. Гольф ваш решение до 12: _<>0Q+0sm"~-я надеюсь, что вы хорошо со мной, добавив это к моему решению.
КарлКастор

8

C, 46 байтов

m(x){putchar(x?x<0?126:45:48);x&&m(-x-(x<0));}

В отличие от большинства (всех?) Других ответов, этот выводит операторы ~и -один за другим.



7

Сетчатка, 19 17 байт

Замените число на одинарное, с нулем на конце. Заменить каждый 1на -~. Удалите двойной негатив, если он есть.

\d+
$*10
1
-~
--

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

Все тестовые случаи одновременно (слегка измененная программа для поддержки нескольких тестовых случаев)



7

Perl 38 35 33 (23 + 1 для -p) 24

s/\d+/"-~"x$&.0/e;s;--;

-13 благодаря Дада


Вы, вероятно, имели в виду, -pа не -r. Также вы можете избавиться от тех последних скобок и точки с запятой: if$h<0достаточно.
Дада

Я сделал, спасибо. Думаю, я написал слишком много ответов в формате sed.
Райли

Возможно, да. (Избавьтесь от последних 2 скобок тоже)
Дада

Вы также можете сохранить 2 байта, выполнив $h<0&&s;.;вместо s/.// if $h<0. ( -pдобавляет ;в конце кода, так что нет необходимости в последнем ;из s;.;;. И a if bпримерно эквивалентно b && a, но в этом случае это экономит вам один байт, потому что вы можете удалить пробел)
Dada

Спасибо, я не знал -p добавил ;тоже.
Райли

6

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

'0',⍨0∘>↓'-~'⍴⍨2×|

'0',⍨ нулевой символ добавляется к

0∘> отрицательность (то есть 1 для чисел ниже 0; 0 для нуля и выше)

упал с

'-~'⍴⍨ строка "~ -" циклически преобразуется в длину

два раза

| абсолютное значение

+ плюс

0∘< положительность (то есть 1 для чисел выше 0)

Попробуй APL онлайн!


6

Haskell, 41 байт

f n=['-'|n>0]++(tail$[1..abs n]>>"-~")++"0"

f n|n<0=tail$f(-n)|x<-[1..n]>>"-~"=x++"0"

Спасибо Ними за 3 байта


tailтерпит неудачу для n=0. Вы можете использовать drop 1вместо этого.
Ними,

@nimi Спасибо; Я понятия не имею, как я это пропустил ..
BlackCap

1
Не тратьте иначе караул : f n|n<0=tail.f$abs n|x<-[1..n]>>"-~"=x++"0".
Ними

1
2 байта для сохранения: ...|n<0=tail$f(-n)|....
Ними,

5

V , 21 байт

/ä
é
D@"ña-~ñá0kgJó--

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

У V очень ограниченная числовая поддержка, и он на самом деле не имеет понятия отрицательных чисел. Это означает, что для поддержки негативов (или даже 0) мы должны использовать некоторые обходные пути.

Объяснение:

/ä                  "Move forward to the first digit
é                   "And enter a newline
D                   "Delete this number, into register '"'
 @"                 "That number times:
   ñ   ñ            "Repeat the following:
    a               "  Append the string:
     -~             "  '-~'
        á0          "Append a 0
          k         "Move up a line
           gJ       "And join these two lines together
             ó--    "Remove the text '--', if it exists

5

JavaScript (ES6), 39 37 байт

x=>"-~".repeat(x<0?-x:x).slice(x<0)+0

Сохранено 2 байта благодаря @Neil


5

Желе , 10 байт

A⁾-~ẋḊẋ¡N0

Это полная программа. Попробуйте онлайн!

Как это работает

A⁾-~ẋḊẋ¡N0  Main link. Argument: n

A           Take the absolute value of n.
 ⁾-~ẋ       Repeat the string "-~" that many times. Result: s
       ¡    Conditional application:
     Ḋ        Dequeue; remove the first element of s...
      ẋ N     if s, repeated -n times, is non-empty.
         0  Print the previous return value. Set the return value to 0.
            (implicit) Print the final return value.

5

Java 7, 95 79 байт

79 байтов:

String s(int x){String t=x<0?"~":"";while((x<0?++x:x--)!=0)t+="-~";return t+0;}

Ungolfed:

String s(int x) {
    String t = x<0 ? "~" : "";
    while((x<0 ? ++x : x--) != 0)
        t += "-~";
    return t+0;
}

Старая версия (95 байт):

String s(int x){return new String(new char[x<0?-x:x]).replace("\0","-~").substring(x<0?1:0)+0;}

Использование:

class A {
    public static void main(String[]a) {
        System.out.println(s(-3));
        System.out.println(s(-2));
        System.out.println(s(-1));
        System.out.println(s(0));
        System.out.println(s(1));
        System.out.println(s(2));
        System.out.println(s(3));
    }
    static String s(int x){String t=x<0?"~":"";while((x<0?++x:x--)!=0)t+="-~";return t+0;}
}

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

Выход:

~-~-~0
~-~0
~0
0
-~0
-~-~0
-~-~-~0

Привет и добро пожаловать в PPCG! Хороший первый пост!
Rɪᴋᴇʀ

Добро пожаловать в PPCG! Хм, это более короткое решение, чем у меня, поэтому я удалю свой ответ и вместо него добавлю ответ. :)
Кевин Круйссен


3

EXCEL: 55 33 байта

=REPT("-~",IF(A1>0,A1,ABS(A1)-1))&"0"

Ввод осуществляется в форме помещения числа в ячейку A1. Формула может пойти куда угодно, кроме А1.


Я не думаю, что это работает для отрицательных чисел ...
Pajonk

3

T-SQL, 87 байт

select substring(replicate('-~',abs(x)),case when x<0then 2 else 1 end,x*x+1)+'0'from #

x*x+1Условие подстроки достаточно, так как x^2+1>=2*abs(x)для всех x.

Как обычно в SQL, входные данные хранятся в таблице:

create table # (x int)

insert into # values (0)
insert into # values (1)
insert into # values (-1)
insert into # values (2)
insert into # values (-2)

3

CJam , 18 14 байтов

Получил вдохновение от ответа Эминьи, чтобы сэкономить 4 байта.

li_z"-~"*\0<>0

Попробуйте онлайн! (Как набор тестов с разделением строк).

объяснение

li      e# Read input and convert to integer N.
_z      e# Duplicate and get |N|.
"-~"*   e# Repeat this string |N| times.
\0<     e# Use the other copy of N to check if it's negative.
>       e# If so, discard the first '-'.
0       e# Put a 0 at the end.

3

Vim - 31 нажатие клавиш

Первый vim golf, пропустил кучу вещей.

`i-~<esc>:s/-\~-/\~-/dwp<left>ii<esc><left>d$@"<esc>a0`

Здорово, добро пожаловать в клуб! :) Вы могли бы сделать :s/^-вместо :s/-\~/\~-и Dвместоd$
DJMcMayhem

Теперь, когда я думаю об этом, я не думаю, что это обрабатывает 0. Вы можете обойти это, увеличивая значение перед удалением с помощью, <C-a>а затем удаляя два символа в конце.
DJMcMayhem

@DJMcMayhem ах, 0iне работает?
Maltysen

Нет, к сожалению нет. 0перемещает курсор на первый символ в текущей строке. Вы можете использовать 0 как счет в V, хотя.
DJMcMayhem



2

Perl 6 , 25 байт

{substr '-~'x.abs~0,0>$_}

Объяснение:

{
  substr
    # string repeat 「-~」 by the absolute value of the input
    '-~' x .abs

    # concatenate 0 to that
    ~ 0

    ,

    # ignore the first character of the string if it is negative
    0 > $_
}

2

Желе, 14 12 байт

-2 байта благодаря @Dennis (верните 0 вместо конкатенации "0", делая это только полной программой.)

0>‘
A⁾-~ẋṫÇ0

Проверьте это в TryItOnline

Как?

0>‘      - link 1 takes an argument, the input
0>       - greater than 0? 1 if true 0 if false
  ‘      - increment

A⁾-~ẋṫÇ0 - main link takes an argument, the input
      Ç  - y = result of previous link as a monad
A        - x = absolute value of input
 ⁾-~     - the string "-~"
    ẋ    - repeat the sting x times
     ṫ   - tail repeatedString[y:] (y will be 1 or 2, Jelly lists are 1-based)
       0 - implicit print then return 0

2

> <>, 18 + 3 = 22 байта

:?!n0$-:0):1go-
-~

Попробуйте онлайн! +3 байта для ​ -vфлага для инициализации стека с помощью ввода. Если предположить, что STDIN пуст, то все в порядке, тогда следующий код будет короче:

:?!ni*:0):1go-
-~

Программа продолжает перелистывать ввод по nмере необходимости, пока он не достигнет 0, после чего произойдет ошибка.

[Loop]
:?!n      If n is 0, output it as a num. If this happens then the stack is now
          empty, and the next subtraction fails
0$-       Subtract n from 0
:0)       Push (n > 0)
:1go      Output the char at (n>0, 1) which is a char from the second line
-         Subtract, overall updating n -> -n-(n>0)

2

Октава, 51 байт

x=input('');[("-~"'*[1:abs(x)>0])((x<0)+1:end),'0']

Сначала откровенно скопируйте подход Matlab с помощью @pajonk, а затем измените некоторые детали, переписав как «внешний продукт» между вектором единиц и символами «- ~» и злоупотребляя индексацией «на лету» (или чем она может быть Позволяет нам сохранить несколько байтов. Мне все еще немного больно, что я не могу заставить индексное выражение занимать меньше байтов.

Octave позволяет (i1) (i2) или даже (...) (i1) (i2) для индексации, где Matlab хочет, чтобы мы хранили переменные между индексами.

((x<0)+1:end)

слишком долго, чтобы описать «пропустить сначала, если». Должен быть лучший способ.


2

PseudoD , 688 579 521 байт

utilizar mate.pseudo
utilizar entsal.pseudo
adquirir n
adquirir a
adquirir r
adquirir i
fijar n a llamar LeerPalabra finargs
si son iguales n y CERO
escribir {0}
salir
fin
fijar a a llamar ValorAbsoluto n finargs
fijar i a CERO
si comparar Importar.Ent.Comparar n < CERO
fijar r a {~}
sino
fijar r a {-}
fin
mientras comparar Importar.Ent.Comparar i < a
escribir r finargs
si son iguales r y {~}
fijar r a {-}
Importar.Ent.Sumar i UNO i
sino
fijar r a {~}
fin
finbucle
si son iguales r y {~}
escribir {~}
fin
escribir {0}

Объясните:

Read a number from STDIN;
If the number is zero (0); Then:
    Writes 0 to STDOUT and exits;
End If;
If the number is less than zero (0); Then:
    Set the fill character to "~";
Else:
    Set the fill character to "-";
End If;
For i = 0; While i is less than abs(number); do:
    Write the fill character to STDOUT;
    If the fill character is "~":
        Set the fill character to "-"
        Increment i by one
    Else:
        Set the fill character to "~"
    End if;
End for;
If the fill character is "~"; Then:
    Write "~" to STDOUT;
End If;
Write "0" to STDOUT

1
Добро пожаловать в PPCG! Это так мало, как это получается? Я вижу некоторые длинные идентификаторы, которые вы, вероятно, могли бы сократить (от "relleno" до "r", menos relleno: P). Я думаю, что вы можете отбросить импорт для стандартной библиотеки, если это только функция или фрагмент кода. Он не запрашивает завершающий перевод новой строки на выходе, так что, возможно, вы можете изменить последнюю EscribeirLinea на Escribeir. Можете ли вы назначить функции более коротким именам ( adquirir e``fijar p a Escribir)?
Федерация с.



1

Лабиринт , 25 байт

`?+#~.
.  ; 6
54_"#2
  @!

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

объяснение

Мне действительно нравится поток управления в этом. IP проходит через цифру 8 (или, я думаю, фактически ∞) по коду, чтобы медленно уменьшить ввод 0при печати соответствующих символов.

Код начинается в левом верхнем углу и идет вправо. Сейчас `ничего не делает. ?читает входные данные и +добавляет их к неявному нулю ниже. Конечно, это тоже ничего не делает, но когда мы снова запустим этот код, он ?будет выдвигать ноль (потому что мы находимся в EOF), а +затем избавимся от этого ноля.

Затем #толкает глубину стека, просто чтобы убедиться, что в стеке есть положительное значение, заставляющее IP поворачиваться на юг, и ;снова отбрасывать его.

Это "неоперация и действует как основная ветвь кода. Можно выделить три случая:

  • Если текущее значение положительное, IP поворачивается направо (запад) и завершает один раунд левого цикла:

    _45.`?+
    _45      Push 45.
       .     Print as character '-'.
        `    Negate the current value (thereby applying the unary minus).
         ?+  Does nothing.
    
  • Если текущее значение отрицательно, IP поворачивается влево (восток) и запускается следующий код:

    #26.~
    #        Push stack depth, 1.
     26      Turn it into a 126.
       .     Print as character '~'.
        ~    Bitwise NOT of the current value (applying the ~).
    

    Обратите внимание, что эти два будут чередоваться (так как оба меняют знак входа), пока значение входа не уменьшится до нуля. В таком случае...

  • Когда текущее значение равно нулю, IP просто продолжает двигаться на юг, выполняет !и затем поворачивает на запад на @. !печатает 0и @завершает программу.

1

GolfScript ,30 24 20 байт

  • Сохранено 6 байтов благодаря xnor.
  • Сохранено 4 байта благодаря Денису.

~."-~"\abs*\0<{(;}*0

Входные данные: -5

Выход: -5 = ~-~-~-~-~0

объяснение

~.     # Input to integer and duplicate
"-~"   # We shall output a repetition of this string
\abs   # Move the input onto the stack and computes abs
*      # Multiply "-~" for abs(input) times
\      # Copy onto the stack the input
0<     # Is it less than 0?
{(;}*  # Yes: remove first '-' from the output
0      # Push 0

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


1
Вам не нужно печатать 2 = , только -~-~0.
xnor

1
Вы можете использовать {(;}*0вместо {(;}{}if 0.
Деннис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.