Bestimmen Sie, ob eine Ganzzahl durch 3 teilbar ist

20

Ihr Ziel ist es, zu bestimmen, ob eine Zahl ohne Verwendung von Bedingungen durch 3 teilbar ist. Der Eingang ist eine vorzeichenlose 8-Bit-Zahl von 0 bis 255. Kreativität wird gefördert!

Du darfst NUR benutzen

  • Gleichheit / Ungleichheit ( ==, !=, >, <, >=, <=)

  • Arithmetic ( +, -, x)

  • Logische Operatoren ( !nicht &&und || oder)

  • Bitweise Operatoren ( ~nicht, &und, |oder, ^xor, <<, >>, >>>arithmetische und logische linke und rechte Verschiebungen)

  • Konstanten (es wäre besser, wenn Sie diese klein halten)

  • Variablenzuordnung

Ausgabe 0wenn falsch, 1wenn wahr.

Standard Atomic Code-Golf-Regeln gelten. Wenn Sie Fragen haben, hinterlassen Sie diese bitte in den Kommentaren. Beispielmethoden hier . Ein Token ist eines der oben genannten, ausgenommen Konstanten und Variablen.

qwr
quelle
@ GregHewgill Mein Tippfehler, es sollte 8-Bit-Nummer sein.
Qwr
2
Dürfen wir nur die oben genannten Operatoren verwenden? Andernfalls würde modulo dies zu einfach machen.
Jwosty
Wie wäre es auch mit einer Tabellensuche?
Greg Hewgill
3
Können Sie klarstellen, was Sie unter keinen Bedingungen verstehen? Ist es auf IF-Anweisungen beschränkt oder gilt es auch für Schleifen?
Ruslan
1
@ Ruslan Sie dürfen nur die oben genannten verwenden.
Qwr

Antworten:

31

C - 2 Token

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

Scheint bis zu 2 31 -1 zu arbeiten.

Danksagung zalgo("nhahtdh")für die multiplikative inverse Idee.

aditsu
quelle
1
+1. War etwas verblüfft, wie das <=funktioniert, und erinnerte sich, dass 0xAAAAAAAB als unsigned intTyp angenommen wird, daher ist das Ergebnis der Multiplikation vorzeichenlos.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
@DigitalTrauma Ungleichheitsoperatoren sind erlaubt, nicht verboten
aditsu
@aditsu Hoppla! Ich muss manchmal genauer lesen! +1 tolle Antwort!
Digital Trauma
@Aditsu, sorry ich bin noob, wie genau funktioniert das?
Kartik_Koro
2
@Kartik_Koro 0xAAAAAAAB * 3 == 1 wegen Überlauf, also für jedes int x, x * 0xAAAAAAAB * 3 == x. Auch y * 3 hat unterschiedliche Werte für unterschiedliches y, daher muss y = x * 0xAAAAAAAB das einzige y sein, so dass y * 3 == x ist. Wenn x ein Vielfaches von 3 ist, muss y x / 3 sein, andernfalls muss es einen Überlauf durchlaufen. Eine einfache Möglichkeit, dies zu überprüfen, besteht darin, y mit x zu vergleichen. Siehe auch en.wikipedia.org/wiki/Modular_multiplicative_inverse
aditsu
17

Python, 3 2 Token

Brute-Force-Lösung, aber es funktioniert.

0x9249249249249249249249249249249249249249249249249249249249249249>>x&1

Vielen Dank an Howard für die Reduzierung um 1 Token.

Greg Hewgill
quelle
Wow! Ihre Lösung ist wahrscheinlich die kürzeste (3 Token), aber ich möchte auch andere Antworten ermutigen.
Qwr
11
Es gibt sogar eine 2 - Token - Lösung: 0x9......>>x&1.
Howard
6

C - 5 4 (?) Token

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

Funktioniert für alle vorzeichenlosen 32-Bit-Nummern .

Dieser Code verwendet das multiplikative inverse Modulo 2 32 eines Divisors, um die Divisionsoperation in eine Multiplikationsoperation umzuwandeln.

Bearbeiten

Meine Lösung (2 Minuten später veröffentlicht) entspricht der Lösung von aditsu. Gutschrift an ihn für die Verwendung von== verbessert sich meine Lösung um 1 Token.

Referenz

n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳
quelle
1
Das ist unglaublich. Ich kannte die magischen Zahlen aus dem berühmten inversen Quadratwurzel-Trick, aber ich wusste nicht, dass er für einen beliebigen Divisor verwendet werden kann. Dies ist Bull: P
qwr
Ja, 0xAAAAAAAB = (2 ^ 33 + 1) / 3 und 171 = (2 ^ 9 + 1) / 3. Ich habe die kleinste Konstante ausgewählt, die den Trick macht. Hmm, eigentlich scheint es auch mit 86 = (2 ^ 8 + 2) / 3 zu
funktionieren
Ratten, sogar 43 = (2 ^ 7 + 1) / 3 funktioniert, nicht sicher, wie ich es verpasst habe. Jetzt bearbeitet
Aditsu
4

C - 15 (?) Token

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

Seit 4 ≡ 1 (mod 3) haben wir 4 n ≡ 1 (mod 3). Die Ziffernsummierungsregel beschränkt sich nicht nur auf die Summierung der Ziffern, sondern ermöglicht es uns auch, die Zahl willkürlich in Ziffernfolgen zu unterteilen und alle Ziffern unter Wahrung der Kongruenz zu summieren.

Ein Beispiel in Basis 10, Divisor = 9:

1234 ≡ 12 + 34 ≡ 1 + 2 + 3 + 4 ≡ 123 + 4 ≡ 1 (Mod 9)

Alle Anweisungen im Programm nutzen diese Eigenschaft. Es kann tatsächlich zu einer Schleife vereinfacht werden, die die Anweisung n = (n & 0x3) + (n >> 2);bis ausführt n < 4, da die Anweisung einfach die Zahl in der Basis 4 an der niedrigstwertigen Stelle aufbricht und die 2 Teile aufaddiert.

n̴̖̋h̴̖̋ã̷͉h̷̭̿d̷̰̀ĥ̷̳
quelle
+1: Interessanterweise funktioniert dies für n bis 512 (tatsächlich n = 590), aber ich bin nicht ganz sicher, warum.
Paul R
@PaulR: Bei größeren Zahlen funktioniert es aufgrund des Übertragens nicht (beachte, dass ich bei der Berechnung zusätzlich verwendet habe). Beachten Sie auch die wiederholten Zeilen.
n̴̖̋h̴̖̋a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
Ja, ich bin mir nicht sicher, warum es für 9-Bit-Werte funktioniert, da es nur 8-Bit-Tests zu sein scheint.
Paul R
Für 9-Bit-Zahlen werden nach der ersten Addition höchstens 5 Bit, nach der ersten Addition wird n = (n & 0x3) + (n >> 2);das Ergebnis auf 3 Bit reduziert und die Wiederholung bewirkt, dass nur 2 Bit übrig
phuclv
1
Oh, ich habe einen Fehler gemacht. Eine 5-Bit-Zahl + eine 4-Bit-Zahl kann eine 6-Bit-Zahl ergeben. Wenn jedoch n <= 588 ist und die oberen 4 Bits und die unteren 2 Bits dieser 6-Bit-Zahl addiert werden, wird nur eine 4-Bit-Summe erzeugt. Erneutes Hinzufügen ergibt eine 2-Bit-Zahl. 589 und 590 in 3 Bits in der letzten Summe aber nebenbei sind sie nicht durch 3 teilbar , so das Ergebnis korrekt ist
phuclv
2

Python (2 Token?)

1&66166908135609254527754848576393090201868562666080322308261476575950359794249L>>x

Oder

1&0x9249249249249249249249249249249249249249249249249249249249249249L>>x

Oder

1&0b1001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001001>>x
ɐɔıɐɔuʇǝɥʇs
quelle
2
Duplikat von Howards Kommentar
aditsu
@aditsu ... Großartige Köpfe denken gleich? Ich schwöre, ich habe das nicht gesehen, bevor ich das gepostet habe.
23ıɐɔuʇǝɥʇs
2

JavaScript - 3 Token

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

Dies missbraucht die Tatsache, dass die Verwendung von bitweisen Operatoren für eine Zahl diese in JavaScript auf eine Ganzzahl abschneidet.

Tyilo
quelle
Sollte seine 4 - Token: =, *, |,==
n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳
1
Ich denke nicht, dass variable Zuweisung als Token zählt.
Tyilo
1

C - 4 Token

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

Funktioniert bis zu 383.

Vorherige Version (größere Konstanten):

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

Funktioniert bis 1535

aditsu
quelle
1

Bash - ???

Ich bin mir nicht sicher, wie ich das bewerten soll.

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

z.B

$ 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

quelle
1

Befunge 93 - 5 Token

Behoben - Division entfernt.

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

Ruft die Eingabe ab, subtrahiert 3 so lange, bis sie kleiner als 0 ist, richtet den Zeiger nach oben ('|') und addiert 3. Wenn der Wert 0 ist, bewegt sich der Zeiger nach rechts (" 1. @" gibt '1' aus), sonst bewegt er sich nach links ("@ " gibt "0" aus). '@' beendet das Programm.

AndoDaan
quelle
1

Batch - 7 Token

Ich glaube

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

Gibt zurück, 1ob die angegebene Zahl (als stdin) durch drei teilbar ist.

unclemeat
quelle
Sind Schleifen erlaubt?
Sergiol
1

Rubin, 6 (?) Marken

Ich bin mir wirklich nicht sicher, wie ich Token zählen soll. OP, können Sie mich punkten?

Ich denke , es ist 6 ... 1, 0, 0, *, 255,x

Beachten Sie, dass dies *keine ganzzahlige Multiplikation ist.

def div3(x)
  ([1,0,0]*255)[x]
end
Nicht dieser Charles
quelle
Wäre ein Token im Sinne des OP nicht nur eines der oben genannten in der Frage?
C5H8NNaO4
@ C5H8NNaO4 Na und? 0?
Nicht dass Charles
@ C5H8NNaO4 vielleicht 4 für Konstanten?
Nicht dass Charles
1

Python 0

Ich gab eariler bekannt, aber ich benutzte conditionals. Hier geht es darum, keine Bedingungen und keine Token zu verwenden, nur Schlüsselwörter

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

Wendet den Trick an, dass ein Vielfaches von 3 Ziffern hat, die zu 3 addieren

Bearbeiten: Unnötiges Lambda entfernt

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

Bearbeiten: Golf weiter (117 Zeichen) noch keine Token

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

Gekillter direkter Zugriff für Pythons raffiniertes Getitem Länger bei 132 Zeichen

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

Dylan Madisetti
quelle
Der Array-Zugriff []ist jedoch nicht zulässig.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
Es ist? Nach diesen Regeln, codegolf.stackexchange.com/tags/atomic-code-golf/info
Dylan Madisetti
In der Frage wird die Regel im Tag-Wiki nicht verwendet. Die Frage hat eine Einschränkung der zulässigen Operationen. Beachten Sie das Wort only.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃ã̷͉h̷̭̿d̷̰̀ĥ̷̳ Nun, es ist gut, dass Python auch ein natives Attribut hat
Dylan Madisetti
0

Python - 25 Token

Um die Dinge in Gang zu bringen, habe ich eine langwierige Lösung, die eine der Antworten aus dem Link in meinem ersten Beitrag enthält. neingegeben wird.

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)

orist äquivalent zu ||.

qwr
quelle
0

JavaScript - 3 Token

Testen Sie es auf der Konsole Ihres Browsers:

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)
William Barbosa
quelle
Wie sind Sie zu diesem Schluss gekommen? Ich zähle ungefähr 37 Spielmarken.
nyuszika7h
Msgstr "Ein Token ist eine der oben genannten Ausnahmen von Konstanten und Variablen". Wie hast du 37 gezählt?
William Barbosa
1
Oh, ich verstehe. Das OP scheint mit der Info-Seite von Atomic-Code-Golf nicht einverstanden zu sein .
nyuszika7h
Eigentlich bin ich mir jetzt nicht sicher, ob ich Recht habe oder nicht. Mein Ergebnis wäre 70+ nach dem Atomic Code Golf Fiddle.
William Barbosa
1
Das Problem betrifft nicht die Anzahl der Token, sondern die von Ihnen verwendeten Vorgänge. Ich glaube nicht, dass toString, parseInt, Schleifen, Arrays usw. erlaubt sind.
Aditsu
0

JavaScript
nicht sicher über das Token #

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

oder wenn der Ausgang für 0 1 sein darf;

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

C5H8NNaO4
quelle
2
Ich muss sagen, ich bin nicht sicher, welche Regeln für diese Herausforderung gelten. Sind Funktionsaufrufe und Eigenschaftszugriffe erlaubt?
C5H8NNaO4
0

Tcl , 83 Bytes

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

Probieren Sie es online!

Sergiol
quelle
Outgolf fehlgeschlagen: 96 Bytes proc T n {set n [expr [join [split [expr [join [split $n ""] +]] ""] +]];expr {$n in {0 3 6 9}}} Online !
Sergiol
Ein weiterer Fehler: ** 87 Bytes ** proc T n {expr {[expr [join [split [expr [join [split $n ""] +]] ""] +]] in {0 3 6 9}}} Probieren Sie es online!
Sergiol