Разделите число на 3 без использования операторов *, /, +, -,%


48

Процитирую этот вопрос на SO (Spoiler alert!):

Этот вопрос был задан в интервью Oracle.

Как бы вы поделили число на 3 без использования операторов *, /, +, -,%?

Номер может быть подписан или не подписан.

Задача решаема, но посмотрите, сможете ли вы написать кратчайший код.

Правила:

  • Выполните необходимое целочисленное деление ( /3)
  • Не использовать операторы , не основанные на тексте *, /, +, -, или %(или их эквиваленты, такие как __div__или add()). Это также относится к операторам увеличения и уменьшения, например i++или i--. Использование операторов для объединения строк и форматирования в порядке. Использование этих символов для разных операторов, таких как унарный -оператор для отрицательных чисел, или *для представления указателя в C, тоже нормально.
  • Входное значение может быть сколь угодно большим (независимо от того, что ваша система может обработать), как положительным, так и отрицательным
  • Ввод может быть на STDIN или ARGV или введен любым другим способом
  • Создайте кратчайший код, который вы можете сделать выше

1
Как округлить результат при положительном результате? Как, когда отрицательный?
dfeuer

Ответы:


15

J, 45 44 10 символов

".,&'r3'":

Работает с негативами:

".,&'r3'": 15
5
   ".,&'r3'": _9
_3
   ".,&'r3'": 3e99
1e99

": - форматировать как текст

,&'r3'- дописать r3до конца

". - выполнить строку, например 15r3


1
Это работает, если вы делаете 3 3 3 #: 9. Похоже, вам нужно знать, как долго будет длиться ваше троичное число. _3]\i.также возможная отправная точка для чего-то, но я не знаю, будет ли это короче, чем ваше решение здесь. Проблема #_3]\i.в том, что она есть, в том, что она всегда округляется вверх, а не вниз.
Гарет

1
Может быть ##~3=_3#\i.для 11 персонажей?
Гарет

1
На самом деле, вы можете уменьшить свой до 10 символов с ##~0 0 1$~.
Гарет

1
Вы можете уменьшить это, используя крючок, 3#.}:(#:~$&3)но он все еще длиннее и не устраняет проблему отрицательного числа.
Гарет

1
Да, вы можете использовать функцию Power ^: или Agenda @. для замены ifили if...elseзамены. В этом случае вы можете использовать @.два глагола, связанные с символом «» (герундия на J-языке), чтобы выбрать один или другой в зависимости от условия.
Гарет

56

С 167503724710

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

Моя программа выводит следующий скрипт:

#!/usr/bin/env python3
import sys

# 71
sys.stdout.write('''#include <stdint.h>
#include <stdio.h>
int32_t div_by_3(int32_t input){''')

# 39 * 2**32
for i in range(-2**31, 2**31):
    # 18 + 11 + 10 = 39
    sys.stdout.write('if(input==%11d)return%10d;' % (i, i / 3))

# 95
sys.stdout.write(r'''return 7;}int main(int c,char**v){int32_t n=atoi(a[1]);printf("%d / 3 = %d\n",n, div_by_3(n));}''')

Количество символов: 71 + 39 * 2 ** 32 + 95 = 167503724710

Ориентиры

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

  • Время выполнения скрипта - запуск в ./test.py | pv --buffer-size=1M --average-rate > /dev/nullтечение около 30 секунд дает скорость около 14,8 МБ / с. Можно предположить, что скорость вывода приблизительно постоянна, поэтому время выполнения до завершения должно составлять около 167503724710 B / (14,8 * 1048576 B / s) ≈ 10794 с.
  • Время компиляции. Компилятор TCC утверждает, что компилирует код C со скоростью 29,6 МБ / с , что обеспечивает время компиляции 167503724710 B / (29,6 * 1048576 B / с) ≈ 5397 с. (Конечно, это может выполняться в конвейере со скриптом.)
  • Размер скомпилированного кода - я попытался оценить его, используя ./test.py | tcc -c - -o /dev/stdout | pv --buffer-size=1M --average-rate > /dev/null, но, похоже, tccничего не выводится, пока не прочитает весь исходный файл.
  • Использование памяти для запуска - поскольку алгоритм является линейным (а tcc не оптимизируется по всем строкам), накладные расходы памяти должны составлять всего несколько килобайт (кроме самого кода, конечно).

22
Это воплощение жесткого кодирования. ++++++++++
Джо З.

4
При этом я уверен, что если вы дадите им исходный файл объемом 160 ГБ и попросите их скомпилировать и протестировать его, они будут смотреть на вас, как на сумасшедшего.
Джо З.

16
Если бы мой начальник попросил меня вычислить деление на три без - + / *%, я бы подумал, что он сумасшедший.
Микаэль Майер

И еще, a[b]это синтаксический сахар *(a + b), который делает дополнение.
Конрад Боровски

12
@NicolasBarbulesco Существует ограничение размера ответов на Stack Exchange.
Timtech

38

Ruby 28

b=->n{n.to_s(3).chop.to_i 3}

Чтобы разделить на 3, нам просто нужно удалить конечный ноль в базовом числе 3: 120 -> 11110 -> 1111 -> 40

Работает с негативами:

ice distantstar:~/virt/golf [349:1]% ruby ./div3.rb
666
222
ice distantstar:~/virt/golf [349]% ruby ./div3.rb
-15        
-5

Руби, 60 45

В качестве альтернативы, без использования базового преобразования:

d = -> n {x = n.abs; r = (0..1.0 / 0) .step (3) .take (x) .index x; n> 0? r: -r}

d=->n{(r=1.step(n.abs,3).to_a.size);n>0?r:-r}

1
Альтернатива без преобразования базы имеет запрещенный /оператор, где Float::INFINITYстал 1.0/0. С Ruby 2.1 можно играть (0..1.0/0).step(3)в гольф 0.step(p,3), удаляя /. Большая проблема в том, что -rиспользуется -для отрицания. Это стоит 5 символов , чтобы изменить -rк ~r.pred, злоупотребляя Integer # пред вычитать 1 без оператора вычитания.
Керни

26

Mathematica, 13 символов

Mean@{#,0,0}&

Это зло: D Я думаю, вы могли бы сохранить &и использовать обычную переменную (другие тоже делают это).
Ив Клетт

3
@YvesKlett: значит, по сути, злой.
GuitarPicker

18

JavaScript, 56

alert(Array(-~prompt()).join().replace(/,,,/g,1).length)

Создает строку длины nповторения ,s и заменяет ,,,на 1. Затем он измеряет полученную длину строки. (Надеюсь, унарный -допускается!)


+1, но это не работает с отрицательными значениями
Francesco Casula

Вопрос ... как это считается? Он использует -оператор отрицания.
Патрик Робертс

@ Патрик Я понял, что спецификация означает отсутствие вычитания - если хотите, можете заменить -~наparseInt()
Кейси Чу

@CaseyChu значение, возвращаемое на -~prompt()единицу больше, чем parseInt(prompt()). Не уверен, как ты справишься с этим.
Патрик Робертс

alert(Array(parseInt(prompt())).slice(1).join().replace(/,,,/g,1).length)
Кейси Чу

16

Питон, 41 38

print"-"[x:]+`len(xrange(2,abs(x),3))`

xrange кажется, может обрабатывать большие числа (я думаю, что предел такой же, как для длинной в C) почти мгновенно.

>>> x = -72
-24

>>> x = 9223372036854775806
3074457345618258602

2
10/3равно 3, а не 4.
Джоэл Корнетт

Выполнение print" -"[x<0]+len (range (2, abs (x), 3)) `` сбрит его до 39 символов
Джоэл Корнетт

Форматирование комментариев в golfexchange все портит. на вышеупомянутом я использовал обратные кавычки, чтобы заключить в len()качестве сокращения дляrepr()
Джоэл Корнетт

Я обновил это. Я не могу использовать range, потому что это на самом деле создаст список. xrangeпросто притворяется, поэтому он может обрабатывать огромные числа, не тратя время и память.
grc

2
Притворись, что это Python 3;) Мне нравится, например, нарезка одного символа.
Джоэл Корнетт

11

Хаскелл, 90 106

d n=snd.head.dropWhile((/=n).fst)$zip([0..]>>=ν)([0..]>>=replicate 3>>=ν);ν q=[negate q,q]

Создает бесконечный (ленивый) список поиска [(0,0),(0,0),(-1,0),(1,0),(-2,0),(2,0),(-3,-1),(3,1), ...], обрезает все элементы, которые не совпадают n( /=это неравенство в Haskell), и возвращает первый, который соответствует.

Это становится намного проще, если нет отрицательных чисел:

25 27

(([0..]>>=replicate 3)!!)

просто возвращает nэлемент th списка [0,0,0,1,1,1,2, ...].


3
oO я никогда не думал об этом втором решении. Я мог бы реализовать что-то подобное в python
помощник

8

C #, 232 байта

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

class l:System.Collections.Generic.List<int>{}class p{static void Main(string[] g){int n=int.Parse(g[0]);l b,a=new l();b=new l();while(a.Count<n)a.Add(1);while(a.Count>2){a.RemoveRange(0,3);b.Add(1);}System.Console.Write(b.Count);}}

Ungolfed

class l : System.Collections.Generic.List<int>
{ }
class p
{
    static void Main(string[] g)
    {
        int n = int.Parse(g[0]);
        l b, a = new l();
        b = new l();
        while (a.Count < n) a.Add(1);
        while (a.Count > 2)
        {
            a.RemoveRange(0, 3);
            b.Add(1);
        }
        System.Console.Write(b.Count);
    }
}

2
Примерно через 5 лет. Вы можете сэкономить 1 байт, удалив из него пробел string[] g, превратив его вstring[]g
Metoniem

Цитата «Не используйте нетекстовые операторы *, /, +, - или% (или их эквиваленты, такие как div или add ()» - вы не используете эквивалент .Add?
Джонатан Фрех

@JonathanFrech Этот метод add не работает с двумя числами, он только добавляет значение в коллекцию
Embodiment of Ignorance

7

Perl (26 22)

$_=3x pop;say s|333||g

Эта версия (ab) использует движок регулярных выражений Perl. Он читает число как последний аргумент командной строки ( pop) и создает строку 3s этой длины ( "3" x $number). Оператор подстановки регулярных выражений ( s///здесь пишется с разными разделителями из-за правил головоломки и с gфлагом lobal) заменяет три символа пустой строкой и возвращает количество подстановок, которое представляет собой входное число, деленное целым числом на три. Можно даже написать без 3, но вышеприведенная версия выглядит смешнее.

$ perl -E '$_=3x pop;say s|333||g' 42
14

2
Привет @ memowe, хорошая работа! Вы можете сохранить еще несколько символов (4), выполнив $_=3x pop;say s|333||g.
Дом Гастингс

2
Когда ввод равен 0, 1 или 2, он печатает пустую строку. Если нужно напечатать 0, то она нуждается в более 3 -х символов (25 всего): '$_=3x pop;say s|333||g||0. Медленно с большими числами, такими как 99999999, и не работает с отрицательными числами.
Керни

1
Используйте -pв командной строке, и вы можете сделать: $_=3x$_;$_=0|s|...||gв общей сложности 22, в том числе охват 0, 1 или 2 входа.
Xcali

6

C 160 символов

Символьное решение с длинным делением с использованием справочных таблиц, т.е. без строки atoi () или printf () для преобразования между строками 10 и целыми числами.

Выходные данные иногда включают ведущий ноль - часть его очарования.

main(int n,char**a){
char*s=a[1],*x=0;
if(*s==45)s=&s[1];
for(;*s;s=&s[1])n=&x[*s&15],x="036"[(int)x],*s=&x["000111222333"[n]&3],x="012012012012"[n]&3;
puts(a[1]);
}

Примечание:

  • злоупотребляет доступом к массиву для реализации добавления.
  • компилируется с помощью clang 4.0, другие компиляторы могут прерваться.

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

./a.out -6            -2
./a.out -5            -1
./a.out -4            -1
./a.out -3            -1
./a.out -2            -0
./a.out -1            -0
./a.out 0             0
./a.out 1             0
./a.out 2             0
./a.out 3             1
./a.out 4             1
./a.out 5             1
./a.out 6             2
./a.out 42            14
./a.out 2011          0670

6

Python 42

int(' -'[x<0]+str(len(range(2,abs(x),3))))

Так как каждое решение, опубликованное здесь, которое я проверил, усекает десятичные дроби здесь, это мое решение, которое делает это.

Python 50 51

int(' -'[x<0]+str(len(range([2,0][x<0],abs(x),3))))

Поскольку python выполняет разделение по полу, вот мое решение, которое реализует это.

Входное целое число находится в переменной x.

Протестировано в Python 2.7, но я подозреваю, что оно работает и в 3.


+1 За предложение обеих альтернатив ситуации с отрицательным значением. Поскольку ответов уже так много, я не буду корректировать спецификацию, чтобы исключить ту или иную опцию, хотя я бы лично согласился с тем, что -3это правильный ответ -10/3.
Гаффи

Для тех, кому небезразлично
Мэтт,

что с умножением и вычитанием в вашем втором решении?
Boothby

@boothby Второе решение реализует разделение по этажам. Я хотел сделать диапазон (0, abs (x), 3) для отрицательных чисел и диапазон (2, abs (x), 3) для положительных чисел. Для этого у меня был диапазон (2 ... затем я вычел 2, когда х отрицательный. Х <0 - Истина, когда х отрицательный, (Истина) * 2 == 2
Мэтт

Я не понимаю разницу между делением по полу и усечением десятичных дробей. Это связано с отрицательным делением?
Джоэл Корнетт

6

JavaScript, 55

alert(parseInt((~~prompt()).toString(3).slice(0,-1),3))

Если никто не может использовать -1, то вот версия, заменяющая его ~0(спасибо, Питер Тейлор!).

alert(parseInt((~~prompt()).toString(3).slice(0,~0),3))

1
@ArtemIce One ~- побитовый оператор, который инвертирует биты операнда (сначала преобразуя его в число). Это самый короткий способ преобразовать строку в число (насколько я знаю).
Inkbug

1
Я чувствую, что использование синтаксического анализа / преобразования строк - это мошенничество, поскольку это a) очень сложный и дорогой процесс по сравнению с побитовыми операциями, b) внутренне использует запрещенные операторы, и c) будет занимать больше символов, чем решение homerolled. Вроде как люди раздражаются, когда вы используете встроенные сортировки, когда их просят реализовать быструю сортировку.
Вуг

1
@Sam Кроме того, ~~преобразуется в целое число, в отличие от +.
Inkbug

1
@Wug Это Codegolf, поэтому речь идет не об эффективности, если это не указано в задании.
Defhlt

3
+1 за использование различных баз. Это одна из моих любимых техник игры в гольф на JavaScript.
DocMax

6

Символы C 83

Число для деления передается через stdin и возвращает его как код выхода из main()(% ERRORLEVEL% в CMD). Этот код злоупотребляет некоторыми версиями MinGW тем, что, когда оптимизация не включена, он обрабатывает последнее значение присваивания как оператор возврата. Вероятно, это может быть немного уменьшено. Поддерживает все номера, которые могут вписаться вint

Если унарное отрицание (-) не разрешено: (129)

I(unsigned a){a=a&1?I(a>>1)<<1:a|1;}main(a,b,c){scanf("%i",&b);a=b;a=a<0?a:I(~a);for(c=0;a<~1;a=I(I(I(a))))c=I(c);b=b<0?I(~c):c;}

Если унарный NEGATE IS разрешается: (123)

I(unsigned a){a=a&1?I(a>>1)<<1:a|1;}main(a,b,c){scanf("%i",&b);a=b;a=a<0?a:-a;for(c=0;a<~1;a=I(I(I(a))))c=I(c);b=b<0?-c:c;}

РЕДАКТИРОВАТЬ: Угорен указал мне, что - ~ это приращение ...

83 символа, если разрешено унарное отрицание: D

main(a,b,c){scanf("%i",&b);a=b;a=a<0?a:-a;for(c=0;a<~1;a=-~-~-~a)c=-~c;b=b<0?-c:c;}

Если разрешено унарное отрицание, x+3есть -~-~-~x.
Угорен

Спасибо тебе за это. Я не знаю, почему это никогда не происходило со мной. Думаю, я не осознавал, что вы можете складывать унары так безвозмездно, хе-хе.
Каслай

5

С, 139 символов

t;A(a,b){return a?A((a&b)<<1,a^b):b;}main(int n,char**a){n=atoi(a[1]);for(n=A(n,n<0?2:1);n&~3;t=A(n>>2,t),n=A(n>>2,n&3));printf("%d\n",t);}

Запустить с номером в качестве аргумента командной строки

  • Обрабатывает как отрицательные, так и положительные числа

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

 ./a.out -6            -2
 ./a.out -5            -1
 ./a.out -4            -1
 ./a.out -3            -1
 ./a.out -2            0
 ./a.out -1            0
 ./a.out 0             0
 ./a.out 1             0
 ./a.out 2             0
 ./a.out 3             1
 ./a.out 4             1
 ./a.out 5             1
 ./a.out 6             2
 ./a.out 42            14
 ./a.out 2011          670

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

  • сохранил 10 символов путем перемешивания сложения (A) для удаления локальных переменных.

1
Красиво сделано. Я старался изо всех сил в битах и ​​получил 239. Я просто не могу разобраться с твоей A, моя функция просто проверяет бит i в числе n. Стандарт C позволяет опускать объявления типов или это что-то компиляторное?
Шион

1
C примет int, если не указано.
Вуг

5

ЗШ - 31 20/21

echo {2..x..3}|wc -w

Для отрицательных чисел:

echo {-2..x..3}|wc -w

С отрицательными числами (ZSH + bc) -62 61

Я, вероятно, не должен давать в качестве ответа две программы, поэтому вот одна, которая работает для любого знака числа:

echo 'obase=10;ibase=3;'`echo 'obase=3;x'|bc|sed 's/.$//'`|bc

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


5

C 81 73 символа

Поддерживает только неотрицательные числа.

char*x,*i;
main(){
    for(scanf("%d",&x);x>2;x=&x[~2])i=&i[1];
    printf("%d",i);
}

Идея состоит в том, чтобы использовать арифметику указателя. Число читается в указатель x, который никуда не указывает. &x[~2]= &x[-3]= x-3используется для вычитания 3. Это повторяется до тех пор, пока число больше 2. iподсчитывает, сколько раз это было сделано ( &i[1]= i+1).


Пытаясь понять код, кто-нибудь пролил свет? Спасибо
Конг Хуэй

@ Чуй, добавил объяснение.
Угорен

@ Югорен, насколько я понимаю, не должен ли printf ("% d") распечатать указатель адреса памяти, который я держу в шестнадцатеричном формате? почему он печатает целое число? или char * я был инициализирован, чтобы указать на адрес памяти 0 по умолчанию? Спасибо
Конг Хуэй

5

Ява 86 79

Предположим, что целое число находится в y:

Преобразует в строку в базе 3, удаляет последний символ (правый сдвиг «>>» в базе 3), затем преобразует обратно в целое число.

Работает на отрицательные числа.

Если число, у, <3 или> -3, то это дает 0.

System.out.print(~2<y&y<3?0:Long.valueOf(Long.toString(y,3).split(".$")[0],3));

Впервые выложить на код гольф. =) Так что пока не могу комментировать.

Спасибо Кевину Круйссену за советы.


Я знаю, что это было более двух лет назад, но вы можете сыграть в гольф несколькими частями: && до &и 2 раза Integerдо Long. (Кроме того, почему вы используете ~2вместо просто -3? Они имеют тот же счетчик байтов.)
Кевин Круйссен

1
@KevinCruijssen Так ностальгирует редактировать мой первый пост после столь долгого. Не был слишком уверен, почему я думал, что ~ 2 тогда было лучше.
Векторизовано

2
@KevinCruijssen хорошо, задача говорит, что вы не можете использовать -, но я не знаю, считается ли это унарным отрицанием.
FlipTack

@FlipTack Ах, ты совершенно прав. В таком случае забудь, я когда-либо говорил это. :)
Кевин Круйссен

4

Python2,6 ( 29 ) ( 71 ) ( 57 ) ( 52 ) (43)

z=len(range(2,abs(x),3))
print (z,-z)[x<0]

print len(range(2,input(),3))

Edit - только что понял, что мы должны обрабатывать и отрицательные целые числа. Это исправлю позже

Edit2 - исправлено

Edit3 - сохранил 5 символов, следуя советам Джоэла Корнетта

Edit4 - так как ввод не обязательно должен быть из STDIN или ARGV, сохраненные 9 символов, не принимая никакого ввода из STDIN


Продолжайтеabs()
defhlt

короче сделатьprint z if x==abs(x) else -z
Джоэл Корнетт

еще лучше,print (z,-z)[x<0]
Джоэл Корнетт

@ArtemIce спасибо, только понял, что могу использовать это после прочтения другого ответа выше.
Elssar

@JoelCornett хм, не знал об этом, спасибо
elssar

4

Javascript, 47 29

Используется evalдля динамического создания /. Используется +только для объединения строк, а не для сложения.

alert(eval(prompt()+"\57"+3))

РЕДАКТИРОВАТЬ: используется "\57"вместоString.fromCharCode(47)


-1 за alert(eval(prompt()+"\573"))?
Шиеру Асакото

4

Рубин ( 43 22 17)

Не только гольф, но и элегантность :)

p Rational gets,3

Выход будет как (41/1). Если оно должно быть целым числом, мы должны добавить .to_iк результату, и если мы изменим to_iна, to_fто мы также можем получить выходные данные для чисел с плавающей запятой.


1
Работает без rationalстроки require на Ruby 1.9.3. Пропуск скобок экономит еще один символ .
Steenslag

4

TI-Basic, 8 байтов

Победитель? :)

int(mean({Ans,0,0

PS Округляет бесконечность для отрицательных чисел (см. Здесь, почему). Вместо округления до нуля замените int(наiPart( для каких - либо изменений байт.

Контрольные примеры

-4:prgmDIVIDE
              -2
11:prgmDIVIDE
               3
109:prgmDIVIDE
              36

3

Python 2.x, 54 53 51

print' -'[x<0],len(range(*(2,-2,x,x,3,-3)[x<0::2]))

Где _дивиденд и вводится как таковой.

>>> x=-19
>>> print' -'[x<0],len(range(*(2,-2,x,x,3,-3)[x<0::2]))
- 6

Примечание: Не уверен, разрешено ли использование интерактивного переводчика, но согласно ОП: «Ввод может быть на STDIN или ARGV или введен любым другим способом»

Редактировать: теперь для Python 3 (работает в 2.x, но печатает кортеж). Работает с негативами.


Также работает в Python 3?
Механическая улитка

Не должен быть подписан; иметь __len__достаточно.
Механическая улитка

len(range(100,1000))дает 900в 3.2.3 на Linux.
Механическая улитка

Это не работает для отрицательных чисел. И в len(xrange(0,_,3))любом случае короче и намного быстрее.
GRC

@Mechanicalsnail: Точка занята. Я признаю Это работает на 3.
Джоэл Корнетт

3

С ++, 191

С основным и включает, его 246, без основного и включает, это только 178. Новые строки засчитываются как 1 символ. Обрабатывает все числа как без знака. Я не получаю предупреждений о том, что main возвращает unsigned int, так что это честная игра.

Моя первая в истории подача кодагола.

#include<iostream>
#define R return
typedef unsigned int U;U a(U x,U y){R y?a(x^y,(x|y^x^y)<<1):x;}U d(U i){if(i==3)R 1;U t=i&3,r=i>>=2;t=a(t,i&3);while(i>>=2)t=a(t,i&3),r=a(r,i);R r&&t?a(r,d(t)):0;}U main(){U i;std::cin>>i,std::cout<<d(i);R 0;}

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

псевдокод:

// typedefs and #defines for brevity

function a(x, y):
    magically add x and y using recursion and bitwise things
    return x+y.

function d(x):
    if x = 3:
        return 1.
    variable total, remainder
    until x is zero:
        remainder = x mod 4
        x = x / 4
        total = total + x
    if total and remainder both zero:
        return 0.
    else:
        return a(total, d(remainder)).

Кроме того, я мог бы исключить метод main, назвав d main и заставив его взять символ ** и используя в качестве выходных данных программы возвращаемое значение. Он вернет число аргументов командной строки, разделенное на три, округленное в меньшую сторону. Это приводит его длину к рекламируемому 191:

#define R return
typedef unsigned int U;U a(U x,U y){R y?a(x^y,(x|y^x^y)<<1):x;}U main(U i,char**q){if(i==3)R 1;U t=i&3,r=i>>=2;t=a(t,i&3);while(i>>=2)t=a(t,i&3),r=a(r,i);R r&&t?a(r,d(t)):0;}

3

Golfscript - 13 символов

~3base);3base

кажется, не обрабатывает отрицательный ввод
Res

1
@res s/seem to //:(. Мне нужно подумать об этом
gnibbler

3

PowerShell 57 или 46

В 57 символов используется %в качестве оператора foreach PowerShell, а не по модулю. Это решение может принимать положительные или отрицательные целые числа.

(-join(1..(Read-Host)|%{1})-replace111,0-replace1).Length

Если *в качестве оператора повторения строк допустимо использовать 46 символов , не умножайте. Эта опция требует положительных целых чисел в качестве входных значений.

("1"*(Read-Host)-replace111,0-replace1).Length

Если вы когда-нибудь вернетесь, я опубликовал исправление ошибки. Если вы хотите, чтобы я удалил мои и включил изменения в ваши, просто дайте мне знать.
Веска

3

р

Они работают только с положительными целыми числами:

max(sapply(split(1:x,1:3), length))
# Gives a warning that should be ignored

Или же:

min(table(rep(1:3, x)[1:x]))

Или же:

length((1:x)[seq(3,x,3)])

Или же:

sum(rep(1,x)[seq(3,x,3)])

[[EDIT]] И уродливый:

trunc(sum(rep(0.3333333333, x)))

[[EDIT2]] Плюс, наверное, лучший - вдохновлен кодом Matlab выше Эллиотом G:

length(seq(1,x,3))

Я хотел реализовать ту же идею, что и в вашем EDIT2, но она не работает для отрицательных чисел:wrong sign in 'by' argument
Andrei Kostyrka

3

SmileBASIC, 58 51 36 байт (без математических функций!)

INPUT N
BGANIM.,4,-3,N
WAIT?BGROT(0)

Объяснение:

INPUT N           'get input
BGANIM 0,"R",-3,N 'smoothly rotate background layer 0 by N degrees over 3 frames
WAIT              'wait 1 frame
PRINT BGROT(0)    'display angle of layer 0

Программа плавно перемещает фоновый слой на 3 кадра, а затем получает угол после 1 кадра, когда он прошел 1/3 своего общего расстояния.

Версия деления поплавка, 38 байт:

INPUT N
BGANIM.,7,-3,N
WAIT?BGVAR(0,7)

Объяснение:

INPUT N           'input
BGANIM 0,"V",-3,N 'smoothly change layer 0's internal variable to N over 3 frames
WAIT              'wait 1 frame
PRINT BGVAR(0,7)  'display layer 0's internal variable

3

Haskell 41 39 символов

Работает с полным набором положительных и отрицательных целых чисел

f n=sum[sum$1:[-2|n<0]|i<-[3,6..abs n]]

Сначала создается список 1 или (-1) (в зависимости от знака ввода) для каждого третьего целого числа от 0 до ввода n.abs(n)для отрицательных чисел включительно.

например n=8 -> [0,3,6]

Затем он возвращает сумму этого списка.


Не работает с отрицательными числами (-3/3 это -1, а не 1).
Кормак

Хорошо, что вы заставили его работать с отрицательными числами, но вы не можете использовать /, прочитайте спецификацию.
Кормак

О боже, ты получил меня дважды. Все исправлено;)
Чарль Крюгер

Приятно! Кстати, вы можете получить 39 символов с fn = sum [сумма $ 1: [- 2 | n <0] | i <- [3,6..abs n]]
Кормак

2

Clojure, 87; работает с негативами; основанный на lazyseqs

(defn d[n](def r(nth(apply interleave(repeat 3(range)))(Math/abs n)))(if(> n 0)r(- r)))

Ungolfed:

(defn d [n]
  (let [r (nth (->> (range) (repeat 3) (apply interleave))
               (Math/abs n))]
        (if (pos? n)
          r
          (- r))))

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.