Розділіть число на 3, не використовуючи операторів *, /, +, -,%


48

Цитуючи це запитання на SO (сповіщення спойлера!):

Це питання було задано в інтерв'ю 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
Так, ви можете використовувати або функцію харчування ^: або Порядок денний @. для ifабо if...elseзаміни. У цьому випадку ви можете використовувати @.два дієслова, пов'язані з символом `` '(герундій у J-говорі), щоб вибрати те чи інше на основі умови.
Гарет

56

C, 167503724710

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

Моя програма - це вихід із наступного сценарію:

#!/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 Б / (14,8 * 1048576 Б / с) ≈ 10794 с.
  • Час компіляції - компілятор TCC претендує на компіляцію коду С зі швидкістю 29,6 Мб / с , що складає час компіляції 167503724710 Б / (29,6 * 1048576 Б / с) ≈ 5397 с. (Звичайно, це може працювати в конвеєрі зі сценарієм.)
  • Розмір компільованого коду - я спробував оцінити його за допомогою ./test.py | tcc -c - -o /dev/stdout | pv --buffer-size=1M --average-rate > /dev/null, але, схоже, tccнічого не видає, поки він не прочитає весь вихідний файл у.
  • Використання пам'яті для запуску - Оскільки алгоритм лінійний (а tcc не оптимізується по лініях), накладні витрати на пам'ять повинні становити лише кілька кілобайт (крім самого коду, звичайно).

22
Це втілення жорсткого кодування. ++++++++++
Joe Z.

4
Попри це, я впевнений, що якщо ви дасте їм вихідний файл розміром 160 ГБ і попросите їх скласти і протестувати, вони дивляться на вас, як ви божевільні.
Джо З.

16
Якби мій начальник попросив мене обчислити поділ на три без - + / *%, я б вважав, що він божевільний.
Mikaël Mayer

І все-таки, a[b]це синтаксичний цукор для *(a + b), який робить додавання.
Конрад Боровський

12
@NicolasBarbulesco Існує обмеження розміру у відповідях на обмін стеками.
Тімтех

38

Рубін 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. З Рубіном 2.1, можна в гольф (0..1.0/0).step(3)в 0.step(p,3), видалення /. Більша проблема полягає в тому, що -rвикористовується -для того, щоб заперечувати. Змінити -rна 5 символів варто ~r.pred, зловживаючи Integer # pred, щоб відняти 1 без оператора віднімання.
kernigh

26

Математика, 13 ряд

Mean@{#,0,0}&

Це лукаво: DI здогадуюсь, що ти можеш зберегти &та використовувати просту змінну (інші теж роблять це).
Ів Клетт

3
@YvesKlett: Середній за своєю суттю злий.
GuitarPicker

18

JavaScript, 56

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

Створює рядок довжиною nповторюваних ,s і замінює ,,,на 1. Потім він вимірює отриману довжину рядка. (Сподіваємось, одинарний -дозволений!)


+1, але це не працює з негативними значеннями
Франческо Касула

А, питання ... як це рахується? Він використовує -оператор заперечення.
Патрік Робертс

@Patrick я прийняв специфікації не маю на увазі не віднімання - якщо ви хочете, ви можете замінити -~з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 (діапазон (2, abs (x), 3))) `` зіб'є його до 39 знаків
Джоел Корнетт

Форматування коментарів golfexchange псує це. вище, я використовував посилання для розміщення len()як скороченняrepr()
Джоел Корнетт

Я оновив його. Я не можу використовувати range, оскільки це фактично створить список. xrangeпросто прикидається, тому він здатний обробляти величезні числа, не витрачаючи часу / пам'яті.
grc

2
Зробіть вигляд, що це Python 3;) Мені подобається одинарне нарізання батончиків btw.
Джоел Корнетт

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)!!)

просто повертає nth елемент списку [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);}}

Безумовно

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 Цей метод додавання не працює на двох числах, він лише додає значення колекції
Втілення Незнання

7

Perl (26 22)

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

У цій версії (ab) використовується регекс-двигун Perl. Він читає число як останній аргумент командного рядка ( pop) і будує рядок 3s такої довжини ( "3" x $number). Оператор заміни регулярних виразів ( s///тут написано різними роздільниками через правила головоломки та з gлобальним прапором) підміняє три символи порожнім рядком і повертає число підстановок, яке є вхідним числом на ціле число, поділене на три. Це навіть можна було б написати без 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, інші компілятори можуть barf.

Тестування:

./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

Пітон 42

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

Оскільки кожне рішення, розміщене тут, що я перевіряв усікання десяткових знаків, - це моє рішення, яке це робить.

Пітон 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.
Гаффі

Для тих, хто дбає про поділ підлоги в python: python-history.blogspot.com/2010/08/…
Метт

що з множенням і відніманням у вашому другому рішенні?
кабінка

@boothby Друге рішення реалізує поділ підлоги. Я хотів зробити діапазон (0, абс (х), 3) для від'ємних чисел і діапазон (2, абс (х), 3) для додатних чисел. Для цього у мене був діапазон (2 ... тоді я віднімав 2, коли х від'ємний. X <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
Я відчуваю, що використання синтаксичного розбору / перетворення є обманом, оскільки його а) дуже складний і дорогий процес порівняно з побітними операціями; б) використовує заборонені оператори внутрішньо, і в) забирає на вааааай більше символів, ніж рішення, що управляється домом. Наче подобається, як люди нарікають, коли ви використовуєте вбудовані у сорти, коли їх попросили реалізувати кварц.
Вуг

1
@Sam Також ~~перетворюється на ціле число, на відміну від +.
Inkbug

1
@Wug Це кодовий гольф, тому мова не йде про ефективність, якщо не зазначено в задачі.
дефлот

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;}

EDIT: ugoren вказував на мене, що ~ ~ приріст ...

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.
ugoren

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

5

C, 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 пропускати декларації типу або це щось із компілятора?
shiona

1
C буде вважати int, якщо не вказано.
Вуг

5

ZSH - 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).


Намагаючись зрозуміти код, хтось пролив світло? Спасибі
Конг Хуй

@Chui, додав пояснення.
ugoren

@ugoren, наскільки я розумію, чи не повинен printf ("% d") роздрукувати вказівник адреси пам'яті, який я тримає в Hex? чому це друк цілого числа? або char * i було ініціалізовано, щоб вказати адресу пам'яті 0 за замовчуванням? Спасибі
Конг Хуй

5

Java 86 79

Припустимо, ціле число знаходиться у:

Перетворює на рядок у базі 3, видаляє останній символ (правий зсув ">>" у базі 3), а потім перетворює назад у ціле число.

Працює для від’ємних чисел.

Якщо число, у, <3 або> -3, то воно дає 0.

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

Перший раз розміщення на коді гольфу. =) Тому поки що не можу коментувати.

Thx Кевін Круїссен для порад.


Я знаю, що це було більше двох років тому, але ви можете пограти в декілька частин: &&до &та 2х Integerдо Long. (Крім того, для чого ви використовуєте ~2замість просто -3? Вони однакові підрахунку байтів.)
Кевін Круїссен

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

2
@KevinCruijssen добре, виклик говорить, що вам заборонено користуватися -, але я не знаю, чи вважається це унарним запереченням.
FlipTack

@FlipTack Ах ви абсолютно праві. У цьому випадку забудь, я коли-небудь це говорив. :)
Kevin Cruijssen

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))

Редагувати - Щойно зрозумів, що і ми повинні обробляти негативні цілі числа. Виправить це пізніше

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

Edit3 - Збережено 5 символів, дотримуючись порад Джоела Корнетта

Edit4 - Оскільки введення не повинно бути обов'язково з STDIN або ARGV, збережено 9 символів, не беручи жодного вводу від stdin


Впередabs()
дефль

коротшеprint z if x==abs(x) else -z
Joel Cornett

ще краще,print (z,-z)[x<0]
Джоел Корнетт

@ArtemIce дякую, тільки зрозумів, що можу це використати, прочитавши іншу відповідь вище.
elssar

@JoelCornett гул, не знав про це, дякую
elssar

4

Javascript, 47 29

Використовує evalдля динамічного генерування а /. Використовується +лише для з'єднання рядків, а не для додавання.

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

EDIT: Використовується "\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лінії на 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 символом. Розглядає всі числа як неподписані. Я не отримую попереджень за те, що головне повертає неподписаний 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)).

Як осторонь, я міг би усунути основний метод, назвавши 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

Гольфскрипт - 13 символів

~3base);3base

чи не здається, і негативний вхід
рес

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

R

Вони працюють лише з натуральними числами:

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]] Плюс, мабуть, найкращий - натхненний вище кодом матлаба Елліотом G:

length(seq(1,x,3))

Я хотів реалізувати ту саму ідею, що і у вашому EDIT2, але це не працює для негативних цифр:wrong sign in 'by' argument
Андрей Костирка

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).
Кормак

Приємно, що ви змусили його працювати на від'ємних числах, але ви не можете використовувати /, прочитайте специфікацію.
Кормак

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

Приємно! Btw Ви можете отримати 39 знаків із fn = sum [сума $ 1: [- 2 | n <0] | i <- [3,6..abs n]]
Кормак

2

Clojure, 87; працює з негативами; на основі лениць

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

Безголівки:

(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.