Визначте, чи ціле число ділиться на 3


20

Ваша мета - визначити, чи число ділиться на 3 без використання умовних умов. Вхід буде непідписаним 8-бітним числом від 0 до 255. Творчість заохочується!

Вам ТОЛЬКО дозволено користуватися

  • Рівність / Нерівність ( ==, !=, >, <, >=, <=)

  • Арифметика ( +, -, x)

  • Логічні оператори ( !не &&, || або або)

  • Побітові оператори ( ~ні, &і, |або, ^що виключає, <<, >>, >>>арифметичні і логічні ліві і праві зрушення)

  • Константи (було б краще, якби ви зберегли ці маленькі)

  • Змінне призначення

Виведіть, 0якщо помилково, 1якщо істинно.

Застосовуються стандартні правила атомного коду-гольфу. Якщо у вас є якісь питання, залиште їх у коментарях. Приклад методів тут . Маркер - це будь-який із наведених вище, виключаючи константи та змінні.


@GregHewgill Мій друк, це повинно бути 8-бітове число.
qwr

2
Чи дозволяється нам використовувати лише вищезазначені оператори? Інакше модуль зробив би цей спосіб занадто простим.
Jwosty

Крім того, як щодо пошуку таблиць?
Грег Хьюгілл

3
Чи можете ви пояснити, що ви маєте на увазі під жодними умовами? Чи обмежується вона операторами IF чи це стосується також таких речей, як петлі?
Руслан

1
@Ruslan Ви можете використовувати лише вищезазначене.
qwr

Відповіді:


31

C - 2 жетони

int div3(int x) {
    return x * 0xAAAAAAAB <= x;
}

Здається, працює до 2 31 -1.

Подяки на zalgo("nhahtdh")мультиплікативну зворотну ідею.


1
+1. Був трохи здивований тим, як <=працює, і пам’ятав, що 0xAAAAAAAB приймається за unsigned intтип, таким чином результат множення не підписується.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Оператори нерівності @DigitalTrauma дозволені, не заборонені
aditsu

@aditsu На жаль! Мені іноді потрібно більш уважно читати! +1 чудова відповідь!
Цифрова травма

@aditsu, вибач, що я noob, як саме це працює?
Kartik_Koro

2
@Kartik_Koro 0xAAAAAAAB * 3 == 1 через переповнення, тому для будь-якого int x, x * 0xAAAAAAAB * 3 == x. Також y * 3 має різні значення для різних y, тому y = x * 0xAAAAAAAB повинен бути єдиним y таким, що y * 3 == x. Якщо x кратне 3, то y має бути x / 3, інакше він повинен працювати через переповнення. Простий спосіб перевірити - порівняти y з x. Також дивіться en.wikipedia.org/wiki/Modular_multiplicative_inverse
aditsu

17

Python, 3 2 лексеми

Рішення грубої сили, але воно працює.

0x9249249249249249249249249249249249249249249249249249249249249249>>x&1

Завдяки Говарду за зменшення на 1 маркер.


Оце Так! Ваше рішення, мабуть, найкоротше (3 лексеми), але я хочу заохотити й інші відповіді.
qwr

11
Існує навіть два маркера рішення: 0x9......>>x&1.
Говард

6

C - 5 4 (?) Лексеми

int div3_m2(uint32_t n) {
    return n == 3 * (n * 0xAAAAAAABull >> 33);
}

Працює для будь-якого 32-бітного безпідписаного числа .

Цей код використовує мультиплікативний зворотний модуль 2 32 дільника для перетворення операції поділу в операцію множення.

Редагувати

Мій розчин (опублікований через 2 хвилини після) має такий же дух, як і рішення адицу. Подяка йому за використання, ==що покращує моє рішення на 1 маркер.

Довідково


1
Це неймовірно. Я знав про магічні числа з відомого зворотного трюку, але не знав, що його можна використовувати для довільного дільника. Це Bull: P
qwr

Так, 0xAAAAAAAB = (2 ^ 33 + 1) / 3 і 171 = (2 ^ 9 + 1) / 3. Я вибрав найменшу константу, яка робить трюк. Хм, насправді також здається, що це працює з 86 = (2 ^ 8 + 2) / 3
aditsu

Щури, навіть 43 = (2 ^ 7 + 1) / 3 працює, не впевнені, як я це пропустив. Відредаговано зараз.
aditsu

4

C - 15 (?) Лексем

int div3_m1(unsigned int n) {
    n = (n & 0xf) + (n >> 4);
    n = (n & 0x3) + (n >> 2);
    n = (n & 0x3) + (n >> 2);
    return n == 0 || n == 3;
}

Оскільки 4 ≡ 1 (mod 3), маємо 4 n ≡ 1 (mod 3). Правило підсумовування цифр не обмежується підбиттям цифр, але також дозволяє нам довільно розбивати число на послідовності цифр і підсумовувати всі їх, зберігаючи конгруентність.

Приклад у базі 10, дільник = 9:

1234 ≡ 12 + 34 ≡ 1 + 2 + 3 + 4 ≡ 123 + 4 ≡ 1 (мод 9)

Усі заяви в програмі використовують це властивість. Насправді його можна спростити до циклу, який запускає оператор n = (n & 0x3) + (n >> 2);до n < 4тих пір , оскільки оператор просто розбиває число в base-4 принаймні значущою цифрою і додає 2 частини вгору.


+1: цікаво, що це працює для n до 512 (насправді n = 590), але я не зовсім впевнений, чому.
Пол Р

@PaulR: Він не працюватиме для більшої кількості через перенесення (зауважте, що я використовував додаток у розрахунку). Також відзначте повторні рядки.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Так, я просто не впевнений, чому він працює для 9-ти бітних значень, оскільки, здається, тестується лише 8 біт?
Пол Р

для 9-бітних чисел після першого Крім того , він стає не більше 5 біт, після того , як перший n = (n & 0x3) + (n >> 2);результат зводиться до 3 біта і повторення викликало те , щоб залишитися тільки 2 біта stackoverflow.com/a/3421654/995714
phuclv

1
ой, я помилився. 5-бітове число + 4-розрядне число може призвести до отримання 6-бітного числа. Але якщо n <= 588, додавши верхній 4 біт і нижній 2 біт цього 6-бітного числа, вийде лише 4-бітна сума. Знову додамо, що призводить до отримання 2-бітного числа. 589 і 590 приводить до 3 біт останньої суми, але, до речі, їх не ділити на 3, тому результат правильний
phuclv

2

Python (2 жетони?)

1&66166908135609254527754848576393090201868562666080322308261476575950359794249L>>x

Або

1&0x9249249249249249249249249249249249249249249249249249249249249249L>>x

Або

1&0b1001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001>>x

2
Дублікат коментаря Говарда
aditsu

@aditsu ... Великі розуми думають однаково? Клянусь, я цього не бачив до того, як опублікував це.
ɐɔıʇǝɥʇuʎs

2

JavaScript - 3 лексеми

function div3(n) {
    var a = n * 0.3333333333333333;
    return (a | 0) == a;
}

Це зловживає тим, що використання побітових операторів на ряді скорочує його до цілого числа в JavaScript.


Повинно бути 4 лексеми: =, *, |,==
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳

1
Я не думаю, що присвоєння змінних не вважається ознакою.
Тиїло

1

C - 4 лексеми

int div3(int x) {
    return ((x * 43) >> 7) * 3 == x;
}

Працює до 383.

Попередня версія (більші константи):

int div3(int x) {
    return ((x * 171) >> 9) * 3 == x;
}

Працює до 1535 року


1

баш - ???

Не знаєте, як це забити.

seq 0 85 | awk '{print $1 * 3}' | grep -w [number] | wc -l

напр

$ seq 0 85 | awk '{print $1 * 3}' | grep -w 11 | wc -l
0

$ seq 0 85 | awk '{print $1 * 3}' | grep -w 12 | wc -l
1

$seq 0 85 | awk '{print $1 * 3}' | grep -w 254 | wc -l
0

$seq 0 85 | awk '{print $1 * 3}' | grep -w 255 | wc -l
1

1

Befunge 93 - 5 жетонів

Виправлено - поділ видалено.

v      @._1.@
         \   
         0   
         +   
         3   
>&>3-:0\`|   
  ^      <   

Отримує введення, продовжує віднімати 3, поки воно не буде меншим за 0, направляє вказівник вгору ('|'), а потім додає 3. Якщо значення 0, то вказівник переміщується вправо (" 1. @" виводить "1"), інакше рухається вліво ("@. " виводить "0"). '@' завершує програму.


1

Пакет - 7 токенів

Я думаю

@echo off
for /L %%a in (0,3,%1) do set a=%%a
if %a%==%1 echo 1

Повертає, 1якщо задане число (як stdin) ділиться на три.


Чи дозволені петлі?
серхіол

1

Рубі, 6 (?) Лексем

Я дійсно не впевнений, як рахувати жетони. ОП, ти можеш забити мене?

Я думаю , що це 6 ... 1, 0, 0, *, 255,x

Зауважте, що *множина не є цілим числом.

def div3(x)
  ([1,0,0]*255)[x]
end

Чи не буде маркування в розумінні ОП лише одним із перерахованих вище у питанні?
C5H8NNaO4

@ C5H8NNaO4 Так що? 0?
Не те, що Чарльз

@ C5H8NNaO4, можливо, 4 для констант?
Не те, що Чарльз

1

Python 0

Я розмістив вушко, але використовував умовні умови. Ось до використання умовних умов і без лексем, а лише до ключових слів

def g(x): return ([[lambda : g(sum(int(y) for y in list(str(x)))),lambda: 0][[False,True].index(x in[0,1,2,4,5,7,8])], lambda: 1][[False,True].index((lambda y: y in[3,6,9])(x))])()

використовує трюк, що у кількох 3 є цифри, які додаються до 3

Редагувати: Видалено непотрібну лямбда

def g(x):return([[lambda: g(sum(int(y) for y in list(str(x)))),lambda:0][[False,True].index(x in[0,1,2,4,5,7,8])], lambda:1][[False,True].index(x in[3,6,9])])()

Редагувати: Далі в гольфі (117 символів) все ще немає жетонів

exec"g=`x:(((`:g(sum(int(y)for y in str(x)),`:0)[x in[0,1,2,4,5,7,8]],`:1)[x in[3,6,9]])()".replace('`','lambda ')

Загинув прямий доступ для витонченого гетьтена пітона на 132 чар

exec"g={0}x:((({0}:g(sum(int(y)for y in str(x))),{0}:0{1}0,1,2,4,5,7,8]),{0}:1{1}3,6,9]))()".format('lambda ',').__getitem__(x in[')

http://www.codeskulptor.org/#user34_uUl7SwOBJb_0.py


[]Однак доступ до масиву заборонений.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳


Ну, питання не використовує правило у вікі тегів. Питання має обмеження щодо операцій. Зауважте слово only.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Добре, що питон також має для цього атрибут
Dylan Madisetti,

0

Пітон - 25 жетонів

Щоб почати все, у мене є тривале рішення - це реалізація однієї з відповідей за посиланням у моєму першому дописі. nє вхідним.

a = (n>>7)-((n&64)>>6)+((n&32)>>5)-((n&16)>>4)+((n&8)>>3)-((n&4)>>2)+((n&2)>>1)-(n&1)
print(a==0 or a==3)

orеквівалентно ||.


0

JavaScript - 3 токена

Перевірте це на консолі браузера:

a = prompt().split('');
sum = 0;

do {
  sum = a.reduce(function(p, c) {
     return parseInt(p) + parseInt(c); 
  });

  a = sum.toString().split('');

} while(a.length > 1)

alert([3, 6, 9].indexOf(+sum) > -1)

Як ти дійшов такого висновку? Я налічую близько 37 лексем.
nyuszika7h

"Маркер - це будь-яке з вищезазначених, виключаючи константи та змінні". Як ти порахував 37?
Вільям Барбоса

1
О Я бачу. Здається, ОП не погоджується з інформаційною сторінкою atomic-code-golf .
nyuszika7h

Власне, зараз я не впевнений, прав я чи ні. Моя оцінка складе 70+ відповідно до атомного коду.
Вільям Барбоса

1
Проблема полягає не в кількості лексем, а в тому, які операції ви використовуєте. Я не думаю, що дозволено String, parseInt, петлі, масиви тощо.
aditsu

0

JavaScript
не впевнений у маркері #

function mod3 (i) { return {'undefined':'100','0':'0'}[[0][i]][i.toString (3).split('').pop ()]}

або якщо вихід для 0 дозволено дорівнювати 1;

function mod3 (i) { return '100'[i.toString (3).split('').pop ()]}


2
Треба сказати, я не впевнений, які правила стосуються цього виклику. Чи дозволено функціонування дзвінків і дозволів до вибору програм?
C5H8NNaO4

0

Tcl , 83 байти

proc T n {while \$n>9 {set n [expr [join [split $n ""] +]]};expr {$n in {0 3 6 9}}}

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


Не вдалося подолати: 96 байт proc T n {set n [expr [join [split [expr [join [split $n ""] +]] ""] +]];expr {$n in {0 3 6 9}}} Спробуйте в Інтернеті!
Серхіол

Ще одна помилка: ** 87 байт ** proc T n {expr {[expr [join [split [expr [join [split $n ""] +]] ""] +]] in {0 3 6 9}}} Спробуйте в Інтернеті!
серхіол
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.